ソースを参照

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

Josh Wilson 19 年 前
コミット
976760f105
70 ファイル変更713 行追加104 行削除
  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 \
     odePlane2dJoint.I odePlane2dJoint.h \
     odeSliderJoint.I odeSliderJoint.h \
     odeSliderJoint.I odeSliderJoint.h \
     odeUniversalJoint.I odeUniversalJoint.h \
     odeUniversalJoint.I odeUniversalJoint.h \
+    odeJointCollection.h \
     odeSimpleSpace.I odeSimpleSpace.h \
     odeSimpleSpace.I odeSimpleSpace.h \
     odeHashSpace.I odeHashSpace.h \
     odeHashSpace.I odeHashSpace.h \
     odeQuadTreeSpace.I odeQuadTreeSpace.h \
     odeQuadTreeSpace.I odeQuadTreeSpace.h \
@@ -64,7 +65,7 @@
     odeHingeJoint.cxx odeHinge2Joint.cxx \
     odeHingeJoint.cxx odeHinge2Joint.cxx \
     odeLMotorJoint.cxx odeNullJoint.cxx \
     odeLMotorJoint.cxx odeNullJoint.cxx \
     odePlane2dJoint.cxx odeSliderJoint.cxx \
     odePlane2dJoint.cxx odeSliderJoint.cxx \
-    odeUniversalJoint.cxx \
+    odeUniversalJoint.cxx odeJointCollection.cxx\
     odeSimpleSpace.cxx \
     odeSimpleSpace.cxx \
     odeHashSpace.cxx odeQuadTreeSpace.cxx \
     odeHashSpace.cxx odeQuadTreeSpace.cxx \
     odeSphereGeom.cxx odeBoxGeom.cxx \
     odeSphereGeom.cxx odeBoxGeom.cxx \
@@ -97,6 +98,7 @@
     odePlane2dJoint.I odePlane2dJoint.h \
     odePlane2dJoint.I odePlane2dJoint.h \
     odeSliderJoint.I odeSliderJoint.h \
     odeSliderJoint.I odeSliderJoint.h \
     odeUniversalJoint.I odeUniversalJoint.h \
     odeUniversalJoint.I odeUniversalJoint.h \
+    odeJointCollection.h \
     odeSimpleSpace.I odeSimpleSpace.h \
     odeSimpleSpace.I odeSimpleSpace.h \
     odeHashSpace.I odeHashSpace.h \
     odeHashSpace.I odeHashSpace.h \
     odeQuadTreeSpace.I odeQuadTreeSpace.h \
     odeQuadTreeSpace.I odeQuadTreeSpace.h \

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

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

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

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

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

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

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

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

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

