Bläddra i källkod

added more robust method triMeshData memory management, ability to downcast joints, geoms, and spaces

Josh Wilson 19 år sedan
förälder
incheckning
976760f105
70 ändrade filer med 713 tillägg och 104 borttagningar
  1. 3 1
      panda/src/ode/Sources.pp
  2. 5 0
      panda/src/ode/odeAMotorJoint.cxx
  3. 5 0
      panda/src/ode/odeAMotorJoint.h
  4. 5 0
      panda/src/ode/odeBallJoint.cxx
  5. 5 0
      panda/src/ode/odeBallJoint.h
  6. 8 0
      panda/src/ode/odeBody.I
  7. 5 3
      panda/src/ode/odeBody.cxx
  8. 2 1
      panda/src/ode/odeBody.h
  9. 5 0
      panda/src/ode/odeBoxGeom.cxx
  10. 5 0
      panda/src/ode/odeBoxGeom.h
  11. 5 0
      panda/src/ode/odeCappedCylinderGeom.cxx
  12. 5 0
      panda/src/ode/odeCappedCylinderGeom.h
  13. 0 2
      panda/src/ode/odeContactGeom.I
  14. 1 1
      panda/src/ode/odeContactGeom.h
  15. 5 0
      panda/src/ode/odeContactJoint.cxx
  16. 5 0
      panda/src/ode/odeContactJoint.h
  17. 5 0
      panda/src/ode/odeConvexGeom.cxx
  18. 5 0
      panda/src/ode/odeConvexGeom.h
  19. 5 0
      panda/src/ode/odeCylinderGeom.cxx
  20. 5 0
      panda/src/ode/odeCylinderGeom.h
  21. 5 0
      panda/src/ode/odeFixedJoint.cxx
  22. 5 0
      panda/src/ode/odeFixedJoint.h
  23. 8 0
      panda/src/ode/odeGeom.I
  24. 93 4
      panda/src/ode/odeGeom.cxx
  25. 43 2
      panda/src/ode/odeGeom.h
  26. 5 0
      panda/src/ode/odeHashSpace.cxx
  27. 5 0
      panda/src/ode/odeHashSpace.h
  28. 5 0
      panda/src/ode/odeHeightFieldGeom.h
  29. 5 0
      panda/src/ode/odeHinge2Joint.cxx
  30. 5 0
      panda/src/ode/odeHinge2Joint.h
  31. 5 0
      panda/src/ode/odeHingeJoint.cxx
  32. 5 0
      panda/src/ode/odeHingeJoint.h
  33. 14 1
      panda/src/ode/odeJoint.I
  34. 87 5
      panda/src/ode/odeJoint.cxx
  35. 42 2
      panda/src/ode/odeJoint.h
  36. 7 0
      panda/src/ode/odeJointGroup.I
  37. 2 0
      panda/src/ode/odeJointGroup.h
  38. 5 0
      panda/src/ode/odeLMotorJoint.cxx
  39. 5 0
      panda/src/ode/odeLMotorJoint.h
  40. 5 0
      panda/src/ode/odeNullJoint.cxx
  41. 5 0
      panda/src/ode/odeNullJoint.h
  42. 5 0
      panda/src/ode/odePlane2dJoint.cxx
  43. 5 0
      panda/src/ode/odePlane2dJoint.h
  44. 5 0
      panda/src/ode/odePlaneGeom.cxx
  45. 5 0
      panda/src/ode/odePlaneGeom.h
  46. 5 0
      panda/src/ode/odeQuadTreeSpace.cxx
  47. 5 0
      panda/src/ode/odeQuadTreeSpace.h
  48. 5 0
      panda/src/ode/odeRayGeom.cxx
  49. 5 0
      panda/src/ode/odeRayGeom.h
  50. 5 0
      panda/src/ode/odeSimpleSpace.cxx
  51. 5 0
      panda/src/ode/odeSimpleSpace.h
  52. 5 0
      panda/src/ode/odeSliderJoint.cxx
  53. 5 0
      panda/src/ode/odeSliderJoint.h
  54. 21 8
      panda/src/ode/odeSpace.cxx
  55. 7 0
      panda/src/ode/odeSpace.h
  56. 5 0
      panda/src/ode/odeSphereGeom.cxx
  57. 5 0
      panda/src/ode/odeSphereGeom.h
  58. 77 5
      panda/src/ode/odeTriMeshData.cxx
  59. 20 2
      panda/src/ode/odeTriMeshData.h
  60. 11 3
      panda/src/ode/odeTriMeshGeom.I
  61. 11 20
      panda/src/ode/odeTriMeshGeom.cxx
  62. 8 10
      panda/src/ode/odeTriMeshGeom.h
  63. 5 0
      panda/src/ode/odeUniversalJoint.cxx
  64. 5 0
      panda/src/ode/odeUniversalJoint.h
  65. 11 16
      panda/src/ode/odeUtil.cxx
  66. 6 7
      panda/src/ode/odeUtil.h
  67. 7 4
      panda/src/ode/odeWorld.I
  68. 1 3
      panda/src/ode/odeWorld.cxx
  69. 2 4
      panda/src/ode/odeWorld.h
  70. 1 0
      panda/src/ode/pode_composite2.cxx

+ 3 - 1
panda/src/ode/Sources.pp

@@ -38,6 +38,7 @@
     odePlane2dJoint.I odePlane2dJoint.h \
     odeSliderJoint.I odeSliderJoint.h \
     odeUniversalJoint.I odeUniversalJoint.h \
+    odeJointCollection.h \
     odeSimpleSpace.I odeSimpleSpace.h \
     odeHashSpace.I odeHashSpace.h \
     odeQuadTreeSpace.I odeQuadTreeSpace.h \
@@ -64,7 +65,7 @@
     odeHingeJoint.cxx odeHinge2Joint.cxx \
     odeLMotorJoint.cxx odeNullJoint.cxx \
     odePlane2dJoint.cxx odeSliderJoint.cxx \
-    odeUniversalJoint.cxx \
+    odeUniversalJoint.cxx odeJointCollection.cxx\
     odeSimpleSpace.cxx \
     odeHashSpace.cxx odeQuadTreeSpace.cxx \
     odeSphereGeom.cxx odeBoxGeom.cxx \
@@ -97,6 +98,7 @@
     odePlane2dJoint.I odePlane2dJoint.h \
     odeSliderJoint.I odeSliderJoint.h \
     odeUniversalJoint.I odeUniversalJoint.h \
+    odeJointCollection.h \
     odeSimpleSpace.I odeSimpleSpace.h \
     odeHashSpace.I odeHashSpace.h \
     odeQuadTreeSpace.I odeQuadTreeSpace.h \

+ 5 - 0
panda/src/ode/odeAMotorJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeAMotorJoint::_type_handle;
 
+OdeAMotorJoint::
+OdeAMotorJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeAMotorJoint::
 OdeAMotorJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateAMotor(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeAMotorJoint.h

@@ -14,6 +14,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeAMotorJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeAMotorJoint(dJointID id);
+
 PUBLISHED:
   OdeAMotorJoint(OdeWorld &world);
   OdeAMotorJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 5 - 0
panda/src/ode/odeBallJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeBallJoint::_type_handle;
 
+OdeBallJoint::
+OdeBallJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeBallJoint::
 OdeBallJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateBall(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeBallJoint.h

@@ -14,6 +14,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeBallJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeBallJoint(dJointID id);
+
 PUBLISHED:
   OdeBallJoint(OdeWorld &world);
   OdeBallJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 8 - 0
panda/src/ode/odeBody.I

@@ -404,3 +404,11 @@ INLINE int OdeBody::
 get_gravity_mode() const {
   return dBodyGetGravityMode(_id);
 }
+
+INLINE int OdeBody::
+compare_to(const OdeBody &other) const {
+  if (_id != other._id) {
+    return _id < other._id ? -1 : 1;
+  }
+  return 0;
+}

+ 5 - 3
panda/src/ode/odeBody.cxx

@@ -41,9 +41,11 @@ destroy() {
   dBodyDestroy(_id);
 }
 
-void OdeBody::
-get_joint(int index, OdeJoint &joint) const {
-  joint._id = dBodyGetJoint(_id, index);
+OdeJoint OdeBody::
+get_joint(int index) const {
+  nassertr(_id != 0, OdeJoint(0));
+  nassertr(index < get_num_joints(), OdeJoint(0)); 
+  return OdeJoint(dBodyGetJoint(_id, index));
 }
 
 void OdeBody::

+ 2 - 1
panda/src/ode/odeBody.h

@@ -127,7 +127,7 @@ PUBLISHED:
   INLINE LVecBase3f get_finite_rotation_axis() const;
 
   INLINE int get_num_joints() const;
-  void get_joint(int index, OdeJoint &joint) const;
+  OdeJoint get_joint(int index) const;
   INLINE void enable();
   INLINE void disable();
   INLINE int is_enabled() const;
@@ -135,6 +135,7 @@ PUBLISHED:
   INLINE int get_gravity_mode() const;
 
   virtual void write(ostream &out = cout, unsigned int indent=0) const;
+  INLINE int compare_to(const OdeBody &other) const;
 
 public:
   INLINE dBodyID get_id() const;

+ 5 - 0
panda/src/ode/odeBoxGeom.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeBoxGeom::_type_handle;
 
+OdeBoxGeom::
+OdeBoxGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeBoxGeom::
 OdeBoxGeom(dReal lx, dReal ly, dReal lz) :
   OdeGeom(dCreateBox(0, lx, ly, lz)) {

+ 5 - 0
panda/src/ode/odeBoxGeom.h

@@ -31,6 +31,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeBoxGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeBoxGeom(dGeomID id);
+
 PUBLISHED:
   OdeBoxGeom(dReal lx, dReal ly, dReal lz);
   OdeBoxGeom(OdeSpace &space, dReal lx, dReal ly, dReal lz);

+ 5 - 0
panda/src/ode/odeCappedCylinderGeom.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeCappedCylinderGeom::_type_handle;
 
+OdeCappedCylinderGeom::
+OdeCappedCylinderGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeCappedCylinderGeom::
 OdeCappedCylinderGeom(dReal radius, dReal length) :
   OdeGeom(dCreateCapsule(0, radius, length)) {

+ 5 - 0
panda/src/ode/odeCappedCylinderGeom.h

@@ -31,6 +31,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeCappedCylinderGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeCappedCylinderGeom(dGeomID id);
+
 PUBLISHED:
   OdeCappedCylinderGeom(dReal radius, dReal length);
   OdeCappedCylinderGeom(OdeSpace &space, dReal radius, dReal length);

+ 0 - 2
panda/src/ode/odeContactGeom.I

@@ -83,5 +83,3 @@ INLINE void OdeContactGeom::
 set_g2(const OdeGeom &geom){
   _contact_geom.g2 = geom._id;
 }
-
-

+ 1 - 1
panda/src/ode/odeContactGeom.h

@@ -54,7 +54,7 @@ PUBLISHED:
   INLINE void set_depth(const dReal depth);          
   INLINE void set_g1(const OdeGeom &geom);
   INLINE void set_g2(const OdeGeom &geom);
-
+  
 public:
   const dContactGeom* get_contact_geom_ptr() const;
 

+ 5 - 0
panda/src/ode/odeContactJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeContactJoint::_type_handle;
 
+OdeContactJoint::
+OdeContactJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeContactJoint::
 OdeContactJoint(OdeWorld &world, const OdeContact &contact) : 
   OdeJoint(dJointCreateContact(world.get_id(), 0, contact.get_contact_ptr())) {

+ 5 - 0
panda/src/ode/odeContactJoint.h

@@ -15,6 +15,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeContactJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeContactJoint(dJointID id);
+
 PUBLISHED:
   OdeContactJoint(OdeWorld &world, const OdeContact &contact);
   OdeContactJoint(OdeWorld &world, OdeJointGroup &joint_group, const OdeContact &contact);

+ 5 - 0
panda/src/ode/odeConvexGeom.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeConvexGeom::_type_handle;
 
+OdeConvexGeom::
+OdeConvexGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeConvexGeom::
 OdeConvexGeom(dReal radius, dReal length) :
   OdeGeom(dCreateConvex(0, radius, length)) {

+ 5 - 0
panda/src/ode/odeConvexGeom.h

@@ -31,6 +31,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeConvexGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeConvexGeom(dGeomID id);
+
 PUBLISHED:
   OdeConvexGeom();
   virtual ~OdeConvexGeom();

+ 5 - 0
panda/src/ode/odeCylinderGeom.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeCylinderGeom::_type_handle;
 
+OdeCylinderGeom::
+OdeCylinderGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeCylinderGeom::
 OdeCylinderGeom(dReal radius, dReal length) :
   OdeGeom(dCreateCylinder(0, radius, length)) {

+ 5 - 0
panda/src/ode/odeCylinderGeom.h

@@ -31,6 +31,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeCylinderGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeCylinderGeom(dGeomID id);
+
 PUBLISHED:
   OdeCylinderGeom(dReal radius, dReal length);
   OdeCylinderGeom(OdeSpace &space, dReal radius, dReal length);

+ 5 - 0
panda/src/ode/odeFixedJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeFixedJoint::_type_handle;
 
+OdeFixedJoint::
+OdeFixedJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeFixedJoint::
 OdeFixedJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateFixed(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeFixedJoint.h

@@ -14,6 +14,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeFixedJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeFixedJoint(dJointID id);
+
 PUBLISHED:
   OdeFixedJoint(OdeWorld &world);
   OdeFixedJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 8 - 0
panda/src/ode/odeGeom.I

@@ -213,3 +213,11 @@ get_offset_quaternion() const {
   dGeomGetOffsetQuaternion(_id, res);
   return LQuaternionf(res[0], res[1], res[2], res[3]);
 }
+
+INLINE int OdeGeom::
+compare_to(const OdeGeom &other) const {
+  if (_id != other._id) {
+    return _id < other._id ? -1 : 1;
+  }
+  return 0;
+}

+ 93 - 4
panda/src/ode/odeGeom.cxx

@@ -29,18 +29,19 @@ OdeGeom(dGeomID id) :
 
 OdeGeom::
 ~OdeGeom() {
+  odegeom_cat.debug() << "~" << get_type() << "(" << _id << ")\n";
 }
 
 void OdeGeom::
 destroy() {
   if (get_class() == OdeTriMeshGeom::get_geom_class()) {
-    OdeTriMeshGeom::unlink_data(_id);
+    OdeTriMeshData::unlink_data(_id);
   }
 }
 
-void OdeGeom::
-get_space(OdeSpace &space) const {
-  space._id = dGeomGetSpace(_id);  
+OdeSpace OdeGeom::
+get_space() const {
+  return OdeSpace(dGeomGetSpace(_id));
 }
 
 
@@ -52,3 +53,91 @@ write(ostream &out, unsigned int indent) const {
   #endif //] NDEBUG
 }
 
+OdeBoxGeom OdeGeom::
+convert_to_box() const {
+  nassertr(_id != 0, OdeBoxGeom((dGeomID)0));
+  nassertr(get_class() == GC_box, OdeBoxGeom((dGeomID)0));
+  return OdeBoxGeom(_id);
+}
+
+OdeCappedCylinderGeom OdeGeom::
+convert_to_capped_cylinder() const {
+  nassertr(_id != 0, OdeCappedCylinderGeom((dGeomID)0));
+  nassertr(get_class() == GC_capped_cylinder, OdeCappedCylinderGeom((dGeomID)0));
+  return OdeCappedCylinderGeom(_id);
+}
+
+/*
+OdeConvexGeom OdeGeom::
+convert_to_convex() const {
+  nassertr(_id != 0, OdeConvexGeom((dGeomID)0));
+  nassertr(get_class() == GC_convex, OdeConvexGeom((dGeomID)0));
+  return OdeConvexGeom(_id);
+}
+*/
+
+OdeCylinderGeom OdeGeom::
+convert_to_cylinder() const {
+  nassertr(_id != 0, OdeCylinderGeom((dGeomID)0));
+  nassertr(get_class() == GC_cylinder, OdeCylinderGeom((dGeomID)0));
+  return OdeCylinderGeom(_id);
+}
+
+/*
+OdeHeightfieldGeom OdeGeom::
+convert_to_heightfield() const {
+  nassertr(_id != 0, OdeHeightfieldGeom((dGeomID)0));
+  nassertr(get_class() == GC_heightfield, OdeHeightfieldGeom((dGeomID)0));
+  return OdeHeightfieldGeom(_id);
+}
+*/
+
+OdePlaneGeom OdeGeom::
+convert_to_plane() const {
+  nassertr(_id != 0, OdePlaneGeom((dGeomID)0));
+  nassertr(get_class() == GC_plane, OdePlaneGeom((dGeomID)0));
+  return OdePlaneGeom(_id);
+}
+
+OdeRayGeom OdeGeom::
+convert_to_ray() const {
+  nassertr(_id != 0, OdeRayGeom((dGeomID)0));
+  nassertr(get_class() == GC_ray, OdeRayGeom((dGeomID)0));
+  return OdeRayGeom(_id);
+}
+
+OdeSphereGeom OdeGeom::
+convert_to_sphere() const {
+  nassertr(_id != 0, OdeSphereGeom((dGeomID)0));
+  nassertr(get_class() == GC_sphere, OdeSphereGeom((dGeomID)0));
+  return OdeSphereGeom(_id);
+}
+
+OdeTriMeshGeom OdeGeom::
+convert_to_tri_mesh() const {
+  nassertr(_id != 0, OdeTriMeshGeom((dGeomID)0));
+  nassertr(get_class() == GC_tri_mesh, OdeTriMeshGeom((dGeomID)0));
+  return OdeTriMeshGeom(_id);
+}
+
+OdeSimpleSpace OdeGeom::
+convert_to_simple_space() const {
+  nassertr(_id != 0, OdeSimpleSpace((dSpaceID)0));
+  nassertr(get_class() == GC_simple_space, OdeSimpleSpace((dSpaceID)0));
+  return OdeSimpleSpace((dSpaceID)_id);
+}
+
+OdeHashSpace OdeGeom::
+convert_to_hash_space() const {
+  nassertr(_id != 0, OdeHashSpace((dSpaceID)0));
+  nassertr(get_class() == GC_hash_space, OdeHashSpace((dSpaceID)0));
+  return OdeHashSpace((dSpaceID)_id);
+}
+
+OdeQuadTreeSpace OdeGeom::
+convert_to_quad_tree_space() const {
+  nassertr(_id != 0, OdeQuadTreeSpace((dSpaceID)0));
+  nassertr(get_class() == GC_quad_tree_space, OdeQuadTreeSpace((dSpaceID)0));
+  return OdeQuadTreeSpace((dSpaceID)_id);
+}
+

+ 43 - 2
panda/src/ode/odeGeom.h

@@ -25,10 +25,21 @@
 #include "bitMask.h"
 
 #include "ode_includes.h"
-#include "odeSpace.h" // Needed for derived classes
+#include "odeSpace.h"
 #include "odeBody.h"
 
+class OdeBoxGeom;
+class OdeCappedCylinderGeom;
+// class OdeConvexGeom;
+class OdeCylinderGeom;
+// class OdeHeightfieldGeom;
+class OdePlaneGeom;
+class OdeRayGeom;
+class OdeSphereGeom;
 class OdeTriMeshGeom;
+class OdeSimpleSpace;
+class OdeHashSpace;
+class OdeQuadTreeSpace;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : OdeGeom
@@ -42,6 +53,22 @@ protected:
   OdeGeom(dGeomID id);
 
 PUBLISHED:
+  enum GeomClass { GC_sphere = 0, 
+		   GC_box,
+		   GC_capped_cylinder,
+		   GC_cylinder,
+		   GC_plane,
+		   GC_ray,
+		   // GC_convex,
+		   // GC_geom_transform,
+		   GC_tri_mesh = 8,
+		   // GC_heightfield,
+		   
+		   GC_simple_space = 10,
+		   GC_hash_space,
+		   GC_quad_tree_space,
+  };
+
   virtual ~OdeGeom();
   void destroy();
 
@@ -79,9 +106,23 @@ PUBLISHED:
   INLINE LMatrix3f get_offset_rotation() const;
   INLINE LQuaternionf get_offset_quaternion() const;
 
-  void get_space(OdeSpace &space) const;
+  OdeSpace get_space() const;
 
   virtual void write(ostream &out = cout, unsigned int indent=0) const;
+  INLINE int compare_to(const OdeGeom &other) const;
+
+  OdeBoxGeom convert_to_box() const;
+  OdeCappedCylinderGeom convert_to_capped_cylinder() const;
+  // OdeConvexGeom convert_to_convex() const;
+  OdeCylinderGeom convert_to_cylinder() const;
+  // OdeHeightfieldGeom convert_to_heightfield() const;
+  OdePlaneGeom convert_to_plane() const;
+  OdeRayGeom convert_to_ray() const;
+  OdeSphereGeom convert_to_sphere() const;
+  OdeTriMeshGeom convert_to_tri_mesh() const;
+  OdeSimpleSpace convert_to_simple_space() const;
+  OdeHashSpace convert_to_hash_space() const;
+  OdeQuadTreeSpace convert_to_quad_tree_space() const;
 
 public:
   INLINE dGeomID get_id() const;

+ 5 - 0
panda/src/ode/odeHashSpace.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeHashSpace::_type_handle;
 
+OdeHashSpace::
+OdeHashSpace(dSpaceID id) :
+  OdeSpace(id) {
+}
+
 OdeHashSpace::
 OdeHashSpace() :
   OdeSpace(dHashSpaceCreate(0)) {

+ 5 - 0
panda/src/ode/odeHashSpace.h

@@ -32,6 +32,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////c
 class EXPCL_PANDAODE OdeHashSpace : public OdeSpace {
+  friend class OdeSpace;
+
+private:
+  OdeHashSpace(dSpaceID id);
+
 PUBLISHED:
   OdeHashSpace();
   OdeHashSpace(OdeSpace &space);

+ 5 - 0
panda/src/ode/odeHeightFieldGeom.h

@@ -31,6 +31,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeHeightfieldGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeHeightfieldGeom(dGeomID id);
+
 PUBLISHED:
   OdeHeightfieldGeom();
   virtual ~OdeHeightfieldGeom();

+ 5 - 0
panda/src/ode/odeHinge2Joint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeHinge2Joint::_type_handle;
 
+OdeHinge2Joint::
+OdeHinge2Joint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeHinge2Joint::
 OdeHinge2Joint(OdeWorld &world) : 
   OdeJoint(dJointCreateHinge2(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeHinge2Joint.h

@@ -14,6 +14,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeHinge2Joint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeHinge2Joint(dJointID id);
+
 PUBLISHED:
   OdeHinge2Joint(OdeWorld &world, OdeJointGroup &joint_group);
   OdeHinge2Joint(OdeWorld &world);

+ 5 - 0
panda/src/ode/odeHingeJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeHingeJoint::_type_handle;
 
+OdeHingeJoint::
+OdeHingeJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeHingeJoint::
 OdeHingeJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateHinge(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeHingeJoint.h

@@ -13,6 +13,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeHingeJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeHingeJoint(dJointID id);
+
 PUBLISHED:
   OdeHingeJoint(OdeWorld &world);
   OdeHingeJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 14 - 1
panda/src/ode/odeJoint.I

@@ -48,4 +48,17 @@ INLINE dJointFeedback *OdeJoint::
 get_feedback() {
   return dJointGetFeedback(_id);
 }
-*/
+*/
+
+INLINE int OdeJoint::
+compare_to(const OdeJoint &other) const {
+  if (_id != other._id) {
+    return _id < other._id ? -1 : 1;
+  }
+  return 0;
+}
+
+INLINE bool OdeJoint::
+operator == (const OdeJoint &other) const {
+  return _id == other._id;
+}

+ 87 - 5
panda/src/ode/odeJoint.cxx

@@ -21,6 +21,13 @@
 
 TypeHandle OdeJoint::_type_handle;
 
+OdeJoint::
+OdeJoint() : 
+  _id(0) {
+  ostream &out = odejoint_cat.debug();
+  out << get_type() << "(" << _id  << ")\n";
+}
+
 OdeJoint::
 OdeJoint(dJointID id) : 
   _id(id) {
@@ -55,14 +62,15 @@ attach_bodies(const OdeBody &body1, const OdeBody &body2) {
 //     Function: OdeJoint::attach_body
 //       Access: Published
 //  Description: Attaches a single OdeBody to this joint at the
-//               specified index.  The other index will be set to the
-//               environment (null).
+//               specified index (0 or 1).  The other index will be 
+//               set to the environment (null).
 //               Consider using the OdeJoint::attach extension
 //               function if you're using the Python interface.
 ////////////////////////////////////////////////////////////////////
 void OdeJoint::
 attach_body(const OdeBody &body, int index) {
   nassertv(body.get_id() != 0);
+  nassertv(index == 0 || index == 1);
   if (index == 0) {
     dJointAttach(_id, body.get_id(), 0);
   } else {
@@ -77,6 +85,7 @@ detach() {
 
 OdeBody OdeJoint::
 get_body(int index) const {
+  nassertr(_id, OdeBody(0));
   nassertr(index == 0 || index == 1, OdeBody(0));
   return OdeBody(dJointGetBody(_id, index));
 }
@@ -107,7 +116,80 @@ write(ostream &out, unsigned int indent) const {
   #endif //] NDEBUG
 }
 
-bool OdeJoint::
-operator==(const OdeJoint &other) {
-  return _id == other._id;
+OdeBallJoint OdeJoint::
+convert_to_ball() const {
+  nassertr(_id != 0, OdeBallJoint(0));
+  nassertr(get_joint_type() == JT_ball, OdeBallJoint(0));
+  return OdeBallJoint(_id);
+}
+
+OdeHingeJoint OdeJoint::
+convert_to_hinge() const {
+  nassertr(_id != 0, OdeHingeJoint(0));
+  nassertr(get_joint_type() == JT_hinge, OdeHingeJoint(0));
+  return OdeHingeJoint(_id);
+}
+
+OdeSliderJoint OdeJoint::
+convert_to_slider() const {
+  nassertr(_id != 0, OdeSliderJoint(0));
+  nassertr(get_joint_type() == JT_slider, OdeSliderJoint(0));
+  return OdeSliderJoint(_id);
+}
+
+OdeContactJoint OdeJoint::
+convert_to_contact() const {
+  nassertr(_id != 0, OdeContactJoint(0));
+  nassertr(get_joint_type() == JT_contact, OdeContactJoint(0));
+  return OdeContactJoint(_id);
+}
+
+OdeUniversalJoint OdeJoint::
+convert_to_universal() const {
+  nassertr(_id != 0, OdeUniversalJoint(0));
+  nassertr(get_joint_type() == JT_universal, OdeUniversalJoint(0));
+  return OdeUniversalJoint(_id);
 }
+
+OdeHinge2Joint OdeJoint::
+convert_to_hinge2() const {
+  nassertr(_id != 0, OdeHinge2Joint(0));
+  nassertr(get_joint_type() == JT_hinge2, OdeHinge2Joint(0));
+  return OdeHinge2Joint(_id);
+}
+
+OdeFixedJoint OdeJoint::
+convert_to_fixed() const {
+  nassertr(_id != 0, OdeFixedJoint(0));
+  nassertr(get_joint_type() == JT_fixed, OdeFixedJoint(0));
+  return OdeFixedJoint(_id);
+}
+
+OdeNullJoint OdeJoint::
+convert_to_null() const {
+  nassertr(_id != 0, OdeNullJoint(0));
+  nassertr(get_joint_type() == JT_null, OdeNullJoint(0));
+  return OdeNullJoint(_id);
+}
+
+OdeAMotorJoint OdeJoint::
+convert_to_a_motor() const {
+  nassertr(_id != 0, OdeAMotorJoint(0));
+  nassertr(get_joint_type() == JT_a_motor, OdeAMotorJoint(0));
+  return OdeAMotorJoint(_id);
+}
+
+OdeLMotorJoint OdeJoint::
+convert_to_l_motor() const {
+  nassertr(_id != 0, OdeLMotorJoint(0));
+  nassertr(get_joint_type() == JT_l_motor, OdeLMotorJoint(0));
+  return OdeLMotorJoint(_id);
+}
+
+OdePlane2dJoint OdeJoint::
+convert_to_plane2d() const {
+  nassertr(_id != 0, OdePlane2dJoint(0));
+  nassertr(get_joint_type() == JT_plane2d, OdePlane2dJoint(0));
+  return OdePlane2dJoint(_id);
+}
+

+ 42 - 2
panda/src/ode/odeJoint.h

@@ -24,12 +24,23 @@
 #include "luse.h"
 
 #include "ode_includes.h"
-#include "odeWorld.h" // Needed for derived classes
+#include "odeWorld.h"      // Needed for derived classes
 #include "odeJointGroup.h"
 
 // Strange, we should be forced to include this by get_body()
 class OdeBody; 
 
+class OdeBallJoint;
+class OdeHingeJoint;
+class OdeSliderJoint;
+class OdeContactJoint;
+class OdeUniversalJoint;
+class OdeHinge2Joint;
+class OdeFixedJoint;
+class OdeNullJoint;
+class OdeAMotorJoint;
+class OdeLMotorJoint;
+class OdePlane2dJoint;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : OdeJoint
@@ -39,10 +50,26 @@ class EXPCL_PANDAODE OdeJoint : public TypedObject {
   friend class OdeBody;
   friend class OdeUtil;
 
+public:
+  OdeJoint();
+
 protected:
   OdeJoint(dJointID id);
 
 PUBLISHED:
+  enum JointType { JT_none = 0,	/* or "unknown" */
+		   JT_ball,
+		   JT_hinge,
+		   JT_slider,
+		   JT_contact,
+		   JT_universal,
+		   JT_hinge2,
+		   JT_fixed,
+		   JT_null,
+		   JT_a_motor,
+		   JT_l_motor,
+		   JT_plane2d };
+
   virtual ~OdeJoint();
   void destroy();
   
@@ -58,7 +85,20 @@ PUBLISHED:
   void detach();
 
   virtual void write(ostream &out = cout, unsigned int indent=0) const;
-  bool operator==(const OdeJoint &other);
+  INLINE int compare_to(const OdeJoint &other) const;
+  INLINE bool operator == (const OdeJoint &other) const;
+
+  OdeBallJoint convert_to_ball() const;
+  OdeHingeJoint convert_to_hinge() const;
+  OdeSliderJoint convert_to_slider() const;
+  OdeContactJoint convert_to_contact() const;
+  OdeUniversalJoint convert_to_universal() const;
+  OdeHinge2Joint convert_to_hinge2() const;
+  OdeFixedJoint convert_to_fixed() const;
+  OdeNullJoint convert_to_null() const;
+  OdeAMotorJoint convert_to_a_motor() const;
+  OdeLMotorJoint convert_to_l_motor() const;
+  OdePlane2dJoint convert_to_plane2d() const;
 
 public: 
   INLINE dJointID get_id() const;

+ 7 - 0
panda/src/ode/odeJointGroup.I

@@ -26,3 +26,10 @@ empty() const {
   dJointGroupEmpty(_id);
 }
 
+INLINE int OdeJointGroup::
+compare_to(const OdeJointGroup &other) const {
+  if (_id != other._id) {
+    return _id < other._id ? -1 : 1;
+  }
+  return 0;
+}

+ 2 - 0
panda/src/ode/odeJointGroup.h

@@ -37,6 +37,8 @@ PUBLISHED:
 
   INLINE void empty() const;
 
+  INLINE int compare_to(const OdeJointGroup &other) const;
+
 public: 
   INLINE dJointGroupID get_id() const;
 

+ 5 - 0
panda/src/ode/odeLMotorJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeLMotorJoint::_type_handle;
 
+OdeLMotorJoint::
+OdeLMotorJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeLMotorJoint::
 OdeLMotorJoint(OdeWorld &world  ) : 
   OdeJoint(dJointCreateLMotor(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeLMotorJoint.h

@@ -13,6 +13,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeLMotorJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeLMotorJoint(dJointID id);
+
 PUBLISHED:
   OdeLMotorJoint(OdeWorld &world);
   OdeLMotorJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 5 - 0
panda/src/ode/odeNullJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeNullJoint::_type_handle;
 
+OdeNullJoint::
+OdeNullJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeNullJoint::
 OdeNullJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateNull(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeNullJoint.h

@@ -13,6 +13,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeNullJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeNullJoint(dJointID id);
+
 PUBLISHED:
   OdeNullJoint(OdeWorld &world);
   OdeNullJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 5 - 0
panda/src/ode/odePlane2dJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdePlane2dJoint::_type_handle;
 
+OdePlane2dJoint::
+OdePlane2dJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdePlane2dJoint::
 OdePlane2dJoint(OdeWorld &world) : 
   OdeJoint(dJointCreatePlane2D(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odePlane2dJoint.h

@@ -13,6 +13,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdePlane2dJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdePlane2dJoint(dJointID id);
+
 PUBLISHED:
   OdePlane2dJoint(OdeWorld &world);
   OdePlane2dJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 5 - 0
panda/src/ode/odePlaneGeom.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdePlaneGeom::_type_handle;
 
+OdePlaneGeom::
+OdePlaneGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdePlaneGeom::
 OdePlaneGeom(dReal a, dReal b, dReal c, dReal d) :
   OdeGeom(dCreatePlane(0, a, b, c, d)) {

+ 5 - 0
panda/src/ode/odePlaneGeom.h

@@ -30,6 +30,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdePlaneGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdePlaneGeom(dGeomID id);
+
 PUBLISHED:
   OdePlaneGeom(dReal a, dReal b, dReal c, dReal d);
   OdePlaneGeom(const LVecBase4f &params);

+ 5 - 0
panda/src/ode/odeQuadTreeSpace.cxx

@@ -34,6 +34,11 @@ sdVector4 LVec3_to_sdVector4(const LVecBase3f& vec) {
   return sdVec4;
 }
 
+OdeQuadTreeSpace::
+OdeQuadTreeSpace(dSpaceID id) :
+  OdeSpace(id) {
+}
+
 OdeQuadTreeSpace::
 OdeQuadTreeSpace(const LPoint3f &center,
 		 const LVecBase3f &extents,

+ 5 - 0
panda/src/ode/odeQuadTreeSpace.h

@@ -31,6 +31,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////c
 class EXPCL_PANDAODE OdeQuadTreeSpace : public OdeSpace {
+  friend class OdeSpace;
+
+private:
+  OdeQuadTreeSpace(dSpaceID id);
+
 PUBLISHED:
   OdeQuadTreeSpace(const LPoint3f &center,
                    const LVecBase3f &extents,

+ 5 - 0
panda/src/ode/odeRayGeom.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeRayGeom::_type_handle;
 
+OdeRayGeom::
+OdeRayGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeRayGeom::
 OdeRayGeom(dReal length) :
   OdeGeom(dCreateRay(0, length)) {

+ 5 - 0
panda/src/ode/odeRayGeom.h

@@ -30,6 +30,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeRayGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeRayGeom(dGeomID id);
+
 PUBLISHED:
   OdeRayGeom(dReal length);
   OdeRayGeom(OdeSpace &space, dReal length);

+ 5 - 0
panda/src/ode/odeSimpleSpace.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeSimpleSpace::_type_handle;
 
+OdeSimpleSpace::
+OdeSimpleSpace(dSpaceID id) :
+  OdeSpace(id) {
+}
+
 OdeSimpleSpace::
 OdeSimpleSpace() :
   OdeSpace(dSimpleSpaceCreate(0)) {

+ 5 - 0
panda/src/ode/odeSimpleSpace.h

@@ -31,6 +31,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////c
 class EXPCL_PANDAODE OdeSimpleSpace : public OdeSpace {
+  friend class OdeSpace;
+
+private:
+  OdeSimpleSpace(dSpaceID id);
+
 PUBLISHED:
   OdeSimpleSpace();
   OdeSimpleSpace(OdeSpace &space);

+ 5 - 0
panda/src/ode/odeSliderJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeSliderJoint::_type_handle;
 
+OdeSliderJoint::
+OdeSliderJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeSliderJoint::
 OdeSliderJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateSlider(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeSliderJoint.h

@@ -13,6 +13,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeSliderJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeSliderJoint(dJointID id);
+
 PUBLISHED:
   OdeSliderJoint(OdeWorld &world);
   OdeSliderJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 21 - 8
panda/src/ode/odeSpace.cxx

@@ -32,14 +32,6 @@ OdeSpace::
 
 void OdeSpace::
 destroy() {
-  if (get_cleanup()) {
-    for (int i = 0; i < get_num_geoms(); ++i) {
-      OdeGeom geom(get_geom(i));
-      if (geom.get_class() == OdeTriMeshGeom::get_geom_class()) {
-        OdeTriMeshGeom::unlink_data(geom.get_id());
-      }
-    }
-  }
   dSpaceDestroy(_id);
 }
 
@@ -90,3 +82,24 @@ write(ostream &out, unsigned int indent) const {
   #endif //] NDEBUG
 }
 
+OdeSimpleSpace OdeSpace::
+convert_to_simple_space() const {
+  nassertr(_id != 0, OdeSimpleSpace((dSpaceID)0));
+  nassertr(get_class() == OdeGeom::GC_simple_space, OdeSimpleSpace((dSpaceID)0));
+  return OdeSimpleSpace(_id);
+}
+
+OdeHashSpace OdeSpace::
+convert_to_hash_space() const {
+  nassertr(_id != 0, OdeHashSpace((dSpaceID)0));
+  nassertr(get_class() == OdeGeom::GC_hash_space, OdeHashSpace((dSpaceID)0));
+  return OdeHashSpace(_id);
+}
+
+OdeQuadTreeSpace OdeSpace::
+convert_to_quad_tree_space() const {
+  nassertr(_id != 0, OdeQuadTreeSpace((dSpaceID)0));
+  nassertr(get_class() == OdeGeom::GC_quad_tree_space, OdeQuadTreeSpace((dSpaceID)0));
+  return OdeQuadTreeSpace(_id);
+}
+

+ 7 - 0
panda/src/ode/odeSpace.h

@@ -28,6 +28,9 @@
 
 class OdeGeom;
 class OdeTriMeshGeom;
+class OdeSimpleSpace;
+class OdeHashSpace;
+class OdeQuadTreeSpace;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : OdeSpace
@@ -70,6 +73,10 @@ PUBLISHED:
 
   virtual void write(ostream &out = cout, unsigned int indent=0) const;
 
+  OdeSimpleSpace convert_to_simple_space() const;
+  OdeHashSpace convert_to_hash_space() const;
+  OdeQuadTreeSpace convert_to_quad_tree_space() const;
+
 public: 
   INLINE dSpaceID get_id() const;
 

+ 5 - 0
panda/src/ode/odeSphereGeom.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeSphereGeom::_type_handle;
 
+OdeSphereGeom::
+OdeSphereGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeSphereGeom::
 OdeSphereGeom(dReal radius) :
   OdeGeom(dCreateSphere(0, radius)) {

+ 5 - 0
panda/src/ode/odeSphereGeom.h

@@ -30,6 +30,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeSphereGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeSphereGeom(dGeomID id);
+
 PUBLISHED:
   OdeSphereGeom(dReal radius);
   OdeSphereGeom(OdeSpace &space, dReal radius);

+ 77 - 5
panda/src/ode/odeTriMeshData.cxx

@@ -19,6 +19,57 @@
 #include "odeTriMeshData.h"
 
 TypeHandle OdeTriMeshData::_type_handle;
+OdeTriMeshData::TriMeshDataMap OdeTriMeshData::_tri_mesh_data_map;
+
+void OdeTriMeshData::
+link_data(dGeomID id, PT(OdeTriMeshData) data) {
+  odetrimeshdata_cat.debug() << get_class_type() << "::link_data(" << id << "->" << data << ")" << "\n";
+  _tri_mesh_data_map[id] = data;
+}
+
+PT(OdeTriMeshData) OdeTriMeshData::
+get_data(dGeomID id) {
+  TriMeshDataMap::iterator iter = _tri_mesh_data_map.find(id);
+  if (iter != _tri_mesh_data_map.end()) {
+    return iter->second;
+  }
+  return 0;
+}
+
+void OdeTriMeshData::
+unlink_data(dGeomID id) {
+  odetrimeshdata_cat.debug() << get_class_type() << "::unlink_data(" << id << ")" << "\n";
+  TriMeshDataMap::iterator iter = _tri_mesh_data_map.find(id);
+  if (iter != _tri_mesh_data_map.end()) {
+    _tri_mesh_data_map.erase(iter);
+  }
+}
+
+void OdeTriMeshData::
+print_data(const string &marker) {
+  odetrimeshdata_cat.debug() << get_class_type() << "::print_data(" << marker << ")\n";
+  TriMeshDataMap::iterator iter = _tri_mesh_data_map.begin();
+  for (;iter != _tri_mesh_data_map.end(); ++iter) {
+    odetrimeshdata_cat.debug() << "\t" << iter->first << " : " << iter->second << "\n";
+  }
+}
+
+void OdeTriMeshData::
+remove_data(OdeTriMeshData *data) {
+  odetrimeshdata_cat.debug() << get_class_type() << "::remove_data(" << data->get_id() << ")" << "\n";
+  TriMeshDataMap::iterator iter = _tri_mesh_data_map.begin();  
+  for (;iter != _tri_mesh_data_map.end(); ++iter) {
+    cout << iter->second << "\t" << data << "\n";
+    if ( iter->second == data ) {
+      cout << "ERASING\n";
+      _tri_mesh_data_map.erase(iter);
+      iter = _tri_mesh_data_map.end();
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
 
 OdeTriMeshData::
 OdeTriMeshData(const NodePath& model, bool use_normals) :
@@ -41,17 +92,24 @@ OdeTriMeshData(const NodePath& model, bool use_normals) :
     build_single1(_vertices, sizeof(StridedVertex), _num_vertices,
 		  _faces, _num_faces * 3, sizeof(StridedTri),
 		  _normals);
-  }    
+  }
+
   preprocess();
 }
 
+// Private copy constructor, shouldn't be copying these objects
+OdeTriMeshData::
+OdeTriMeshData(const OdeTriMeshData &other) {
+}
+
 OdeTriMeshData::
 ~OdeTriMeshData() {
   odetrimeshdata_cat.debug() << "~" << get_type() << "(" << _id << ")" << "\n";
-  dGeomTriMeshDataDestroy(_id);
+  destroy();
   if (_vertices != 0) {
     delete[] _vertices;
     _vertices = 0;
+    _num_vertices = 0;
   }
   if (_faces != 0) {
     delete[] _faces;
@@ -59,10 +117,24 @@ OdeTriMeshData::
   }
   if (_normals != 0) {
     delete[] _normals;
-    _normals = 0;
   }
 }
 
+void OdeTriMeshData::
+destroy() {
+  odetrimeshdata_cat.debug() << get_type() << "::destroy(" << _id << ")" << "\n";
+  if (_id != 0) {
+    dGeomTriMeshDataDestroy(_id);
+    remove_data(this);
+    _id = 0; 
+  }
+}
+
+// Private assignment operator, shouldn't be copying these objects
+void OdeTriMeshData::
+operator = (const OdeTriMeshData &other) {
+}
+
 void OdeTriMeshData::
 process_model(const NodePath& model, bool &use_normals) {
   // TODO: assert if _vertices is something other than 0.
@@ -231,6 +303,6 @@ write_faces(ostream &out) const {
 void OdeTriMeshData::
 write(ostream &out, unsigned int indent) const {
   out.width(indent); out << "" << get_type() << "(id = " << _id << ") : " \
-			 << "" << "Vertices: " << _num_vertices << ", " \
-			 << "" << "Triangles: " << _num_faces << "\n";
+			 << "" << "Vertices: " << (_id ? _num_vertices : 0) << ", " \
+			 << "" << "Triangles: " << (_id ? _num_faces : 0);
 }

+ 20 - 2
panda/src/ode/odeTriMeshData.h

@@ -37,12 +37,27 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeTriMeshData : public TypedReferenceCount {
+public:
+  static void link_data(dGeomID id, PT(OdeTriMeshData) data);
+  static PT(OdeTriMeshData) get_data(dGeomID id);
+  static void unlink_data(dGeomID id);
+  static void remove_data(OdeTriMeshData *data);
+  static void print_data(const string &marker);
+
+private:
+  typedef pmap<dGeomID, PT(OdeTriMeshData)> TriMeshDataMap;
+  static TriMeshDataMap _tri_mesh_data_map;
+
 PUBLISHED:
+
+  enum DataType { DT_face_normals = 0,
+		  DT_last_transformation };
+
   OdeTriMeshData(const NodePath& model, bool use_normals = false);
   virtual ~OdeTriMeshData();
 
-  enum DataType { DT_face_normals,
-		  DT_last_transformation };
+  void destroy();
+  
   // INLINE void set(int data_id, void* in_data);
   // INLINE void* get(int data_id);
   // INLINE void get_buffer(unsigned char** buf, int* buf_len) const;
@@ -81,6 +96,9 @@ private:
   void analyze(const Geom *geom);
   void analyze(const GeomPrimitive *geom);
 
+  OdeTriMeshData(const OdeTriMeshData &other);
+  void operator = (const OdeTriMeshData &other);
+  
 protected:
   struct StridedVertex{
     dReal Vertex[3];

+ 11 - 3
panda/src/ode/odeTriMeshGeom.I

@@ -18,33 +18,38 @@
 
 INLINE void OdeTriMeshGeom::
 set_data(OdeTriMeshData &data) {
-  // unlink_data(_id); // not necessary?
+  nassertv(_id != 0);
   dGeomTriMeshSetData(_id, data.get_id());
-  link_data(_id, data);
+  OdeTriMeshData::link_data(_id, &data);
 }
 
 INLINE PT(OdeTriMeshData) OdeTriMeshGeom::
 get_data() const {
-  return MeshData[_id];
+  nassertr(_id != 0 ,0);
+  return OdeTriMeshData::get_data(_id);
 }
 
 INLINE void OdeTriMeshGeom::
 enable_TC(int geom_class, int enable){
+  nassertv(_id != 0);
   dGeomTriMeshEnableTC(_id, geom_class, enable);
 }
 
 INLINE int OdeTriMeshGeom::
 is_TC_enabled(int geom_class) const {
+  nassertr(_id != 0, 0);
   return dGeomTriMeshIsTCEnabled(_id, geom_class);
 }
 
 INLINE void OdeTriMeshGeom::
 clear_TC_cache(const OdeGeom &geom){
+  nassertv(_id != 0);
   dGeomTriMeshClearTCCache(_id);
 }
 
 INLINE void OdeTriMeshGeom::
 get_triangle(int face_index, LPoint3f &v0, LPoint3f &v1, LPoint3f &v2) const {
+  nassertv(_id != 0);
   dVector3 dv0, dv1, dv2;
   dGeomTriMeshGetTriangle(_id, face_index, &dv0, &dv1, &dv2);
   
@@ -55,6 +60,7 @@ get_triangle(int face_index, LPoint3f &v0, LPoint3f &v1, LPoint3f &v2) const {
 
 INLINE LPoint3f OdeTriMeshGeom::
 get_point(int face_index, dReal u, dReal v) const {
+  nassertr(_id != 0, LPoint3f(0));
   dVector3 out;
   dGeomTriMeshGetPoint(_id, face_index, u, v, out);
   return LPoint3f(out[0], out[1], out[2]);
@@ -62,11 +68,13 @@ get_point(int face_index, dReal u, dReal v) const {
 
 INLINE int OdeTriMeshGeom::
 get_num_triangles() const {
+  nassertr(_id != 0, 0);
   return dGeomTriMeshGetTriangleCount(_id);
 }
 
 INLINE dTriMeshDataID OdeTriMeshGeom::
 get_data_id() const {
+  nassertr(_id != 0, 0);
   return dGeomTriMeshGetTriMeshDataID(_id);
 }
 

+ 11 - 20
panda/src/ode/odeTriMeshGeom.cxx

@@ -20,23 +20,28 @@
 #include "odeTriMeshGeom.h"
 
 TypeHandle OdeTriMeshGeom::_type_handle;
-TriMeshDataMap OdeTriMeshGeom::MeshData;
+
+OdeTriMeshGeom::
+OdeTriMeshGeom(dGeomID id) :
+  OdeGeom(id) {
+}
 
 OdeTriMeshGeom::
 OdeTriMeshGeom(OdeTriMeshData &data) :
   OdeGeom(dCreateTriMesh(0, data.get_id(), 0, 0, 0)) {
-  link_data(_id, data);
+  OdeTriMeshData::link_data(_id, &data);
 }
 
 OdeTriMeshGeom::
 OdeTriMeshGeom(OdeSpace &space, OdeTriMeshData &data) :
   OdeGeom(dCreateTriMesh(space.get_id(), data.get_id(), 0, 0, 0)) {
-  link_data(_id, data);
+  OdeTriMeshData::link_data(_id, &data);
 }
 
 OdeTriMeshGeom::
-OdeTriMeshGeom(OdeTriMeshGeom &copy) :
+OdeTriMeshGeom(const OdeTriMeshGeom &copy) :
   OdeGeom(dCreateTriMesh(0, copy.get_data_id(), 0, 0, 0)) {
+  OdeTriMeshData::link_data(_id, copy.get_data());
 }
 
 OdeTriMeshGeom::
@@ -44,20 +49,6 @@ OdeTriMeshGeom::
 }
 
 void OdeTriMeshGeom::
-link_data(dGeomID id, OdeTriMeshData &data) {
-  odegeom_cat.debug() << get_class_type() << "(" << id << ") linking to data: " << data.get_id() << "\n";
-  MeshData[id] = &data;
-}
-
-void OdeTriMeshGeom::
-unlink_data(dGeomID id) {
-  TriMeshDataMap::iterator iter = MeshData.find(id);
-  
-  if (iter != MeshData.end()) {
-    odegeom_cat.debug() << get_class_type() << "(" << id << ") unlinking from data: " << iter->second->get_id() << "\n";
-  } else {
-    odegeom_cat.warning() << get_class_type() << "(" << id << ") Unlinking from absent data!\n";
-  }
-
-  MeshData.erase(id);
+destroy() {
+  OdeTriMeshData::unlink_data(_id);
 }

+ 8 - 10
panda/src/ode/odeTriMeshGeom.h

@@ -30,20 +30,20 @@
 //       Class : OdeTriMeshGeom
 // Description : 
 ////////////////////////////////////////////////////////////////////
-
-typedef pmap<dGeomID, PT(OdeTriMeshData)> TriMeshDataMap;
-
 class EXPCL_PANDAODE OdeTriMeshGeom : public OdeGeom {
-protected:
-  static TriMeshDataMap MeshData;
+  friend class OdeGeom;
+
+private:
+  OdeTriMeshGeom(dGeomID id);
 
 PUBLISHED:
-  //ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback);
+  /* ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback); */
   OdeTriMeshGeom(OdeTriMeshData &data);
   OdeTriMeshGeom(OdeSpace &space, OdeTriMeshData &data);
-  OdeTriMeshGeom(OdeTriMeshGeom &copy);
+  OdeTriMeshGeom(const OdeTriMeshGeom &copy);
   virtual ~OdeTriMeshGeom();
-
+  
+  void destroy();
   INLINE void set_data(OdeTriMeshData &data);
   INLINE PT(OdeTriMeshData) get_data() const;
   INLINE void enable_TC(int geom_class, int enable);
@@ -56,8 +56,6 @@ PUBLISHED:
 public:
   INLINE static int get_geom_class() { return dTriMeshClass; };
   INLINE dTriMeshDataID get_data_id() const;
-  static void link_data(dGeomID, OdeTriMeshData &data);
-  static void unlink_data(dGeomID);
 
 private:
   void operator = (const OdeTriMeshGeom &copy);

+ 5 - 0
panda/src/ode/odeUniversalJoint.cxx

@@ -21,6 +21,11 @@
 
 TypeHandle OdeUniversalJoint::_type_handle;
 
+OdeUniversalJoint::
+OdeUniversalJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeUniversalJoint::
 OdeUniversalJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateUniversal(world.get_id(), 0)) {

+ 5 - 0
panda/src/ode/odeUniversalJoint.h

@@ -14,6 +14,11 @@
 // Description : 
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeUniversalJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeUniversalJoint(dJointID id);
+
 PUBLISHED:
   OdeUniversalJoint(OdeWorld &world);
   OdeUniversalJoint(OdeWorld &world, OdeJointGroup &joint_group);

+ 11 - 16
panda/src/ode/odeUtil.cxx

@@ -18,31 +18,26 @@
 
 #include "odeUtil.h"
 
-void OdeUtil::
-get_connecting_joint(const OdeBody &body1, const OdeBody &body2, OdeJoint &joint) {
-  joint._id = dConnectingJoint(body1.get_id(),body2.get_id());
+OdeJoint OdeUtil::
+get_connecting_joint(const OdeBody &body1, const OdeBody &body2) {
+  return OdeJoint(dConnectingJoint(body1.get_id(),body2.get_id()));
 }
 
-/*
-OdeJointList OdeUtil::
+OdeJointCollection OdeUtil::
 get_connecting_joint_list(const OdeBody &body1, const OdeBody &body2) {
   const int max_possible_joints = min(body1.get_num_joints(), body1.get_num_joints());
 
-  dJointID *joint_list_store = new dJointID[max_possible_joints];
-  OdeJointList joint_list;
-
-  int num_joints = dConnectingJointList(body1.get_id(),
-					body2.get_id(),
-					joint_list_store);
-
+  dJointID *joint_list = new dJointID[max_possible_joints];
+  int num_joints = dConnectingJointList(body1.get_id(), body2.get_id(),
+					joint_list);
+  OdeJointCollection joints;
   for (int i = 0; i < num_joints; i++) {
-    joint_list.push_back(body1.get_world()->get_joint(joint_list_store[i]));
+    joints.add_joint(OdeJoint(joint_list[i]));
   }
   
-  delete joint_list_store;
-  return joint_list;
+  delete[] joint_list;
+  return joints;
 }
-*/
 
 int OdeUtil::
 are_connected(const OdeBody &body1, const OdeBody &body2) {

+ 6 - 7
panda/src/ode/odeUtil.h

@@ -24,6 +24,8 @@
 #include "luse.h"
 
 #include "ode_includes.h"
+#include "odeJointCollection.h"
+
 class OdeBody;
 class OdeJoint;
 
@@ -33,11 +35,10 @@ class OdeJoint;
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeUtil {
 PUBLISHED:
-  static void get_connecting_joint(const OdeBody &body1,
-				   const OdeBody &body2,
-				   OdeJoint &joint);
-  // static OdeJointList get_connecting_joint_list(const OdeBody &body1,
-  // 					const OdeBody &body2);
+  static OdeJoint get_connecting_joint(const OdeBody &body1,
+				       const OdeBody &body2);
+  static OdeJointCollection get_connecting_joint_list(const OdeBody &body1,
+						      const OdeBody &body2);
   static int are_connected(const OdeBody &body1,
                            const OdeBody &body2);
   static int are_connected_excluding(const OdeBody &body1,
@@ -46,6 +47,4 @@ PUBLISHED:
   
 };
 
-// #include "odeUtil.I"
-
 #endif

+ 7 - 4
panda/src/ode/odeWorld.I

@@ -180,7 +180,10 @@ set_auto_disable_flag(int do_auto_disable) {
   dWorldSetAutoDisableFlag(_id, do_auto_disable);
 }
 
-INLINE string OdeWorld::
-get_name() const {
-  return _name;
-}
+INLINE int OdeWorld::
+compare_to(const OdeWorld &other) const {
+  if (_id != other._id) {
+    return _id < other._id ? -1 : 1;
+  }
+  return 0;
+}

+ 1 - 3
panda/src/ode/odeWorld.cxx

@@ -22,15 +22,13 @@
 TypeHandle OdeWorld::_type_handle;
 
 OdeWorld::
-OdeWorld(const string &name) : 
-  _name(name),
+OdeWorld() : 
   _id(dWorldCreate()) {
   odeworld_cat.debug() << get_type() << "(" << _id << ")" << "\n";
 }
 
 OdeWorld::
 OdeWorld(const OdeWorld &copy) :
-  _name(copy._name),
   _id(copy._id) {
 }
 

+ 2 - 4
panda/src/ode/odeWorld.h

@@ -33,7 +33,7 @@ class OdeJoint;
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeWorld : public TypedObject {
 PUBLISHED:
-  OdeWorld(const string &name = "");
+  OdeWorld();
   OdeWorld(const OdeWorld &copy);
   virtual ~OdeWorld();
   void destroy();
@@ -70,13 +70,11 @@ PUBLISHED:
   INLINE int get_auto_disable_flag() const;
   INLINE void set_auto_disable_flag(int do_auto_disable);
 
-  INLINE string get_name() const;
-
+  INLINE int compare_to(const OdeWorld &other) const;
 public: 
   INLINE dWorldID get_id() const;
   
 private:
-  string _name;
   dWorldID _id;
 
 public:

+ 1 - 0
panda/src/ode/pode_composite2.cxx

@@ -10,4 +10,5 @@
 #include "odeNullJoint.cxx"
 #include "odeSliderJoint.cxx"
 #include "odeUniversalJoint.cxx"
+#include "odeJointCollection.cxx"