@@ -404,3 +404,11 @@ INLINE int OdeBody::
 get_gravity_mode() const {
 get_gravity_mode() const {
   return dBodyGetGravityMode(_id);
   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);
   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::
 void OdeBody::

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

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

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

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

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

@@ -31,6 +31,11 @@
 // Description : 
 // Description : 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeBoxGeom : public OdeGeom {
 class EXPCL_PANDAODE OdeBoxGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeBoxGeom(dGeomID id);
+
 PUBLISHED:
 PUBLISHED:
   OdeBoxGeom(dReal lx, dReal ly, dReal lz);
   OdeBoxGeom(dReal lx, dReal ly, dReal lz);
   OdeBoxGeom(OdeSpace &space, 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;
 TypeHandle OdeCappedCylinderGeom::_type_handle;
 
 
+OdeCappedCylinderGeom::
+OdeCappedCylinderGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeCappedCylinderGeom::
 OdeCappedCylinderGeom::
 OdeCappedCylinderGeom(dReal radius, dReal length) :
 OdeCappedCylinderGeom(dReal radius, dReal length) :
   OdeGeom(dCreateCapsule(0, radius, length)) {
   OdeGeom(dCreateCapsule(0, radius, length)) {

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

@@ -31,6 +31,11 @@
 // Description : 
 // Description : 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeCappedCylinderGeom : public OdeGeom {
 class EXPCL_PANDAODE OdeCappedCylinderGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeCappedCylinderGeom(dGeomID id);
+
 PUBLISHED:
 PUBLISHED:
   OdeCappedCylinderGeom(dReal radius, dReal length);
   OdeCappedCylinderGeom(dReal radius, dReal length);
   OdeCappedCylinderGeom(OdeSpace &space, 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){
 set_g2(const OdeGeom &geom){
   _contact_geom.g2 = geom._id;
   _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_depth(const dReal depth);          
   INLINE void set_g1(const OdeGeom &geom);
   INLINE void set_g1(const OdeGeom &geom);
   INLINE void set_g2(const OdeGeom &geom);
   INLINE void set_g2(const OdeGeom &geom);
-
+  
 public:
 public:
   const dContactGeom* get_contact_geom_ptr() const;
   const dContactGeom* get_contact_geom_ptr() const;
 
 

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

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

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

@@ -15,6 +15,11 @@
 // Description : 
 // Description : 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeContactJoint : public OdeJoint {
 class EXPCL_PANDAODE OdeContactJoint : public OdeJoint {
+  friend class OdeJoint;
+
+private:
+  OdeContactJoint(dJointID id);
+
 PUBLISHED:
 PUBLISHED:
   OdeContactJoint(OdeWorld &world, const OdeContact &contact);
   OdeContactJoint(OdeWorld &world, const OdeContact &contact);
   OdeContactJoint(OdeWorld &world, OdeJointGroup &joint_group, 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;
 TypeHandle OdeConvexGeom::_type_handle;
 
 
+OdeConvexGeom::
+OdeConvexGeom(dGeomID id) :
+  OdeGeom(id) {
+}
+
 OdeConvexGeom::
 OdeConvexGeom::
 OdeConvexGeom(dReal radius, dReal length) :
 OdeConvexGeom(dReal radius, dReal length) :
   OdeGeom(dCreateConvex(0, radius, length)) {
   OdeGeom(dCreateConvex(0, radius, length)) {

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

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

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

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

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

@@ -31,6 +31,11 @@
 // Description : 
 // Description : 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeCylinderGeom : public OdeGeom {
 class EXPCL_PANDAODE OdeCylinderGeom : public OdeGeom {
+  friend class OdeGeom;
+
+private:
+  OdeCylinderGeom(dGeomID id);
+
 PUBLISHED:
 PUBLISHED:
   OdeCylinderGeom(dReal radius, dReal length);
   OdeCylinderGeom(dReal radius, dReal length);
   OdeCylinderGeom(OdeSpace &space, 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;
 TypeHandle OdeFixedJoint::_type_handle;
 
 
+OdeFixedJoint::
+OdeFixedJoint(dJointID id) : 
+  OdeJoint(id) {
+}
+
 OdeFixedJoint::
 OdeFixedJoint::
 OdeFixedJoint(OdeWorld &world) : 
 OdeFixedJoint(OdeWorld &world) : 
   OdeJoint(dJointCreateFixed(world.get_id(), 0)) {
   OdeJoint(dJointCreateFixed(world.get_id(), 0)) {

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

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

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

@@ -213,3 +213,11 @@ get_offset_quaternion() const {
   dGeomGetOffsetQuaternion(_id, res);
   dGeomGetOffsetQuaternion(_id, res);
   return LQuaternionf(res[0], res[1], res[2], res[3]);
   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() {
 ~OdeGeom() {
+  odegeom_cat.debug() << "~" << get_type() << "(" << _id << ")\n";
 }
 }
 
 
 void OdeGeom::
 void OdeGeom::
 destroy() {
 destroy() {
   if (get_class() == OdeTriMeshGeom::get_geom_class()) {
   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
   #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 "bitMask.h"
 
 
 #include "ode_includes.h"
 #include "ode_includes.h"
-#include "odeSpace.h" // Needed for derived classes
+#include "odeSpace.h"
 #include "odeBody.h"
 #include "odeBody.h"
 
 
+class OdeBoxGeom;
+class OdeCappedCylinderGeom;
+// class OdeConvexGeom;
+class OdeCylinderGeom;
+// class OdeHeightfieldGeom;
+class OdePlaneGeom;
+class OdeRayGeom;
+class OdeSphereGeom;
 class OdeTriMeshGeom;
 class OdeTriMeshGeom;
+class OdeSimpleSpace;
+class OdeHashSpace;
+class OdeQuadTreeSpace;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : OdeGeom
 //       Class : OdeGeom
@@ -42,6 +53,22 @@ protected:
   OdeGeom(dGeomID id);
   OdeGeom(dGeomID id);
 
 
 PUBLISHED:
 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();
   virtual ~OdeGeom();
   void destroy();
   void destroy();
 
 
@@ -79,9 +106,23 @@ PUBLISHED:
   INLINE LMatrix3f get_offset_rotation() const;
   INLINE LMatrix3f get_offset_rotation() const;
   INLINE LQuaternionf get_offset_quaternion() 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;
   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:
 public:
   INLINE dGeomID get_id() const;
   INLINE dGeomID get_id() const;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -48,4 +48,17 @@ INLINE dJointFeedback *OdeJoint::
 get_feedback() {
 get_feedback() {
   return dJointGetFeedback(_id);
   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;
 TypeHandle OdeJoint::_type_handle;
 
 
+OdeJoint::
+OdeJoint() : 
+  _id(0) {
+  ostream &out = odejoint_cat.debug();
+  out << get_type() << "(" << _id  << ")\n";
+}
+
 OdeJoint::
 OdeJoint::
 OdeJoint(dJointID id) : 
 OdeJoint(dJointID id) : 
   _id(id) {
   _id(id) {
@@ -55,14 +62,15 @@ attach_bodies(const OdeBody &body1, const OdeBody &body2) {
 //     Function: OdeJoint::attach_body
 //     Function: OdeJoint::attach_body
 //       Access: Published
 //       Access: Published
 //  Description: Attaches a single OdeBody to this joint at the
 //  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
 //               Consider using the OdeJoint::attach extension
 //               function if you're using the Python interface.
 //               function if you're using the Python interface.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OdeJoint::
 void OdeJoint::
 attach_body(const OdeBody &body, int index) {
 attach_body(const OdeBody &body, int index) {
   nassertv(body.get_id() != 0);
   nassertv(body.get_id() != 0);
+  nassertv(index == 0 || index == 1);
   if (index == 0) {
   if (index == 0) {
     dJointAttach(_id, body.get_id(), 0);
     dJointAttach(_id, body.get_id(), 0);
   } else {
   } else {
@@ -77,6 +85,7 @@ detach() {
 
 
 OdeBody OdeJoint::
 OdeBody OdeJoint::
 get_body(int index) const {
 get_body(int index) const {
+  nassertr(_id, OdeBody(0));
   nassertr(index == 0 || index == 1, OdeBody(0));
   nassertr(index == 0 || index == 1, OdeBody(0));
   return OdeBody(dJointGetBody(_id, index));
   return OdeBody(dJointGetBody(_id, index));
 }
 }
@@ -107,7 +116,80 @@ write(ostream &out, unsigned int indent) const {
   #endif //] NDEBUG
   #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 "luse.h"
 
 
 #include "ode_includes.h"
 #include "ode_includes.h"
-#include "odeWorld.h" // Needed for derived classes
+#include "odeWorld.h"      // Needed for derived classes
 #include "odeJointGroup.h"
 #include "odeJointGroup.h"
 
 
 // Strange, we should be forced to include this by get_body()
 // Strange, we should be forced to include this by get_body()
 class OdeBody; 
 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
 //       Class : OdeJoint
@@ -39,10 +50,26 @@ class EXPCL_PANDAODE OdeJoint : public TypedObject {
   friend class OdeBody;
   friend class OdeBody;
   friend class OdeUtil;
   friend class OdeUtil;
 
 
+public:
+  OdeJoint();
+
 protected:
 protected:
   OdeJoint(dJointID id);
   OdeJoint(dJointID id);
 
 
 PUBLISHED:
 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();
   virtual ~OdeJoint();
   void destroy();
   void destroy();
   
   
@@ -58,7 +85,20 @@ PUBLISHED:
   void detach();
   void detach();
 
 
   virtual void write(ostream &out = cout, unsigned int indent=0) const;
   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: 
 public: 
   INLINE dJointID get_id() const;
   INLINE dJointID get_id() const;

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

@@ -26,3 +26,10 @@ empty() const {
   dJointGroupEmpty(_id);
   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 void empty() const;
 
 
+  INLINE int compare_to(const OdeJointGroup &other) const;
+
 public: 
 public: 
   INLINE dJointGroupID get_id() const;
   INLINE dJointGroupID get_id() const;
 
 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -32,14 +32,6 @@ OdeSpace::
 
 
 void OdeSpace::
 void OdeSpace::
 destroy() {
 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);
   dSpaceDestroy(_id);
 }
 }
 
 
@@ -90,3 +82,24 @@ write(ostream &out, unsigned int indent) const {
   #endif //] NDEBUG
   #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 OdeGeom;
 class OdeTriMeshGeom;
 class OdeTriMeshGeom;
+class OdeSimpleSpace;
+class OdeHashSpace;
+class OdeQuadTreeSpace;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : OdeSpace
 //       Class : OdeSpace
@@ -70,6 +73,10 @@ PUBLISHED:
 
 
   virtual void write(ostream &out = cout, unsigned int indent=0) const;
   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: 
 public: 
   INLINE dSpaceID get_id() const;
   INLINE dSpaceID get_id() const;
 
 

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

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

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

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

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

@@ -19,6 +19,57 @@
 #include "odeTriMeshData.h"
 #include "odeTriMeshData.h"
 
 
 TypeHandle OdeTriMeshData::_type_handle;
 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::
 OdeTriMeshData(const NodePath& model, bool use_normals) :
 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,
     build_single1(_vertices, sizeof(StridedVertex), _num_vertices,
 		  _faces, _num_faces * 3, sizeof(StridedTri),
 		  _faces, _num_faces * 3, sizeof(StridedTri),
 		  _normals);
 		  _normals);
-  }    
+  }
+
   preprocess();
   preprocess();
 }
 }
 
 
+// Private copy constructor, shouldn't be copying these objects
+OdeTriMeshData::
+OdeTriMeshData(const OdeTriMeshData &other) {
+}
+
 OdeTriMeshData::
 OdeTriMeshData::
 ~OdeTriMeshData() {
 ~OdeTriMeshData() {
   odetrimeshdata_cat.debug() << "~" << get_type() << "(" << _id << ")" << "\n";
   odetrimeshdata_cat.debug() << "~" << get_type() << "(" << _id << ")" << "\n";
-  dGeomTriMeshDataDestroy(_id);
+  destroy();
   if (_vertices != 0) {
   if (_vertices != 0) {
     delete[] _vertices;
     delete[] _vertices;
     _vertices = 0;
     _vertices = 0;
+    _num_vertices = 0;
   }
   }
   if (_faces != 0) {
   if (_faces != 0) {
     delete[] _faces;
     delete[] _faces;
@@ -59,10 +117,24 @@ OdeTriMeshData::
   }
   }
   if (_normals != 0) {
   if (_normals != 0) {
     delete[] _normals;
     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::
 void OdeTriMeshData::
 process_model(const NodePath& model, bool &use_normals) {
 process_model(const NodePath& model, bool &use_normals) {
   // TODO: assert if _vertices is something other than 0.
   // TODO: assert if _vertices is something other than 0.
@@ -231,6 +303,6 @@ write_faces(ostream &out) const {
 void OdeTriMeshData::
 void OdeTriMeshData::
 write(ostream &out, unsigned int indent) const {
 write(ostream &out, unsigned int indent) const {
   out.width(indent); out << "" << get_type() << "(id = " << _id << ") : " \
   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 : 
 // Description : 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeTriMeshData : public TypedReferenceCount {
 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:
 PUBLISHED:
+
+  enum DataType { DT_face_normals = 0,
+		  DT_last_transformation };
+
   OdeTriMeshData(const NodePath& model, bool use_normals = false);
   OdeTriMeshData(const NodePath& model, bool use_normals = false);
   virtual ~OdeTriMeshData();
   virtual ~OdeTriMeshData();
 
 
-  enum DataType { DT_face_normals,
-		  DT_last_transformation };
+  void destroy();
+  
   // INLINE void set(int data_id, void* in_data);
   // INLINE void set(int data_id, void* in_data);
   // INLINE void* get(int data_id);
   // INLINE void* get(int data_id);
   // INLINE void get_buffer(unsigned char** buf, int* buf_len) const;
   // INLINE void get_buffer(unsigned char** buf, int* buf_len) const;
@@ -81,6 +96,9 @@ private:
   void analyze(const Geom *geom);
   void analyze(const Geom *geom);
   void analyze(const GeomPrimitive *geom);
   void analyze(const GeomPrimitive *geom);
 
 
+  OdeTriMeshData(const OdeTriMeshData &other);
+  void operator = (const OdeTriMeshData &other);
+  
 protected:
 protected:
   struct StridedVertex{
   struct StridedVertex{
     dReal Vertex[3];
     dReal Vertex[3];

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

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

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

@@ -20,23 +20,28 @@
 #include "odeTriMeshGeom.h"
 #include "odeTriMeshGeom.h"
 
 
 TypeHandle OdeTriMeshGeom::_type_handle;
 TypeHandle OdeTriMeshGeom::_type_handle;
-TriMeshDataMap OdeTriMeshGeom::MeshData;
+
+OdeTriMeshGeom::
+OdeTriMeshGeom(dGeomID id) :
+  OdeGeom(id) {
+}
 
 
 OdeTriMeshGeom::
 OdeTriMeshGeom::
 OdeTriMeshGeom(OdeTriMeshData &data) :
 OdeTriMeshGeom(OdeTriMeshData &data) :
   OdeGeom(dCreateTriMesh(0, data.get_id(), 0, 0, 0)) {
   OdeGeom(dCreateTriMesh(0, data.get_id(), 0, 0, 0)) {
-  link_data(_id, data);
+  OdeTriMeshData::link_data(_id, &data);
 }
 }
 
 
 OdeTriMeshGeom::
 OdeTriMeshGeom::
 OdeTriMeshGeom(OdeSpace &space, OdeTriMeshData &data) :
 OdeTriMeshGeom(OdeSpace &space, OdeTriMeshData &data) :
   OdeGeom(dCreateTriMesh(space.get_id(), data.get_id(), 0, 0, 0)) {
   OdeGeom(dCreateTriMesh(space.get_id(), data.get_id(), 0, 0, 0)) {
-  link_data(_id, data);
+  OdeTriMeshData::link_data(_id, &data);
 }
 }
 
 
 OdeTriMeshGeom::
 OdeTriMeshGeom::
-OdeTriMeshGeom(OdeTriMeshGeom &copy) :
+OdeTriMeshGeom(const OdeTriMeshGeom &copy) :
   OdeGeom(dCreateTriMesh(0, copy.get_data_id(), 0, 0, 0)) {
   OdeGeom(dCreateTriMesh(0, copy.get_data_id(), 0, 0, 0)) {
+  OdeTriMeshData::link_data(_id, copy.get_data());
 }
 }
 
 
 OdeTriMeshGeom::
 OdeTriMeshGeom::
@@ -44,20 +49,6 @@ OdeTriMeshGeom::
 }
 }
 
 
 void 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
 //       Class : OdeTriMeshGeom
 // Description : 
 // Description : 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-
-typedef pmap<dGeomID, PT(OdeTriMeshData)> TriMeshDataMap;
-
 class EXPCL_PANDAODE OdeTriMeshGeom : public OdeGeom {
 class EXPCL_PANDAODE OdeTriMeshGeom : public OdeGeom {
-protected:
-  static TriMeshDataMap MeshData;
+  friend class OdeGeom;
+
+private:
+  OdeTriMeshGeom(dGeomID id);
 
 
 PUBLISHED:
 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(OdeTriMeshData &data);
   OdeTriMeshGeom(OdeSpace &space, OdeTriMeshData &data);
   OdeTriMeshGeom(OdeSpace &space, OdeTriMeshData &data);
-  OdeTriMeshGeom(OdeTriMeshGeom &copy);
+  OdeTriMeshGeom(const OdeTriMeshGeom &copy);
   virtual ~OdeTriMeshGeom();
   virtual ~OdeTriMeshGeom();
-
+  
+  void destroy();
   INLINE void set_data(OdeTriMeshData &data);
   INLINE void set_data(OdeTriMeshData &data);
   INLINE PT(OdeTriMeshData) get_data() const;
   INLINE PT(OdeTriMeshData) get_data() const;
   INLINE void enable_TC(int geom_class, int enable);
   INLINE void enable_TC(int geom_class, int enable);
@@ -56,8 +56,6 @@ PUBLISHED:
 public:
 public:
   INLINE static int get_geom_class() { return dTriMeshClass; };
   INLINE static int get_geom_class() { return dTriMeshClass; };
   INLINE dTriMeshDataID get_data_id() const;
   INLINE dTriMeshDataID get_data_id() const;
-  static void link_data(dGeomID, OdeTriMeshData &data);
-  static void unlink_data(dGeomID);
 
 
 private:
 private:
   void operator = (const OdeTriMeshGeom &copy);
   void operator = (const OdeTriMeshGeom &copy);

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

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

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

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

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

@@ -18,31 +18,26 @@
 
 
 #include "odeUtil.h"
 #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) {
 get_connecting_joint_list(const OdeBody &body1, const OdeBody &body2) {
   const int max_possible_joints = min(body1.get_num_joints(), body1.get_num_joints());
   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++) {
   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::
 int OdeUtil::
 are_connected(const OdeBody &body1, const OdeBody &body2) {
 are_connected(const OdeBody &body1, const OdeBody &body2) {

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

@@ -24,6 +24,8 @@
 #include "luse.h"
 #include "luse.h"
 
 
 #include "ode_includes.h"
 #include "ode_includes.h"
+#include "odeJointCollection.h"
+
 class OdeBody;
 class OdeBody;
 class OdeJoint;
 class OdeJoint;
 
 
@@ -33,11 +35,10 @@ class OdeJoint;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAODE OdeUtil {
 class EXPCL_PANDAODE OdeUtil {
 PUBLISHED:
 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,
   static int are_connected(const OdeBody &body1,
                            const OdeBody &body2);
                            const OdeBody &body2);
   static int are_connected_excluding(const OdeBody &body1,
   static int are_connected_excluding(const OdeBody &body1,
@@ -46,6 +47,4 @@ PUBLISHED:
   
   
 };
 };
 
 
-// #include "odeUtil.I"
-
 #endif
 #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);
   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;
 TypeHandle OdeWorld::_type_handle;
 
 
 OdeWorld::
 OdeWorld::
-OdeWorld(const string &name) : 
-  _name(name),
+OdeWorld() : 
   _id(dWorldCreate()) {
   _id(dWorldCreate()) {
   odeworld_cat.debug() << get_type() << "(" << _id << ")" << "\n";
   odeworld_cat.debug() << get_type() << "(" << _id << ")" << "\n";
 }
 }
 
 
 OdeWorld::
 OdeWorld::
 OdeWorld(const OdeWorld &copy) :
 OdeWorld(const OdeWorld &copy) :
-  _name(copy._name),
   _id(copy._id) {
   _id(copy._id) {
 }
 }
 
 

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

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

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

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