Browse Source

bullet: make thread-safe by adding global lock mechanism

Also addresses some memory leaks.
deflected 7 years ago
parent
commit
9afdb78d94
100 changed files with 3469 additions and 2519 deletions
  1. 2 2
      panda/src/bullet/bulletBaseCharacterControllerNode.h
  2. 0 129
      panda/src/bullet/bulletBodyNode.I
  3. 220 20
      panda/src/bullet/bulletBodyNode.cxx
  4. 17 14
      panda/src/bullet/bulletBodyNode.h
  5. 0 17
      panda/src/bullet/bulletBoxShape.I
  6. 24 0
      panda/src/bullet/bulletBoxShape.cxx
  7. 2 2
      panda/src/bullet/bulletBoxShape.h
  8. 0 20
      panda/src/bullet/bulletCapsuleShape.I
  9. 27 0
      panda/src/bullet/bulletCapsuleShape.cxx
  10. 2 2
      panda/src/bullet/bulletCapsuleShape.h
  11. 2 0
      panda/src/bullet/bulletCharacterControllerNode.I
  12. 37 9
      panda/src/bullet/bulletCharacterControllerNode.cxx
  13. 4 2
      panda/src/bullet/bulletCharacterControllerNode.h
  14. 0 20
      panda/src/bullet/bulletConeShape.I
  15. 26 0
      panda/src/bullet/bulletConeShape.cxx
  16. 2 2
      panda/src/bullet/bulletConeShape.h
  17. 0 18
      panda/src/bullet/bulletConeTwistConstraint.I
  18. 31 0
      panda/src/bullet/bulletConeTwistConstraint.cxx
  19. 2 2
      panda/src/bullet/bulletConeTwistConstraint.h
  20. 0 16
      panda/src/bullet/bulletConvexHullShape.I
  21. 26 0
      panda/src/bullet/bulletConvexHullShape.cxx
  22. 2 2
      panda/src/bullet/bulletConvexHullShape.h
  23. 0 27
      panda/src/bullet/bulletConvexPointCloudShape.I
  24. 32 0
      panda/src/bullet/bulletConvexPointCloudShape.cxx
  25. 3 3
      panda/src/bullet/bulletConvexPointCloudShape.h
  26. 0 44
      panda/src/bullet/bulletCylinderShape.I
  27. 55 0
      panda/src/bullet/bulletCylinderShape.cxx
  28. 5 5
      panda/src/bullet/bulletCylinderShape.h
  29. 2 3
      panda/src/bullet/bulletDebugNode.cxx
  30. 1 3
      panda/src/bullet/bulletDebugNode.h
  31. 0 18
      panda/src/bullet/bulletGenericConstraint.I
  32. 28 0
      panda/src/bullet/bulletGenericConstraint.cxx
  33. 2 2
      panda/src/bullet/bulletGenericConstraint.h
  34. 0 20
      panda/src/bullet/bulletGhostNode.I
  35. 41 7
      panda/src/bullet/bulletGhostNode.cxx
  36. 6 4
      panda/src/bullet/bulletGhostNode.h
  37. 0 30
      panda/src/bullet/bulletHeightfieldShape.I
  38. 39 1
      panda/src/bullet/bulletHeightfieldShape.cxx
  39. 2 2
      panda/src/bullet/bulletHeightfieldShape.h
  40. 0 18
      panda/src/bullet/bulletHingeConstraint.I
  41. 33 0
      panda/src/bullet/bulletHingeConstraint.cxx
  42. 2 2
      panda/src/bullet/bulletHingeConstraint.h
  43. 0 225
      panda/src/bullet/bulletManifoldPoint.I
  44. 266 0
      panda/src/bullet/bulletManifoldPoint.cxx
  45. 24 24
      panda/src/bullet/bulletManifoldPoint.h
  46. 0 58
      panda/src/bullet/bulletMinkowskiSumShape.I
  47. 66 0
      panda/src/bullet/bulletMinkowskiSumShape.cxx
  48. 6 6
      panda/src/bullet/bulletMinkowskiSumShape.h
  49. 0 45
      panda/src/bullet/bulletMultiSphereShape.I
  50. 52 0
      panda/src/bullet/bulletMultiSphereShape.cxx
  51. 5 5
      panda/src/bullet/bulletMultiSphereShape.h
  52. 7 0
      panda/src/bullet/bulletPersistentManifold.cxx
  53. 0 34
      panda/src/bullet/bulletPlaneShape.I
  54. 40 0
      panda/src/bullet/bulletPlaneShape.cxx
  55. 4 4
      panda/src/bullet/bulletPlaneShape.h
  56. 0 35
      panda/src/bullet/bulletRigidBodyNode.I
  57. 129 17
      panda/src/bullet/bulletRigidBodyNode.cxx
  58. 11 7
      panda/src/bullet/bulletRigidBodyNode.h
  59. 2 157
      panda/src/bullet/bulletRotationalLimitMotor.I
  60. 174 2
      panda/src/bullet/bulletRotationalLimitMotor.cxx
  61. 19 19
      panda/src/bullet/bulletRotationalLimitMotor.h
  62. 0 63
      panda/src/bullet/bulletShape.I
  63. 87 2
      panda/src/bullet/bulletShape.cxx
  64. 8 7
      panda/src/bullet/bulletShape.h
  65. 0 18
      panda/src/bullet/bulletSliderConstraint.I
  66. 43 0
      panda/src/bullet/bulletSliderConstraint.cxx
  67. 2 2
      panda/src/bullet/bulletSliderConstraint.h
  68. 0 436
      panda/src/bullet/bulletSoftBodyConfig.I
  69. 489 0
      panda/src/bullet/bulletSoftBodyConfig.cxx
  70. 49 49
      panda/src/bullet/bulletSoftBodyConfig.h
  71. 0 63
      panda/src/bullet/bulletSoftBodyMaterial.I
  72. 69 0
      panda/src/bullet/bulletSoftBodyMaterial.cxx
  73. 7 7
      panda/src/bullet/bulletSoftBodyMaterial.h
  74. 0 53
      panda/src/bullet/bulletSoftBodyNode.I
  75. 137 11
      panda/src/bullet/bulletSoftBodyNode.cxx
  76. 11 8
      panda/src/bullet/bulletSoftBodyNode.h
  77. 1 0
      panda/src/bullet/bulletSoftBodyShape.cxx
  78. 11 0
      panda/src/bullet/bulletSoftBodyWorldInfo.cxx
  79. 0 18
      panda/src/bullet/bulletSphereShape.I
  80. 23 0
      panda/src/bullet/bulletSphereShape.cxx
  81. 2 2
      panda/src/bullet/bulletSphereShape.h
  82. 4 0
      panda/src/bullet/bulletSphericalConstraint.cxx
  83. 2 159
      panda/src/bullet/bulletTranslationalLimitMotor.I
  84. 177 2
      panda/src/bullet/bulletTranslationalLimitMotor.cxx
  85. 18 18
      panda/src/bullet/bulletTranslationalLimitMotor.h
  86. 0 28
      panda/src/bullet/bulletTriangleMesh.I
  87. 78 3
      panda/src/bullet/bulletTriangleMesh.cxx
  88. 9 3
      panda/src/bullet/bulletTriangleMesh.h
  89. 0 21
      panda/src/bullet/bulletTriangleMeshShape.I
  90. 27 1
      panda/src/bullet/bulletTriangleMeshShape.cxx
  91. 2 2
      panda/src/bullet/bulletTriangleMeshShape.h
  92. 1 116
      panda/src/bullet/bulletVehicle.I
  93. 162 9
      panda/src/bullet/bulletVehicle.cxx
  94. 16 15
      panda/src/bullet/bulletVehicle.h
  95. 0 71
      panda/src/bullet/bulletWheel.I
  96. 128 0
      panda/src/bullet/bulletWheel.cxx
  97. 8 8
      panda/src/bullet/bulletWheel.h
  98. 0 135
      panda/src/bullet/bulletWorld.I
  99. 374 62
      panda/src/bullet/bulletWorld.cxx
  100. 42 23
      panda/src/bullet/bulletWorld.h

+ 2 - 2
panda/src/bullet/bulletBaseCharacterControllerNode.h

@@ -43,8 +43,8 @@ public:
   virtual btPairCachingGhostObject *get_ghost() const = 0;
   virtual btCharacterControllerInterface *get_character() const = 0;
 
-  virtual void sync_p2b(PN_stdfloat dt, int num_substeps) = 0;
-  virtual void sync_b2p() = 0;
+  virtual void do_sync_p2b(PN_stdfloat dt, int num_substeps) = 0;
+  virtual void do_sync_b2p() = 0;
 
 public:
   static TypeHandle get_class_type() {

+ 0 - 129
panda/src/bullet/bulletBodyNode.I

@@ -84,51 +84,6 @@ get_collision_response() const {
   return !get_collision_flag(btCollisionObject::CF_NO_CONTACT_RESPONSE);
 }
 
-/**
- *
- */
-INLINE void BulletBodyNode::
-set_collision_flag(int flag, bool value) {
-
-  int flags = get_object()->getCollisionFlags();
-
-  if (value == true) {
-    flags |= flag;
-  }
-  else {
-    flags &= ~(flag);
-  }
-
-  get_object()->setCollisionFlags(flags);
-}
-
-/**
- *
- */
-INLINE bool BulletBodyNode::
-get_collision_flag(int flag) const {
-
-  return (get_object()->getCollisionFlags() & flag) ? true : false;
-}
-
-/**
- *
- */
-INLINE bool BulletBodyNode::
-is_static() const {
-
-  return get_object()->isStaticObject();
-}
-
-/**
- *
- */
-INLINE bool BulletBodyNode::
-is_kinematic() const {
-
-  return get_object()->isKinematicObject();
-}
-
 /**
  *
  */
@@ -147,90 +102,6 @@ set_kinematic(bool value) {
   set_collision_flag(btCollisionObject::CF_KINEMATIC_OBJECT, value);
 }
 
-/**
- *
- */
-INLINE PN_stdfloat BulletBodyNode::
-get_restitution() const {
-
-  return get_object()->getRestitution();
-}
-
-/**
- *
- */
-INLINE void BulletBodyNode::
-set_restitution(PN_stdfloat restitution) {
-
-  return get_object()->setRestitution(restitution);
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletBodyNode::
-get_friction() const {
-
-  return get_object()->getFriction();
-}
-
-/**
- *
- */
-INLINE void BulletBodyNode::
-set_friction(PN_stdfloat friction) {
-
-  return get_object()->setFriction(friction);
-}
-
-#if BT_BULLET_VERSION >= 281
-/**
- *
- */
-INLINE PN_stdfloat BulletBodyNode::
-get_rolling_friction() const {
-
-  return get_object()->getRollingFriction();
-}
-
-/**
- *
- */
-INLINE void BulletBodyNode::
-set_rolling_friction(PN_stdfloat friction) {
-
-  return get_object()->setRollingFriction(friction);
-}
-#endif
-
-/**
- *
- */
-INLINE bool BulletBodyNode::
-has_anisotropic_friction() const {
-
-  return get_object()->hasAnisotropicFriction();
-}
-
-/**
- *
- */
-INLINE int BulletBodyNode::
-get_num_shapes() const {
-
-  return _shapes.size();
-}
-
-/**
- *
- */
-INLINE BulletShape *BulletBodyNode::
-get_shape(int idx) const {
-
-  nassertr(idx >= 0 && idx < (int)_shapes.size(), NULL);
-  return _shapes[idx];
-}
-
 /**
  * Enables or disables the debug visualisation for this collision object.  By
  * default the debug visualisation is enabled.

+ 220 - 20
panda/src/bullet/bulletBodyNode.cxx

@@ -41,9 +41,11 @@ BulletBodyNode(const char *name) : PandaNode(name) {
  */
 BulletBodyNode::
 BulletBodyNode(const BulletBodyNode &copy) :
-  PandaNode(copy),
-  _shapes(copy._shapes)
+  PandaNode(copy)
 {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shapes = copy._shapes;
   if (copy._shape && copy._shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
     // btCompoundShape does not define a copy constructor.  Manually copy.
     btCompoundShape *shape = new btCompoundShape;
@@ -148,16 +150,168 @@ safe_to_flatten_below() const {
  *
  */
 void BulletBodyNode::
-output(ostream &out) const {
+do_output(ostream &out) const {
 
   PandaNode::output(out);
 
-  out << " (" << get_num_shapes() << " shapes)";
+  out << " (" << _shapes.size() << " shapes)";
+
+  out << (get_object()->isActive() ? " active" : " inactive");
+
+  if (get_object()->isStaticObject()) out << " static";
+  if (get_object()->isKinematicObject()) out << " kinematic";
+}
+
+/**
+ *
+ */
+void BulletBodyNode::
+output(ostream &out) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_output(out);
+}
+
+/**
+ *
+ */
+void BulletBodyNode::
+set_collision_flag(int flag, bool value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  int flags = get_object()->getCollisionFlags();
+
+  if (value == true) {
+    flags |= flag;
+  }
+  else {
+    flags &= ~(flag);
+  }
+
+  get_object()->setCollisionFlags(flags);
+}
+
+/**
+ *
+ */
+bool BulletBodyNode::
+get_collision_flag(int flag) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (get_object()->getCollisionFlags() & flag) ? true : false;
+}
+
+/**
+ *
+ */
+bool BulletBodyNode::
+is_static() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->isStaticObject();
+}
+
+/**
+ *
+ */
+bool BulletBodyNode::
+is_kinematic() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->isKinematicObject();
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletBodyNode::
+get_restitution() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->getRestitution();
+}
+
+/**
+ *
+ */
+void BulletBodyNode::
+set_restitution(PN_stdfloat restitution) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->setRestitution(restitution);
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletBodyNode::
+get_friction() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->getFriction();
+}
+
+/**
+ *
+ */
+void BulletBodyNode::
+set_friction(PN_stdfloat friction) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->setFriction(friction);
+}
 
-  out << (is_active() ? " active" : " inactive");
+#if BT_BULLET_VERSION >= 281
+/**
+ *
+ */
+PN_stdfloat BulletBodyNode::
+get_rolling_friction() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  if (is_static()) out << " static";
-  if (is_kinematic()) out << " kinematic";
+  return get_object()->getRollingFriction();
+}
+
+/**
+ *
+ */
+void BulletBodyNode::
+set_rolling_friction(PN_stdfloat friction) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->setRollingFriction(friction);
+}
+#endif
+
+/**
+ *
+ */
+bool BulletBodyNode::
+has_anisotropic_friction() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return get_object()->hasAnisotropicFriction();
+}
+
+/**
+ *
+ */
+int BulletBodyNode::
+get_num_shapes() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _shapes.size();
+}
+
+/**
+ *
+ */
+BulletShape *BulletBodyNode::
+get_shape(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr(idx >= 0 && idx < (int)_shapes.size(), NULL);
+  return _shapes[idx];
 }
 
 /**
@@ -165,6 +319,16 @@ output(ostream &out) const {
  */
 void BulletBodyNode::
 add_shape(BulletShape *bullet_shape, const TransformState *ts) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_add_shape(bullet_shape, ts);
+}
+
+/**
+ * Assumes the lock(bullet global lock) is held by the caller
+ */
+void BulletBodyNode::
+do_add_shape(BulletShape *bullet_shape, const TransformState *ts) {
 
   nassertv(get_object());
   nassertv(ts);
@@ -246,7 +410,7 @@ add_shape(BulletShape *bullet_shape, const TransformState *ts) {
   // Restore the local scaling again
   np.set_scale(scale);
 
-  shape_changed();
+  do_shape_changed();
 }
 
 /**
@@ -254,6 +418,7 @@ add_shape(BulletShape *bullet_shape, const TransformState *ts) {
  */
 void BulletBodyNode::
 remove_shape(BulletShape *shape) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(get_object());
 
@@ -312,7 +477,7 @@ remove_shape(BulletShape *shape) {
       compound->removeChildShape(shape->ptr());
     }
 
-    shape_changed();
+    do_shape_changed();
   }
 }
 
@@ -333,6 +498,7 @@ is_identity(btTransform &trans) {
  */
 LPoint3 BulletBodyNode::
 get_shape_pos(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertr(idx >= 0 && idx < (int)_shapes.size(), LPoint3::zero());
 
@@ -352,14 +518,17 @@ get_shape_pos(int idx) const {
  */
 LMatrix4 BulletBodyNode::
 get_shape_mat(int idx) const {
-  return get_shape_transform(idx)->get_mat();
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return do_get_shape_transform(idx)->get_mat();
 }
 
 /**
  *
  */
 CPT(TransformState) BulletBodyNode::
-get_shape_transform(int idx) const {
+do_get_shape_transform(int idx) const {
+
   nassertr(idx >= 0 && idx < (int)_shapes.size(), TransformState::make_identity());
 
   btCollisionShape *root = get_object()->getCollisionShape();
@@ -386,13 +555,25 @@ get_shape_transform(int idx) const {
   return TransformState::make_identity();
 }
 
+/**
+ *
+ */
+CPT(TransformState) BulletBodyNode::
+get_shape_transform(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return do_get_shape_transform(idx);
+}
+
+
 /**
  * Hook which will be called whenever the total shape of a body changed.  Used
  * for example to update the mass properties (inertia) of a rigid body.  The
  * default implementation does nothing.
+ * Assumes the lock(bullet global lock) is held
  */
 void BulletBodyNode::
-shape_changed() {
+do_shape_changed() {
 
 }
 
@@ -401,6 +582,7 @@ shape_changed() {
  */
 void BulletBodyNode::
 set_deactivation_time(PN_stdfloat dt) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   get_object()->setDeactivationTime(dt);
 }
@@ -410,6 +592,7 @@ set_deactivation_time(PN_stdfloat dt) {
  */
 PN_stdfloat BulletBodyNode::
 get_deactivation_time() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return get_object()->getDeactivationTime();
 }
@@ -419,6 +602,7 @@ get_deactivation_time() const {
  */
 bool BulletBodyNode::
 is_active() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return get_object()->isActive();
 }
@@ -428,6 +612,7 @@ is_active() const {
  */
 void BulletBodyNode::
 set_active(bool active, bool force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   if (active) {
     get_object()->activate(force);
@@ -457,10 +642,12 @@ force_active(bool active) {
  */
 void BulletBodyNode::
 set_deactivation_enabled(bool enabled) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   // Don't change the state if it's currently active and we enable
   // deactivation.
-  if (enabled != is_deactivation_enabled()) {
+  bool is_enabled = get_object()->getActivationState() != DISABLE_DEACTIVATION;
+  if (enabled != is_enabled) {
 
     // It's OK to set to ACTIVE_TAG even if we don't mean to activate it; it
     // will be disabled right away if the deactivation timer has run out.
@@ -474,6 +661,7 @@ set_deactivation_enabled(bool enabled) {
  */
 bool BulletBodyNode::
 is_deactivation_enabled() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (get_object()->getActivationState() != DISABLE_DEACTIVATION);
 }
@@ -483,6 +671,7 @@ is_deactivation_enabled() const {
  */
 bool BulletBodyNode::
 check_collision_with(PandaNode *node) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btCollisionObject *obj = BulletWorld::get_collision_object(node);
 
@@ -499,6 +688,7 @@ check_collision_with(PandaNode *node) {
  */
 LVecBase3 BulletBodyNode::
 get_anisotropic_friction() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVecBase3(get_object()->getAnisotropicFriction());
 }
@@ -508,6 +698,7 @@ get_anisotropic_friction() const {
  */
 void BulletBodyNode::
 set_anisotropic_friction(const LVecBase3 &friction) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!friction.is_nan());
   get_object()->setAnisotropicFriction(LVecBase3_to_btVector3(friction));
@@ -518,6 +709,7 @@ set_anisotropic_friction(const LVecBase3 &friction) {
  */
 bool BulletBodyNode::
 has_contact_response() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return get_object()->hasContactResponse();
 }
@@ -527,7 +719,8 @@ has_contact_response() const {
  */
 PN_stdfloat BulletBodyNode::
 get_contact_processing_threshold() const {
-
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+  
   return get_object()->getContactProcessingThreshold();
 }
 
@@ -537,6 +730,7 @@ get_contact_processing_threshold() const {
  */
 void BulletBodyNode::
 set_contact_processing_threshold(PN_stdfloat threshold) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   get_object()->setContactProcessingThreshold(threshold);
 }
@@ -546,6 +740,7 @@ set_contact_processing_threshold(PN_stdfloat threshold) {
  */
 PN_stdfloat BulletBodyNode::
 get_ccd_swept_sphere_radius() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return get_object()->getCcdSweptSphereRadius();
 }
@@ -555,6 +750,7 @@ get_ccd_swept_sphere_radius() const {
  */
 void BulletBodyNode::
 set_ccd_swept_sphere_radius(PN_stdfloat radius) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return get_object()->setCcdSweptSphereRadius(radius);
 }
@@ -564,6 +760,7 @@ set_ccd_swept_sphere_radius(PN_stdfloat radius) {
  */
 PN_stdfloat BulletBodyNode::
 get_ccd_motion_threshold() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return get_object()->getCcdMotionThreshold();
 }
@@ -573,6 +770,7 @@ get_ccd_motion_threshold() const {
  */
 void BulletBodyNode::
 set_ccd_motion_threshold(PN_stdfloat threshold) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return get_object()->setCcdMotionThreshold(threshold);
 }
@@ -582,6 +780,7 @@ set_ccd_motion_threshold(PN_stdfloat threshold) {
  */
 void BulletBodyNode::
 add_shapes_from_collision_solids(CollisionNode *cnode) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   PT(BulletTriangleMesh) mesh = NULL;
 
@@ -594,7 +793,7 @@ add_shapes_from_collision_solids(CollisionNode *cnode) {
       CPT(CollisionSphere) sphere = DCAST(CollisionSphere, solid);
       CPT(TransformState) ts = TransformState::make_pos(sphere->get_center());
 
-      add_shape(BulletSphereShape::make_from_solid(sphere), ts);
+      do_add_shape(BulletSphereShape::make_from_solid(sphere), ts);
     }
 
     // CollisionBox
@@ -602,14 +801,14 @@ add_shapes_from_collision_solids(CollisionNode *cnode) {
       CPT(CollisionBox) box = DCAST(CollisionBox, solid);
       CPT(TransformState) ts = TransformState::make_pos(box->get_center());
 
-      add_shape(BulletBoxShape::make_from_solid(box), ts);
+      do_add_shape(BulletBoxShape::make_from_solid(box), ts);
     }
 
     // CollisionPlane
     else if (CollisionPlane::get_class_type() == type) {
       CPT(CollisionPlane) plane = DCAST(CollisionPlane, solid);
 
-      add_shape(BulletPlaneShape::make_from_solid(plane));
+      do_add_shape(BulletPlaneShape::make_from_solid(plane));
     }
 
     // CollisionGeom
@@ -625,13 +824,13 @@ add_shapes_from_collision_solids(CollisionNode *cnode) {
         LPoint3 p2 = polygon->get_point(i-1);
         LPoint3 p3 = polygon->get_point(i);
 
-        mesh->add_triangle(p1, p2, p3, true);
+        mesh->do_add_triangle(p1, p2, p3, true);
       }
     }
   }
 
-  if (mesh && mesh->get_num_triangles() > 0) {
-    add_shape(new BulletTriangleMeshShape(mesh, true));
+  if (mesh && mesh->do_get_num_triangles() > 0) {
+    do_add_shape(new BulletTriangleMeshShape(mesh, true));
   }
 }
 
@@ -651,6 +850,7 @@ set_transform_dirty() {
  */
 BoundingSphere BulletBodyNode::
 get_shape_bounds() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
 /*
   btTransform tr;

+ 17 - 14
panda/src/bullet/bulletBodyNode.h

@@ -42,8 +42,8 @@ PUBLISHED:
   void add_shape(BulletShape *shape, const TransformState *xform=TransformState::make_identity());
   void remove_shape(BulletShape *shape);
 
-  INLINE int get_num_shapes() const;
-  INLINE BulletShape *get_shape(int idx) const;
+  int get_num_shapes() const;
+  BulletShape *get_shape(int idx) const;
   MAKE_SEQ(get_shapes, get_num_shapes, get_shape);
 
   LPoint3 get_shape_pos(int idx) const;
@@ -54,8 +54,8 @@ PUBLISHED:
   void add_shapes_from_collision_solids(CollisionNode *cnode);
 
   // Static and kinematic
-  INLINE bool is_static() const;
-  INLINE bool is_kinematic() const;
+  bool is_static() const;
+  bool is_kinematic() const;
   
   INLINE void set_static(bool value);
   INLINE void set_kinematic(bool value);
@@ -92,19 +92,19 @@ PUBLISHED:
   INLINE bool is_debug_enabled() const;
 
   // Friction and Restitution
-  INLINE PN_stdfloat get_restitution() const;
-  INLINE void set_restitution(PN_stdfloat restitution);
+  PN_stdfloat get_restitution() const;
+  void set_restitution(PN_stdfloat restitution);
 
-  INLINE PN_stdfloat get_friction() const;
-  INLINE void set_friction(PN_stdfloat friction);
+  PN_stdfloat get_friction() const;
+  void set_friction(PN_stdfloat friction);
 
 #if BT_BULLET_VERSION >= 281
-  INLINE PN_stdfloat get_rolling_friction() const;
-  INLINE void set_rolling_friction(PN_stdfloat friction);
+  PN_stdfloat get_rolling_friction() const;
+  void set_rolling_friction(PN_stdfloat friction);
   MAKE_PROPERTY(rolling_friction, get_rolling_friction, set_rolling_friction);
 #endif
 
-  INLINE bool has_anisotropic_friction() const;
+  bool has_anisotropic_friction() const;
   void set_anisotropic_friction(const LVecBase3 &friction);
   LVecBase3 get_anisotropic_friction() const;
 
@@ -151,10 +151,11 @@ public:
   virtual bool safe_to_flatten_below() const;
 
   virtual void output(ostream &out) const;
+  virtual void do_output(ostream &out) const;
 
 protected:
-  INLINE void set_collision_flag(int flag, bool value);
-  INLINE bool get_collision_flag(int flag) const;
+  void set_collision_flag(int flag, bool value);
+  bool get_collision_flag(int flag) const;
 
   btCollisionShape *_shape;
 
@@ -162,7 +163,9 @@ protected:
   BulletShapes _shapes;
 
 private:
-  virtual void shape_changed();
+  virtual void do_shape_changed();
+  void do_add_shape(BulletShape *shape, const TransformState *xform=TransformState::make_identity());
+  CPT(TransformState) do_get_shape_transform(int idx) const;
 
   static bool is_identity(btTransform &trans);
 

+ 0 - 17
panda/src/bullet/bulletBoxShape.I

@@ -28,20 +28,3 @@ INLINE BulletBoxShape::
 
   delete _shape;
 }
-
-/**
- *
- */
-INLINE BulletBoxShape::
-BulletBoxShape(const BulletBoxShape &copy) :
-  _shape(copy._shape), _half_extents(copy._half_extents) {
-}
-
-/**
- *
- */
-INLINE void BulletBoxShape::
-operator = (const BulletBoxShape &copy) {
-  _shape = copy._shape;
-  _half_extents = copy._half_extents;
-}

+ 24 - 0
panda/src/bullet/bulletBoxShape.cxx

@@ -28,6 +28,28 @@ BulletBoxShape(const LVecBase3 &halfExtents) : _half_extents(halfExtents) {
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletBoxShape::
+BulletBoxShape(const BulletBoxShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _half_extents = copy._half_extents;
+}
+
+/**
+ *
+ */
+void BulletBoxShape::
+operator = (const BulletBoxShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _half_extents = copy._half_extents;
+}
+
 /**
  *
  */
@@ -42,6 +64,7 @@ ptr() const {
  */
 LVecBase3 BulletBoxShape::
 get_half_extents_without_margin() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVecBase3(_shape->getHalfExtentsWithoutMargin());
 }
@@ -51,6 +74,7 @@ get_half_extents_without_margin() const {
  */
 LVecBase3 BulletBoxShape::
 get_half_extents_with_margin() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVecBase3(_shape->getHalfExtentsWithMargin());
 }

+ 2 - 2
panda/src/bullet/bulletBoxShape.h

@@ -33,8 +33,8 @@ private:
 
 PUBLISHED:
   explicit BulletBoxShape(const LVecBase3 &halfExtents);
-  INLINE BulletBoxShape(const BulletBoxShape &copy);
-  INLINE void operator = (const BulletBoxShape &copy);
+  BulletBoxShape(const BulletBoxShape &copy);
+  void operator = (const BulletBoxShape &copy);
   INLINE ~BulletBoxShape();
 
   LVecBase3 get_half_extents_without_margin() const;

+ 0 - 20
panda/src/bullet/bulletCapsuleShape.I

@@ -30,26 +30,6 @@ INLINE BulletCapsuleShape::
   delete _shape;
 }
 
-/**
- *
- */
-INLINE BulletCapsuleShape::
-BulletCapsuleShape(const BulletCapsuleShape &copy) :
-  _shape(copy._shape),
-  _radius(copy._radius),
-  _height(copy._height) {
-}
-
-/**
- *
- */
-INLINE void BulletCapsuleShape::
-operator = (const BulletCapsuleShape &copy) {
-  _shape = copy._shape;
-  _radius = copy._radius;
-  _height = copy._height;
-}
-
 /**
  * Returns the radius that was used to construct this capsule.
  */

+ 27 - 0
panda/src/bullet/bulletCapsuleShape.cxx

@@ -38,9 +38,35 @@ BulletCapsuleShape(PN_stdfloat radius, PN_stdfloat height, BulletUpAxis up) :
     break;
   }
 
+  nassertv(_shape);
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletCapsuleShape::
+BulletCapsuleShape(const BulletCapsuleShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _radius = copy._radius;
+  _height = copy._height;
+}
+
+/**
+ *
+ */
+void BulletCapsuleShape::
+operator = (const BulletCapsuleShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _radius = copy._radius;
+  _height = copy._height;
+}
+
+
 /**
  *
  */
@@ -122,6 +148,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
     break;
   }
 
+  nassertv(_shape);
   _shape->setUserPointer(this);
   _shape->setMargin(margin);
 }

+ 2 - 2
panda/src/bullet/bulletCapsuleShape.h

@@ -30,8 +30,8 @@ private:
 
 PUBLISHED:
   explicit BulletCapsuleShape(PN_stdfloat radius, PN_stdfloat height, BulletUpAxis up=Z_up);
-  INLINE BulletCapsuleShape(const BulletCapsuleShape &copy);
-  INLINE void operator = (const BulletCapsuleShape &copy);
+  BulletCapsuleShape(const BulletCapsuleShape &copy);
+  void operator = (const BulletCapsuleShape &copy);
   INLINE ~BulletCapsuleShape();
 
   INLINE PN_stdfloat get_radius() const;

+ 2 - 0
panda/src/bullet/bulletCharacterControllerNode.I

@@ -17,6 +17,8 @@
 INLINE BulletCharacterControllerNode::
 ~BulletCharacterControllerNode() {
 
+  delete _character;
+  delete _ghost;
 }
 
 /**

+ 37 - 9
panda/src/bullet/bulletCharacterControllerNode.cxx

@@ -77,6 +77,7 @@ BulletCharacterControllerNode(BulletShape *shape, PN_stdfloat step_height, const
  */
 void BulletCharacterControllerNode::
 set_linear_movement(const LVector3 &movement, bool is_local) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!movement.is_nan());
 
@@ -89,18 +90,19 @@ set_linear_movement(const LVector3 &movement, bool is_local) {
  */
 void BulletCharacterControllerNode::
 set_angular_movement(PN_stdfloat omega) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _angular_movement = omega;
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletCharacterControllerNode::
-sync_p2b(PN_stdfloat dt, int num_substeps) {
+do_sync_p2b(PN_stdfloat dt, int num_substeps) {
 
   // Synchronise global transform
-  transform_changed();
+  do_transform_changed();
 
   // Angular rotation
   btScalar angle = dt * deg_2_rad(_angular_movement);
@@ -131,10 +133,10 @@ sync_p2b(PN_stdfloat dt, int num_substeps) {
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletCharacterControllerNode::
-sync_b2p() {
+do_sync_b2p() {
 
   NodePath np = NodePath::any_path((PandaNode *)this);
   LVecBase3 scale = np.get_net_transform()->get_scale();
@@ -154,10 +156,10 @@ sync_b2p() {
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletCharacterControllerNode::
-transform_changed() {
+do_transform_changed() {
 
   if (_sync_disable) return;
 
@@ -187,10 +189,23 @@ transform_changed() {
     _ghost->getWorldTransform().setBasis(m);
 
     // Set scale
-    _shape->set_local_scale(scale);
+    _shape->do_set_local_scale(scale);
   }
 }
 
+/**
+ *
+ */
+void BulletCharacterControllerNode::
+transform_changed() {
+
+  if (_sync_disable) return;
+
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_transform_changed();
+}
+
 /**
  *
  */
@@ -205,6 +220,7 @@ get_shape() const {
  */
 bool BulletCharacterControllerNode::
 is_on_ground() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _character->onGround();
 }
@@ -214,6 +230,7 @@ is_on_ground() const {
  */
 bool BulletCharacterControllerNode::
 can_jump() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _character->canJump();
 }
@@ -223,6 +240,7 @@ can_jump() const {
  */
 void BulletCharacterControllerNode::
 do_jump() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _character->jump();
 }
@@ -232,6 +250,7 @@ do_jump() {
  */
 void BulletCharacterControllerNode::
 set_fall_speed(PN_stdfloat fall_speed) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _character->setFallSpeed((btScalar)fall_speed);
 }
@@ -241,6 +260,7 @@ set_fall_speed(PN_stdfloat fall_speed) {
  */
 void BulletCharacterControllerNode::
 set_jump_speed(PN_stdfloat jump_speed) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _character->setJumpSpeed((btScalar)jump_speed);
 }
@@ -250,6 +270,7 @@ set_jump_speed(PN_stdfloat jump_speed) {
  */
 void BulletCharacterControllerNode::
 set_max_jump_height(PN_stdfloat max_jump_height) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _character->setMaxJumpHeight((btScalar)max_jump_height);
 }
@@ -259,6 +280,7 @@ set_max_jump_height(PN_stdfloat max_jump_height) {
  */
 void BulletCharacterControllerNode::
 set_max_slope(PN_stdfloat max_slope) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _character->setMaxSlope((btScalar)max_slope);
 }
@@ -268,6 +290,7 @@ set_max_slope(PN_stdfloat max_slope) {
  */
 PN_stdfloat BulletCharacterControllerNode::
 get_max_slope() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_character->getMaxSlope();
 }
@@ -277,6 +300,8 @@ get_max_slope() const {
  */
 PN_stdfloat BulletCharacterControllerNode::
 get_gravity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
 #if BT_BULLET_VERSION >= 285
   return -(PN_stdfloat)_character->getGravity()[_up];
 #else
@@ -289,6 +314,8 @@ get_gravity() const {
  */
 void BulletCharacterControllerNode::
 set_gravity(PN_stdfloat gravity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
 #if BT_BULLET_VERSION >= 285
   _character->setGravity(up_vectors[_up] * -(btScalar)gravity);
 #else
@@ -301,6 +328,7 @@ set_gravity(PN_stdfloat gravity) {
  */
 void BulletCharacterControllerNode::
 set_use_ghost_sweep_test(bool value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _character->setUseGhostSweepTest(value);
-}
+}

+ 4 - 2
panda/src/bullet/bulletCharacterControllerNode.h

@@ -64,8 +64,8 @@ public:
   INLINE virtual btPairCachingGhostObject *get_ghost() const;
   INLINE virtual btCharacterControllerInterface *get_character() const;
 
-  virtual void sync_p2b(PN_stdfloat dt, int num_substeps);
-  virtual void sync_b2p();
+  virtual void do_sync_p2b(PN_stdfloat dt, int num_substeps);
+  virtual void do_sync_b2p();
 
 protected:
   virtual void transform_changed();
@@ -85,6 +85,8 @@ private:
   bool _linear_movement_is_local;
   PN_stdfloat _angular_movement;
 
+  void do_transform_changed();
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 0 - 20
panda/src/bullet/bulletConeShape.I

@@ -30,26 +30,6 @@ INLINE BulletConeShape::
   delete _shape;
 }
 
-/**
- *
- */
-INLINE BulletConeShape::
-BulletConeShape(const BulletConeShape &copy) :
-  _shape(copy._shape),
-  _radius(copy._radius),
-  _height(copy._height) {
-}
-
-/**
- *
- */
-INLINE void BulletConeShape::
-operator = (const BulletConeShape &copy) {
-  _shape = copy._shape;
-  _radius = copy._radius;
-  _height = copy._height;
-}
-
 /**
  * Returns the radius that was passed into the constructor.
  */

+ 26 - 0
panda/src/bullet/bulletConeShape.cxx

@@ -38,9 +38,34 @@ BulletConeShape(PN_stdfloat radius, PN_stdfloat height, BulletUpAxis up) :
     break;
   }
 
+  nassertv(_shape);
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletConeShape::
+BulletConeShape(const BulletConeShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _radius = copy._radius;
+  _height = copy._height;
+}
+
+/**
+ *
+ */
+void BulletConeShape::
+operator = (const BulletConeShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _radius = copy._radius;
+  _height = copy._height;
+}
+
 /**
  *
  */
@@ -122,6 +147,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
     break;
   }
 
+  nassertv(_shape);
   _shape->setUserPointer(this);
   _shape->setMargin(margin);
 }

+ 2 - 2
panda/src/bullet/bulletConeShape.h

@@ -30,8 +30,8 @@ private:
 
 PUBLISHED:
   explicit BulletConeShape(PN_stdfloat radius, PN_stdfloat height, BulletUpAxis up=Z_up);
-  INLINE BulletConeShape(const BulletConeShape &copy);
-  INLINE void operator = (const BulletConeShape &copy);
+  BulletConeShape(const BulletConeShape &copy);
+  void operator = (const BulletConeShape &copy);
   INLINE ~BulletConeShape();
 
   INLINE PN_stdfloat get_radius() const;

+ 0 - 18
panda/src/bullet/bulletConeTwistConstraint.I

@@ -19,21 +19,3 @@ INLINE BulletConeTwistConstraint::
 
   delete _constraint;
 }
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletConeTwistConstraint::
-get_frame_a() const {
-
-  return btTrans_to_TransformState(_constraint->getAFrame());
-}
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletConeTwistConstraint::
-get_frame_b() const {
-
-  return btTrans_to_TransformState(_constraint->getBFrame());
-}

+ 31 - 0
panda/src/bullet/bulletConeTwistConstraint.cxx

@@ -63,6 +63,7 @@ ptr() const {
  */
 void BulletConeTwistConstraint::
 set_limit(int index, PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   value = deg_2_rad(value);
 
@@ -74,6 +75,7 @@ set_limit(int index, PN_stdfloat value) {
  */
 void BulletConeTwistConstraint::
 set_limit(PN_stdfloat swing1, PN_stdfloat swing2, PN_stdfloat twist, PN_stdfloat softness, PN_stdfloat bias, PN_stdfloat relaxation) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   swing1 = deg_2_rad(swing1);
   swing2 = deg_2_rad(swing2);
@@ -87,6 +89,7 @@ set_limit(PN_stdfloat swing1, PN_stdfloat swing2, PN_stdfloat twist, PN_stdfloat
  */
 void BulletConeTwistConstraint::
 set_damping(PN_stdfloat damping) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setDamping(damping);
 }
@@ -96,6 +99,7 @@ set_damping(PN_stdfloat damping) {
  */
 PN_stdfloat BulletConeTwistConstraint::
 get_fix_threshold() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _constraint->getFixThresh();
 }
@@ -105,6 +109,7 @@ get_fix_threshold() const {
  */
 void BulletConeTwistConstraint::
 set_fix_threshold(PN_stdfloat threshold) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setFixThresh(threshold);
 }
@@ -114,6 +119,7 @@ set_fix_threshold(PN_stdfloat threshold) {
  */
 void BulletConeTwistConstraint::
 enable_motor(bool enable) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->enableMotor(enable);
 }
@@ -123,6 +129,7 @@ enable_motor(bool enable) {
  */
 void BulletConeTwistConstraint::
 set_max_motor_impulse(PN_stdfloat max_impulse) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMaxMotorImpulse(max_impulse);
 }
@@ -132,6 +139,7 @@ set_max_motor_impulse(PN_stdfloat max_impulse) {
  */
 void BulletConeTwistConstraint::
 set_max_motor_impulse_normalized(PN_stdfloat max_impulse) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMaxMotorImpulseNormalized(max_impulse);
 }
@@ -141,6 +149,7 @@ set_max_motor_impulse_normalized(PN_stdfloat max_impulse) {
  */
 void BulletConeTwistConstraint::
 set_motor_target(const LQuaternion &quat) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMotorTarget(LQuaternion_to_btQuat(quat));
 }
@@ -150,6 +159,7 @@ set_motor_target(const LQuaternion &quat) {
  */
 void BulletConeTwistConstraint::
 set_motor_target_in_constraint_space(const LQuaternion &quat) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMotorTargetInConstraintSpace(LQuaternion_to_btQuat(quat));
 }
@@ -159,9 +169,30 @@ set_motor_target_in_constraint_space(const LQuaternion &quat) {
  */
 void BulletConeTwistConstraint::
 set_frames(const TransformState *ts_a, const TransformState *ts_b) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btTransform frame_a = TransformState_to_btTrans(ts_a);
   btTransform frame_b = TransformState_to_btTrans(ts_b);
 
   _constraint->setFrames(frame_a, frame_b);
 }
+
+/**
+ *
+ */
+CPT(TransformState) BulletConeTwistConstraint::
+get_frame_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getAFrame());
+}
+
+/**
+ *
+ */
+CPT(TransformState) BulletConeTwistConstraint::
+get_frame_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getBFrame());
+}

+ 2 - 2
panda/src/bullet/bulletConeTwistConstraint.h

@@ -53,8 +53,8 @@ PUBLISHED:
   void set_motor_target_in_constraint_space(const LQuaternion &quat);
 
   void set_frames(const TransformState *ts_a, const TransformState *ts_b);
-  INLINE CPT(TransformState) get_frame_a() const;
-  INLINE CPT(TransformState) get_frame_b() const;
+  CPT(TransformState) get_frame_a() const;
+  CPT(TransformState) get_frame_b() const;
 
   MAKE_PROPERTY(fix_threshold, get_fix_threshold, set_fix_threshold);
   MAKE_PROPERTY(frame_a, get_frame_a);

+ 0 - 16
panda/src/bullet/bulletConvexHullShape.I

@@ -19,19 +19,3 @@ INLINE BulletConvexHullShape::
 
   delete _shape;
 }
-
-/**
- *
- */
-INLINE BulletConvexHullShape::
-BulletConvexHullShape(const BulletConvexHullShape &copy) :
-  _shape(copy._shape) {
-}
-
-/**
- *
- */
-INLINE void BulletConvexHullShape::
-operator = (const BulletConvexHullShape &copy) {
-  _shape = copy._shape;
-}

+ 26 - 0
panda/src/bullet/bulletConvexHullShape.cxx

@@ -29,6 +29,26 @@ BulletConvexHullShape() {
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletConvexHullShape::
+BulletConvexHullShape(const BulletConvexHullShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+}
+
+/**
+ *
+ */
+void BulletConvexHullShape::
+operator = (const BulletConvexHullShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+}
+
 /**
  *
  */
@@ -43,6 +63,7 @@ ptr() const {
  */
 void BulletConvexHullShape::
 add_point(const LPoint3 &p) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _shape->addPoint(LVecBase3_to_btVector3(p));
 }
@@ -52,6 +73,10 @@ add_point(const LPoint3 &p) {
  */
 void BulletConvexHullShape::
 add_array(const PTA_LVecBase3 &points) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  if (_shape)
+      delete _shape;
 
   _shape = new btConvexHullShape(NULL, 0);
   _shape->setUserPointer(this);
@@ -75,6 +100,7 @@ add_array(const PTA_LVecBase3 &points) {
  */
 void BulletConvexHullShape::
 add_geom(const Geom *geom, const TransformState *ts) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(geom);
   nassertv(ts);

+ 2 - 2
panda/src/bullet/bulletConvexHullShape.h

@@ -29,8 +29,8 @@
 class EXPCL_PANDABULLET BulletConvexHullShape : public BulletShape {
 PUBLISHED:
   BulletConvexHullShape();
-  INLINE BulletConvexHullShape(const BulletConvexHullShape &copy);
-  INLINE void operator = (const BulletConvexHullShape &copy);
+  BulletConvexHullShape(const BulletConvexHullShape &copy);
+  void operator = (const BulletConvexHullShape &copy);
   INLINE ~BulletConvexHullShape();
 
   void add_point(const LPoint3 &p);

+ 0 - 27
panda/src/bullet/bulletConvexPointCloudShape.I

@@ -28,30 +28,3 @@ INLINE BulletConvexPointCloudShape::
 
   delete _shape;
 }
-
-/**
- *
- */
-INLINE BulletConvexPointCloudShape::
-BulletConvexPointCloudShape(const BulletConvexPointCloudShape &copy) :
-  _scale(copy._scale),
-  _shape(copy._shape) {
-}
-
-/**
- *
- */
-INLINE void BulletConvexPointCloudShape::
-operator = (const BulletConvexPointCloudShape &copy) {
-  _scale = copy._scale;
-  _shape = copy._shape;
-}
-
-/**
- *
- */
-INLINE int BulletConvexPointCloudShape::
-get_num_points() const {
-
-  return _shape->getNumPoints();
-}

+ 32 - 0
panda/src/bullet/bulletConvexPointCloudShape.cxx

@@ -84,6 +84,38 @@ BulletConvexPointCloudShape(const Geom *geom, LVecBase3 scale) {
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletConvexPointCloudShape::
+BulletConvexPointCloudShape(const BulletConvexPointCloudShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _scale = copy._scale;
+  _shape = copy._shape;
+}
+
+/**
+ *
+ */
+void BulletConvexPointCloudShape::
+operator = (const BulletConvexPointCloudShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _scale = copy._scale;
+  _shape = copy._shape;
+}
+
+/**
+ *
+ */
+int BulletConvexPointCloudShape::
+get_num_points() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _shape->getNumPoints();
+}
+
 /**
  * Tells the BamReader how to create objects of type BulletShape.
  */

+ 3 - 3
panda/src/bullet/bulletConvexPointCloudShape.h

@@ -33,11 +33,11 @@ private:
 PUBLISHED:
   explicit BulletConvexPointCloudShape(const PTA_LVecBase3 &points, LVecBase3 scale=LVecBase3(1.));
   explicit BulletConvexPointCloudShape(const Geom *geom, LVecBase3 scale=LVecBase3(1.));
-  INLINE BulletConvexPointCloudShape(const BulletConvexPointCloudShape &copy);
-  INLINE void operator = (const BulletConvexPointCloudShape &copy);
+  BulletConvexPointCloudShape(const BulletConvexPointCloudShape &copy);
+  void operator = (const BulletConvexPointCloudShape &copy);
   INLINE ~BulletConvexPointCloudShape();
 
-  INLINE int get_num_points() const;
+  int get_num_points() const;
 
   MAKE_PROPERTY(num_points, get_num_points);
 

+ 0 - 44
panda/src/bullet/bulletCylinderShape.I

@@ -28,47 +28,3 @@ INLINE BulletCylinderShape::
 
   delete _shape;
 }
-
-/**
- *
- */
-INLINE BulletCylinderShape::
-BulletCylinderShape(const BulletCylinderShape &copy) :
-  _shape(copy._shape), _half_extents(copy._half_extents) {
-}
-
-/**
- *
- */
-INLINE void BulletCylinderShape::
-operator = (const BulletCylinderShape &copy) {
-  _shape = copy._shape;
-  _half_extents = copy._half_extents;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletCylinderShape::
-get_radius() const {
-
-  return (PN_stdfloat)_shape->getRadius();
-}
-
-/**
- *
- */
-INLINE LVecBase3 BulletCylinderShape::
-get_half_extents_without_margin() const {
-
-  return btVector3_to_LVecBase3(_shape->getHalfExtentsWithoutMargin());
-}
-
-/**
- *
- */
-INLINE LVecBase3 BulletCylinderShape::
-get_half_extents_with_margin() const {
-
-  return btVector3_to_LVecBase3(_shape->getHalfExtentsWithMargin());
-}

+ 55 - 0
panda/src/bullet/bulletCylinderShape.cxx

@@ -39,6 +39,7 @@ BulletCylinderShape(const LVector3 &half_extents, BulletUpAxis up) :
     break;
   }
 
+  nassertv(_shape);
   _shape->setUserPointer(this);
 }
 
@@ -66,9 +67,32 @@ BulletCylinderShape(PN_stdfloat radius, PN_stdfloat height, BulletUpAxis up) {
     break;
   }
 
+  nassertv(_shape);
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletCylinderShape::
+BulletCylinderShape(const BulletCylinderShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _half_extents = copy._half_extents;
+}
+
+/**
+ *
+ */
+void BulletCylinderShape::
+operator = (const BulletCylinderShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _half_extents = copy._half_extents;
+}
+
 /**
  *
  */
@@ -78,6 +102,36 @@ ptr() const {
   return _shape;
 }
 
+/**
+ *
+ */
+PN_stdfloat BulletCylinderShape::
+get_radius() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_shape->getRadius();
+}
+
+/**
+ *
+ */
+LVecBase3 BulletCylinderShape::
+get_half_extents_without_margin() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVecBase3(_shape->getHalfExtentsWithoutMargin());
+}
+
+/**
+ *
+ */
+LVecBase3 BulletCylinderShape::
+get_half_extents_with_margin() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVecBase3(_shape->getHalfExtentsWithMargin());
+}
+
 /**
  * Tells the BamReader how to create objects of type BulletShape.
  */
@@ -150,6 +204,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
     break;
   }
 
+  nassertv(_shape);
   _shape->setUserPointer(this);
   _shape->setMargin(margin);
 }

+ 5 - 5
panda/src/bullet/bulletCylinderShape.h

@@ -31,13 +31,13 @@ private:
 PUBLISHED:
   explicit BulletCylinderShape(PN_stdfloat radius, PN_stdfloat height, BulletUpAxis up=Z_up);
   explicit BulletCylinderShape(const LVector3 &half_extents, BulletUpAxis up=Z_up);
-  INLINE BulletCylinderShape(const BulletCylinderShape &copy);
-  INLINE void operator = (const BulletCylinderShape &copy);
+  BulletCylinderShape(const BulletCylinderShape &copy);
+  void operator = (const BulletCylinderShape &copy);
   INLINE ~BulletCylinderShape();
 
-  INLINE PN_stdfloat get_radius() const;
-  INLINE LVecBase3 get_half_extents_without_margin() const;
-  INLINE LVecBase3 get_half_extents_with_margin() const;
+  PN_stdfloat get_radius() const;
+  LVecBase3 get_half_extents_without_margin() const;
+  LVecBase3 get_half_extents_with_margin() const;
 
   MAKE_PROPERTY(radius, get_radius);
   MAKE_PROPERTY(half_extents_without_margin, get_half_extents_without_margin);

+ 2 - 3
panda/src/bullet/bulletDebugNode.cxx

@@ -169,7 +169,7 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
   PT(Geom) debug_triangles;
 
   {
-    LightMutexHolder holder(_lock);
+    LightMutexHolder holder(BulletWorld::get_global_lock());
     if (_debug_world == nullptr) {
       return;
     }
@@ -270,8 +270,7 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
  *
  */
 void BulletDebugNode::
-sync_b2p(btDynamicsWorld *world) {
-  LightMutexHolder holder(_lock);
+do_sync_b2p(btDynamicsWorld *world) {
 
   _debug_world = world;
   _debug_stale = true;

+ 1 - 3
panda/src/bullet/bulletDebugNode.h

@@ -17,7 +17,6 @@
 #include "pandabase.h"
 
 #include "bullet_includes.h"
-#include "lightMutex.h"
 
 /**
  *
@@ -55,7 +54,7 @@ public:
   virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data);
 
 private:
-  void sync_b2p(btDynamicsWorld *world);
+  void do_sync_b2p(btDynamicsWorld *world);
 
   struct Line {
     LVecBase3 _p0;
@@ -101,7 +100,6 @@ private:
     int _mode;
   };
 
-  LightMutex _lock;
   DebugDraw _drawer;
 
   bool _debug_stale;

+ 0 - 18
panda/src/bullet/bulletGenericConstraint.I

@@ -19,21 +19,3 @@ INLINE BulletGenericConstraint::
 
   delete _constraint;
 }
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletGenericConstraint::
-get_frame_a() const {
-
-  return btTrans_to_TransformState(_constraint->getFrameOffsetA());
-}
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletGenericConstraint::
-get_frame_b() const {
-
-  return btTrans_to_TransformState(_constraint->getFrameOffsetB());
-}

+ 28 - 0
panda/src/bullet/bulletGenericConstraint.cxx

@@ -63,6 +63,7 @@ ptr() const {
  */
 LVector3 BulletGenericConstraint::
 get_axis(int axis) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertr(axis >= 0, LVector3::zero());
   nassertr(axis <= 3, LVector3::zero());
@@ -76,6 +77,7 @@ get_axis(int axis) const {
  */
 PN_stdfloat BulletGenericConstraint::
 get_pivot(int axis) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertr(axis >= 0, 0.0f);
   nassertr(axis <= 3, 0.0f);
@@ -89,6 +91,7 @@ get_pivot(int axis) const {
  */
 PN_stdfloat BulletGenericConstraint::
 get_angle(int axis) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertr(axis >= 0, 0.0f);
   nassertr(axis <= 3, 0.0f);
@@ -102,6 +105,7 @@ get_angle(int axis) const {
  */
 void BulletGenericConstraint::
 set_linear_limit(int axis, PN_stdfloat low, PN_stdfloat high) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(axis >= 0);
   nassertv(axis <= 3);
@@ -115,6 +119,7 @@ set_linear_limit(int axis, PN_stdfloat low, PN_stdfloat high) {
  */
 void BulletGenericConstraint::
 set_angular_limit(int axis, PN_stdfloat low, PN_stdfloat high) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(axis >= 0);
   nassertv(axis <= 3);
@@ -126,11 +131,32 @@ set_angular_limit(int axis, PN_stdfloat low, PN_stdfloat high) {
   _constraint->setLimit(axis + 3, low, high);
 }
 
+/**
+ *
+ */
+CPT(TransformState) BulletGenericConstraint::
+get_frame_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getFrameOffsetA());
+}
+
+/**
+ *
+ */
+CPT(TransformState) BulletGenericConstraint::
+get_frame_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getFrameOffsetB());
+}
+
 /**
  *
  */
 BulletRotationalLimitMotor BulletGenericConstraint::
 get_rotational_limit_motor(int axis) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return BulletRotationalLimitMotor(*_constraint->getRotationalLimitMotor(axis));
 }
@@ -140,6 +166,7 @@ get_rotational_limit_motor(int axis) {
  */
 BulletTranslationalLimitMotor BulletGenericConstraint::
 get_translational_limit_motor() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return BulletTranslationalLimitMotor(*_constraint->getTranslationalLimitMotor());
 }
@@ -149,6 +176,7 @@ get_translational_limit_motor() {
  */
 void BulletGenericConstraint::
 set_frames(const TransformState *ts_a, const TransformState *ts_b) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btTransform frame_a = TransformState_to_btTrans(ts_a);
   btTransform frame_b = TransformState_to_btTrans(ts_b);

+ 2 - 2
panda/src/bullet/bulletGenericConstraint.h

@@ -57,8 +57,8 @@ PUBLISHED:
 
   // Frames
   void set_frames(const TransformState *ts_a, const TransformState *ts_b);
-  INLINE CPT(TransformState) get_frame_a() const;
-  INLINE CPT(TransformState) get_frame_b() const;
+  CPT(TransformState) get_frame_a() const;
+  CPT(TransformState) get_frame_b() const;
 
   MAKE_PROPERTY(translational_limit_motor, get_translational_limit_motor);
   MAKE_PROPERTY(frame_a, get_frame_a);

+ 0 - 20
panda/src/bullet/bulletGhostNode.I

@@ -20,23 +20,3 @@ INLINE BulletGhostNode::
   delete _ghost;
 }
 
-/**
- *
- */
-INLINE int BulletGhostNode::
-get_num_overlapping_nodes() const {
-
-  return _ghost->getNumOverlappingObjects();
-}
-
-/**
- *
- */
-INLINE PandaNode *BulletGhostNode::
-get_overlapping_node(int idx) const {
-
-  nassertr(idx >=0 && idx < _ghost->getNumOverlappingObjects(), NULL);
-
-  btCollisionObject *object = _ghost->getOverlappingObject(idx);
-  return (object) ? (PandaNode *)object->getUserPointer() : NULL;
-}

+ 41 - 7
panda/src/bullet/bulletGhostNode.cxx

@@ -53,6 +53,7 @@ get_object() const {
  */
 void BulletGhostNode::
 parents_changed() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   Parents parents = get_parents();
   for (size_t i = 0; i < parents.get_num_parents(); ++i) {
@@ -73,10 +74,10 @@ parents_changed() {
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletGhostNode::
-transform_changed() {
+do_transform_changed() {
 
   if (_sync_disable) return;
 
@@ -98,27 +99,60 @@ transform_changed() {
       if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
         for (int i=0; i<get_num_shapes(); i++) {
           PT(BulletShape) shape = _shapes[i];
-          shape->set_local_scale(scale);
+          shape->do_set_local_scale(scale);
         }
       }
     }
   }
 }
 
+void BulletGhostNode::
+transform_changed() {
+
+  if (_sync_disable) return;
+
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_transform_changed();
+}
+
 /**
  *
  */
-void BulletGhostNode::
-sync_p2b() {
+int BulletGhostNode::
+get_num_overlapping_nodes() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  transform_changed();
+  return _ghost->getNumOverlappingObjects();
 }
 
 /**
  *
  */
+PandaNode *BulletGhostNode::
+get_overlapping_node(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr(idx >=0 && idx < _ghost->getNumOverlappingObjects(), NULL);
+
+  btCollisionObject *object = _ghost->getOverlappingObject(idx);
+  return (object) ? (PandaNode *)object->getUserPointer() : NULL;
+}
+
+/**
+ * Assumes the lock(bullet global lock) is held by the caller
+ */
+void BulletGhostNode::
+do_sync_p2b() {
+
+  do_transform_changed();
+}
+
+/**
+ *  Assumes the lock(bullet global lock) is held by the caller
+ */
 void BulletGhostNode::
-sync_b2p() {
+do_sync_b2p() {
 
   NodePath np = NodePath::any_path((PandaNode *)this);
   LVecBase3 scale = np.get_net_transform()->get_scale();

+ 6 - 4
panda/src/bullet/bulletGhostNode.h

@@ -34,8 +34,8 @@ PUBLISHED:
   INLINE ~BulletGhostNode();
 
   // Overlapping
-  INLINE int get_num_overlapping_nodes() const;
-  INLINE PandaNode *get_overlapping_node(int idx) const;
+  int get_num_overlapping_nodes() const;
+  PandaNode *get_overlapping_node(int idx) const;
   MAKE_SEQ(get_overlapping_nodes, get_num_overlapping_nodes, get_overlapping_node);
   
   MAKE_SEQ_PROPERTY(overlapping_nodes, get_num_overlapping_nodes, get_overlapping_node);
@@ -43,8 +43,8 @@ PUBLISHED:
 public:
   virtual btCollisionObject *get_object() const;
 
-  void sync_p2b();
-  void sync_b2p();
+  void do_sync_p2b();
+  void do_sync_b2p();
 
 protected:
   virtual void parents_changed();
@@ -57,6 +57,8 @@ private:
 
   btPairCachingGhostObject *_ghost;
 
+  void do_transform_changed();
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 0 - 30
panda/src/bullet/bulletHeightfieldShape.I

@@ -32,33 +32,3 @@ INLINE BulletHeightfieldShape::
   delete _shape;
   delete [] _data;
 }
-
-/**
- *
- */
-INLINE BulletHeightfieldShape::
-BulletHeightfieldShape(const BulletHeightfieldShape &copy) :
-  _shape(copy._shape),
-  _num_rows(copy._num_rows),
-  _num_cols(copy._num_cols),
-  _max_height(copy._max_height),
-  _up(copy._up) {
-
-  size_t size = (size_t)_num_rows * (size_t)_num_cols;
-  _data = new btScalar[size];
-  memcpy(_data, copy._data, size * sizeof(btScalar));
-}
-
-/**
- *
- */
-INLINE void BulletHeightfieldShape::
-operator = (const BulletHeightfieldShape &copy) {
-  _shape = copy._shape;
-  _num_rows = copy._num_rows;
-  _num_cols = copy._num_cols;
-
-  size_t size = (size_t)_num_rows * (size_t)_num_cols;
-  _data = new btScalar[size];
-  memcpy(_data, copy._data, size * sizeof(btScalar));
-}

+ 39 - 1
panda/src/bullet/bulletHeightfieldShape.cxx

@@ -61,6 +61,7 @@ ptr() const {
  */
 void BulletHeightfieldShape::
 set_use_diamond_subdivision(bool flag) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _shape->setUseDiamondSubdivision(flag);
 }
@@ -104,6 +105,42 @@ BulletHeightfieldShape(Texture *tex, PN_stdfloat max_height, BulletUpAxis up) :
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletHeightfieldShape::
+BulletHeightfieldShape(const BulletHeightfieldShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _num_rows = copy._num_rows;
+  _num_cols = copy._num_cols;
+  _max_height = copy._max_height;
+  _up = copy._up;
+
+  size_t size = (size_t)_num_rows * (size_t)_num_cols;
+  _data = new btScalar[size];
+  memcpy(_data, copy._data, size * sizeof(btScalar));
+}
+
+/**
+ *
+ */
+void BulletHeightfieldShape::
+operator = (const BulletHeightfieldShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _num_rows = copy._num_rows;
+  _num_cols = copy._num_cols;
+  _max_height = copy._max_height;
+  _up = copy._up;
+
+  size_t size = (size_t)_num_rows * (size_t)_num_cols;
+  _data = new btScalar[size];
+  memcpy(_data, copy._data, size * sizeof(btScalar));
+}
+
 /**
  * Tells the BamReader how to create objects of type BulletShape.
  */
@@ -169,8 +206,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   _num_cols = scan.get_int32();
 
   size_t size = (size_t)_num_rows * (size_t)_num_cols;
-  delete[] _data;
+  delete [] _data;
   _data = new float[size];
+
   for (size_t i = 0; i < size; ++i) {
     _data[i]  = scan.get_stdfloat();
   }

+ 2 - 2
panda/src/bullet/bulletHeightfieldShape.h

@@ -34,8 +34,8 @@ private:
 PUBLISHED:
   explicit BulletHeightfieldShape(const PNMImage &image, PN_stdfloat max_height, BulletUpAxis up=Z_up);
   explicit BulletHeightfieldShape(Texture *tex, PN_stdfloat max_height, BulletUpAxis up=Z_up);
-  INLINE BulletHeightfieldShape(const BulletHeightfieldShape &copy);
-  INLINE void operator = (const BulletHeightfieldShape &copy);
+  BulletHeightfieldShape(const BulletHeightfieldShape &copy);
+  void operator = (const BulletHeightfieldShape &copy);
   INLINE ~BulletHeightfieldShape();
 
   void set_use_diamond_subdivision(bool flag=true);

+ 0 - 18
panda/src/bullet/bulletHingeConstraint.I

@@ -19,21 +19,3 @@ INLINE BulletHingeConstraint::
 
   delete _constraint;
 }
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletHingeConstraint::
-get_frame_a() const {
-
-  return btTrans_to_TransformState(_constraint->getAFrame());
-}
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletHingeConstraint::
-get_frame_b() const {
-
-  return btTrans_to_TransformState(_constraint->getBFrame());
-}

+ 33 - 0
panda/src/bullet/bulletHingeConstraint.cxx

@@ -111,6 +111,7 @@ ptr() const {
  */
 void BulletHingeConstraint::
 set_angular_only(bool value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _constraint->setAngularOnly(value);
 }
@@ -120,6 +121,7 @@ set_angular_only(bool value) {
  */
 bool BulletHingeConstraint::
 get_angular_only() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _constraint->getAngularOnly();
 }
@@ -129,6 +131,7 @@ get_angular_only() const {
  */
 void BulletHingeConstraint::
 set_limit(PN_stdfloat low, PN_stdfloat high, PN_stdfloat softness, PN_stdfloat bias, PN_stdfloat relaxation) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   low  = deg_2_rad(low);
   high = deg_2_rad(high);
@@ -141,6 +144,7 @@ set_limit(PN_stdfloat low, PN_stdfloat high, PN_stdfloat softness, PN_stdfloat b
  */
 void BulletHingeConstraint::
 set_axis(const LVector3 &axis) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!axis.is_nan());
 
@@ -153,6 +157,7 @@ set_axis(const LVector3 &axis) {
  */
 PN_stdfloat BulletHingeConstraint::
 get_lower_limit() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return rad_2_deg(_constraint->getLowerLimit());
 }
@@ -162,6 +167,7 @@ get_lower_limit() const {
  */
 PN_stdfloat BulletHingeConstraint::
 get_upper_limit() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return rad_2_deg(_constraint->getUpperLimit());
 }
@@ -171,6 +177,7 @@ get_upper_limit() const {
  */
 PN_stdfloat BulletHingeConstraint::
 get_hinge_angle() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return rad_2_deg(_constraint->getHingeAngle());
 }
@@ -184,6 +191,7 @@ get_hinge_angle() {
  */
 void BulletHingeConstraint::
 enable_angular_motor(bool enable, PN_stdfloat target_velocity, PN_stdfloat max_impulse) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->enableAngularMotor(enable, target_velocity, max_impulse);
 }
@@ -193,6 +201,7 @@ enable_angular_motor(bool enable, PN_stdfloat target_velocity, PN_stdfloat max_i
  */
 void BulletHingeConstraint::
 enable_motor(bool enable) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->enableMotor(enable);
 }
@@ -203,6 +212,7 @@ enable_motor(bool enable) {
  */
 void BulletHingeConstraint::
 set_max_motor_impulse(PN_stdfloat max_impulse) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMaxMotorImpulse(max_impulse);
 }
@@ -212,6 +222,7 @@ set_max_motor_impulse(PN_stdfloat max_impulse) {
  */
 void BulletHingeConstraint::
 set_motor_target(const LQuaternion &quat, PN_stdfloat dt) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMotorTarget(LQuaternion_to_btQuat(quat), dt);
 }
@@ -221,6 +232,7 @@ set_motor_target(const LQuaternion &quat, PN_stdfloat dt) {
  */
 void BulletHingeConstraint::
 set_motor_target(PN_stdfloat target_angle, PN_stdfloat dt) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMotorTarget(target_angle, dt);
 }
@@ -230,9 +242,30 @@ set_motor_target(PN_stdfloat target_angle, PN_stdfloat dt) {
  */
 void BulletHingeConstraint::
 set_frames(const TransformState *ts_a, const TransformState *ts_b) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btTransform frame_a = TransformState_to_btTrans(ts_a);
   btTransform frame_b = TransformState_to_btTrans(ts_b);
 
   _constraint->setFrames(frame_a, frame_b);
 }
+
+/**
+ *
+ */
+CPT(TransformState) BulletHingeConstraint::
+get_frame_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getAFrame());
+}
+
+/**
+ *
+ */
+CPT(TransformState) BulletHingeConstraint::
+get_frame_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getBFrame());
+}

+ 2 - 2
panda/src/bullet/bulletHingeConstraint.h

@@ -69,8 +69,8 @@ PUBLISHED:
   void set_motor_target(PN_stdfloat target_angle, PN_stdfloat dt);
 
   void set_frames(const TransformState *ts_a, const TransformState *ts_b);
-  INLINE CPT(TransformState) get_frame_a() const;
-  INLINE CPT(TransformState) get_frame_b() const;
+  CPT(TransformState) get_frame_a() const;
+  CPT(TransformState) get_frame_b() const;
 
   MAKE_PROPERTY(hinge_angle, get_hinge_angle);
   MAKE_PROPERTY(lower_limit, get_lower_limit);

+ 0 - 225
panda/src/bullet/bulletManifoldPoint.I

@@ -18,228 +18,3 @@ INLINE BulletManifoldPoint::
 ~BulletManifoldPoint() {
 
 }
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_lateral_friction_initialized(bool value) {
-#if BT_BULLET_VERSION >= 285
-  if (value) {
-    _pt.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED;
-  } else {
-    _pt.m_contactPointFlags &= ~BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED;
-  }
-#else
-  _pt.m_lateralFrictionInitialized = value;
-#endif
-}
-
-/**
- *
- */
-INLINE bool BulletManifoldPoint::
-get_lateral_friction_initialized() const {
-#if BT_BULLET_VERSION >= 285
-  return (_pt.m_contactPointFlags & BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED) != 0;
-#else
-  return _pt.m_lateralFrictionInitialized;
-#endif
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_lateral_friction_dir1(const LVecBase3 &dir) {
-
-  _pt.m_lateralFrictionDir1 = LVecBase3_to_btVector3(dir);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletManifoldPoint::
-get_lateral_friction_dir1() const {
-
-  return btVector3_to_LVector3(_pt.m_lateralFrictionDir1);
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_lateral_friction_dir2(const LVecBase3 &dir) {
-
-  _pt.m_lateralFrictionDir2 = LVecBase3_to_btVector3(dir);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletManifoldPoint::
-get_lateral_friction_dir2() const {
-
-  return btVector3_to_LVector3(_pt.m_lateralFrictionDir2);
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_contact_motion1(PN_stdfloat value) {
-
-  _pt.m_contactMotion1 = (btScalar)value;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_contact_motion1() const {
-
-  return (PN_stdfloat)_pt.m_contactMotion1;
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_contact_motion2(PN_stdfloat value) {
-
-  _pt.m_contactMotion2 = (btScalar)value;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_contact_motion2() const {
-
-  return (PN_stdfloat)_pt.m_contactMotion2;
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_combined_friction(PN_stdfloat value) {
-
-  _pt.m_combinedFriction = (btScalar)value;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_combined_friction() const {
-
-  return (PN_stdfloat)_pt.m_combinedFriction;
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_combined_restitution(PN_stdfloat value) {
-
-  _pt.m_combinedRestitution = (btScalar)value;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_combined_restitution() const {
-
-  return (PN_stdfloat)_pt.m_combinedRestitution;
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_applied_impulse(PN_stdfloat value) {
-
-  _pt.m_appliedImpulse = (btScalar)value;
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_applied_impulse_lateral1(PN_stdfloat value) {
-
-  _pt.m_appliedImpulseLateral1 = (btScalar)value;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_applied_impulse_lateral1() const {
-
-  return (PN_stdfloat)_pt.m_appliedImpulseLateral1;
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_applied_impulse_lateral2(PN_stdfloat value) {
-
-  _pt.m_appliedImpulseLateral2 = (btScalar)value;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_applied_impulse_lateral2() const {
-
-  return (PN_stdfloat)_pt.m_appliedImpulseLateral2;
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_contact_cfm1(PN_stdfloat value) {
-#if BT_BULLET_VERSION < 285
-  _pt.m_contactCFM1 = (btScalar)value;
-#endif
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_contact_cfm1() const {
-#if BT_BULLET_VERSION < 285
-  return (PN_stdfloat)_pt.m_contactCFM1;
-#else
-  return 0;
-#endif
-}
-
-/**
- *
- */
-INLINE void BulletManifoldPoint::
-set_contact_cfm2(PN_stdfloat value) {
-#if BT_BULLET_VERSION < 285
-  _pt.m_contactCFM2 = (btScalar)value;
-#endif
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletManifoldPoint::
-get_contact_cfm2() const {
-#if BT_BULLET_VERSION < 285
-  return (PN_stdfloat)_pt.m_contactCFM2;
-#else
-  return 0;
-#endif
-}

+ 266 - 0
panda/src/bullet/bulletManifoldPoint.cxx

@@ -46,6 +46,7 @@ operator=(const BulletManifoldPoint& other) {
  */
 int BulletManifoldPoint::
 get_life_time() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _pt.getLifeTime();
 }
@@ -55,6 +56,7 @@ get_life_time() const {
  */
 PN_stdfloat BulletManifoldPoint::
 get_distance() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_pt.getDistance();
 }
@@ -64,6 +66,7 @@ get_distance() const {
  */
 PN_stdfloat BulletManifoldPoint::
 get_applied_impulse() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_pt.getAppliedImpulse();
 }
@@ -73,6 +76,7 @@ get_applied_impulse() const {
  */
 LPoint3 BulletManifoldPoint::
 get_position_world_on_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LPoint3(_pt.getPositionWorldOnA());
 }
@@ -82,6 +86,7 @@ get_position_world_on_a() const {
  */
 LPoint3 BulletManifoldPoint::
 get_position_world_on_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LPoint3(_pt.getPositionWorldOnB());
 }
@@ -91,6 +96,7 @@ get_position_world_on_b() const {
  */
 LVector3 BulletManifoldPoint::
 get_normal_world_on_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_pt.m_normalWorldOnB);
 }
@@ -100,6 +106,7 @@ get_normal_world_on_b() const {
  */
 LPoint3 BulletManifoldPoint::
 get_local_point_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LPoint3(_pt.m_localPointA);
 }
@@ -109,6 +116,7 @@ get_local_point_a() const {
  */
 LPoint3 BulletManifoldPoint::
 get_local_point_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LPoint3(_pt.m_localPointB);
 }
@@ -118,6 +126,7 @@ get_local_point_b() const {
  */
 int BulletManifoldPoint::
 get_part_id0() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _pt.m_partId0;
 }
@@ -127,6 +136,7 @@ get_part_id0() const {
  */
 int BulletManifoldPoint::
 get_part_id1() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _pt.m_partId1;
 }
@@ -136,6 +146,7 @@ get_part_id1() const {
  */
 int BulletManifoldPoint::
 get_index0() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _pt.m_index0;
 }
@@ -145,6 +156,261 @@ get_index0() const {
  */
 int BulletManifoldPoint::
 get_index1() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _pt.m_index1;
 }
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_lateral_friction_initialized(bool value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+#if BT_BULLET_VERSION >= 285
+  if (value) {
+    _pt.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED;
+  } else {
+    _pt.m_contactPointFlags &= ~BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED;
+  }
+#else
+  _pt.m_lateralFrictionInitialized = value;
+#endif
+}
+
+/**
+ *
+ */
+bool BulletManifoldPoint::
+get_lateral_friction_initialized() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+#if BT_BULLET_VERSION >= 285
+  return (_pt.m_contactPointFlags & BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED) != 0;
+#else
+  return _pt.m_lateralFrictionInitialized;
+#endif
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_lateral_friction_dir1(const LVecBase3 &dir) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_lateralFrictionDir1 = LVecBase3_to_btVector3(dir);
+}
+
+/**
+ *
+ */
+LVector3 BulletManifoldPoint::
+get_lateral_friction_dir1() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_pt.m_lateralFrictionDir1);
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_lateral_friction_dir2(const LVecBase3 &dir) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_lateralFrictionDir2 = LVecBase3_to_btVector3(dir);
+}
+
+/**
+ *
+ */
+LVector3 BulletManifoldPoint::
+get_lateral_friction_dir2() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_pt.m_lateralFrictionDir2);
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_contact_motion1(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_contactMotion1 = (btScalar)value;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_contact_motion1() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_pt.m_contactMotion1;
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_contact_motion2(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_contactMotion2 = (btScalar)value;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_contact_motion2() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_pt.m_contactMotion2;
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_combined_friction(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_combinedFriction = (btScalar)value;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_combined_friction() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_pt.m_combinedFriction;
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_combined_restitution(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_combinedRestitution = (btScalar)value;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_combined_restitution() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_pt.m_combinedRestitution;
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_applied_impulse(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_appliedImpulse = (btScalar)value;
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_applied_impulse_lateral1(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_appliedImpulseLateral1 = (btScalar)value;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_applied_impulse_lateral1() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_pt.m_appliedImpulseLateral1;
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_applied_impulse_lateral2(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _pt.m_appliedImpulseLateral2 = (btScalar)value;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_applied_impulse_lateral2() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_pt.m_appliedImpulseLateral2;
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_contact_cfm1(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+#if BT_BULLET_VERSION < 285
+  _pt.m_contactCFM1 = (btScalar)value;
+#endif
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_contact_cfm1() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+#if BT_BULLET_VERSION < 285
+  return (PN_stdfloat)_pt.m_contactCFM1;
+#else
+  return 0;
+#endif
+}
+
+/**
+ *
+ */
+void BulletManifoldPoint::
+set_contact_cfm2(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+#if BT_BULLET_VERSION < 285
+  _pt.m_contactCFM2 = (btScalar)value;
+#endif
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletManifoldPoint::
+get_contact_cfm2() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+#if BT_BULLET_VERSION < 285
+  return (PN_stdfloat)_pt.m_contactCFM2;
+#else
+  return 0;
+#endif
+}

+ 24 - 24
panda/src/bullet/bulletManifoldPoint.h

@@ -43,30 +43,30 @@ PUBLISHED:
   int get_index0() const;
   int get_index1() const;
 
-  INLINE void set_lateral_friction_initialized(bool value);
-  INLINE void set_lateral_friction_dir1(const LVecBase3 &dir);
-  INLINE void set_lateral_friction_dir2(const LVecBase3 &dir);
-  INLINE void set_contact_motion1(PN_stdfloat value);
-  INLINE void set_contact_motion2(PN_stdfloat value);
-  INLINE void set_combined_friction(PN_stdfloat value);
-  INLINE void set_combined_restitution(PN_stdfloat value);
-  INLINE void set_applied_impulse(PN_stdfloat value);
-  INLINE void set_applied_impulse_lateral1(PN_stdfloat value);
-  INLINE void set_applied_impulse_lateral2(PN_stdfloat value);
-  INLINE void set_contact_cfm1(PN_stdfloat value);
-  INLINE void set_contact_cfm2(PN_stdfloat value);
-
-  INLINE bool get_lateral_friction_initialized() const;
-  INLINE LVector3 get_lateral_friction_dir1() const;
-  INLINE LVector3 get_lateral_friction_dir2() const;
-  INLINE PN_stdfloat get_contact_motion1() const;
-  INLINE PN_stdfloat get_contact_motion2() const;
-  INLINE PN_stdfloat get_combined_friction() const;
-  INLINE PN_stdfloat get_combined_restitution() const;
-  INLINE PN_stdfloat get_applied_impulse_lateral1() const;
-  INLINE PN_stdfloat get_applied_impulse_lateral2() const;
-  INLINE PN_stdfloat get_contact_cfm1() const;
-  INLINE PN_stdfloat get_contact_cfm2() const;
+  void set_lateral_friction_initialized(bool value);
+  void set_lateral_friction_dir1(const LVecBase3 &dir);
+  void set_lateral_friction_dir2(const LVecBase3 &dir);
+  void set_contact_motion1(PN_stdfloat value);
+  void set_contact_motion2(PN_stdfloat value);
+  void set_combined_friction(PN_stdfloat value);
+  void set_combined_restitution(PN_stdfloat value);
+  void set_applied_impulse(PN_stdfloat value);
+  void set_applied_impulse_lateral1(PN_stdfloat value);
+  void set_applied_impulse_lateral2(PN_stdfloat value);
+  void set_contact_cfm1(PN_stdfloat value);
+  void set_contact_cfm2(PN_stdfloat value);
+
+  bool get_lateral_friction_initialized() const;
+  LVector3 get_lateral_friction_dir1() const;
+  LVector3 get_lateral_friction_dir2() const;
+  PN_stdfloat get_contact_motion1() const;
+  PN_stdfloat get_contact_motion2() const;
+  PN_stdfloat get_combined_friction() const;
+  PN_stdfloat get_combined_restitution() const;
+  PN_stdfloat get_applied_impulse_lateral1() const;
+  PN_stdfloat get_applied_impulse_lateral2() const;
+  PN_stdfloat get_contact_cfm1() const;
+  PN_stdfloat get_contact_cfm2() const;
 
   MAKE_PROPERTY(life_time, get_life_time);
   MAKE_PROPERTY(distance, get_distance);

+ 0 - 58
panda/src/bullet/bulletMinkowskiSumShape.I

@@ -30,64 +30,6 @@ INLINE BulletMinkowskiSumShape::
   delete _shape;
 }
 
-/**
- *
- */
-INLINE BulletMinkowskiSumShape::
-BulletMinkowskiSumShape(const BulletMinkowskiSumShape &copy) :
-  _shape(copy._shape),
-  _shape_a(copy._shape_a),
-  _shape_b(copy._shape_b) {
-}
-
-/**
- *
- */
-INLINE void BulletMinkowskiSumShape::
-operator = (const BulletMinkowskiSumShape &copy) {
-  _shape = copy._shape;
-  _shape_a = copy._shape_a;
-  _shape_b = copy._shape_b;
-}
-
-/**
- *
- */
-INLINE void BulletMinkowskiSumShape::
-set_transform_a(const TransformState *ts) {
-
-  nassertv(ts);
-  _shape->setTransformA(TransformState_to_btTrans(ts));
-}
-
-/**
- *
- */
-INLINE void BulletMinkowskiSumShape::
-set_transform_b(const TransformState *ts) {
-
-  nassertv(ts);
-  _shape->setTransformB(TransformState_to_btTrans(ts));
-}
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletMinkowskiSumShape::
-get_transform_a() const {
-
-  return btTrans_to_TransformState(_shape->getTransformA());
-}
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletMinkowskiSumShape::
-get_transform_b() const {
-
-  return btTrans_to_TransformState(_shape->GetTransformB());
-}
-
 /**
  *
  */

+ 66 - 0
panda/src/bullet/bulletMinkowskiSumShape.cxx

@@ -33,6 +33,30 @@ BulletMinkowskiSumShape(const BulletShape *shape_a, const BulletShape *shape_b)
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletMinkowskiSumShape::
+BulletMinkowskiSumShape(const BulletMinkowskiSumShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _shape_a = copy._shape_a;
+  _shape_b = copy._shape_b;
+}
+
+/**
+ *
+ */
+void BulletMinkowskiSumShape::
+operator = (const BulletMinkowskiSumShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _shape_a = copy._shape_a;
+  _shape_b = copy._shape_b;
+}
+
 /**
  *
  */
@@ -42,6 +66,48 @@ ptr() const {
   return _shape;
 }
 
+/**
+ *
+ */
+void BulletMinkowskiSumShape::
+set_transform_a(const TransformState *ts) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(ts);
+  _shape->setTransformA(TransformState_to_btTrans(ts));
+}
+
+/**
+ *
+ */
+void BulletMinkowskiSumShape::
+set_transform_b(const TransformState *ts) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(ts);
+  _shape->setTransformB(TransformState_to_btTrans(ts));
+}
+
+/**
+ *
+ */
+CPT(TransformState) BulletMinkowskiSumShape::
+get_transform_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_shape->getTransformA());
+}
+
+/**
+ *
+ */
+CPT(TransformState) BulletMinkowskiSumShape::
+get_transform_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_shape->GetTransformB());
+}
+
 /**
  * Tells the BamReader how to create objects of type BulletShape.
  */

+ 6 - 6
panda/src/bullet/bulletMinkowskiSumShape.h

@@ -32,14 +32,14 @@ private:
 
 PUBLISHED:
   explicit BulletMinkowskiSumShape(const BulletShape *shape_a, const BulletShape *shape_b);
-  INLINE BulletMinkowskiSumShape(const BulletMinkowskiSumShape &copy);
-  INLINE void operator = (const BulletMinkowskiSumShape &copy);
+  BulletMinkowskiSumShape(const BulletMinkowskiSumShape &copy);
+  void operator = (const BulletMinkowskiSumShape &copy);
   INLINE ~BulletMinkowskiSumShape();
 
-  INLINE void set_transform_a(const TransformState *ts);
-  INLINE void set_transform_b(const TransformState *ts);
-  INLINE CPT(TransformState) get_transform_a() const;
-  INLINE CPT(TransformState) get_transform_b() const;
+  void set_transform_a(const TransformState *ts);
+  void set_transform_b(const TransformState *ts);
+  CPT(TransformState) get_transform_a() const;
+  CPT(TransformState) get_transform_b() const;
 
   INLINE const BulletShape *get_shape_a() const;
   INLINE const BulletShape *get_shape_b() const;

+ 0 - 45
panda/src/bullet/bulletMultiSphereShape.I

@@ -19,48 +19,3 @@ INLINE BulletMultiSphereShape::
 
   delete _shape;
 }
-
-/**
- *
- */
-INLINE BulletMultiSphereShape::
-BulletMultiSphereShape(const BulletMultiSphereShape &copy) :
-  _shape(copy._shape) {
-}
-
-/**
- *
- */
-INLINE void BulletMultiSphereShape::
-operator = (const BulletMultiSphereShape &copy) {
-  _shape = copy._shape;
-}
-
-/**
- *
- */
-INLINE int BulletMultiSphereShape::
-get_sphere_count() const {
-
-  return _shape->getSphereCount();
-}
-
-/**
- *
- */
-INLINE LPoint3 BulletMultiSphereShape::
-get_sphere_pos(int index) const {
-
-  nassertr(index >=0 && index <_shape->getSphereCount(), LPoint3::zero());
-  return btVector3_to_LPoint3(_shape->getSpherePosition(index));
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletMultiSphereShape::
-get_sphere_radius(int index) const {
-
-  nassertr(index >=0 && index <_shape->getSphereCount(), 0.0);
-  return (PN_stdfloat)_shape->getSphereRadius(index);
-}

+ 52 - 0
panda/src/bullet/bulletMultiSphereShape.cxx

@@ -42,6 +42,26 @@ BulletMultiSphereShape(const PTA_LVecBase3 &points, const PTA_stdfloat &radii) {
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletMultiSphereShape::
+BulletMultiSphereShape(const BulletMultiSphereShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+}
+
+/**
+ *
+ */
+void BulletMultiSphereShape::
+operator = (const BulletMultiSphereShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+}
+
 /**
  *
  */
@@ -51,6 +71,38 @@ ptr() const {
   return _shape;
 }
 
+/**
+ *
+ */
+int BulletMultiSphereShape::
+get_sphere_count() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _shape->getSphereCount();
+}
+
+/**
+ *
+ */
+LPoint3 BulletMultiSphereShape::
+get_sphere_pos(int index) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr(index >=0 && index <_shape->getSphereCount(), LPoint3::zero());
+  return btVector3_to_LPoint3(_shape->getSpherePosition(index));
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletMultiSphereShape::
+get_sphere_radius(int index) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr(index >=0 && index <_shape->getSphereCount(), 0.0);
+  return (PN_stdfloat)_shape->getSphereRadius(index);
+}
+
 /**
  * Tells the BamReader how to create objects of type BulletShape.
  */

+ 5 - 5
panda/src/bullet/bulletMultiSphereShape.h

@@ -31,13 +31,13 @@ private:
 
 PUBLISHED:
   explicit BulletMultiSphereShape(const PTA_LVecBase3 &points, const PTA_stdfloat &radii);
-  INLINE BulletMultiSphereShape(const BulletMultiSphereShape &copy);
-  INLINE void operator = (const BulletMultiSphereShape &copy);
+  BulletMultiSphereShape(const BulletMultiSphereShape &copy);
+  void operator = (const BulletMultiSphereShape &copy);
   INLINE ~BulletMultiSphereShape();
 
-  INLINE int get_sphere_count() const;
-  INLINE LPoint3 get_sphere_pos(int index) const;
-  INLINE PN_stdfloat get_sphere_radius(int index) const;
+  int get_sphere_count() const;
+  LPoint3 get_sphere_pos(int index) const;
+  PN_stdfloat get_sphere_radius(int index) const;
 
   MAKE_PROPERTY(sphere_count, get_sphere_count);
   MAKE_SEQ_PROPERTY(sphere_pos, get_sphere_count, get_sphere_pos);

+ 7 - 0
panda/src/bullet/bulletPersistentManifold.cxx

@@ -27,6 +27,7 @@ BulletPersistentManifold(btPersistentManifold *manifold) : _manifold(manifold) {
  */
 PN_stdfloat BulletPersistentManifold::
 get_contact_breaking_threshold() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_manifold->getContactBreakingThreshold();
 }
@@ -36,6 +37,7 @@ get_contact_breaking_threshold() const {
  */
 PN_stdfloat BulletPersistentManifold::
 get_contact_processing_threshold() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_manifold->getContactProcessingThreshold();
 }
@@ -45,6 +47,7 @@ get_contact_processing_threshold() const {
  */
 void BulletPersistentManifold::
 clear_manifold() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _manifold->clearManifold();
 }
@@ -54,6 +57,7 @@ clear_manifold() {
  */
 PandaNode *BulletPersistentManifold::
 get_node0() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
 #if BT_BULLET_VERSION >= 281
   const btCollisionObject *obj = _manifold->getBody0();
@@ -69,6 +73,7 @@ get_node0() {
  */
 PandaNode *BulletPersistentManifold::
 get_node1() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
 #if BT_BULLET_VERSION >= 281
   const btCollisionObject *obj = _manifold->getBody1();
@@ -84,6 +89,7 @@ get_node1() {
  */
 int BulletPersistentManifold::
 get_num_manifold_points() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _manifold->getNumContacts();
 }
@@ -93,6 +99,7 @@ get_num_manifold_points() const {
  */
 BulletManifoldPoint *BulletPersistentManifold::
 get_manifold_point(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertr(idx < _manifold->getNumContacts(), NULL)
 

+ 0 - 34
panda/src/bullet/bulletPlaneShape.I

@@ -19,37 +19,3 @@ INLINE BulletPlaneShape::
 
   delete _shape;
 }
-
-/**
- *
- */
-INLINE BulletPlaneShape::
-BulletPlaneShape(const BulletPlaneShape &copy) :
-  _shape(copy._shape) {
-}
-
-/**
- *
- */
-INLINE void BulletPlaneShape::
-operator = (const BulletPlaneShape &copy) {
-  _shape = copy._shape;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletPlaneShape::
-get_plane_constant() const {
-
-  return (PN_stdfloat)_shape->getPlaneConstant();
-}
-
-/**
- *
- */
-INLINE LVector3 BulletPlaneShape::
-get_plane_normal() const {
-
-  return btVector3_to_LVector3(_shape->getPlaneNormal());
-}

+ 40 - 0
panda/src/bullet/bulletPlaneShape.cxx

@@ -27,6 +27,26 @@ BulletPlaneShape(const LVector3 &normal, PN_stdfloat constant) {
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletPlaneShape::
+BulletPlaneShape(const BulletPlaneShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+}
+
+/**
+ *
+ */
+void BulletPlaneShape::
+operator = (const BulletPlaneShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+}
+
 /**
  *
  */
@@ -36,6 +56,26 @@ ptr() const {
   return _shape;
 }
 
+/**
+ *
+ */
+PN_stdfloat BulletPlaneShape::
+get_plane_constant() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_shape->getPlaneConstant();
+}
+
+/**
+ *
+ */
+LVector3 BulletPlaneShape::
+get_plane_normal() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_shape->getPlaneNormal());
+}
+
 /**
  *
  */

+ 4 - 4
panda/src/bullet/bulletPlaneShape.h

@@ -33,12 +33,12 @@ private:
 
 PUBLISHED:
   explicit BulletPlaneShape(const LVector3 &normal, PN_stdfloat constant);
-  INLINE BulletPlaneShape(const BulletPlaneShape &copy);
-  INLINE void operator = (const BulletPlaneShape &copy);
+  BulletPlaneShape(const BulletPlaneShape &copy);
+  void operator = (const BulletPlaneShape &copy);
   INLINE ~BulletPlaneShape();
 
-  INLINE LVector3 get_plane_normal() const;
-  INLINE PN_stdfloat get_plane_constant() const;
+  LVector3 get_plane_normal() const;
+  PN_stdfloat get_plane_constant() const;
 
   static BulletPlaneShape *make_from_solid(const CollisionPlane *solid);
 

+ 0 - 35
panda/src/bullet/bulletRigidBodyNode.I

@@ -20,38 +20,3 @@ INLINE BulletRigidBodyNode::
   delete _rigid;
 }
 
-/**
- *
- */
-INLINE void BulletRigidBodyNode::
-set_linear_damping(PN_stdfloat value) {
-
-  _rigid->setDamping(value, _rigid->getAngularDamping());
-}
-
-/**
- *
- */
-INLINE void BulletRigidBodyNode::
-set_angular_damping(PN_stdfloat value) {
-
-  _rigid->setDamping(_rigid->getLinearDamping(), value);
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletRigidBodyNode::
-get_linear_damping() const {
-
-  return (PN_stdfloat)_rigid->getLinearDamping();
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletRigidBodyNode::
-get_angular_damping() const {
-
-  return (PN_stdfloat)_rigid->getAngularDamping();
-}

+ 129 - 17
panda/src/bullet/bulletRigidBodyNode.cxx

@@ -48,9 +48,11 @@ BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
  */
 BulletRigidBodyNode::
 BulletRigidBodyNode(const BulletRigidBodyNode &copy) :
-  BulletBodyNode(copy),
-  _motion(copy._motion)
+  BulletBodyNode(copy)
 {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motion = copy._motion;
   _rigid = new btRigidBody(*copy._rigid);
   _rigid->setUserPointer(this);
   _rigid->setCollisionShape(_shape);
@@ -64,6 +66,7 @@ BulletRigidBodyNode(const BulletRigidBodyNode &copy) :
  */
 PandaNode *BulletRigidBodyNode::
 make_copy() const {
+
   return new BulletRigidBodyNode(*this);
 }
 
@@ -72,10 +75,11 @@ make_copy() const {
  */
 void BulletRigidBodyNode::
 output(ostream &out) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  BulletBodyNode::output(out);
+  BulletBodyNode::do_output(out);
 
-  out << " mass=" << get_mass();
+  out << " mass=" << do_get_mass();
 }
 
 /**
@@ -93,10 +97,10 @@ get_object() const {
  * The default implementation does nothing.
  */
 void BulletRigidBodyNode::
-shape_changed() {
+do_shape_changed() {
 
-  set_mass(get_mass());
-  transform_changed();
+  do_set_mass(do_get_mass());
+  do_transform_changed();
 }
 
 /**
@@ -104,9 +108,10 @@ shape_changed() {
  * automatically computed from the shape of the body.  Setting a value of zero
  * for mass will make the body static.  A value of zero can be considered an
  * infinite mass.
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletRigidBodyNode::
-set_mass(PN_stdfloat mass) {
+do_set_mass(PN_stdfloat mass) {
 
   btScalar bt_mass = mass;
   btVector3 bt_inertia(0.0, 0.0, 0.0);
@@ -119,12 +124,26 @@ set_mass(PN_stdfloat mass) {
   _rigid->updateInertiaTensor();
 }
 
+/**
+ * Sets the mass of a rigid body.  This also modifies the inertia, which is
+ * automatically computed from the shape of the body.  Setting a value of zero
+ * for mass will make the body static.  A value of zero can be considered an
+ * infinite mass.
+ */
+void BulletRigidBodyNode::
+set_mass(PN_stdfloat mass) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_set_mass(mass);
+}
+
 /**
  * Returns the total mass of a rigid body.  A value of zero means that the
  * body is staic, i.e.  has an infinite mass.
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 PN_stdfloat BulletRigidBodyNode::
-get_mass() const {
+do_get_mass() const {
 
   btScalar inv_mass = _rigid->getInvMass();
   btScalar mass = (inv_mass == btScalar(0.0)) ? btScalar(0.0) : btScalar(1.0) / inv_mass;
@@ -132,11 +151,24 @@ get_mass() const {
   return mass;
 }
 
+/**
+ * Returns the total mass of a rigid body.  A value of zero means that the
+ * body is staic, i.e.  has an infinite mass.
+ */
+PN_stdfloat BulletRigidBodyNode::
+get_mass() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return do_get_mass();
+}
+
+
 /**
  * Returns the inverse mass of a rigid body.
  */
 PN_stdfloat BulletRigidBodyNode::
 get_inv_mass() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_rigid->getInvMass();
 }
@@ -153,6 +185,7 @@ get_inv_mass() const {
  */
 void BulletRigidBodyNode::
 set_inertia(const LVecBase3 &inertia) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btVector3 inv_inertia(
     inertia.get_x() == 0.0 ? btScalar(0.0) : btScalar(1.0 / inertia.get_x()),
@@ -171,6 +204,7 @@ set_inertia(const LVecBase3 &inertia) {
  */
 LVector3 BulletRigidBodyNode::
 get_inertia() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btVector3 inv_inertia = _rigid->getInvInertiaDiagLocal();
   LVector3 inertia(
@@ -187,6 +221,7 @@ get_inertia() const {
  */
 LVector3 BulletRigidBodyNode::
 get_inv_inertia_diag_local() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getInvInertiaDiagLocal());
 }
@@ -196,6 +231,7 @@ get_inv_inertia_diag_local() const {
  */
 LMatrix3 BulletRigidBodyNode::
 get_inv_inertia_tensor_world() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btMatrix3x3_to_LMatrix3(_rigid->getInvInertiaTensorWorld());
 }
@@ -205,6 +241,7 @@ get_inv_inertia_tensor_world() const {
  */
 void BulletRigidBodyNode::
 apply_force(const LVector3 &force, const LPoint3 &pos) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!force.is_nan());
   nassertv_always(!pos.is_nan());
@@ -218,6 +255,7 @@ apply_force(const LVector3 &force, const LPoint3 &pos) {
  */
 void BulletRigidBodyNode::
 apply_central_force(const LVector3 &force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!force.is_nan());
 
@@ -229,6 +267,7 @@ apply_central_force(const LVector3 &force) {
  */
 void BulletRigidBodyNode::
 apply_torque(const LVector3 &torque) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!torque.is_nan());
 
@@ -240,6 +279,7 @@ apply_torque(const LVector3 &torque) {
  */
 void BulletRigidBodyNode::
 apply_torque_impulse(const LVector3 &torque) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!torque.is_nan());
 
@@ -251,6 +291,7 @@ apply_torque_impulse(const LVector3 &torque) {
  */
 void BulletRigidBodyNode::
 apply_impulse(const LVector3 &impulse, const LPoint3 &pos) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!impulse.is_nan());
   nassertv_always(!pos.is_nan());
@@ -264,6 +305,7 @@ apply_impulse(const LVector3 &impulse, const LPoint3 &pos) {
  */
 void BulletRigidBodyNode::
 apply_central_impulse(const LVector3 &impulse) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!impulse.is_nan());
 
@@ -271,10 +313,10 @@ apply_central_impulse(const LVector3 &impulse) {
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletRigidBodyNode::
-transform_changed() {
+do_transform_changed() {
 
   if (_motion.sync_disabled()) return;
 
@@ -289,7 +331,7 @@ transform_changed() {
   _motion.set_net_transform(ts);
 
   // For dynamic or static bodies we directly apply the new transform.
-  if (!is_kinematic()) {
+  if (!(get_object()->isKinematicObject())) {
     btTransform trans = TransformState_to_btTrans(ts);
     _rigid->setCenterOfMassTransform(trans);
   }
@@ -317,18 +359,31 @@ transform_changed() {
  *
  */
 void BulletRigidBodyNode::
-sync_p2b() {
+transform_changed() {
+
+  if (_motion.sync_disabled()) return;
+
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_transform_changed();
+}
+
+/**
+ * Assumes the lock(bullet global lock) is held by the caller
+ */
+void BulletRigidBodyNode::
+do_sync_p2b() {
 
-  if (is_kinematic()) {
-    transform_changed();
+  if (get_object()->isKinematicObject()) {
+    do_transform_changed();
   }
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletRigidBodyNode::
-sync_b2p() {
+do_sync_b2p() {
 
   _motion.sync_b2p((PandaNode *)this);
 }
@@ -338,6 +393,7 @@ sync_b2p() {
  */
 LVector3 BulletRigidBodyNode::
 get_linear_velocity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getLinearVelocity());
 }
@@ -347,6 +403,7 @@ get_linear_velocity() const {
  */
 LVector3 BulletRigidBodyNode::
 get_angular_velocity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getAngularVelocity());
 }
@@ -356,6 +413,7 @@ get_angular_velocity() const {
  */
 void BulletRigidBodyNode::
 set_linear_velocity(const LVector3 &velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!velocity.is_nan());
 
@@ -367,17 +425,59 @@ set_linear_velocity(const LVector3 &velocity) {
  */
 void BulletRigidBodyNode::
 set_angular_velocity(const LVector3 &velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!velocity.is_nan());
 
   _rigid->setAngularVelocity(LVecBase3_to_btVector3(velocity));
 }
 
+/**
+ *
+ */
+void BulletRigidBodyNode::
+set_linear_damping(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _rigid->setDamping(value, _rigid->getAngularDamping());
+}
+
+/**
+ *
+ */
+void BulletRigidBodyNode::
+set_angular_damping(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _rigid->setDamping(_rigid->getLinearDamping(), value);
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletRigidBodyNode::
+get_linear_damping() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_rigid->getLinearDamping();
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletRigidBodyNode::
+get_angular_damping() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_rigid->getAngularDamping();
+}
+
 /**
  *
  */
 void BulletRigidBodyNode::
 clear_forces() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _rigid->clearForces();
 }
@@ -387,6 +487,7 @@ clear_forces() {
  */
 PN_stdfloat BulletRigidBodyNode::
 get_linear_sleep_threshold() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _rigid->getLinearSleepingThreshold();
 }
@@ -396,6 +497,7 @@ get_linear_sleep_threshold() const {
  */
 PN_stdfloat BulletRigidBodyNode::
 get_angular_sleep_threshold() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _rigid->getAngularSleepingThreshold();
 }
@@ -405,6 +507,7 @@ get_angular_sleep_threshold() const {
  */
 void BulletRigidBodyNode::
 set_linear_sleep_threshold(PN_stdfloat threshold) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _rigid->setSleepingThresholds(threshold, _rigid->getAngularSleepingThreshold());
 }
@@ -414,6 +517,7 @@ set_linear_sleep_threshold(PN_stdfloat threshold) {
  */
 void BulletRigidBodyNode::
 set_angular_sleep_threshold(PN_stdfloat threshold) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _rigid->setSleepingThresholds(_rigid->getLinearSleepingThreshold(), threshold);
 }
@@ -423,6 +527,7 @@ set_angular_sleep_threshold(PN_stdfloat threshold) {
  */
 void BulletRigidBodyNode::
 set_gravity(const LVector3 &gravity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv_always(!gravity.is_nan());
 
@@ -434,6 +539,7 @@ set_gravity(const LVector3 &gravity) {
  */
 LVector3 BulletRigidBodyNode::
 get_gravity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getGravity());
 }
@@ -443,6 +549,7 @@ get_gravity() const {
  */
 LVector3 BulletRigidBodyNode::
 get_linear_factor() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getLinearFactor());
 }
@@ -452,6 +559,7 @@ get_linear_factor() const {
  */
 LVector3 BulletRigidBodyNode::
 get_angular_factor() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getAngularFactor());
 }
@@ -461,6 +569,7 @@ get_angular_factor() const {
  */
 void BulletRigidBodyNode::
 set_linear_factor(const LVector3 &factor) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _rigid->setLinearFactor(LVecBase3_to_btVector3(factor));
 }
@@ -470,6 +579,7 @@ set_linear_factor(const LVector3 &factor) {
  */
 void BulletRigidBodyNode::
 set_angular_factor(const LVector3 &factor) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _rigid->setAngularFactor(LVecBase3_to_btVector3(factor));
 }
@@ -479,6 +589,7 @@ set_angular_factor(const LVector3 &factor) {
  */
 LVector3 BulletRigidBodyNode::
 get_total_force() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getTotalForce());
 }
@@ -488,6 +599,7 @@ get_total_force() const {
  */
 LVector3 BulletRigidBodyNode::
 get_total_torque() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_rigid->getTotalTorque());
 }

+ 11 - 7
panda/src/bullet/bulletRigidBodyNode.h

@@ -50,10 +50,10 @@ PUBLISHED:
   void set_angular_velocity(const LVector3 &velocity);
 
   // Damping
-  INLINE PN_stdfloat get_linear_damping() const;
-  INLINE PN_stdfloat get_angular_damping() const;
-  INLINE void set_linear_damping(PN_stdfloat value);
-  INLINE void set_angular_damping(PN_stdfloat value);
+  PN_stdfloat get_linear_damping() const;
+  PN_stdfloat get_angular_damping() const;
+  void set_linear_damping(PN_stdfloat value);
+  void set_angular_damping(PN_stdfloat value);
 
   // Forces
   void clear_forces();
@@ -108,14 +108,18 @@ public:
 
   virtual void output(ostream &out) const;
 
-  void sync_p2b();
-  void sync_b2p();
+  void do_sync_p2b();
+  void do_sync_b2p();
 
 protected:
   virtual void transform_changed();
 
 private:
-  virtual void shape_changed();
+  virtual void do_shape_changed();
+  void do_transform_changed();
+
+  void do_set_mass(PN_stdfloat mass);
+  PN_stdfloat do_get_mass() const;
 
   // The motion state is used for synchronisation between Bullet and the
   // Panda3D scene graph.

+ 2 - 157
panda/src/bullet/bulletRotationalLimitMotor.I

@@ -14,162 +14,7 @@
 /**
  *
  */
-INLINE bool BulletRotationalLimitMotor::
-is_limited() const {
+INLINE BulletRotationalLimitMotor::
+~BulletRotationalLimitMotor() {
 
-  return _motor.isLimited();
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_motor_enabled(bool enabled) {
-
-  _motor.m_enableMotor = enabled;
-}
-
-/**
- *
- */
-INLINE bool BulletRotationalLimitMotor::
-get_motor_enabled() const {
-
-  return _motor.m_enableMotor;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_low_limit(PN_stdfloat limit) {
-
-  _motor.m_loLimit = (btScalar)limit;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_high_limit(PN_stdfloat limit) {
-
-  _motor.m_hiLimit = (btScalar)limit;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_target_velocity(PN_stdfloat velocity) {
-
-  _motor.m_targetVelocity = (btScalar)velocity;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_max_motor_force(PN_stdfloat force) {
-
-  _motor.m_maxMotorForce = (btScalar)force;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_max_limit_force(PN_stdfloat force) {
-
-  _motor.m_maxLimitForce = (btScalar)force;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_damping(PN_stdfloat damping) {
-
-  _motor.m_damping = (btScalar)damping;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_softness(PN_stdfloat softness) {
-
-  _motor.m_limitSoftness = (btScalar)softness;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_bounce(PN_stdfloat bounce) {
-
-  _motor.m_bounce = (btScalar)bounce;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_normal_cfm(PN_stdfloat cfm) {
-
-  _motor.m_normalCFM = (btScalar)cfm;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_stop_cfm(PN_stdfloat cfm) {
-
-  _motor.m_stopCFM = (btScalar)cfm;
-}
-
-/**
- *
- */
-INLINE void BulletRotationalLimitMotor::
-set_stop_erp(PN_stdfloat erp) {
-
-  _motor.m_stopERP = (btScalar)erp;
-}
-
-/**
- * Retrieves the current value of angle: 0 = free, 1 = at low limit, 2 = at
- * high limit.
- */
-INLINE int BulletRotationalLimitMotor::
-get_current_limit() const {
-
-  return _motor.m_currentLimit;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletRotationalLimitMotor::
-get_current_error() const {
-
-  return (PN_stdfloat)_motor.m_currentLimitError;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletRotationalLimitMotor::
-get_current_position() const {
-
-  return (PN_stdfloat)_motor.m_currentPosition;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletRotationalLimitMotor::
-get_accumulated_impulse() const {
-
-  return (PN_stdfloat)_motor.m_accumulatedImpulse;
 }

+ 174 - 2
panda/src/bullet/bulletRotationalLimitMotor.cxx

@@ -34,7 +34,179 @@ BulletRotationalLimitMotor(const BulletRotationalLimitMotor &copy)
 /**
  *
  */
-BulletRotationalLimitMotor::
-~BulletRotationalLimitMotor() {
+bool BulletRotationalLimitMotor::
+is_limited() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _motor.isLimited();
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_motor_enabled(bool enabled) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_enableMotor = enabled;
+}
+
+/**
+ *
+ */
+bool BulletRotationalLimitMotor::
+get_motor_enabled() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _motor.m_enableMotor;
+}
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_low_limit(PN_stdfloat limit) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_loLimit = (btScalar)limit;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_high_limit(PN_stdfloat limit) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_hiLimit = (btScalar)limit;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_target_velocity(PN_stdfloat velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_targetVelocity = (btScalar)velocity;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_max_motor_force(PN_stdfloat force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_maxMotorForce = (btScalar)force;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_max_limit_force(PN_stdfloat force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_maxLimitForce = (btScalar)force;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_damping(PN_stdfloat damping) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_damping = (btScalar)damping;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_softness(PN_stdfloat softness) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_limitSoftness = (btScalar)softness;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_bounce(PN_stdfloat bounce) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_bounce = (btScalar)bounce;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_normal_cfm(PN_stdfloat cfm) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_normalCFM = (btScalar)cfm;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_stop_cfm(PN_stdfloat cfm) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_stopCFM = (btScalar)cfm;
+}
+
+/**
+ *
+ */
+void BulletRotationalLimitMotor::
+set_stop_erp(PN_stdfloat erp) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_stopERP = (btScalar)erp;
+}
+
+/**
+ * Retrieves the current value of angle: 0 = free, 1 = at low limit, 2 = at
+ * high limit.
+ */
+int BulletRotationalLimitMotor::
+get_current_limit() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _motor.m_currentLimit;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletRotationalLimitMotor::
+get_current_error() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_motor.m_currentLimitError;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletRotationalLimitMotor::
+get_current_position() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_motor.m_currentPosition;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletRotationalLimitMotor::
+get_accumulated_impulse() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
+  return (PN_stdfloat)_motor.m_accumulatedImpulse;
 }

+ 19 - 19
panda/src/bullet/bulletRotationalLimitMotor.h

@@ -28,27 +28,27 @@ class EXPCL_PANDABULLET BulletRotationalLimitMotor {
 
 PUBLISHED:
   BulletRotationalLimitMotor(const BulletRotationalLimitMotor &copy);
-  ~BulletRotationalLimitMotor();
+  INLINE ~BulletRotationalLimitMotor();
 
-  INLINE void set_motor_enabled(bool enable);
-  INLINE void set_low_limit(PN_stdfloat limit);
-  INLINE void set_high_limit(PN_stdfloat limit);
-  INLINE void set_target_velocity(PN_stdfloat velocity);
-  INLINE void set_max_motor_force(PN_stdfloat force);
-  INLINE void set_max_limit_force(PN_stdfloat force);
-  INLINE void set_damping(PN_stdfloat damping);
-  INLINE void set_softness(PN_stdfloat softness);
-  INLINE void set_bounce(PN_stdfloat bounce);
-  INLINE void set_normal_cfm(PN_stdfloat cfm);
-  INLINE void set_stop_cfm(PN_stdfloat cfm);
-  INLINE void set_stop_erp(PN_stdfloat erp);
+  void set_motor_enabled(bool enable);
+  void set_low_limit(PN_stdfloat limit);
+  void set_high_limit(PN_stdfloat limit);
+  void set_target_velocity(PN_stdfloat velocity);
+  void set_max_motor_force(PN_stdfloat force);
+  void set_max_limit_force(PN_stdfloat force);
+  void set_damping(PN_stdfloat damping);
+  void set_softness(PN_stdfloat softness);
+  void set_bounce(PN_stdfloat bounce);
+  void set_normal_cfm(PN_stdfloat cfm);
+  void set_stop_cfm(PN_stdfloat cfm);
+  void set_stop_erp(PN_stdfloat erp);
 
-  INLINE bool is_limited() const;
-  INLINE bool get_motor_enabled() const;
-  INLINE int get_current_limit() const;
-  INLINE PN_stdfloat get_current_error() const;
-  INLINE PN_stdfloat get_current_position() const;
-  INLINE PN_stdfloat get_accumulated_impulse() const;
+  bool is_limited() const;
+  bool get_motor_enabled() const;
+  int get_current_limit() const;
+  PN_stdfloat get_current_error() const;
+  PN_stdfloat get_current_position() const;
+  PN_stdfloat get_accumulated_impulse() const;
 
   MAKE_PROPERTY(limited, is_limited);
   MAKE_PROPERTY(motor_enabled, get_motor_enabled, set_motor_enabled);

+ 0 - 63
panda/src/bullet/bulletShape.I

@@ -18,66 +18,3 @@ INLINE BulletShape::
 ~BulletShape() {
 
 }
-
-/**
- *
- */
-INLINE bool BulletShape::
-is_polyhedral() const {
-
-  return ptr()->isPolyhedral();
-}
-
-/**
- *
- */
-INLINE bool BulletShape::
-is_convex() const {
-
-  return ptr()->isConvex();
-}
-
-/**
- *
- */
-INLINE bool BulletShape::
-is_convex_2d() const {
-
-  return ptr()->isConvex2d();
-}
-
-/**
- *
- */
-INLINE bool BulletShape::
-is_concave() const {
-
-  return ptr()->isConcave();
-}
-
-/**
- *
- */
-INLINE bool BulletShape::
-is_infinite() const {
-
-  return ptr()->isInfinite();
-}
-
-/**
- *
- */
-INLINE bool BulletShape::
-is_non_moving() const {
-
-  return ptr()->isNonMoving();
-}
-
-/**
- *
- */
-INLINE bool BulletShape::
-is_soft_body() const {
-
-  return ptr()->isSoftBody();
-}

+ 87 - 2
panda/src/bullet/bulletShape.cxx

@@ -21,6 +21,7 @@ TypeHandle BulletShape::_type_handle;
  */
 const char *BulletShape::
 get_name() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return ptr()->getName();
 }
@@ -30,6 +31,7 @@ get_name() const {
  */
 PN_stdfloat BulletShape::
 get_margin() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return ptr()->getMargin();
 }
@@ -39,6 +41,7 @@ get_margin() const {
  */
 void BulletShape::
 set_margin(PN_stdfloat margin) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   ptr()->setMargin(margin);
 }
@@ -48,25 +51,37 @@ set_margin(PN_stdfloat margin) {
  */
 LVecBase3 BulletShape::
 get_local_scale() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVecBase3(ptr()->getLocalScaling());
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletShape::
-set_local_scale(const LVecBase3 &scale) {
+do_set_local_scale(const LVecBase3 &scale) {
 
   nassertv(!scale.is_nan());
   ptr()->setLocalScaling(LVecBase3_to_btVector3(scale));
 }
 
+/**
+ *
+ */
+void BulletShape::
+set_local_scale(const LVecBase3 &scale) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_set_local_scale(scale);
+}
+
 /**
  * Returns the current bounds of this collision shape.
  */
 BoundingSphere BulletShape::
 get_shape_bounds() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
 /*
   btTransform tr;
@@ -87,3 +102,73 @@ cout << "origin " << aabbMin.x() << " " << aabbMin.y() << " " << aabbMin.z() <<
 
   return bounds;
 }
+
+/**
+ *
+ */
+bool BulletShape::
+is_polyhedral() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return ptr()->isPolyhedral();
+}
+
+/**
+ *
+ */
+bool BulletShape::
+is_convex() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return ptr()->isConvex();
+}
+
+/**
+ *
+ */
+bool BulletShape::
+is_convex_2d() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return ptr()->isConvex2d();
+}
+
+/**
+ *
+ */
+bool BulletShape::
+is_concave() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return ptr()->isConcave();
+}
+
+/**
+ *
+ */
+bool BulletShape::
+is_infinite() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return ptr()->isInfinite();
+}
+
+/**
+ *
+ */
+bool BulletShape::
+is_non_moving() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return ptr()->isNonMoving();
+}
+
+/**
+ *
+ */
+bool BulletShape::
+is_soft_body() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return ptr()->isSoftBody();
+}

+ 8 - 7
panda/src/bullet/bulletShape.h

@@ -31,13 +31,13 @@ protected:
 PUBLISHED:
   INLINE virtual ~BulletShape();
 
-  INLINE bool is_polyhedral() const;
-  INLINE bool is_convex() const;
-  INLINE bool is_convex_2d() const;
-  INLINE bool is_concave() const;
-  INLINE bool is_infinite() const;
-  INLINE bool is_non_moving() const;
-  INLINE bool is_soft_body() const;
+  bool is_polyhedral() const;
+  bool is_convex() const;
+  bool is_convex_2d() const;
+  bool is_concave() const;
+  bool is_infinite() const;
+  bool is_non_moving() const;
+  bool is_soft_body() const;
 
   void set_margin(PN_stdfloat margin);
   const char *get_name() const;
@@ -61,6 +61,7 @@ public:
   virtual btCollisionShape *ptr() const = 0;
   LVecBase3 get_local_scale() const;
   void set_local_scale(const LVecBase3 &scale);
+  void do_set_local_scale(const LVecBase3 &scale);
 
 public:
   static TypeHandle get_class_type() {

+ 0 - 18
panda/src/bullet/bulletSliderConstraint.I

@@ -19,21 +19,3 @@ INLINE BulletSliderConstraint::
 
   delete _constraint;
 }
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletSliderConstraint::
-get_frame_a() const {
-
-  return btTrans_to_TransformState(_constraint->getFrameOffsetA());
-}
-
-/**
- *
- */
-INLINE CPT(TransformState) BulletSliderConstraint::
-get_frame_b() const {
-
-  return btTrans_to_TransformState(_constraint->getFrameOffsetB());
-}

+ 43 - 0
panda/src/bullet/bulletSliderConstraint.cxx

@@ -65,6 +65,7 @@ ptr() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_lower_linear_limit() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getLowerLinLimit();
 }
@@ -74,6 +75,7 @@ get_lower_linear_limit() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_upper_linear_limit() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getUpperLinLimit();
 }
@@ -83,6 +85,7 @@ get_upper_linear_limit() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_lower_angular_limit() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return rad_2_deg(_constraint->getLowerAngLimit());
 }
@@ -92,6 +95,7 @@ get_lower_angular_limit() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_upper_angular_limit() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return rad_2_deg(_constraint->getUpperAngLimit());
 }
@@ -101,6 +105,7 @@ get_upper_angular_limit() const {
  */
 void BulletSliderConstraint::
 set_lower_linear_limit(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setLowerLinLimit((btScalar)value);
 }
@@ -110,6 +115,7 @@ set_lower_linear_limit(PN_stdfloat value) {
  */
 void BulletSliderConstraint::
 set_upper_linear_limit(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setUpperLinLimit((btScalar)value);
 }
@@ -119,6 +125,7 @@ set_upper_linear_limit(PN_stdfloat value) {
  */
 void BulletSliderConstraint::
 set_lower_angular_limit(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setLowerAngLimit((btScalar)deg_2_rad(value));
 }
@@ -128,6 +135,7 @@ set_lower_angular_limit(PN_stdfloat value) {
  */
 void BulletSliderConstraint::
 set_upper_angular_limit(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setUpperAngLimit((btScalar)deg_2_rad(value));
 }
@@ -137,6 +145,7 @@ set_upper_angular_limit(PN_stdfloat value) {
  */
 PN_stdfloat BulletSliderConstraint::
 get_linear_pos() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getLinearPos();
 }
@@ -146,6 +155,7 @@ get_linear_pos() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_angular_pos() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getAngularPos();
 }
@@ -155,6 +165,7 @@ get_angular_pos() const {
  */
 void BulletSliderConstraint::
 set_powered_linear_motor(bool on) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setPoweredLinMotor(on);
 }
@@ -164,6 +175,7 @@ set_powered_linear_motor(bool on) {
  */
 void BulletSliderConstraint::
 set_target_linear_motor_velocity(PN_stdfloat target_velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setTargetLinMotorVelocity((btScalar)target_velocity);
 }
@@ -173,6 +185,7 @@ set_target_linear_motor_velocity(PN_stdfloat target_velocity) {
  */
 void BulletSliderConstraint::
 set_max_linear_motor_force(PN_stdfloat max_force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMaxLinMotorForce((btScalar)max_force);
 }
@@ -182,6 +195,7 @@ set_max_linear_motor_force(PN_stdfloat max_force) {
  */
 bool BulletSliderConstraint::
 get_powered_linear_motor() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _constraint->getPoweredLinMotor();
 }
@@ -191,6 +205,7 @@ get_powered_linear_motor() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_target_linear_motor_velocity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getTargetLinMotorVelocity();
 }
@@ -200,6 +215,7 @@ get_target_linear_motor_velocity() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_max_linear_motor_force() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getMaxLinMotorForce();
 }
@@ -209,6 +225,7 @@ get_max_linear_motor_force() const {
  */
 void BulletSliderConstraint::
 set_powered_angular_motor(bool on) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setPoweredAngMotor(on);
 }
@@ -218,6 +235,7 @@ set_powered_angular_motor(bool on) {
  */
 void BulletSliderConstraint::
 set_target_angular_motor_velocity(PN_stdfloat target_velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setTargetAngMotorVelocity((btScalar)target_velocity);
 }
@@ -227,6 +245,7 @@ set_target_angular_motor_velocity(PN_stdfloat target_velocity) {
  */
 void BulletSliderConstraint::
 set_max_angular_motor_force(PN_stdfloat max_force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _constraint->setMaxAngMotorForce((btScalar)max_force);
 }
@@ -236,6 +255,7 @@ set_max_angular_motor_force(PN_stdfloat max_force) {
  */
 bool BulletSliderConstraint::
 get_powered_angular_motor() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _constraint->getPoweredAngMotor();
 }
@@ -245,6 +265,7 @@ get_powered_angular_motor() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_target_angular_motor_velocity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getTargetAngMotorVelocity();
 }
@@ -254,6 +275,7 @@ get_target_angular_motor_velocity() const {
  */
 PN_stdfloat BulletSliderConstraint::
 get_max_angular_motor_force() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_constraint->getMaxAngMotorForce();
 }
@@ -263,9 +285,30 @@ get_max_angular_motor_force() const {
  */
 void BulletSliderConstraint::
 set_frames(const TransformState *ts_a, const TransformState *ts_b) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btTransform frame_a = TransformState_to_btTrans(ts_a);
   btTransform frame_b = TransformState_to_btTrans(ts_b);
 
   _constraint->setFrames(frame_a, frame_b);
 }
+
+/**
+ *
+ */
+CPT(TransformState) BulletSliderConstraint::
+get_frame_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getFrameOffsetA());
+}
+
+/**
+ *
+ */
+CPT(TransformState) BulletSliderConstraint::
+get_frame_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btTrans_to_TransformState(_constraint->getFrameOffsetB());
+}

+ 2 - 2
panda/src/bullet/bulletSliderConstraint.h

@@ -70,8 +70,8 @@ PUBLISHED:
 
   // Frames
   void set_frames(const TransformState *ts_a, const TransformState *ts_b);
-  INLINE CPT(TransformState) get_frame_a() const;
-  INLINE CPT(TransformState) get_frame_b() const;
+  CPT(TransformState) get_frame_a() const;
+  CPT(TransformState) get_frame_b() const;
 
   MAKE_PROPERTY(linear_pos, get_linear_pos);
   MAKE_PROPERTY(angular_pos, get_angular_pos);

+ 0 - 436
panda/src/bullet/bulletSoftBodyConfig.I

@@ -18,439 +18,3 @@ INLINE BulletSoftBodyConfig::
 ~BulletSoftBodyConfig() {
 
 }
-
-/**
- * Getter for property kVCF.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_velocities_correction_factor() const {
-
-  return (PN_stdfloat)_cfg.kVCF;
-}
-
-/**
- * Setter for property kVCF.
- */
-INLINE void BulletSoftBodyConfig::
-set_velocities_correction_factor(PN_stdfloat value) {
-
-  _cfg.kVCF = (btScalar)value;
-}
-
-/**
- * Getter for property kDP.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_damping_coefficient() const {
-
-  return (PN_stdfloat)_cfg.kDP;
-}
-
-/**
- * Setter for property kDP.
- */
-INLINE void BulletSoftBodyConfig::
-set_damping_coefficient(PN_stdfloat value) {
-
-  _cfg.kDP = (btScalar)value;
-}
-
-/**
- * Getter for property kDG.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_drag_coefficient() const {
-
-  return (PN_stdfloat)_cfg.kDG;
-}
-
-/**
- * Setter for property kDG.
- */
-INLINE void BulletSoftBodyConfig::
-set_drag_coefficient(PN_stdfloat value) {
-
-  _cfg.kDG = (btScalar)value;
-}
-
-/**
- * Getter for property kLF.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_lift_coefficient() const {
-
-  return (PN_stdfloat)_cfg.kLF;
-}
-
-/**
- * Setter for property kLF.
- */
-INLINE void BulletSoftBodyConfig::
-set_lift_coefficient(PN_stdfloat value) {
-
-  _cfg.kLF = (btScalar)value;
-}
-
-/**
- * Getter for property kPR.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_pressure_coefficient() const {
-
-  return (PN_stdfloat)_cfg.kPR;
-}
-
-/**
- * Setter for property kPR.
- */
-INLINE void BulletSoftBodyConfig::
-set_pressure_coefficient(PN_stdfloat value) {
-
-  _cfg.kPR = (btScalar)value;
-}
-
-/**
- * Getter for property kVC.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_volume_conservation_coefficient() const {
-
-  return (PN_stdfloat)_cfg.kVC;
-}
-
-/**
- * Setter for property kVC.
- */
-INLINE void BulletSoftBodyConfig::
-set_volume_conservation_coefficient(PN_stdfloat value) {
-
-  _cfg.kVC = (btScalar)value;
-}
-
-/**
- * Getter for property kDF.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_dynamic_friction_coefficient() const {
-
-  return (PN_stdfloat)_cfg.kDF;
-}
-
-/**
- * Setter for property kDF.
- */
-INLINE void BulletSoftBodyConfig::
-set_dynamic_friction_coefficient(PN_stdfloat value) {
-
-  _cfg.kDF = (btScalar)value;
-}
-
-/**
- * Getter for property kMT.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_pose_matching_coefficient() const {
-
-  return (PN_stdfloat)_cfg.kMT;
-}
-
-/**
- * Setter for property kMT.
- */
-INLINE void BulletSoftBodyConfig::
-set_pose_matching_coefficient(PN_stdfloat value) {
-
-  _cfg.kMT = (btScalar)value;
-}
-
-/**
- * Getter for property kCHR.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_rigid_contacts_hardness() const {
-
-  return (PN_stdfloat)_cfg.kCHR;
-}
-
-/**
- * Setter for property kCHR.
- */
-INLINE void BulletSoftBodyConfig::
-set_rigid_contacts_hardness(PN_stdfloat value) {
-
-  _cfg.kCHR = (btScalar)value;
-}
-
-/**
- * Getter for property kKHR.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_kinetic_contacts_hardness() const {
-
-  return (PN_stdfloat)_cfg.kKHR;
-}
-
-/**
- * Setter for property kKHR.
- */
-INLINE void BulletSoftBodyConfig::
-set_kinetic_contacts_hardness(PN_stdfloat value) {
-
-  _cfg.kKHR = (btScalar)value;
-}
-
-/**
- * Getter for property kSHR.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_soft_contacts_hardness() const {
-
-  return (PN_stdfloat)_cfg.kSHR;
-}
-
-/**
- * Setter for property kSHR.
- */
-INLINE void BulletSoftBodyConfig::
-set_soft_contacts_hardness(PN_stdfloat value) {
-
-  _cfg.kSHR = (btScalar)value;
-}
-
-/**
- * Getter for property kAHR.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_anchors_hardness() const {
-
-  return (PN_stdfloat)_cfg.kAHR;
-}
-
-/**
- * Setter for property kAHR.
- */
-INLINE void BulletSoftBodyConfig::
-set_anchors_hardness(PN_stdfloat value) {
-
-  _cfg.kAHR = (btScalar)value;
-}
-
-/**
- * Getter for property kSRHR_CL.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_soft_vs_rigid_hardness() const {
-
-  return (PN_stdfloat)_cfg.kSRHR_CL;
-}
-
-/**
- * Setter for property kSRHR_CL.
- */
-INLINE void BulletSoftBodyConfig::
-set_soft_vs_rigid_hardness(PN_stdfloat value) {
-
-  _cfg.kSRHR_CL = (btScalar)value;
-}
-
-/**
- * Getter for property kSKHR_CL.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_soft_vs_kinetic_hardness() const {
-
-  return (PN_stdfloat)_cfg.kSKHR_CL;
-}
-
-/**
- * Setter for property kSKHR_CL.
- */
-INLINE void BulletSoftBodyConfig::
-set_soft_vs_kinetic_hardness(PN_stdfloat value) {
-
-  _cfg.kSKHR_CL = (btScalar)value;
-}
-
-/**
- * Getter for property kSSHR_CL.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_soft_vs_soft_hardness() const {
-
-  return (PN_stdfloat)_cfg.kSSHR_CL;
-}
-
-/**
- * Setter for property kSSHR_CL.
- */
-INLINE void BulletSoftBodyConfig::
-set_soft_vs_soft_hardness(PN_stdfloat value) {
-
-  _cfg.kSSHR_CL = (btScalar)value;
-}
-
-/**
- * Getter for property kSR_SPLT_CL.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_soft_vs_rigid_impulse_split() const {
-
-  return (PN_stdfloat)_cfg.kSR_SPLT_CL;
-}
-
-/**
- * Setter for property kSR_SPLT_CL.
- */
-INLINE void BulletSoftBodyConfig::
-set_soft_vs_rigid_impulse_split(PN_stdfloat value) {
-
-  _cfg.kSR_SPLT_CL = (btScalar)value;
-}
-
-/**
- * Getter for property kSK_SPLT_CL.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_soft_vs_kinetic_impulse_split() const {
-
-  return (PN_stdfloat)_cfg.kSK_SPLT_CL;
-}
-
-/**
- * Setter for property kSK_SPLT_CL.
- */
-INLINE void BulletSoftBodyConfig::
-set_soft_vs_kinetic_impulse_split(PN_stdfloat value) {
-
-  _cfg.kSK_SPLT_CL = (btScalar)value;
-}
-
-/**
- * Getter for property kSS_SPLT_CL.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_soft_vs_soft_impulse_split() const {
-
-  return (PN_stdfloat)_cfg.kSS_SPLT_CL;
-}
-
-/**
- * Setter for property kSS_SPLT_CL.
- */
-INLINE void BulletSoftBodyConfig::
-set_soft_vs_soft_impulse_split(PN_stdfloat value) {
-
-  _cfg.kSS_SPLT_CL = (btScalar)value;
-}
-
-/**
- * Getter for property maxvolume.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_maxvolume() const {
-
-  return (PN_stdfloat)_cfg.maxvolume;
-}
-
-/**
- * Setter for property maxvolume.
- */
-INLINE void BulletSoftBodyConfig::
-set_maxvolume(PN_stdfloat value) {
-
-  _cfg.maxvolume = (btScalar)value;
-}
-
-/**
- * Getter for property timescale.
- */
-INLINE PN_stdfloat BulletSoftBodyConfig::
-get_timescale() const {
-
-  return (PN_stdfloat)_cfg.timescale;
-}
-
-/**
- * Setter for property timescale.
- */
-INLINE void BulletSoftBodyConfig::
-set_timescale(PN_stdfloat value) {
-
-  _cfg.timescale = (btScalar)value;
-}
-
-/**
- * Getter for property piterations.
- */
-INLINE int BulletSoftBodyConfig::
-get_positions_solver_iterations() const {
-
-  return _cfg.piterations;
-}
-
-/**
- * Setter for property piterations.
- */
-INLINE void BulletSoftBodyConfig::
-set_positions_solver_iterations(int value) {
-
-  nassertv(value > 0);
-  _cfg.piterations = value;
-}
-
-/**
- * Getter for property viterations.
- */
-INLINE int BulletSoftBodyConfig::
-get_velocities_solver_iterations() const {
-
-  return _cfg.viterations;
-}
-
-/**
- * Setter for property viterations.
- */
-INLINE void BulletSoftBodyConfig::
-set_velocities_solver_iterations(int value) {
-
-  nassertv(value > 0);
-  _cfg.viterations = value;
-}
-
-/**
- * Getter for property diterations.
- */
-INLINE int BulletSoftBodyConfig::
-get_drift_solver_iterations() const {
-
-  return _cfg.diterations;
-}
-
-/**
- * Setter for property diterations.
- */
-INLINE void BulletSoftBodyConfig::
-set_drift_solver_iterations(int value) {
-
-  nassertv(value > 0);
-  _cfg.diterations = value;
-}
-
-/**
- * Getter for property citerations.
- */
-INLINE int BulletSoftBodyConfig::
-get_cluster_solver_iterations() const {
-
-  return _cfg.citerations;
-}
-
-/**
- * Setter for property citerations.
- */
-INLINE void BulletSoftBodyConfig::
-set_cluster_solver_iterations(int value) {
-
-  nassertv(value > 0);
-  _cfg.citerations = value;
-}

+ 489 - 0
panda/src/bullet/bulletSoftBodyConfig.cxx

@@ -26,6 +26,7 @@ BulletSoftBodyConfig(btSoftBody::Config &cfg) : _cfg(cfg) {
  */
 void BulletSoftBodyConfig::
 clear_all_collision_flags() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _cfg.collisions = 0;
 }
@@ -35,6 +36,7 @@ clear_all_collision_flags() {
  */
 void BulletSoftBodyConfig::
 set_collision_flag(CollisionFlag flag, bool value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   if (value == true) {
     _cfg.collisions |= flag;
@@ -49,6 +51,7 @@ set_collision_flag(CollisionFlag flag, bool value) {
  */
 bool BulletSoftBodyConfig::
 get_collision_flag(CollisionFlag flag) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (_cfg.collisions & flag) ? true : false;
 }
@@ -58,6 +61,7 @@ get_collision_flag(CollisionFlag flag) const {
  */
 void BulletSoftBodyConfig::
 set_aero_model(AeroModel value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _cfg.aeromodel = (btSoftBody::eAeroModel::_)value;
 }
@@ -67,6 +71,491 @@ set_aero_model(AeroModel value) {
  */
 BulletSoftBodyConfig::AeroModel BulletSoftBodyConfig::
 get_aero_model() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (AeroModel)_cfg.aeromodel;
 }
+
+/**
+ * Getter for property kVCF.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_velocities_correction_factor() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kVCF;
+}
+
+/**
+ * Setter for property kVCF.
+ */
+void BulletSoftBodyConfig::
+set_velocities_correction_factor(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kVCF = (btScalar)value;
+}
+
+/**
+ * Getter for property kDP.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_damping_coefficient() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kDP;
+}
+
+/**
+ * Setter for property kDP.
+ */
+void BulletSoftBodyConfig::
+set_damping_coefficient(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kDP = (btScalar)value;
+}
+
+/**
+ * Getter for property kDG.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_drag_coefficient() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kDG;
+}
+
+/**
+ * Setter for property kDG.
+ */
+void BulletSoftBodyConfig::
+set_drag_coefficient(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kDG = (btScalar)value;
+}
+
+/**
+ * Getter for property kLF.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_lift_coefficient() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kLF;
+}
+
+/**
+ * Setter for property kLF.
+ */
+void BulletSoftBodyConfig::
+set_lift_coefficient(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kLF = (btScalar)value;
+}
+
+/**
+ * Getter for property kPR.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_pressure_coefficient() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kPR;
+}
+
+/**
+ * Setter for property kPR.
+ */
+void BulletSoftBodyConfig::
+set_pressure_coefficient(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kPR = (btScalar)value;
+}
+
+/**
+ * Getter for property kVC.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_volume_conservation_coefficient() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kVC;
+}
+
+/**
+ * Setter for property kVC.
+ */
+void BulletSoftBodyConfig::
+set_volume_conservation_coefficient(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kVC = (btScalar)value;
+}
+
+/**
+ * Getter for property kDF.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_dynamic_friction_coefficient() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kDF;
+}
+
+/**
+ * Setter for property kDF.
+ */
+void BulletSoftBodyConfig::
+set_dynamic_friction_coefficient(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kDF = (btScalar)value;
+}
+
+/**
+ * Getter for property kMT.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_pose_matching_coefficient() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kMT;
+}
+
+/**
+ * Setter for property kMT.
+ */
+void BulletSoftBodyConfig::
+set_pose_matching_coefficient(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kMT = (btScalar)value;
+}
+
+/**
+ * Getter for property kCHR.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_rigid_contacts_hardness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kCHR;
+}
+
+/**
+ * Setter for property kCHR.
+ */
+void BulletSoftBodyConfig::
+set_rigid_contacts_hardness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kCHR = (btScalar)value;
+}
+
+/**
+ * Getter for property kKHR.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_kinetic_contacts_hardness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kKHR;
+}
+
+/**
+ * Setter for property kKHR.
+ */
+void BulletSoftBodyConfig::
+set_kinetic_contacts_hardness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kKHR = (btScalar)value;
+}
+
+/**
+ * Getter for property kSHR.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_soft_contacts_hardness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kSHR;
+}
+
+/**
+ * Setter for property kSHR.
+ */
+void BulletSoftBodyConfig::
+set_soft_contacts_hardness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kSHR = (btScalar)value;
+}
+
+/**
+ * Getter for property kAHR.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_anchors_hardness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kAHR;
+}
+
+/**
+ * Setter for property kAHR.
+ */
+void BulletSoftBodyConfig::
+set_anchors_hardness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kAHR = (btScalar)value;
+}
+
+/**
+ * Getter for property kSRHR_CL.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_soft_vs_rigid_hardness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kSRHR_CL;
+}
+
+/**
+ * Setter for property kSRHR_CL.
+ */
+void BulletSoftBodyConfig::
+set_soft_vs_rigid_hardness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kSRHR_CL = (btScalar)value;
+}
+
+/**
+ * Getter for property kSKHR_CL.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_soft_vs_kinetic_hardness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kSKHR_CL;
+}
+
+/**
+ * Setter for property kSKHR_CL.
+ */
+void BulletSoftBodyConfig::
+set_soft_vs_kinetic_hardness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kSKHR_CL = (btScalar)value;
+}
+
+/**
+ * Getter for property kSSHR_CL.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_soft_vs_soft_hardness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kSSHR_CL;
+}
+
+/**
+ * Setter for property kSSHR_CL.
+ */
+void BulletSoftBodyConfig::
+set_soft_vs_soft_hardness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kSSHR_CL = (btScalar)value;
+}
+
+/**
+ * Getter for property kSR_SPLT_CL.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_soft_vs_rigid_impulse_split() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kSR_SPLT_CL;
+}
+
+/**
+ * Setter for property kSR_SPLT_CL.
+ */
+void BulletSoftBodyConfig::
+set_soft_vs_rigid_impulse_split(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kSR_SPLT_CL = (btScalar)value;
+}
+
+/**
+ * Getter for property kSK_SPLT_CL.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_soft_vs_kinetic_impulse_split() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kSK_SPLT_CL;
+}
+
+/**
+ * Setter for property kSK_SPLT_CL.
+ */
+void BulletSoftBodyConfig::
+set_soft_vs_kinetic_impulse_split(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kSK_SPLT_CL = (btScalar)value;
+}
+
+/**
+ * Getter for property kSS_SPLT_CL.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_soft_vs_soft_impulse_split() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.kSS_SPLT_CL;
+}
+
+/**
+ * Setter for property kSS_SPLT_CL.
+ */
+void BulletSoftBodyConfig::
+set_soft_vs_soft_impulse_split(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.kSS_SPLT_CL = (btScalar)value;
+}
+
+/**
+ * Getter for property maxvolume.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_maxvolume() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.maxvolume;
+}
+
+/**
+ * Setter for property maxvolume.
+ */
+void BulletSoftBodyConfig::
+set_maxvolume(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.maxvolume = (btScalar)value;
+}
+
+/**
+ * Getter for property timescale.
+ */
+PN_stdfloat BulletSoftBodyConfig::
+get_timescale() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_cfg.timescale;
+}
+
+/**
+ * Setter for property timescale.
+ */
+void BulletSoftBodyConfig::
+set_timescale(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _cfg.timescale = (btScalar)value;
+}
+
+/**
+ * Getter for property piterations.
+ */
+int BulletSoftBodyConfig::
+get_positions_solver_iterations() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _cfg.piterations;
+}
+
+/**
+ * Setter for property piterations.
+ */
+void BulletSoftBodyConfig::
+set_positions_solver_iterations(int value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(value > 0);
+  _cfg.piterations = value;
+}
+
+/**
+ * Getter for property viterations.
+ */
+int BulletSoftBodyConfig::
+get_velocities_solver_iterations() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _cfg.viterations;
+}
+
+/**
+ * Setter for property viterations.
+ */
+void BulletSoftBodyConfig::
+set_velocities_solver_iterations(int value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(value > 0);
+  _cfg.viterations = value;
+}
+
+/**
+ * Getter for property diterations.
+ */
+int BulletSoftBodyConfig::
+get_drift_solver_iterations() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _cfg.diterations;
+}
+
+/**
+ * Setter for property diterations.
+ */
+void BulletSoftBodyConfig::
+set_drift_solver_iterations(int value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(value > 0);
+  _cfg.diterations = value;
+}
+
+/**
+ * Getter for property citerations.
+ */
+int BulletSoftBodyConfig::
+get_cluster_solver_iterations() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _cfg.citerations;
+}
+
+/**
+ * Setter for property citerations.
+ */
+void BulletSoftBodyConfig::
+set_cluster_solver_iterations(int value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(value > 0);
+  _cfg.citerations = value;
+}

+ 49 - 49
panda/src/bullet/bulletSoftBodyConfig.h

@@ -51,55 +51,55 @@ PUBLISHED:
   void set_aero_model(AeroModel value);
   AeroModel get_aero_model() const;
 
-  INLINE void set_velocities_correction_factor(PN_stdfloat value);
-  INLINE void set_damping_coefficient(PN_stdfloat value);
-  INLINE void set_drag_coefficient(PN_stdfloat value);
-  INLINE void set_lift_coefficient(PN_stdfloat value);
-  INLINE void set_pressure_coefficient(PN_stdfloat value);
-  INLINE void set_volume_conservation_coefficient(PN_stdfloat value);
-  INLINE void set_dynamic_friction_coefficient(PN_stdfloat value);
-  INLINE void set_pose_matching_coefficient(PN_stdfloat value);
-  INLINE void set_rigid_contacts_hardness(PN_stdfloat value);
-  INLINE void set_kinetic_contacts_hardness(PN_stdfloat value);
-  INLINE void set_soft_contacts_hardness(PN_stdfloat value);
-  INLINE void set_anchors_hardness(PN_stdfloat value);
-  INLINE void set_soft_vs_rigid_hardness(PN_stdfloat value);
-  INLINE void set_soft_vs_kinetic_hardness(PN_stdfloat value);
-  INLINE void set_soft_vs_soft_hardness(PN_stdfloat value);
-  INLINE void set_soft_vs_rigid_impulse_split(PN_stdfloat value);
-  INLINE void set_soft_vs_kinetic_impulse_split(PN_stdfloat value);
-  INLINE void set_soft_vs_soft_impulse_split(PN_stdfloat value);
-  INLINE void set_maxvolume(PN_stdfloat value);
-  INLINE void set_timescale(PN_stdfloat value);
-  INLINE void set_positions_solver_iterations(int value);
-  INLINE void set_velocities_solver_iterations(int value);
-  INLINE void set_drift_solver_iterations( int value);
-  INLINE void set_cluster_solver_iterations(int value);
-
-  INLINE PN_stdfloat get_velocities_correction_factor() const;
-  INLINE PN_stdfloat get_damping_coefficient() const;
-  INLINE PN_stdfloat get_drag_coefficient() const;
-  INLINE PN_stdfloat get_lift_coefficient() const;
-  INLINE PN_stdfloat get_pressure_coefficient() const;
-  INLINE PN_stdfloat get_volume_conservation_coefficient() const;
-  INLINE PN_stdfloat get_dynamic_friction_coefficient() const;
-  INLINE PN_stdfloat get_pose_matching_coefficient() const;
-  INLINE PN_stdfloat get_rigid_contacts_hardness() const;
-  INLINE PN_stdfloat get_kinetic_contacts_hardness() const;
-  INLINE PN_stdfloat get_soft_contacts_hardness() const;
-  INLINE PN_stdfloat get_anchors_hardness() const;
-  INLINE PN_stdfloat get_soft_vs_rigid_hardness() const;
-  INLINE PN_stdfloat get_soft_vs_kinetic_hardness() const;
-  INLINE PN_stdfloat get_soft_vs_soft_hardness() const;
-  INLINE PN_stdfloat get_soft_vs_rigid_impulse_split() const;
-  INLINE PN_stdfloat get_soft_vs_kinetic_impulse_split() const;
-  INLINE PN_stdfloat get_soft_vs_soft_impulse_split() const;
-  INLINE PN_stdfloat get_maxvolume() const;
-  INLINE PN_stdfloat get_timescale() const;
-  INLINE int get_positions_solver_iterations() const;
-  INLINE int get_velocities_solver_iterations() const;
-  INLINE int get_drift_solver_iterations() const;
-  INLINE int get_cluster_solver_iterations() const;
+  void set_velocities_correction_factor(PN_stdfloat value);
+  void set_damping_coefficient(PN_stdfloat value);
+  void set_drag_coefficient(PN_stdfloat value);
+  void set_lift_coefficient(PN_stdfloat value);
+  void set_pressure_coefficient(PN_stdfloat value);
+  void set_volume_conservation_coefficient(PN_stdfloat value);
+  void set_dynamic_friction_coefficient(PN_stdfloat value);
+  void set_pose_matching_coefficient(PN_stdfloat value);
+  void set_rigid_contacts_hardness(PN_stdfloat value);
+  void set_kinetic_contacts_hardness(PN_stdfloat value);
+  void set_soft_contacts_hardness(PN_stdfloat value);
+  void set_anchors_hardness(PN_stdfloat value);
+  void set_soft_vs_rigid_hardness(PN_stdfloat value);
+  void set_soft_vs_kinetic_hardness(PN_stdfloat value);
+  void set_soft_vs_soft_hardness(PN_stdfloat value);
+  void set_soft_vs_rigid_impulse_split(PN_stdfloat value);
+  void set_soft_vs_kinetic_impulse_split(PN_stdfloat value);
+  void set_soft_vs_soft_impulse_split(PN_stdfloat value);
+  void set_maxvolume(PN_stdfloat value);
+  void set_timescale(PN_stdfloat value);
+  void set_positions_solver_iterations(int value);
+  void set_velocities_solver_iterations(int value);
+  void set_drift_solver_iterations( int value);
+  void set_cluster_solver_iterations(int value);
+
+  PN_stdfloat get_velocities_correction_factor() const;
+  PN_stdfloat get_damping_coefficient() const;
+  PN_stdfloat get_drag_coefficient() const;
+  PN_stdfloat get_lift_coefficient() const;
+  PN_stdfloat get_pressure_coefficient() const;
+  PN_stdfloat get_volume_conservation_coefficient() const;
+  PN_stdfloat get_dynamic_friction_coefficient() const;
+  PN_stdfloat get_pose_matching_coefficient() const;
+  PN_stdfloat get_rigid_contacts_hardness() const;
+  PN_stdfloat get_kinetic_contacts_hardness() const;
+  PN_stdfloat get_soft_contacts_hardness() const;
+  PN_stdfloat get_anchors_hardness() const;
+  PN_stdfloat get_soft_vs_rigid_hardness() const;
+  PN_stdfloat get_soft_vs_kinetic_hardness() const;
+  PN_stdfloat get_soft_vs_soft_hardness() const;
+  PN_stdfloat get_soft_vs_rigid_impulse_split() const;
+  PN_stdfloat get_soft_vs_kinetic_impulse_split() const;
+  PN_stdfloat get_soft_vs_soft_impulse_split() const;
+  PN_stdfloat get_maxvolume() const;
+  PN_stdfloat get_timescale() const;
+  int get_positions_solver_iterations() const;
+  int get_velocities_solver_iterations() const;
+  int get_drift_solver_iterations() const;
+  int get_cluster_solver_iterations() const;
 
   MAKE_PROPERTY(aero_model, get_aero_model, set_aero_model);
   MAKE_PROPERTY(velocities_correction_factor, get_velocities_correction_factor, set_velocities_correction_factor);

+ 0 - 63
panda/src/bullet/bulletSoftBodyMaterial.I

@@ -30,66 +30,3 @@ empty() {
 
   return BulletSoftBodyMaterial(material);
 }
-
-/**
- *
- */
-INLINE btSoftBody::Material &BulletSoftBodyMaterial::
-get_material() const {
-
-  return _material;
-}
-
-/**
- * Getter for the property m_kLST.
- */
-INLINE PN_stdfloat BulletSoftBodyMaterial::
-get_linear_stiffness() const {
-
-  return (PN_stdfloat)_material.m_kLST;
-}
-
-/**
- * Setter for the property m_kLST.
- */
-INLINE void BulletSoftBodyMaterial::
-set_linear_stiffness(PN_stdfloat value) {
-
-  _material.m_kLST = (btScalar)value;
-}
-
-/**
- * Getter for the property m_kAST.
- */
-INLINE PN_stdfloat BulletSoftBodyMaterial::
-get_angular_stiffness() const {
-
-  return (PN_stdfloat)_material.m_kAST;
-}
-
-/**
- * Setter for the property m_kAST.
- */
-INLINE void BulletSoftBodyMaterial::
-set_angular_stiffness(PN_stdfloat value) {
-
-  _material.m_kAST = (btScalar)value;
-}
-
-/**
- * Getter for the property m_kVST.
- */
-INLINE PN_stdfloat BulletSoftBodyMaterial::
-get_volume_preservation() const {
-
-  return (PN_stdfloat)_material.m_kVST;
-}
-
-/**
- * Setter for the property m_kVST.
- */
-INLINE void BulletSoftBodyMaterial::
-set_volume_preservation(PN_stdfloat value) {
-
-  _material.m_kVST = (btScalar)value;
-}

+ 69 - 0
panda/src/bullet/bulletSoftBodyMaterial.cxx

@@ -20,3 +20,72 @@ BulletSoftBodyMaterial::
 BulletSoftBodyMaterial(btSoftBody::Material &material) : _material(material) {
 
 }
+
+/**
+ *
+ */
+btSoftBody::Material &BulletSoftBodyMaterial::
+get_material() const {
+
+  return _material;
+}
+
+/**
+ * Getter for the property m_kLST.
+ */
+PN_stdfloat BulletSoftBodyMaterial::
+get_linear_stiffness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_material.m_kLST;
+}
+
+/**
+ * Setter for the property m_kLST.
+ */
+void BulletSoftBodyMaterial::
+set_linear_stiffness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _material.m_kLST = (btScalar)value;
+}
+
+/**
+ * Getter for the property m_kAST.
+ */
+PN_stdfloat BulletSoftBodyMaterial::
+get_angular_stiffness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_material.m_kAST;
+}
+
+/**
+ * Setter for the property m_kAST.
+ */
+void BulletSoftBodyMaterial::
+set_angular_stiffness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _material.m_kAST = (btScalar)value;
+}
+
+/**
+ * Getter for the property m_kVST.
+ */
+PN_stdfloat BulletSoftBodyMaterial::
+get_volume_preservation() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_material.m_kVST;
+}
+
+/**
+ * Setter for the property m_kVST.
+ */
+void BulletSoftBodyMaterial::
+set_volume_preservation(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _material.m_kVST = (btScalar)value;
+}

+ 7 - 7
panda/src/bullet/bulletSoftBodyMaterial.h

@@ -27,14 +27,14 @@ PUBLISHED:
   INLINE ~BulletSoftBodyMaterial();
   INLINE static BulletSoftBodyMaterial empty();
 
-  INLINE PN_stdfloat get_linear_stiffness() const;
-  INLINE void set_linear_stiffness(PN_stdfloat value);
+  PN_stdfloat get_linear_stiffness() const;
+  void set_linear_stiffness(PN_stdfloat value);
   
-  INLINE PN_stdfloat get_angular_stiffness() const;
-  INLINE void set_angular_stiffness(PN_stdfloat value);
-  
-  INLINE PN_stdfloat get_volume_preservation() const;
-  INLINE void set_volume_preservation(PN_stdfloat value);
+  PN_stdfloat get_angular_stiffness() const;
+  void set_angular_stiffness(PN_stdfloat value);
+
+  PN_stdfloat get_volume_preservation() const;
+  void set_volume_preservation(PN_stdfloat value);
   
   MAKE_PROPERTY(linear_stiffness, get_linear_stiffness, set_linear_stiffness);
   MAKE_PROPERTY(angular_stiffness, get_angular_stiffness, set_angular_stiffness);

+ 0 - 53
panda/src/bullet/bulletSoftBodyNode.I

@@ -40,56 +40,3 @@ empty() {
   return BulletSoftBodyNodeElement(node);
 }
 
-/**
- *
- */
-INLINE LPoint3 BulletSoftBodyNodeElement::
-get_pos() const {
-
-  return btVector3_to_LPoint3(_node.m_x);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletSoftBodyNodeElement::
-get_normal() const {
-
-  return btVector3_to_LVector3(_node.m_n);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletSoftBodyNodeElement::
-get_velocity() const {
-
-  return btVector3_to_LVector3(_node.m_v);
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletSoftBodyNodeElement::
-get_inv_mass() const {
-
-  return (PN_stdfloat)_node.m_im;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletSoftBodyNodeElement::
-get_area() const {
-
-  return (PN_stdfloat)_node.m_area;
-}
-
-/**
- *
- */
-INLINE int BulletSoftBodyNodeElement::
-is_attached() const {
-
-  return (PN_stdfloat)_node.m_battach;
-}

+ 137 - 11
panda/src/bullet/bulletSoftBodyNode.cxx

@@ -66,6 +66,7 @@ get_object() const {
  */
 BulletSoftBodyConfig BulletSoftBodyNode::
 get_cfg() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return BulletSoftBodyConfig(_soft->m_cfg);
 }
@@ -75,6 +76,7 @@ get_cfg() {
  */
 BulletSoftBodyWorldInfo BulletSoftBodyNode::
 get_world_info() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return BulletSoftBodyWorldInfo(*(_soft->m_worldInfo));
 }
@@ -84,6 +86,7 @@ get_world_info() {
  */
 int BulletSoftBodyNode::
 get_num_materials() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _soft->m_materials.size();
 }
@@ -93,8 +96,9 @@ get_num_materials() const {
  */
 BulletSoftBodyMaterial BulletSoftBodyNode::
 get_material(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  nassertr(idx >= 0 && idx < get_num_materials(), BulletSoftBodyMaterial::empty());
+  nassertr(idx >= 0 && idx < _soft->m_materials.size(), BulletSoftBodyMaterial::empty());
 
   btSoftBody::Material *material = _soft->m_materials[idx];
   return BulletSoftBodyMaterial(*material);
@@ -105,6 +109,7 @@ get_material(int idx) const {
  */
 BulletSoftBodyMaterial BulletSoftBodyNode::
 append_material() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btSoftBody::Material *material = _soft->appendMaterial();
   nassertr(material, BulletSoftBodyMaterial::empty());
@@ -117,6 +122,7 @@ append_material() {
  */
 int BulletSoftBodyNode::
 get_num_nodes() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _soft->m_nodes.size();
 }
@@ -126,6 +132,7 @@ get_num_nodes() const {
  */
 BulletSoftBodyNodeElement BulletSoftBodyNode::
 get_node(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertr(idx >=0 && idx < get_num_nodes(), BulletSoftBodyNodeElement::empty());
   return BulletSoftBodyNodeElement(_soft->m_nodes[idx]);
@@ -136,6 +143,7 @@ get_node(int idx) const {
  */
 void BulletSoftBodyNode::
 generate_bending_constraints(int distance, BulletSoftBodyMaterial *material) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   if (material) {
     _soft->generateBendingConstraints(distance, &(material->get_material()));
@@ -150,6 +158,7 @@ generate_bending_constraints(int distance, BulletSoftBodyMaterial *material) {
  */
 void BulletSoftBodyNode::
 randomize_constraints() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->randomizeConstraints();
 }
@@ -159,9 +168,10 @@ randomize_constraints() {
  */
 void BulletSoftBodyNode::
 transform_changed() {
-
   if (_sync_disable) return;
 
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
   NodePath np = NodePath::any_path((PandaNode *)this);
   CPT(TransformState) ts = np.get_net_transform();
 
@@ -174,7 +184,7 @@ transform_changed() {
     btTransform trans = TransformState_to_btTrans(ts);
 
     // Offset between current approx center and current initial transform
-    btVector3 pos = LVecBase3_to_btVector3(this->get_aabb().get_approx_center());
+    btVector3 pos = LVecBase3_to_btVector3(this->do_get_aabb().get_approx_center());
     btVector3 origin = _soft->m_initialWorldTransform.getOrigin();
     btVector3 offset = pos - origin;
 
@@ -205,16 +215,16 @@ transform_changed() {
  *
  */
 void BulletSoftBodyNode::
-sync_p2b() {
+do_sync_p2b() {
 
   // transform_changed(); Disabled for now...
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletSoftBodyNode::
-sync_b2p() {
+do_sync_b2p() {
 
   // Render softbody
   if (_geom) {
@@ -266,7 +276,7 @@ sync_b2p() {
 
   // Update the synchronized transform with the current approximate center of
   // the soft body
-  LVecBase3 pos = this->get_aabb().get_approx_center();
+  LVecBase3 pos = this->do_get_aabb().get_approx_center();
   CPT(TransformState) ts = TransformState::make_pos(pos);
 
   NodePath np = NodePath::any_path((PandaNode *)this);
@@ -291,6 +301,19 @@ sync_b2p() {
  */
 int BulletSoftBodyNode::
 get_closest_node_index(LVecBase3 point, bool local) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return do_get_closest_node_index(point, local);
+}
+
+/**
+ * Returns the index of the node which is closest to the given point.  The
+ * distance between each node and the given point is computed in world space
+ * if local=false, and in local space if local=true.
+ * Assumes the lock(bullet global lock) is held by the caller
+ */
+int BulletSoftBodyNode::
+do_get_closest_node_index(LVecBase3 point, bool local) {
 
   btScalar max_dist_sqr = 1e30;
   btVector3 point_x = LVecBase3_to_btVector3(point);
@@ -322,11 +345,12 @@ get_closest_node_index(LVecBase3 point, bool local) {
  */
 void BulletSoftBodyNode::
 link_geom(Geom *geom) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(geom->get_vertex_data()->has_column(InternalName::get_vertex()));
   nassertv(geom->get_vertex_data()->has_column(InternalName::get_normal()));
 
-  sync_p2b();
+  do_sync_p2b();
 
   _geom = geom;
 
@@ -349,7 +373,7 @@ link_geom(Geom *geom) {
 
   while (!vertices.is_at_end()) {
     LVecBase3 point = vertices.get_data3();
-    int node_idx = get_closest_node_index(point, true);
+    int node_idx = do_get_closest_node_index(point, true);
     indices.set_data1i(node_idx);
   }
 }
@@ -359,6 +383,7 @@ link_geom(Geom *geom) {
  */
 void BulletSoftBodyNode::
 unlink_geom() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _geom = NULL;
 }
@@ -368,6 +393,7 @@ unlink_geom() {
  */
 void BulletSoftBodyNode::
 link_curve(NurbsCurveEvaluator *curve) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(curve->get_num_vertices() == _soft->m_nodes.size());
 
@@ -379,6 +405,7 @@ link_curve(NurbsCurveEvaluator *curve) {
  */
 void BulletSoftBodyNode::
 unlink_curve() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _curve = NULL;
 }
@@ -388,6 +415,7 @@ unlink_curve() {
  */
 void BulletSoftBodyNode::
 link_surface(NurbsSurfaceEvaluator *surface) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(surface->get_num_u_vertices() * surface->get_num_v_vertices() == _soft->m_nodes.size());
 
@@ -399,6 +427,7 @@ link_surface(NurbsSurfaceEvaluator *surface) {
  */
 void BulletSoftBodyNode::
 unlink_surface() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _surface = NULL;
 }
@@ -408,6 +437,16 @@ unlink_surface() {
  */
 BoundingBox BulletSoftBodyNode::
 get_aabb() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return do_get_aabb();
+}
+
+/**
+ *
+ */
+BoundingBox BulletSoftBodyNode::
+do_get_aabb() const {
 
   btVector3 pMin;
   btVector3 pMax;
@@ -425,6 +464,7 @@ get_aabb() const {
  */
 void BulletSoftBodyNode::
 set_volume_mass(PN_stdfloat mass) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->setVolumeMass(mass);
 }
@@ -434,6 +474,7 @@ set_volume_mass(PN_stdfloat mass) {
  */
 void BulletSoftBodyNode::
 set_total_mass(PN_stdfloat mass, bool fromfaces) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->setTotalMass(mass, fromfaces);
 }
@@ -443,6 +484,7 @@ set_total_mass(PN_stdfloat mass, bool fromfaces) {
  */
 void BulletSoftBodyNode::
 set_volume_density(PN_stdfloat density) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->setVolumeDensity(density);
 }
@@ -452,6 +494,7 @@ set_volume_density(PN_stdfloat density) {
  */
 void BulletSoftBodyNode::
 set_total_density(PN_stdfloat density) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->setTotalDensity(density);
 }
@@ -461,6 +504,7 @@ set_total_density(PN_stdfloat density) {
  */
 void BulletSoftBodyNode::
 set_mass(int node, PN_stdfloat mass) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->setMass(node, mass);
 }
@@ -470,6 +514,7 @@ set_mass(int node, PN_stdfloat mass) {
  */
 PN_stdfloat BulletSoftBodyNode::
 get_mass(int node) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _soft->getMass(node);
 }
@@ -479,6 +524,7 @@ get_mass(int node) const {
  */
 PN_stdfloat BulletSoftBodyNode::
 get_total_mass() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _soft->getTotalMass();
 }
@@ -488,6 +534,7 @@ get_total_mass() const {
  */
 PN_stdfloat BulletSoftBodyNode::
 get_volume() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _soft->getVolume();
 }
@@ -497,6 +544,7 @@ get_volume() const {
  */
 void BulletSoftBodyNode::
 add_force(const LVector3 &force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!force.is_nan());
   _soft->addForce(LVecBase3_to_btVector3(force));
@@ -507,6 +555,7 @@ add_force(const LVector3 &force) {
  */
 void BulletSoftBodyNode::
 add_force(const LVector3 &force, int node) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!force.is_nan());
   _soft->addForce(LVecBase3_to_btVector3(force), node);
@@ -517,6 +566,7 @@ add_force(const LVector3 &force, int node) {
  */
 void BulletSoftBodyNode::
 set_velocity(const LVector3 &velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!velocity.is_nan());
   _soft->setVelocity(LVecBase3_to_btVector3(velocity));
@@ -527,6 +577,7 @@ set_velocity(const LVector3 &velocity) {
  */
 void BulletSoftBodyNode::
 add_velocity(const LVector3 &velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!velocity.is_nan());
   _soft->addVelocity(LVecBase3_to_btVector3(velocity));
@@ -537,6 +588,7 @@ add_velocity(const LVector3 &velocity) {
  */
 void BulletSoftBodyNode::
 add_velocity(const LVector3 &velocity, int node) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!velocity.is_nan());
   _soft->addVelocity(LVecBase3_to_btVector3(velocity), node);
@@ -547,6 +599,7 @@ add_velocity(const LVector3 &velocity, int node) {
  */
 void BulletSoftBodyNode::
 generate_clusters(int k, int maxiterations) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->generateClusters(k, maxiterations);
 }
@@ -556,6 +609,7 @@ generate_clusters(int k, int maxiterations) {
  */
 void BulletSoftBodyNode::
 release_clusters() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->releaseClusters();
 }
@@ -565,6 +619,7 @@ release_clusters() {
  */
 void BulletSoftBodyNode::
 release_cluster(int index) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->releaseCluster(index);
 }
@@ -574,6 +629,7 @@ release_cluster(int index) {
  */
 int BulletSoftBodyNode::
 get_num_clusters() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _soft->clusterCount();
 }
@@ -583,6 +639,7 @@ get_num_clusters() const {
  */
 LVecBase3 BulletSoftBodyNode::
 cluster_com(int cluster) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVecBase3(_soft->clusterCom(cluster));
 }
@@ -592,6 +649,7 @@ cluster_com(int cluster) const {
  */
 void BulletSoftBodyNode::
 set_pose(bool bvolume, bool bframe) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _soft->setPose(bvolume, bframe);
 }
@@ -601,11 +659,12 @@ set_pose(bool bvolume, bool bframe) {
  */
 void BulletSoftBodyNode::
 append_anchor(int node, BulletRigidBodyNode *body, bool disable) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(node < _soft->m_nodes.size())
   nassertv(body);
 
-  body->sync_p2b();
+  body->do_sync_p2b();
 
   btRigidBody *ptr = (btRigidBody *)body->get_object();
   _soft->appendAnchor(node, ptr, disable);
@@ -616,12 +675,13 @@ append_anchor(int node, BulletRigidBodyNode *body, bool disable) {
  */
 void BulletSoftBodyNode::
 append_anchor(int node, BulletRigidBodyNode *body, const LVector3 &pivot, bool disable) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(node < _soft->m_nodes.size())
   nassertv(body);
   nassertv(!pivot.is_nan());
 
-  body->sync_p2b();
+  body->do_sync_p2b();
 
   btRigidBody *ptr = (btRigidBody *)body->get_object();
   _soft->appendAnchor(node, ptr, LVecBase3_to_btVector3(pivot), disable);
@@ -642,6 +702,7 @@ BulletSoftBodyNodeElement(btSoftBody::Node &node) : _node(node) {
  */
 int BulletSoftBodyNode::
 get_point_index(LVecBase3 p, PTA_LVecBase3 points) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   PN_stdfloat eps = 1.0e-6f; // TODO make this a config option
 
@@ -979,6 +1040,7 @@ make_tet_mesh(BulletSoftBodyWorldInfo &info, const char *ele, const char *face,
  */
 void BulletSoftBodyNode::
 append_linear_joint(BulletBodyNode *body, int cluster, PN_stdfloat erp, PN_stdfloat cfm, PN_stdfloat split) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(body);
 
@@ -998,6 +1060,7 @@ append_linear_joint(BulletBodyNode *body, int cluster, PN_stdfloat erp, PN_stdfl
  */
 void BulletSoftBodyNode::
 append_linear_joint(BulletBodyNode *body, const LPoint3 &pos, PN_stdfloat erp, PN_stdfloat cfm, PN_stdfloat split) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(body);
 
@@ -1017,6 +1080,7 @@ append_linear_joint(BulletBodyNode *body, const LPoint3 &pos, PN_stdfloat erp, P
  */
 void BulletSoftBodyNode::
 append_angular_joint(BulletBodyNode *body, const LVector3 &axis, PN_stdfloat erp, PN_stdfloat cfm, PN_stdfloat split, BulletSoftBodyControl *control) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(body);
 
@@ -1037,6 +1101,7 @@ append_angular_joint(BulletBodyNode *body, const LVector3 &axis, PN_stdfloat erp
  */
 void BulletSoftBodyNode::
 set_wind_velocity(const LVector3 &velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!velocity.is_nan());
   _soft->setWindVelocity(LVecBase3_to_btVector3(velocity));
@@ -1047,6 +1112,67 @@ set_wind_velocity(const LVector3 &velocity) {
  */
 LVector3 BulletSoftBodyNode::
 get_wind_velocity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_soft->getWindVelocity());
 }
+
+/**
+ *
+ */
+LPoint3 BulletSoftBodyNodeElement::
+get_pos() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LPoint3(_node.m_x);
+}
+
+/**
+ *
+ */
+LVector3 BulletSoftBodyNodeElement::
+get_normal() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_node.m_n);
+}
+
+/**
+ *
+ */
+LVector3 BulletSoftBodyNodeElement::
+get_velocity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_node.m_v);
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletSoftBodyNodeElement::
+get_inv_mass() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_node.m_im;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletSoftBodyNodeElement::
+get_area() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_node.m_area;
+}
+
+/**
+ *
+ */
+int BulletSoftBodyNodeElement::
+is_attached() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_node.m_battach;
+}

+ 11 - 8
panda/src/bullet/bulletSoftBodyNode.h

@@ -43,12 +43,12 @@ PUBLISHED:
   INLINE ~BulletSoftBodyNodeElement();
   INLINE static BulletSoftBodyNodeElement empty();
 
-  INLINE LPoint3 get_pos() const;
-  INLINE LVector3 get_velocity() const;
-  INLINE LVector3 get_normal() const;
-  INLINE PN_stdfloat get_inv_mass() const;
-  INLINE PN_stdfloat get_area() const;
-  INLINE int is_attached() const;
+  LPoint3 get_pos() const;
+  LVector3 get_velocity() const;
+  LVector3 get_normal() const;
+  PN_stdfloat get_inv_mass() const;
+  PN_stdfloat get_area() const;
+  int is_attached() const;
 
   MAKE_PROPERTY(pos, get_pos);
   MAKE_PROPERTY(velocity, get_velocity);
@@ -221,8 +221,8 @@ PUBLISHED:
 public:
   virtual btCollisionObject *get_object() const;
 
-  void sync_p2b();
-  void sync_b2p();
+  void do_sync_p2b();
+  void do_sync_b2p();
 
 protected:
   virtual void transform_changed();
@@ -240,6 +240,9 @@ private:
   static int get_point_index(LVecBase3 p, PTA_LVecBase3 points);
   static int next_line(const char *buffer);
 
+  BoundingBox do_get_aabb() const;
+  int do_get_closest_node_index(LVecBase3 point, bool local);
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 1 - 0
panda/src/bullet/bulletSoftBodyShape.cxx

@@ -40,6 +40,7 @@ ptr() const {
  */
 BulletSoftBodyNode *BulletSoftBodyShape::
 get_body() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   if (_shape->m_body) {
     return (BulletSoftBodyNode *)_shape->m_body->getUserPointer();

+ 11 - 0
panda/src/bullet/bulletSoftBodyWorldInfo.cxx

@@ -26,6 +26,7 @@ BulletSoftBodyWorldInfo(btSoftBodyWorldInfo &info) : _info(info) {
  */
 void BulletSoftBodyWorldInfo::
 garbage_collect(int lifetime) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_sparsesdf.GarbageCollect(lifetime);
 }
@@ -35,6 +36,7 @@ garbage_collect(int lifetime) {
  */
 void BulletSoftBodyWorldInfo::
 set_air_density(PN_stdfloat density) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.air_density = (btScalar)density;
 }
@@ -44,6 +46,7 @@ set_air_density(PN_stdfloat density) {
  */
 void BulletSoftBodyWorldInfo::
 set_water_density(PN_stdfloat density) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.water_density = (btScalar)density;
 }
@@ -53,6 +56,7 @@ set_water_density(PN_stdfloat density) {
  */
 void BulletSoftBodyWorldInfo::
 set_water_offset(PN_stdfloat offset) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.water_offset = (btScalar)offset;
 }
@@ -62,6 +66,7 @@ set_water_offset(PN_stdfloat offset) {
  */
 void BulletSoftBodyWorldInfo::
 set_water_normal(const LVector3 &normal) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!normal.is_nan());
   _info.water_normal.setValue(normal.get_x(), normal.get_y(), normal.get_z());
@@ -72,6 +77,7 @@ set_water_normal(const LVector3 &normal) {
  */
 void BulletSoftBodyWorldInfo::
 set_gravity(const LVector3 &gravity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!gravity.is_nan());
   _info.m_gravity.setValue(gravity.get_x(), gravity.get_y(), gravity.get_z());
@@ -82,6 +88,7 @@ set_gravity(const LVector3 &gravity) {
  */
 PN_stdfloat BulletSoftBodyWorldInfo::
 get_air_density() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.air_density;
 }
@@ -91,6 +98,7 @@ get_air_density() const {
  */
 PN_stdfloat BulletSoftBodyWorldInfo::
 get_water_density() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.water_density;
 }
@@ -100,6 +108,7 @@ get_water_density() const {
  */
 PN_stdfloat BulletSoftBodyWorldInfo::
 get_water_offset() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.water_offset;
 }
@@ -109,6 +118,7 @@ get_water_offset() const {
  */
 LVector3 BulletSoftBodyWorldInfo::
 get_water_normal() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_info.water_normal);
 }
@@ -118,6 +128,7 @@ get_water_normal() const {
  */
 LVector3 BulletSoftBodyWorldInfo::
 get_gravity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_info.m_gravity);
 }

+ 0 - 18
panda/src/bullet/bulletSphereShape.I

@@ -20,24 +20,6 @@ INLINE BulletSphereShape::
   delete _shape;
 }
 
-/**
- *
- */
-INLINE BulletSphereShape::
-BulletSphereShape(const BulletSphereShape &copy) :
-  _shape(copy._shape),
-  _radius(copy._radius) {
-}
-
-/**
- *
- */
-INLINE void BulletSphereShape::
-operator = (const BulletSphereShape &copy) {
-  _shape = copy._shape;
-  _radius = copy._radius;
-}
-
 /**
  * Returns the radius that was used to construct this sphere.
  */

+ 23 - 0
panda/src/bullet/bulletSphereShape.cxx

@@ -25,6 +25,29 @@ BulletSphereShape(PN_stdfloat radius) : _radius(radius) {
   _shape->setUserPointer(this);
 }
 
+/**
+ *
+ */
+BulletSphereShape::
+BulletSphereShape(const BulletSphereShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _radius = copy._radius;
+}
+
+/**
+ *
+ */
+void BulletSphereShape::
+operator = (const BulletSphereShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _shape = copy._shape;
+  _radius = copy._radius;
+}
+
+
 /**
  *
  */

+ 2 - 2
panda/src/bullet/bulletSphereShape.h

@@ -32,8 +32,8 @@ private:
 
 PUBLISHED:
   explicit BulletSphereShape(PN_stdfloat radius);
-  INLINE BulletSphereShape(const BulletSphereShape &copy);
-  INLINE void operator = (const BulletSphereShape &copy);
+  BulletSphereShape(const BulletSphereShape &copy);
+  void operator = (const BulletSphereShape &copy);
   INLINE ~BulletSphereShape();
 
   INLINE PN_stdfloat get_radius() const;

+ 4 - 0
panda/src/bullet/bulletSphericalConstraint.cxx

@@ -61,6 +61,7 @@ ptr() const {
  */
 void BulletSphericalConstraint::
 set_pivot_a(const LPoint3 &pivot_a) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!pivot_a.is_nan());
   _constraint->setPivotA(LVecBase3_to_btVector3(pivot_a));
@@ -71,6 +72,7 @@ set_pivot_a(const LPoint3 &pivot_a) {
  */
 void BulletSphericalConstraint::
 set_pivot_b(const LPoint3 &pivot_b) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!pivot_b.is_nan());
   _constraint->setPivotB(LVecBase3_to_btVector3(pivot_b));
@@ -81,6 +83,7 @@ set_pivot_b(const LPoint3 &pivot_b) {
  */
 LPoint3 BulletSphericalConstraint::
 get_pivot_in_a() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LPoint3(_constraint->getPivotInA());
 }
@@ -90,6 +93,7 @@ get_pivot_in_a() const {
  */
 LPoint3 BulletSphericalConstraint::
 get_pivot_in_b() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LPoint3(_constraint->getPivotInB());
 }

+ 2 - 159
panda/src/bullet/bulletTranslationalLimitMotor.I

@@ -14,164 +14,7 @@
 /**
  *
  */
-INLINE bool BulletTranslationalLimitMotor::
-is_limited(int axis) const {
+INLINE BulletTranslationalLimitMotor::
+~BulletTranslationalLimitMotor() {
 
-  nassertr((0 <= axis) && (axis <= 2), false);
-  return _motor.isLimited(axis);
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_motor_enabled(int axis, bool enabled) {
-
-  nassertv((0 <= axis) && (axis <= 2));
-  _motor.m_enableMotor[axis] = enabled;
-}
-
-/**
- *
- */
-INLINE bool BulletTranslationalLimitMotor::
-get_motor_enabled(int axis) const {
-
-  nassertr((0 <= axis) && (axis <= 2), false);
-  return _motor.m_enableMotor[axis];
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_low_limit(const LVecBase3 &limit) {
-
-  nassertv(!limit.is_nan());
-  _motor.m_lowerLimit = LVecBase3_to_btVector3(limit);
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_high_limit(const LVecBase3 &limit) {
-
-  nassertv(!limit.is_nan());
-  _motor.m_upperLimit = LVecBase3_to_btVector3(limit);
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_target_velocity(const LVecBase3 &velocity) {
-
-  nassertv(!velocity.is_nan());
-  _motor.m_targetVelocity = LVecBase3_to_btVector3(velocity);
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_max_motor_force(const LVecBase3 &force) {
-
-  nassertv(!force.is_nan());
-  _motor.m_maxMotorForce = LVecBase3_to_btVector3(force);
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_damping(PN_stdfloat damping) {
-
-  _motor.m_damping = (btScalar)damping;
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_softness(PN_stdfloat softness) {
-
-  _motor.m_limitSoftness = (btScalar)softness;
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_restitution(PN_stdfloat restitution) {
-
-  _motor.m_restitution = (btScalar)restitution;
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_normal_cfm(const LVecBase3 &cfm) {
-
-  nassertv(!cfm.is_nan());
-  _motor.m_normalCFM = LVecBase3_to_btVector3(cfm);
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_stop_cfm(const LVecBase3 &cfm) {
-
-  nassertv(!cfm.is_nan());
-  _motor.m_stopCFM = LVecBase3_to_btVector3(cfm);
-}
-
-/**
- *
- */
-INLINE void BulletTranslationalLimitMotor::
-set_stop_erp(const LVecBase3 &erp) {
-
-  nassertv(!erp.is_nan());
-  _motor.m_stopERP = LVecBase3_to_btVector3(erp);
-}
-
-/**
- * Retrieves the current value of angle: 0 = free, 1 = at low limit, 2 = at
- * high limit.
- */
-INLINE int BulletTranslationalLimitMotor::
-get_current_limit(int axis) const {
-
-  nassertr((0 <= axis) && (axis <= 2), false);
-  return _motor.m_currentLimit[axis];
-}
-
-/**
- *
- */
-INLINE LVector3 BulletTranslationalLimitMotor::
-get_current_error() const {
-
-  return btVector3_to_LVector3(_motor.m_currentLimitError);
-}
-
-/**
- *
- */
-INLINE LPoint3 BulletTranslationalLimitMotor::
-get_current_diff() const {
-
-  return btVector3_to_LPoint3(_motor.m_currentLinearDiff);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletTranslationalLimitMotor::
-get_accumulated_impulse() const {
-
-  return btVector3_to_LVector3(_motor.m_accumulatedImpulse);
 }

+ 177 - 2
panda/src/bullet/bulletTranslationalLimitMotor.cxx

@@ -34,7 +34,182 @@ BulletTranslationalLimitMotor(const BulletTranslationalLimitMotor &copy)
 /**
  *
  */
-BulletTranslationalLimitMotor::
-~BulletTranslationalLimitMotor() {
+bool BulletTranslationalLimitMotor::
+is_limited(int axis) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr((0 <= axis) && (axis <= 2), false);
+  return _motor.isLimited(axis);
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_motor_enabled(int axis, bool enabled) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv((0 <= axis) && (axis <= 2));
+  _motor.m_enableMotor[axis] = enabled;
+}
+
+/**
+ *
+ */
+bool BulletTranslationalLimitMotor::
+get_motor_enabled(int axis) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr((0 <= axis) && (axis <= 2), false);
+  return _motor.m_enableMotor[axis];
+}
+
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_low_limit(const LVecBase3 &limit) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(!limit.is_nan());
+  _motor.m_lowerLimit = LVecBase3_to_btVector3(limit);
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_high_limit(const LVecBase3 &limit) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(!limit.is_nan());
+  _motor.m_upperLimit = LVecBase3_to_btVector3(limit);
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_target_velocity(const LVecBase3 &velocity) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(!velocity.is_nan());
+  _motor.m_targetVelocity = LVecBase3_to_btVector3(velocity);
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_max_motor_force(const LVecBase3 &force) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(!force.is_nan());
+  _motor.m_maxMotorForce = LVecBase3_to_btVector3(force);
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_damping(PN_stdfloat damping) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_damping = (btScalar)damping;
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_softness(PN_stdfloat softness) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_limitSoftness = (btScalar)softness;
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_restitution(PN_stdfloat restitution) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _motor.m_restitution = (btScalar)restitution;
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_normal_cfm(const LVecBase3 &cfm) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(!cfm.is_nan());
+  _motor.m_normalCFM = LVecBase3_to_btVector3(cfm);
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_stop_cfm(const LVecBase3 &cfm) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(!cfm.is_nan());
+  _motor.m_stopCFM = LVecBase3_to_btVector3(cfm);
+}
+
+/**
+ *
+ */
+void BulletTranslationalLimitMotor::
+set_stop_erp(const LVecBase3 &erp) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertv(!erp.is_nan());
+  _motor.m_stopERP = LVecBase3_to_btVector3(erp);
+}
+
+/**
+ * Retrieves the current value of angle: 0 = free, 1 = at low limit, 2 = at
+ * high limit.
+ */
+int BulletTranslationalLimitMotor::
+get_current_limit(int axis) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr((0 <= axis) && (axis <= 2), false);
+  return _motor.m_currentLimit[axis];
+}
+
+/**
+ *
+ */
+LVector3 BulletTranslationalLimitMotor::
+get_current_error() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_motor.m_currentLimitError);
+}
+
+/**
+ *
+ */
+LPoint3 BulletTranslationalLimitMotor::
+get_current_diff() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LPoint3(_motor.m_currentLinearDiff);
+}
+
+/**
+ *
+ */
+LVector3 BulletTranslationalLimitMotor::
+get_accumulated_impulse() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
+  return btVector3_to_LVector3(_motor.m_accumulatedImpulse);
 }

+ 18 - 18
panda/src/bullet/bulletTranslationalLimitMotor.h

@@ -28,26 +28,26 @@ class EXPCL_PANDABULLET BulletTranslationalLimitMotor {
 
 PUBLISHED:
   BulletTranslationalLimitMotor(const BulletTranslationalLimitMotor &copy);
-  ~BulletTranslationalLimitMotor();
+  INLINE ~BulletTranslationalLimitMotor();
 
-  INLINE void set_motor_enabled(int axis, bool enable);
-  INLINE void set_low_limit(const LVecBase3 &limit);
-  INLINE void set_high_limit(const LVecBase3 &limit);
-  INLINE void set_target_velocity(const LVecBase3 &velocity);
-  INLINE void set_max_motor_force(const LVecBase3 &force);
-  INLINE void set_damping(PN_stdfloat damping);
-  INLINE void set_softness(PN_stdfloat softness);
-  INLINE void set_restitution(PN_stdfloat restitution);
-  INLINE void set_normal_cfm(const LVecBase3 &cfm);
-  INLINE void set_stop_erp(const LVecBase3 &erp);
-  INLINE void set_stop_cfm(const LVecBase3 &cfm);
+  void set_motor_enabled(int axis, bool enable);
+  void set_low_limit(const LVecBase3 &limit);
+  void set_high_limit(const LVecBase3 &limit);
+  void set_target_velocity(const LVecBase3 &velocity);
+  void set_max_motor_force(const LVecBase3 &force);
+  void set_damping(PN_stdfloat damping);
+  void set_softness(PN_stdfloat softness);
+  void set_restitution(PN_stdfloat restitution);
+  void set_normal_cfm(const LVecBase3 &cfm);
+  void set_stop_erp(const LVecBase3 &erp);
+  void set_stop_cfm(const LVecBase3 &cfm);
 
-  INLINE bool is_limited(int axis) const;
-  INLINE bool get_motor_enabled(int axis) const;
-  INLINE int get_current_limit(int axis) const;
-  INLINE LVector3 get_current_error() const;
-  INLINE LPoint3 get_current_diff() const;
-  INLINE LVector3 get_accumulated_impulse() const;
+  bool is_limited(int axis) const;
+  bool get_motor_enabled(int axis) const;
+  int get_current_limit(int axis) const;
+  LVector3 get_current_error() const;
+  LPoint3 get_current_diff() const;
+  LVector3 get_accumulated_impulse() const;
 
   MAKE_PROPERTY(current_error, get_current_error);
   MAKE_PROPERTY(current_diff, get_current_diff);

+ 0 - 28
panda/src/bullet/bulletTriangleMesh.I

@@ -19,34 +19,6 @@ ptr() const {
   return (btStridingMeshInterface *)&_mesh;
 }
 
-/**
- * Returns the number of vertices in this triangle mesh.
- */
-INLINE size_t BulletTriangleMesh::
-get_num_vertices() const {
-  return _vertices.size();
-}
-
-/**
- * Returns the vertex at the given vertex index.
- */
-INLINE LPoint3 BulletTriangleMesh::
-get_vertex(size_t index) const {
-  nassertr(index < _vertices.size(), LPoint3::zero());
-  const btVector3 &vertex = _vertices[index];
-  return LPoint3(vertex[0], vertex[1], vertex[2]);
-}
-
-/**
- * Returns the vertex indices making up the given triangle index.
- */
-INLINE LVecBase3i BulletTriangleMesh::
-get_triangle(size_t index) const {
-  index *= 3;
-  nassertr(index + 2 < _indices.size(), LVecBase3i::zero());
-  return LVecBase3i(_indices[index], _indices[index + 1], _indices[index + 2]);
-}
-
 /**
  *
  */

+ 78 - 3
panda/src/bullet/bulletTriangleMesh.cxx

@@ -36,14 +36,60 @@ BulletTriangleMesh()
   _mesh.addIndexedMesh(mesh);
 }
 
+/**
+ * Returns the number of vertices in this triangle mesh.
+ */
+size_t BulletTriangleMesh::
+get_num_vertices() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _vertices.size();
+}
+
+/**
+ * Returns the vertex at the given vertex index.
+ */
+LPoint3 BulletTriangleMesh::
+get_vertex(size_t index) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  nassertr(index < _vertices.size(), LPoint3::zero());
+  const btVector3 &vertex = _vertices[index];
+  return LPoint3(vertex[0], vertex[1], vertex[2]);
+}
+
+/**
+ * Returns the vertex indices making up the given triangle index.
+ */
+LVecBase3i BulletTriangleMesh::
+get_triangle(size_t index) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  index *= 3;
+  nassertr(index + 2 < _indices.size(), LVecBase3i::zero());
+  return LVecBase3i(_indices[index], _indices[index + 1], _indices[index + 2]);
+}
+
 /**
  * Returns the number of triangles in this triangle mesh.
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 size_t BulletTriangleMesh::
-get_num_triangles() const {
+do_get_num_triangles() const {
+
   return _indices.size() / 3;
 }
 
+/**
+ * Returns the number of triangles in this triangle mesh.
+ */
+size_t BulletTriangleMesh::
+get_num_triangles() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return do_get_num_triangles();
+}
+
 /**
  * Used to reserve memory in anticipation of the given amount of vertices and
  * indices being added to the triangle mesh.  This is useful if you are about
@@ -51,6 +97,8 @@ get_num_triangles() const {
  */
 void BulletTriangleMesh::
 preallocate(int num_verts, int num_indices) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
   _vertices.reserve(num_verts);
   _indices.reserve(num_indices);
 
@@ -66,9 +114,11 @@ preallocate(int num_verts, int num_indices) {
  * add duplicate vertices if they already exist in the triangle mesh, within
  * the tolerance specified by set_welding_distance().  This comes at a
  * significant performance cost, especially for large meshes.
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletTriangleMesh::
-add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remove_duplicate_vertices) {
+do_add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remove_duplicate_vertices) {
+
   nassertv(!p0.is_nan());
   nassertv(!p1.is_nan());
   nassertv(!p2.is_nan());
@@ -96,6 +146,21 @@ add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remov
   mesh.m_triangleIndexBase = (unsigned char *)&_indices[0];
 }
 
+/**
+ * Adds a triangle with the indicated coordinates.
+ *
+ * If remove_duplicate_vertices is true, it will make sure that it does not
+ * add duplicate vertices if they already exist in the triangle mesh, within
+ * the tolerance specified by set_welding_distance().  This comes at a
+ * significant performance cost, especially for large meshes.
+ */
+void BulletTriangleMesh::
+add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remove_duplicate_vertices) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  do_add_triangle(p0, p1, p2, remove_duplicate_vertices);
+}
+
 /**
  * Sets the square of the distance at which vertices will be merged
  * together when adding geometry with remove_duplicate_vertices set to true.
@@ -105,6 +170,8 @@ add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remov
  */
 void BulletTriangleMesh::
 set_welding_distance(PN_stdfloat distance) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
   _welding_distance = distance;
 }
 
@@ -114,6 +181,8 @@ set_welding_distance(PN_stdfloat distance) {
  */
 PN_stdfloat BulletTriangleMesh::
 get_welding_distance() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
   return _welding_distance;
 }
 
@@ -129,6 +198,8 @@ get_welding_distance() const {
  */
 void BulletTriangleMesh::
 add_geom(const Geom *geom, bool remove_duplicate_vertices, const TransformState *ts) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
   nassertv(geom);
   nassertv(ts);
 
@@ -241,6 +312,8 @@ add_geom(const Geom *geom, bool remove_duplicate_vertices, const TransformState
  */
 void BulletTriangleMesh::
 add_array(const PTA_LVecBase3 &points, const PTA_int &indices, bool remove_duplicate_vertices) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
   btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
 
   _indices.reserve(_indices.size() + indices.size());
@@ -279,7 +352,9 @@ add_array(const PTA_LVecBase3 &points, const PTA_int &indices, bool remove_dupli
  */
 void BulletTriangleMesh::
 output(ostream &out) const {
-  out << get_type() << ", " << get_num_triangles() << " triangles";
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  out << get_type() << ", " << _indices.size() / 3 << " triangles";
 }
 
 /**

+ 9 - 3
panda/src/bullet/bulletTriangleMesh.h

@@ -55,10 +55,16 @@ PUBLISHED:
   virtual void write(ostream &out, int indent_level) const;
 
 public:
-  INLINE size_t get_num_vertices() const;
-  INLINE LPoint3 get_vertex(size_t index) const;
+  size_t get_num_vertices() const;
+  LPoint3 get_vertex(size_t index) const;
 
-  INLINE LVecBase3i get_triangle(size_t index) const;
+  LVecBase3i get_triangle(size_t index) const;
+
+  size_t do_get_num_triangles() const;
+  void do_add_triangle(const LPoint3 &p0,
+                       const LPoint3 &p1,
+                       const LPoint3 &p2,
+                       bool remove_duplicate_vertices=false);
 
 PUBLISHED:
   MAKE_PROPERTY(welding_distance, get_welding_distance, set_welding_distance);

+ 0 - 21
panda/src/bullet/bulletTriangleMeshShape.I

@@ -11,27 +11,6 @@
  * @date 2010-02-09
  */
 
-/**
- *
- */
-INLINE BulletTriangleMeshShape::
-BulletTriangleMeshShape(const BulletTriangleMeshShape &copy) :
-  _bvh_shape(copy._bvh_shape),
-  _gimpact_shape(copy._gimpact_shape),
-  _mesh(copy._mesh) {
-}
-
-/**
- *
- */
-INLINE void BulletTriangleMeshShape::
-operator = (const BulletTriangleMeshShape &copy) {
-
-  _bvh_shape = copy._bvh_shape;
-  _gimpact_shape = copy._gimpact_shape;
-  _mesh = copy._mesh;
-}
-
 /**
  *
  */

+ 27 - 1
panda/src/bullet/bulletTriangleMeshShape.cxx

@@ -36,6 +36,7 @@ BulletTriangleMeshShape() :
 /**
  * The parameters 'compress' and 'bvh' are only used if 'dynamic' is set to
  * FALSE.
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 BulletTriangleMeshShape::
 BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress, bool bvh) :
@@ -50,7 +51,7 @@ BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress, b
   }
 
   // Assert that mesh has at least one triangle
-  if (mesh->get_num_triangles() == 0) {
+  if (mesh->do_get_num_triangles() == 0) {
     bullet_cat.warning() << "mesh has zero triangles! adding degenerated triangle." << endl;
     mesh->add_triangle(LPoint3::zero(), LPoint3::zero(), LPoint3::zero());
   }
@@ -78,6 +79,30 @@ BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress, b
   }
 }
 
+/**
+ *
+ */
+BulletTriangleMeshShape::
+BulletTriangleMeshShape(const BulletTriangleMeshShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _bvh_shape = copy._bvh_shape;
+  _gimpact_shape = copy._gimpact_shape;
+  _mesh = copy._mesh;
+}
+
+/**
+ *
+ */
+void BulletTriangleMeshShape::
+operator = (const BulletTriangleMeshShape &copy) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _bvh_shape = copy._bvh_shape;
+  _gimpact_shape = copy._gimpact_shape;
+  _mesh = copy._mesh;
+}
+
 /**
  *
  */
@@ -100,6 +125,7 @@ ptr() const {
  */
 void BulletTriangleMeshShape::
 refit_tree(const LPoint3 &aabb_min, const LPoint3 &aabb_max) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!aabb_max.is_nan());
   nassertv(!aabb_max.is_nan());

+ 2 - 2
panda/src/bullet/bulletTriangleMeshShape.h

@@ -32,8 +32,8 @@ private:
 
 PUBLISHED:
   explicit BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress=true, bool bvh=true);
-  INLINE BulletTriangleMeshShape(const BulletTriangleMeshShape &copy);
-  INLINE void operator = (const BulletTriangleMeshShape &copy);
+  BulletTriangleMeshShape(const BulletTriangleMeshShape &copy);
+  void operator = (const BulletTriangleMeshShape &copy);
   INLINE ~BulletTriangleMeshShape();
 
   void refit_tree(const LPoint3 &aabb_min, const LPoint3 &aabb_max);

+ 1 - 116
panda/src/bullet/bulletVehicle.I

@@ -18,6 +18,7 @@ INLINE BulletVehicle::
 ~BulletVehicle() {
 
   delete _vehicle;
+  delete _raycaster;
 }
 
 /**
@@ -40,119 +41,3 @@ get_tuning() {
   return _tuning;
 }
 
-/**
- * Returns the number of wheels this vehicle has.
- */
-INLINE int BulletVehicle::
-get_num_wheels() const {
-
-  return _vehicle->getNumWheels();
-}
-
-/**
- *
- */
-void BulletVehicleTuning::
-set_suspension_stiffness(PN_stdfloat value) {
-
-  _.m_suspensionStiffness = (btScalar)value;
-}
-
-/**
- *
- */
-void BulletVehicleTuning::
-set_suspension_compression(PN_stdfloat value) {
-
-  _.m_suspensionCompression = (btScalar)value;
-}
-
-/**
- *
- */
-void BulletVehicleTuning::
-set_suspension_damping(PN_stdfloat value) {
-
-  _.m_suspensionDamping = (btScalar)value;
-}
-
-/**
- *
- */
-void BulletVehicleTuning::
-set_max_suspension_travel_cm(PN_stdfloat value) {
-
-  _.m_maxSuspensionTravelCm = (btScalar)value;
-}
-
-/**
- *
- */
-void BulletVehicleTuning::
-set_friction_slip(PN_stdfloat value) {
-
-  _.m_frictionSlip = (btScalar)value;
-}
-
-/**
- *
- */
-void BulletVehicleTuning::
-set_max_suspension_force(PN_stdfloat value) {
-
-  _.m_maxSuspensionForce = (btScalar)value;
-}
-
-/**
- *
- */
-PN_stdfloat BulletVehicleTuning::
-get_suspension_stiffness() const {
-
-  return (PN_stdfloat)_.m_suspensionStiffness;
-}
-
-/**
- *
- */
-PN_stdfloat BulletVehicleTuning::
-get_suspension_compression() const {
-
-  return (PN_stdfloat)_.m_suspensionCompression;
-}
-
-/**
- *
- */
-PN_stdfloat BulletVehicleTuning::
-get_suspension_damping() const {
-
-  return (PN_stdfloat)_.m_suspensionDamping;
-}
-
-/**
- *
- */
-PN_stdfloat BulletVehicleTuning::
-get_max_suspension_travel_cm() const {
-
-  return (PN_stdfloat)_.m_maxSuspensionTravelCm;
-}
-
-/**
- *
- */
-PN_stdfloat BulletVehicleTuning::
-get_friction_slip() const {
-
-  return (PN_stdfloat)_.m_frictionSlip;
-}
-
-/**
- *
- */
-PN_stdfloat BulletVehicleTuning::
-get_max_suspension_force() const {
-
-  return (PN_stdfloat)_.m_maxSuspensionForce;
-}

+ 162 - 9
panda/src/bullet/bulletVehicle.cxx

@@ -39,6 +39,7 @@ BulletVehicle(BulletWorld *world, BulletRigidBodyNode *chassis) {
  */
 void BulletVehicle::
 set_coordinate_system(BulletUpAxis up) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   switch (up) {
   case X_up:
@@ -62,26 +63,39 @@ set_coordinate_system(BulletUpAxis up) {
  */
 LVector3 BulletVehicle::
 get_forward_vector() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_vehicle->getForwardVector());
 }
 
 /**
  * Returns the chassis of this vehicle.  The chassis is a rigid body node.
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 BulletRigidBodyNode *BulletVehicle::
-get_chassis() {
+do_get_chassis() {
 
   btRigidBody *bodyPtr = _vehicle->getRigidBody();
   return (bodyPtr) ? (BulletRigidBodyNode *)bodyPtr->getUserPointer() : NULL;
 }
 
+/**
+ * Returns the chassis of this vehicle.  The chassis is a rigid body node.
+ */
+BulletRigidBodyNode *BulletVehicle::
+get_chassis() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return do_get_chassis();
+}
+
 /**
  * Returns the current speed in kilometers per hour.  Convert to miles using:
  * km/h * 0.62 = mph
  */
 PN_stdfloat BulletVehicle::
 get_current_speed_km_hour() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_vehicle->getCurrentSpeedKmHour();
 }
@@ -91,6 +105,7 @@ get_current_speed_km_hour() const {
  */
 void BulletVehicle::
 reset_suspension() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _vehicle->resetSuspension();
 }
@@ -100,8 +115,9 @@ reset_suspension() {
  */
 PN_stdfloat BulletVehicle::
 get_steering_value(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  nassertr(idx < get_num_wheels(), 0.0f);
+  nassertr(idx < _vehicle->getNumWheels(), 0.0f);
   return rad_2_deg(_vehicle->getSteeringValue(idx));
 }
 
@@ -110,8 +126,9 @@ get_steering_value(int idx) const {
  */
 void BulletVehicle::
 set_steering_value(PN_stdfloat steering, int idx) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  nassertv(idx < get_num_wheels());
+  nassertv(idx < _vehicle->getNumWheels());
   _vehicle->setSteeringValue(deg_2_rad(steering), idx);
 }
 
@@ -120,8 +137,9 @@ set_steering_value(PN_stdfloat steering, int idx) {
  */
 void BulletVehicle::
 apply_engine_force(PN_stdfloat force, int idx) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  nassertv(idx < get_num_wheels());
+  nassertv(idx < _vehicle->getNumWheels());
   _vehicle->applyEngineForce(force, idx);
 }
 
@@ -130,8 +148,9 @@ apply_engine_force(PN_stdfloat force, int idx) {
  */
 void BulletVehicle::
 set_brake(PN_stdfloat brake, int idx) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  nassertv(idx < get_num_wheels());
+  nassertv(idx < _vehicle->getNumWheels());
   _vehicle->setBrake(brake, idx);
 }
 
@@ -140,6 +159,7 @@ set_brake(PN_stdfloat brake, int idx) {
  */
 void BulletVehicle::
 set_pitch_control(PN_stdfloat pitch) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _vehicle->setPitchControl(pitch);
 }
@@ -149,6 +169,7 @@ set_pitch_control(PN_stdfloat pitch) {
  */
 BulletWheel BulletVehicle::
 create_wheel() {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   btVector3 pos(0.0, 0.0, 0.0);
   btVector3 direction = get_axis(_vehicle->getUpAxis());
@@ -182,24 +203,35 @@ get_axis(int idx) {
   }
 }
 
+/**
+ * Returns the number of wheels this vehicle has.
+ */
+int BulletVehicle::
+get_num_wheels() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _vehicle->getNumWheels();
+}
+
 /**
  * Returns the BulletWheel with index idx.  Causes an AssertionError if idx is
  * equal or larger than the number of wheels.
  */
 BulletWheel BulletVehicle::
 get_wheel(int idx) const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
-  nassertr(idx < get_num_wheels(), BulletWheel::empty());
+  nassertr(idx < _vehicle->getNumWheels(), BulletWheel::empty());
   return BulletWheel(_vehicle->getWheelInfo(idx));
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletVehicle::
-sync_b2p() {
+do_sync_b2p() {
 
-  for (int i=0; i < get_num_wheels(); i++) {
+  for (int i=0; i < _vehicle->getNumWheels(); i++) {
     btWheelInfo info = _vehicle->getWheelInfo(i);
 
     PandaNode *node = (PandaNode *)info.m_clientInfo;
@@ -216,3 +248,124 @@ sync_b2p() {
     }
   }
 }
+
+/**
+ *
+ */
+void BulletVehicleTuning::
+set_suspension_stiffness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _.m_suspensionStiffness = (btScalar)value;
+}
+
+/**
+ *
+ */
+void BulletVehicleTuning::
+set_suspension_compression(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _.m_suspensionCompression = (btScalar)value;
+}
+
+/**
+ *
+ */
+void BulletVehicleTuning::
+set_suspension_damping(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _.m_suspensionDamping = (btScalar)value;
+}
+
+/**
+ *
+ */
+void BulletVehicleTuning::
+set_max_suspension_travel_cm(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _.m_maxSuspensionTravelCm = (btScalar)value;
+}
+
+/**
+ *
+ */
+void BulletVehicleTuning::
+set_friction_slip(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _.m_frictionSlip = (btScalar)value;
+}
+
+/**
+ *
+ */
+void BulletVehicleTuning::
+set_max_suspension_force(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  _.m_maxSuspensionForce = (btScalar)value;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletVehicleTuning::
+get_suspension_stiffness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_.m_suspensionStiffness;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletVehicleTuning::
+get_suspension_compression() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_.m_suspensionCompression;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletVehicleTuning::
+get_suspension_damping() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_.m_suspensionDamping;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletVehicleTuning::
+get_max_suspension_travel_cm() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_.m_maxSuspensionTravelCm;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletVehicleTuning::
+get_friction_slip() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_.m_frictionSlip;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletVehicleTuning::
+get_max_suspension_force() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return (PN_stdfloat)_.m_maxSuspensionForce;
+}
+

+ 16 - 15
panda/src/bullet/bulletVehicle.h

@@ -32,19 +32,19 @@ class BulletWheel;
 class EXPCL_PANDABULLET BulletVehicleTuning {
 
 PUBLISHED:
-  INLINE void set_suspension_stiffness(PN_stdfloat value);
-  INLINE void set_suspension_compression(PN_stdfloat value);
-  INLINE void set_suspension_damping(PN_stdfloat value);
-  INLINE void set_max_suspension_travel_cm(PN_stdfloat value);
-  INLINE void set_friction_slip(PN_stdfloat value);
-  INLINE void set_max_suspension_force(PN_stdfloat value);
-
-  INLINE PN_stdfloat get_suspension_stiffness() const;
-  INLINE PN_stdfloat get_suspension_compression() const;
-  INLINE PN_stdfloat get_suspension_damping() const;
-  INLINE PN_stdfloat get_max_suspension_travel_cm() const;
-  INLINE PN_stdfloat get_friction_slip() const;
-  INLINE PN_stdfloat get_max_suspension_force() const;
+  void set_suspension_stiffness(PN_stdfloat value);
+  void set_suspension_compression(PN_stdfloat value);
+  void set_suspension_damping(PN_stdfloat value);
+  void set_max_suspension_travel_cm(PN_stdfloat value);
+  void set_friction_slip(PN_stdfloat value);
+  void set_max_suspension_force(PN_stdfloat value);
+
+  PN_stdfloat get_suspension_stiffness() const;
+  PN_stdfloat get_suspension_compression() const;
+  PN_stdfloat get_suspension_damping() const;
+  PN_stdfloat get_max_suspension_travel_cm() const;
+  PN_stdfloat get_friction_slip() const;
+  PN_stdfloat get_max_suspension_force() const;
 
   MAKE_PROPERTY(suspension_stiffness, get_suspension_stiffness, set_suspension_stiffness);
   MAKE_PROPERTY(suspension_compression, get_suspension_compression, set_suspension_compression);
@@ -87,7 +87,7 @@ PUBLISHED:
   // Wheels
   BulletWheel create_wheel();
 
-  INLINE int get_num_wheels() const;
+  int get_num_wheels() const;
   BulletWheel get_wheel(int idx) const;
   MAKE_SEQ(get_wheels, get_num_wheels, get_wheel);
 
@@ -102,8 +102,9 @@ PUBLISHED:
 
 public:
   INLINE btRaycastVehicle *get_vehicle() const;
+  BulletRigidBodyNode *do_get_chassis();
 
-  void sync_b2p();
+  void do_sync_b2p();
 
 private:
   btRaycastVehicle *_vehicle;

+ 0 - 71
panda/src/bullet/bulletWheel.I

@@ -40,74 +40,3 @@ empty() {
   return BulletWheel(info);
 }
 
-/**
- *
- */
-INLINE bool BulletWheelRaycastInfo::
-is_in_contact() const {
-
-  return _info.m_isInContact;
-}
-
-/**
- *
- */
-INLINE PN_stdfloat BulletWheelRaycastInfo::
-get_suspension_length() const {
-
-  return _info.m_suspensionLength;
-}
-
-/**
- *
- */
-INLINE LPoint3 BulletWheelRaycastInfo::
-get_contact_point_ws() const {
-
-  return btVector3_to_LPoint3(_info.m_contactPointWS);
-}
-
-/**
- *
- */
-INLINE LPoint3 BulletWheelRaycastInfo::
-get_hard_point_ws() const {
-
-  return btVector3_to_LPoint3(_info.m_hardPointWS);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletWheelRaycastInfo::
-get_contact_normal_ws() const {
-
-  return btVector3_to_LVector3(_info.m_contactNormalWS);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletWheelRaycastInfo::
-get_wheel_direction_ws() const {
-
-  return btVector3_to_LVector3(_info.m_wheelDirectionWS);
-}
-
-/**
- *
- */
-INLINE LVector3 BulletWheelRaycastInfo::
-get_wheel_axle_ws() const {
-
-  return btVector3_to_LVector3(_info.m_wheelAxleWS);
-}
-
-/**
- *
- */
-INLINE PandaNode *BulletWheelRaycastInfo::
-get_ground_object() const {
-
-  return _info.m_groundObject ? (PandaNode *)_info.m_groundObject : NULL;
-}

+ 128 - 0
panda/src/bullet/bulletWheel.cxx

@@ -34,6 +34,7 @@ BulletWheelRaycastInfo(btWheelInfo::RaycastInfo &info) : _info(info) {
  */
 BulletWheelRaycastInfo BulletWheel::
 get_raycast_info() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return BulletWheelRaycastInfo(_info.m_raycastInfo);
 }
@@ -43,6 +44,7 @@ get_raycast_info() const {
  */
 PN_stdfloat BulletWheel::
 get_suspension_rest_length() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.getSuspensionRestLength();
 }
@@ -52,6 +54,7 @@ get_suspension_rest_length() const {
  */
 void BulletWheel::
 set_suspension_stiffness(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_suspensionStiffness = (btScalar)value;
 }
@@ -61,6 +64,7 @@ set_suspension_stiffness(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_suspension_stiffness() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_suspensionStiffness;
 }
@@ -71,6 +75,7 @@ get_suspension_stiffness() const {
  */
 void BulletWheel::
 set_max_suspension_travel_cm(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_maxSuspensionTravelCm = (btScalar)value;
 }
@@ -80,6 +85,7 @@ set_max_suspension_travel_cm(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_max_suspension_travel_cm() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_maxSuspensionTravelCm;
 }
@@ -89,6 +95,7 @@ get_max_suspension_travel_cm() const {
  */
 void BulletWheel::
 set_friction_slip(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_frictionSlip = (btScalar)value;
 }
@@ -98,6 +105,7 @@ set_friction_slip(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_friction_slip() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_frictionSlip;
 }
@@ -107,6 +115,7 @@ get_friction_slip() const {
  */
 void BulletWheel::
 set_max_suspension_force(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_maxSuspensionForce = (btScalar)value;
 }
@@ -116,6 +125,7 @@ set_max_suspension_force(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_max_suspension_force() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_maxSuspensionForce;
 }
@@ -125,6 +135,7 @@ get_max_suspension_force() const {
  */
 void BulletWheel::
 set_wheels_damping_compression(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_wheelsDampingCompression = (btScalar)value;
 }
@@ -134,6 +145,7 @@ set_wheels_damping_compression(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_wheels_damping_compression() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_wheelsDampingCompression;
 }
@@ -143,6 +155,7 @@ get_wheels_damping_compression() const {
  */
 void BulletWheel::
 set_wheels_damping_relaxation(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_wheelsDampingRelaxation = (btScalar)value;
 }
@@ -152,6 +165,7 @@ set_wheels_damping_relaxation(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_wheels_damping_relaxation() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_wheelsDampingRelaxation;
 }
@@ -164,6 +178,7 @@ get_wheels_damping_relaxation() const {
  */
 void BulletWheel::
 set_roll_influence(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_rollInfluence = (btScalar)value;
 }
@@ -174,6 +189,7 @@ set_roll_influence(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_roll_influence() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_rollInfluence;
 }
@@ -183,6 +199,7 @@ get_roll_influence() const {
  */
 void BulletWheel::
 set_wheel_radius(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_wheelsRadius = (btScalar)value;
 }
@@ -192,6 +209,7 @@ set_wheel_radius(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_wheel_radius() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_wheelsRadius;
 }
@@ -201,6 +219,7 @@ get_wheel_radius() const {
  */
 void BulletWheel::
 set_steering(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_steering = (btScalar)value;
 }
@@ -210,6 +229,7 @@ set_steering(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_steering() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_steering;
 }
@@ -219,6 +239,7 @@ get_steering() const {
  */
 void BulletWheel::
 set_rotation(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_rotation = (btScalar)value;
 }
@@ -228,6 +249,7 @@ set_rotation(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_rotation() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_rotation;
 }
@@ -237,6 +259,7 @@ get_rotation() const {
  */
 void BulletWheel::
 set_delta_rotation(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_deltaRotation = (btScalar)value;
 }
@@ -246,6 +269,7 @@ set_delta_rotation(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_delta_rotation() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_deltaRotation;
 }
@@ -255,6 +279,7 @@ get_delta_rotation() const {
  */
 void BulletWheel::
 set_engine_force(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_engineForce = (btScalar)value;
 }
@@ -264,6 +289,7 @@ set_engine_force(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_engine_force() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_engineForce;
 }
@@ -273,6 +299,7 @@ get_engine_force() const {
  */
 void BulletWheel::
 set_brake(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_brake = (btScalar)value;
 }
@@ -282,6 +309,7 @@ set_brake(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_brake() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_brake;
 }
@@ -291,6 +319,7 @@ get_brake() const {
  */
 void BulletWheel::
 set_skid_info(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_skidInfo = (btScalar)value;
 }
@@ -300,6 +329,7 @@ set_skid_info(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_skid_info() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_skidInfo;
 }
@@ -309,6 +339,7 @@ get_skid_info() const {
  */
 void BulletWheel::
 set_wheels_suspension_force(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_wheelsSuspensionForce = (btScalar)value;
 }
@@ -318,6 +349,7 @@ set_wheels_suspension_force(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_wheels_suspension_force() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_wheelsSuspensionForce;
 }
@@ -327,6 +359,7 @@ get_wheels_suspension_force() const {
  */
 void BulletWheel::
 set_suspension_relative_velocity(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_suspensionRelativeVelocity = (btScalar)value;
 }
@@ -336,6 +369,7 @@ set_suspension_relative_velocity(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_suspension_relative_velocity() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_suspensionRelativeVelocity;
 }
@@ -345,6 +379,7 @@ get_suspension_relative_velocity() const {
  */
 void BulletWheel::
 set_clipped_inv_connection_point_cs(PN_stdfloat value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_clippedInvContactDotSuspension = (btScalar)value;
 }
@@ -354,6 +389,7 @@ set_clipped_inv_connection_point_cs(PN_stdfloat value) {
  */
 PN_stdfloat BulletWheel::
 get_clipped_inv_connection_point_cs() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (PN_stdfloat)_info.m_clippedInvContactDotSuspension;
 }
@@ -363,6 +399,7 @@ get_clipped_inv_connection_point_cs() const {
  */
 void BulletWheel::
 set_chassis_connection_point_cs(const LPoint3 &pos) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!pos.is_nan());
   _info.m_chassisConnectionPointCS = LVecBase3_to_btVector3(pos);
@@ -373,6 +410,7 @@ set_chassis_connection_point_cs(const LPoint3 &pos) {
  */
 LPoint3 BulletWheel::
 get_chassis_connection_point_cs() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LPoint3(_info.m_chassisConnectionPointCS);
 }
@@ -383,6 +421,7 @@ get_chassis_connection_point_cs() const {
  */
 void BulletWheel::
 set_wheel_direction_cs(const LVector3 &dir) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!dir.is_nan());
   _info.m_wheelDirectionCS = LVecBase3_to_btVector3(dir);
@@ -393,6 +432,7 @@ set_wheel_direction_cs(const LVector3 &dir) {
  */
 LVector3 BulletWheel::
 get_wheel_direction_cs() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_info.m_wheelDirectionCS);
 }
@@ -402,6 +442,7 @@ get_wheel_direction_cs() const {
  */
 void BulletWheel::
 set_wheel_axle_cs(const LVector3 &axle) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!axle.is_nan());
   _info.m_wheelAxleCS = LVecBase3_to_btVector3(axle);
@@ -412,6 +453,7 @@ set_wheel_axle_cs(const LVector3 &axle) {
  */
 LVector3 BulletWheel::
 get_wheel_axle_cs() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btVector3_to_LVector3(_info.m_wheelAxleCS);
 }
@@ -421,6 +463,7 @@ get_wheel_axle_cs() const {
  */
 void BulletWheel::
 set_world_transform(const LMatrix4 &mat) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   nassertv(!mat.is_nan());
   _info.m_worldTransform = LMatrix4_to_btTrans(mat);
@@ -431,6 +474,7 @@ set_world_transform(const LMatrix4 &mat) {
  */
 LMatrix4 BulletWheel::
 get_world_transform() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return btTrans_to_LMatrix4(_info.m_worldTransform);
 }
@@ -440,6 +484,7 @@ get_world_transform() const {
  */
 void BulletWheel::
 set_front_wheel(bool value) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_bIsFrontWheel = value;
 }
@@ -449,6 +494,7 @@ set_front_wheel(bool value) {
  */
 bool BulletWheel::
 is_front_wheel() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return _info.m_bIsFrontWheel;
 }
@@ -458,6 +504,7 @@ is_front_wheel() const {
  */
 void BulletWheel::
 set_node(PandaNode *node) {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   _info.m_clientInfo = (void *)node;
 }
@@ -468,6 +515,87 @@ set_node(PandaNode *node) {
  */
 PandaNode *BulletWheel::
 get_node() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
 
   return (_info.m_clientInfo == NULL) ? NULL : (PandaNode *)_info.m_clientInfo;
 }
+
+/**
+ *
+ */
+bool BulletWheelRaycastInfo::
+is_in_contact() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _info.m_isInContact;
+}
+
+/**
+ *
+ */
+PN_stdfloat BulletWheelRaycastInfo::
+get_suspension_length() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _info.m_suspensionLength;
+}
+
+/**
+ *
+ */
+LPoint3 BulletWheelRaycastInfo::
+get_contact_point_ws() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LPoint3(_info.m_contactPointWS);
+}
+
+/**
+ *
+ */
+LPoint3 BulletWheelRaycastInfo::
+get_hard_point_ws() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LPoint3(_info.m_hardPointWS);
+}
+
+/**
+ *
+ */
+LVector3 BulletWheelRaycastInfo::
+get_contact_normal_ws() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_info.m_contactNormalWS);
+}
+
+/**
+ *
+ */
+LVector3 BulletWheelRaycastInfo::
+get_wheel_direction_ws() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_info.m_wheelDirectionWS);
+}
+
+/**
+ *
+ */
+LVector3 BulletWheelRaycastInfo::
+get_wheel_axle_ws() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return btVector3_to_LVector3(_info.m_wheelAxleWS);
+}
+
+/**
+ *
+ */
+PandaNode *BulletWheelRaycastInfo::
+get_ground_object() const {
+  LightMutexHolder holder(BulletWorld::get_global_lock());
+
+  return _info.m_groundObject ? (PandaNode *)_info.m_groundObject : NULL;
+}

+ 8 - 8
panda/src/bullet/bulletWheel.h

@@ -30,14 +30,14 @@ class EXPCL_PANDABULLET BulletWheelRaycastInfo {
 PUBLISHED:
   INLINE ~BulletWheelRaycastInfo();
 
-  INLINE bool is_in_contact() const;
-  INLINE PN_stdfloat get_suspension_length() const;
-  INLINE LVector3 get_contact_normal_ws() const;
-  INLINE LVector3 get_wheel_direction_ws() const;
-  INLINE LVector3 get_wheel_axle_ws() const;
-  INLINE LPoint3 get_contact_point_ws() const;
-  INLINE LPoint3 get_hard_point_ws() const;
-  INLINE PandaNode *get_ground_object() const;
+  bool is_in_contact() const;
+  PN_stdfloat get_suspension_length() const;
+  LVector3 get_contact_normal_ws() const;
+  LVector3 get_wheel_direction_ws() const;
+  LVector3 get_wheel_axle_ws() const;
+  LPoint3 get_contact_point_ws() const;
+  LPoint3 get_hard_point_ws() const;
+  PandaNode *get_ground_object() const;
 
   MAKE_PROPERTY(in_contact, is_in_contact);
   MAKE_PROPERTY(suspension_length, get_suspension_length);

+ 0 - 135
panda/src/bullet/bulletWorld.I

@@ -50,19 +50,6 @@ INLINE BulletWorld::
   delete _broadphase;
 }
 
-/**
- *
- */
-INLINE void BulletWorld::
-set_debug_node(BulletDebugNode *node) {
-  nassertv(node);
-  if (node != _debug) {
-    clear_debug_node();
-    _debug = node;
-    _world->setDebugDrawer(&(_debug->_drawer));
-  }
-}
-
 /**
  *
  */
@@ -108,125 +95,3 @@ get_dispatcher() const {
   return _dispatcher;
 }
 
-/**
- *
- */
-INLINE int BulletWorld::
-get_num_rigid_bodies() const {
-
-  return _bodies.size();
-}
-
-/**
- *
- */
-INLINE BulletRigidBodyNode *BulletWorld::
-get_rigid_body(int idx) const {
-
-  nassertr(idx >= 0 && idx < (int)_bodies.size(), NULL);
-  return _bodies[idx];
-}
-
-/**
- *
- */
-INLINE int BulletWorld::
-get_num_soft_bodies() const {
-
-  return _softbodies.size();
-}
-
-/**
- *
- */
-INLINE BulletSoftBodyNode *BulletWorld::
-get_soft_body(int idx) const {
-
-  nassertr(idx >= 0 && idx < (int)_softbodies.size(), NULL);
-  return _softbodies[idx];
-}
-
-/**
- *
- */
-INLINE int BulletWorld::
-get_num_ghosts() const {
-
-  return _ghosts.size();
-}
-
-/**
- *
- */
-INLINE BulletGhostNode *BulletWorld::
-get_ghost(int idx) const {
-
-  nassertr(idx >= 0 && idx < (int)_ghosts.size(), NULL);
-  return _ghosts[idx];
-}
-
-/**
- *
- */
-INLINE int BulletWorld::
-get_num_characters() const {
-
-  return _characters.size();
-}
-
-/**
- *
- */
-INLINE BulletBaseCharacterControllerNode *BulletWorld::
-get_character(int idx) const {
-
-  nassertr(idx >= 0 && idx < (int)_characters.size(), NULL);
-  return _characters[idx];
-}
-
-/**
- *
- */
-INLINE int BulletWorld::
-get_num_vehicles() const {
-
-  return _vehicles.size();
-}
-
-/**
- *
- */
-INLINE BulletVehicle *BulletWorld::
-get_vehicle(int idx) const {
-
-  nassertr(idx >= 0 && idx < (int)_vehicles.size(), NULL);
-  return _vehicles[idx];
-}
-
-/**
- *
- */
-INLINE int BulletWorld::
-get_num_constraints() const {
-
-  return _constraints.size();
-}
-
-/**
- *
- */
-INLINE BulletConstraint *BulletWorld::
-get_constraint(int idx) const {
-
-  nassertr(idx >= 0 && idx < (int)_constraints.size(), NULL);
-  return _constraints[idx];
-}
-
-/**
- *
- */
-INLINE int BulletWorld::
-get_num_manifolds() const {
-
-  return _world->getDispatcher()->getNumManifolds();
-}

+ 374 - 62
panda/src/bullet/bulletWorld.cxx

@@ -118,6 +118,17 @@ BulletWorld() {
   _world->getSolverInfo().m_numIterations = bullet_solver_iterations;
 }
 
+/**
+ *
+ */
+LightMutex &BulletWorld::
+get_global_lock() {
+  
+  static LightMutex lock;
+  
+  return lock;
+}
+
 /**
  *
  */
@@ -127,13 +138,33 @@ get_world_info() {
   return BulletSoftBodyWorldInfo(_info);
 }
 
+/**
+ *
+ */
+void BulletWorld::
+set_debug_node(BulletDebugNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  nassertv(node);
+  if (node != _debug) {
+    if (_debug != nullptr) {
+        _debug->_debug_stale = false;
+        _debug->_debug_world = nullptr;
+    }
+
+    _debug = node;
+    _world->setDebugDrawer(&(_debug->_drawer));
+  }
+}
+
 /**
  * Removes a debug node that has been assigned to this BulletWorld.
  */
 void BulletWorld::
 clear_debug_node() {
+  LightMutexHolder holder(get_global_lock());
+
   if (_debug != nullptr) {
-    LightMutexHolder holder(_debug->_lock);
     _debug->_debug_stale = false;
     _debug->_debug_world = nullptr;
     _world->setDebugDrawer(nullptr);
@@ -146,6 +177,7 @@ clear_debug_node() {
  */
 void BulletWorld::
 set_gravity(const LVector3 &gravity) {
+  LightMutexHolder holder(get_global_lock());
 
   _world->setGravity(LVecBase3_to_btVector3(gravity));
   _info.m_gravity.setValue(gravity.get_x(), gravity.get_y(), gravity.get_z());
@@ -156,6 +188,7 @@ set_gravity(const LVector3 &gravity) {
  */
 void BulletWorld::
 set_gravity(PN_stdfloat gx, PN_stdfloat gy, PN_stdfloat gz) {
+  LightMutexHolder holder(get_global_lock());
 
   _world->setGravity(btVector3((btScalar)gx, (btScalar)gy, (btScalar)gz));
   _info.m_gravity.setValue((btScalar)gx, (btScalar)gy, (btScalar)gz);
@@ -166,6 +199,7 @@ set_gravity(PN_stdfloat gx, PN_stdfloat gy, PN_stdfloat gz) {
  */
 const LVector3 BulletWorld::
 get_gravity() const {
+  LightMutexHolder holder(get_global_lock());
 
   return btVector3_to_LVector3(_world->getGravity());
 }
@@ -175,6 +209,7 @@ get_gravity() const {
  */
 int BulletWorld::
 do_physics(PN_stdfloat dt, int max_substeps, PN_stdfloat stepsize) {
+  LightMutexHolder holder(get_global_lock());
 
   _pstat_physics.start();
 
@@ -182,7 +217,7 @@ do_physics(PN_stdfloat dt, int max_substeps, PN_stdfloat stepsize) {
 
   // Synchronize Panda to Bullet
   _pstat_p2b.start();
-  sync_p2b(dt, num_substeps);
+  do_sync_p2b(dt, num_substeps);
   _pstat_p2b.stop();
 
   // Simulation
@@ -192,13 +227,13 @@ do_physics(PN_stdfloat dt, int max_substeps, PN_stdfloat stepsize) {
 
   // Synchronize Bullet to Panda
   _pstat_b2p.start();
-  sync_b2p();
+  do_sync_b2p();
   _info.m_sparsesdf.GarbageCollect(bullet_gc_lifetime);
   _pstat_b2p.stop();
 
   // Render debug
   if (_debug) {
-    _debug->sync_b2p(_world);
+    _debug->do_sync_b2p(_world);
   }
 
   _pstat_physics.stop();
@@ -207,52 +242,52 @@ do_physics(PN_stdfloat dt, int max_substeps, PN_stdfloat stepsize) {
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-sync_p2b(PN_stdfloat dt, int num_substeps) {
+do_sync_p2b(PN_stdfloat dt, int num_substeps) {
 
-  for (int i=0; i < get_num_rigid_bodies(); i++) {
-    get_rigid_body(i)->sync_p2b();
+  for (int i=0; i < _bodies.size(); i++) {
+    _bodies[i]->do_sync_p2b();
   }
 
-  for (int i=0; i < get_num_soft_bodies(); i++) {
-    get_soft_body(i)->sync_p2b();
+  for (int i=0; i < _softbodies.size(); i++) {
+    _softbodies[i]->do_sync_p2b();
   }
 
-  for (int i=0; i < get_num_ghosts(); i++) {
-    get_ghost(i)->sync_p2b();
+  for (int i=0; i < _ghosts.size(); i++) {
+    _ghosts[i]->do_sync_p2b();
   }
 
-  for (int i=0; i < get_num_characters(); i++) {
-    get_character(i)->sync_p2b(dt, num_substeps);
+  for (int i=0; i < _characters.size(); i++) {
+    _characters[i]->do_sync_p2b(dt, num_substeps);
   }
 }
 
 /**
- *
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-sync_b2p() {
+do_sync_b2p() {
 
-  for (int i=0; i < get_num_vehicles(); i++) {
-    get_vehicle(i)->sync_b2p();
+  for (int i=0; i < _vehicles.size(); i++) {
+    _vehicles[i]->do_sync_b2p();
   }
 
-  for (int i=0; i < get_num_rigid_bodies(); i++) {
-    get_rigid_body(i)->sync_b2p();
+  for (int i=0; i < _bodies.size(); i++) {
+    _bodies[i]->do_sync_b2p();
   }
 
-  for (int i=0; i < get_num_soft_bodies(); i++) {
-    get_soft_body(i)->sync_b2p();
+  for (int i=0; i < _softbodies.size(); i++) {
+    _softbodies[i]->do_sync_b2p();
   }
 
-  for (int i=0; i < get_num_ghosts(); i++) {
-    get_ghost(i)->sync_b2p();
+  for (int i=0; i < _ghosts.size(); i++) {
+    _ghosts[i]->do_sync_b2p();
   }
 
-  for (int i=0; i < get_num_characters(); i++) {
-    get_character(i)->sync_b2p();
+  for (int i=0; i < _characters.size(); i++) {
+    _characters[i]->do_sync_b2p();
   }
 }
 
@@ -261,24 +296,25 @@ sync_b2p() {
  */
 void BulletWorld::
 attach(TypedObject *object) {
+  LightMutexHolder holder(get_global_lock());
 
   if (object->is_of_type(BulletGhostNode::get_class_type())) {
-    attach_ghost(DCAST(BulletGhostNode, object));
+    do_attach_ghost(DCAST(BulletGhostNode, object));
   }
   else if (object->is_of_type(BulletRigidBodyNode::get_class_type())) {
-    attach_rigid_body(DCAST(BulletRigidBodyNode, object));
+    do_attach_rigid_body(DCAST(BulletRigidBodyNode, object));
   }
   else if (object->is_of_type(BulletSoftBodyNode::get_class_type())) {
-    attach_soft_body(DCAST(BulletSoftBodyNode, object));
+    do_attach_soft_body(DCAST(BulletSoftBodyNode, object));
   }
   else if (object->is_of_type(BulletBaseCharacterControllerNode::get_class_type())) {
-    attach_character(DCAST(BulletBaseCharacterControllerNode, object));
+    do_attach_character(DCAST(BulletBaseCharacterControllerNode, object));
   }
   else if (object->is_of_type(BulletVehicle::get_class_type())) {
-    attach_vehicle(DCAST(BulletVehicle, object));
+    do_attach_vehicle(DCAST(BulletVehicle, object));
   }
   else if (object->is_of_type(BulletConstraint::get_class_type())) {
-    attach_constraint(DCAST(BulletConstraint, object));
+    do_attach_constraint(DCAST(BulletConstraint, object));
   }
   else {
     bullet_cat->error() << "not a bullet world object!" << endl;
@@ -290,24 +326,25 @@ attach(TypedObject *object) {
  */
 void BulletWorld::
 remove(TypedObject *object) {
+  LightMutexHolder holder(get_global_lock());
 
   if (object->is_of_type(BulletGhostNode::get_class_type())) {
-    remove_ghost(DCAST(BulletGhostNode, object));
+    do_remove_ghost(DCAST(BulletGhostNode, object));
   }
   else if (object->is_of_type(BulletRigidBodyNode::get_class_type())) {
-    remove_rigid_body(DCAST(BulletRigidBodyNode, object));
+    do_remove_rigid_body(DCAST(BulletRigidBodyNode, object));
   }
   else if (object->is_of_type(BulletSoftBodyNode::get_class_type())) {
-    remove_soft_body(DCAST(BulletSoftBodyNode, object));
+    do_remove_soft_body(DCAST(BulletSoftBodyNode, object));
   }
   else if (object->is_of_type(BulletBaseCharacterControllerNode::get_class_type())) {
-    remove_character(DCAST(BulletBaseCharacterControllerNode, object));
+    do_remove_character(DCAST(BulletBaseCharacterControllerNode, object));
   }
   else if (object->is_of_type(BulletVehicle::get_class_type())) {
-    remove_vehicle(DCAST(BulletVehicle, object));
+    do_remove_vehicle(DCAST(BulletVehicle, object));
   }
   else if (object->is_of_type(BulletConstraint::get_class_type())) {
-    remove_constraint(DCAST(BulletConstraint, object));
+    do_remove_constraint(DCAST(BulletConstraint, object));
   }
   else {
     bullet_cat->error() << "not a bullet world object!" << endl;
@@ -319,6 +356,127 @@ remove(TypedObject *object) {
  */
 void BulletWorld::
 attach_rigid_body(BulletRigidBodyNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_attach_rigid_body(node);
+}
+
+/**
+ * Deprecated.! Please use BulletWorld::remove
+ */
+void BulletWorld::
+remove_rigid_body(BulletRigidBodyNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_remove_rigid_body(node);
+}
+
+/**
+ * Deprecated!  Please use BulletWorld::attach
+ */
+void BulletWorld::
+attach_soft_body(BulletSoftBodyNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_attach_soft_body(node);
+}
+
+/**
+ * Deprecated.! Please use BulletWorld::remove
+ */
+void BulletWorld::
+remove_soft_body(BulletSoftBodyNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_remove_soft_body(node);
+}
+
+/**
+ * Deprecated!  Please use BulletWorld::attach
+ */
+void BulletWorld::
+attach_ghost(BulletGhostNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_attach_ghost(node);
+}
+
+/**
+ * Deprecated.! Please use BulletWorld::remove
+ */
+void BulletWorld::
+remove_ghost(BulletGhostNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_remove_ghost(node);
+}
+
+/**
+ * Deprecated!  Please use BulletWorld::attach
+ */
+void BulletWorld::
+attach_character(BulletBaseCharacterControllerNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_attach_character(node);
+}
+
+/**
+ * Deprecated.! Please use BulletWorld::remove
+ */
+void BulletWorld::
+remove_character(BulletBaseCharacterControllerNode *node) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_remove_character(node);
+}
+
+/**
+ * Deprecated!  Please use BulletWorld::attach
+ */
+void BulletWorld::
+attach_vehicle(BulletVehicle *vehicle) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_attach_vehicle(vehicle);
+}
+
+/**
+ * Deprecated.! Please use BulletWorld::remove
+ */
+void BulletWorld::
+remove_vehicle(BulletVehicle *vehicle) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_remove_vehicle(vehicle);
+}
+
+/**
+ * Attaches a single constraint to a world.  Collision checks between the
+ * linked objects will be disabled if the second parameter is set to TRUE.
+ */
+void BulletWorld::
+attach_constraint(BulletConstraint *constraint, bool linked_collision) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_attach_constraint(constraint, linked_collision);
+}
+
+/**
+ * Deprecated.! Please use BulletWorld::remove
+ */
+void BulletWorld::
+remove_constraint(BulletConstraint *constraint) {
+  LightMutexHolder holder(get_global_lock());
+
+  do_remove_constraint(constraint);
+}
+
+/**
+ * Assumes the lock(bullet global lock) is held by the caller
+ */
+void BulletWorld::
+do_attach_rigid_body(BulletRigidBodyNode *node) {
 
   nassertv(node);
 
@@ -338,10 +496,10 @@ attach_rigid_body(BulletRigidBodyNode *node) {
 }
 
 /**
- * Deprecated.! Please use BulletWorld::remove
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-remove_rigid_body(BulletRigidBodyNode *node) {
+do_remove_rigid_body(BulletRigidBodyNode *node) {
 
   nassertv(node);
 
@@ -361,10 +519,10 @@ remove_rigid_body(BulletRigidBodyNode *node) {
 }
 
 /**
- * Deprecated!  Please use BulletWorld::attach
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-attach_soft_body(BulletSoftBodyNode *node) {
+do_attach_soft_body(BulletSoftBodyNode *node) {
 
   nassertv(node);
 
@@ -388,10 +546,10 @@ attach_soft_body(BulletSoftBodyNode *node) {
 }
 
 /**
- * Deprecated.! Please use BulletWorld::remove
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-remove_soft_body(BulletSoftBodyNode *node) {
+do_remove_soft_body(BulletSoftBodyNode *node) {
 
   nassertv(node);
 
@@ -411,10 +569,10 @@ remove_soft_body(BulletSoftBodyNode *node) {
 }
 
 /**
- * Deprecated!  Please use BulletWorld::attach
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-attach_ghost(BulletGhostNode *node) {
+do_attach_ghost(BulletGhostNode *node) {
 
   nassertv(node);
 
@@ -452,10 +610,10 @@ enum CollisionFilterGroups {
 }
 
 /**
- * Deprecated.! Please use BulletWorld::remove
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-remove_ghost(BulletGhostNode *node) {
+do_remove_ghost(BulletGhostNode *node) {
 
   nassertv(node);
 
@@ -475,10 +633,10 @@ remove_ghost(BulletGhostNode *node) {
 }
 
 /**
- * Deprecated!  Please use BulletWorld::attach
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-attach_character(BulletBaseCharacterControllerNode *node) {
+do_attach_character(BulletBaseCharacterControllerNode *node) {
 
   nassertv(node);
 
@@ -501,10 +659,10 @@ attach_character(BulletBaseCharacterControllerNode *node) {
 }
 
 /**
- * Deprecated.! Please use BulletWorld::remove
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-remove_character(BulletBaseCharacterControllerNode *node) {
+do_remove_character(BulletBaseCharacterControllerNode *node) {
 
   nassertv(node);
 
@@ -523,10 +681,10 @@ remove_character(BulletBaseCharacterControllerNode *node) {
 }
 
 /**
- * Deprecated!  Please use BulletWorld::attach
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-attach_vehicle(BulletVehicle *vehicle) {
+do_attach_vehicle(BulletVehicle *vehicle) {
 
   nassertv(vehicle);
 
@@ -544,14 +702,14 @@ attach_vehicle(BulletVehicle *vehicle) {
 }
 
 /**
- * Deprecated.! Please use BulletWorld::remove
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-remove_vehicle(BulletVehicle *vehicle) {
+do_remove_vehicle(BulletVehicle *vehicle) {
 
   nassertv(vehicle);
 
-  remove_rigid_body(vehicle->get_chassis());
+  do_remove_rigid_body(vehicle->do_get_chassis());
 
   BulletVehicles::iterator found;
   PT(BulletVehicle) ptvehicle = vehicle;
@@ -569,9 +727,10 @@ remove_vehicle(BulletVehicle *vehicle) {
 /**
  * Attaches a single constraint to a world.  Collision checks between the
  * linked objects will be disabled if the second parameter is set to TRUE.
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-attach_constraint(BulletConstraint *constraint, bool linked_collision) {
+do_attach_constraint(BulletConstraint *constraint, bool linked_collision) {
 
   nassertv(constraint);
 
@@ -589,10 +748,10 @@ attach_constraint(BulletConstraint *constraint, bool linked_collision) {
 }
 
 /**
- * Deprecated.! Please use BulletWorld::remove
+ * Assumes the lock(bullet global lock) is held by the caller
  */
 void BulletWorld::
-remove_constraint(BulletConstraint *constraint) {
+do_remove_constraint(BulletConstraint *constraint) {
 
   nassertv(constraint);
 
@@ -609,11 +768,148 @@ remove_constraint(BulletConstraint *constraint) {
   }
 }
 
+/**
+ *
+ */
+int BulletWorld::
+get_num_rigid_bodies() const {
+  LightMutexHolder holder(get_global_lock());
+
+  return _bodies.size();
+}
+
+/**
+ *
+ */
+BulletRigidBodyNode *BulletWorld::
+get_rigid_body(int idx) const {
+  LightMutexHolder holder(get_global_lock());
+
+  nassertr(idx >= 0 && idx < (int)_bodies.size(), NULL);
+  return _bodies[idx];
+}
+
+/**
+ *
+ */
+int BulletWorld::
+get_num_soft_bodies() const {
+  LightMutexHolder holder(get_global_lock());
+
+  return _softbodies.size();
+}
+
+/**
+ *
+ */
+BulletSoftBodyNode *BulletWorld::
+get_soft_body(int idx) const {
+  LightMutexHolder holder(get_global_lock());
+
+  nassertr(idx >= 0 && idx < (int)_softbodies.size(), NULL);
+  return _softbodies[idx];
+}
+
+/**
+ *
+ */
+int BulletWorld::
+get_num_ghosts() const {
+  LightMutexHolder holder(get_global_lock());
+
+  return _ghosts.size();
+}
+
+/**
+ *
+ */
+BulletGhostNode *BulletWorld::
+get_ghost(int idx) const {
+  LightMutexHolder holder(get_global_lock());
+
+  nassertr(idx >= 0 && idx < (int)_ghosts.size(), NULL);
+  return _ghosts[idx];
+}
+
+/**
+ *
+ */
+int BulletWorld::
+get_num_characters() const {
+  LightMutexHolder holder(get_global_lock());
+
+  return _characters.size();
+}
+
+/**
+ *
+ */
+BulletBaseCharacterControllerNode *BulletWorld::
+get_character(int idx) const {
+  LightMutexHolder holder(get_global_lock());
+
+  nassertr(idx >= 0 && idx < (int)_characters.size(), NULL);
+  return _characters[idx];
+}
+
+/**
+ *
+ */
+int BulletWorld::
+get_num_vehicles() const {
+  LightMutexHolder holder(get_global_lock());
+
+  return _vehicles.size();
+}
+
+/**
+ *
+ */
+BulletVehicle *BulletWorld::
+get_vehicle(int idx) const {
+  LightMutexHolder holder(get_global_lock());
+
+  nassertr(idx >= 0 && idx < (int)_vehicles.size(), NULL);
+  return _vehicles[idx];
+}
+
+/**
+ *
+ */
+int BulletWorld::
+get_num_constraints() const {
+  LightMutexHolder holder(get_global_lock());
+
+  return _constraints.size();
+}
+
+/**
+ *
+ */
+BulletConstraint *BulletWorld::
+get_constraint(int idx) const {
+  LightMutexHolder holder(get_global_lock());
+
+  nassertr(idx >= 0 && idx < (int)_constraints.size(), NULL);
+  return _constraints[idx];
+}
+
+/**
+ *
+ */
+int BulletWorld::
+get_num_manifolds() const {
+  LightMutexHolder holder(get_global_lock());
+
+  return _world->getDispatcher()->getNumManifolds();
+}
+
 /**
  *
  */
 BulletClosestHitRayResult BulletWorld::
 ray_test_closest(const LPoint3 &from_pos, const LPoint3 &to_pos, const CollideMask &mask) const {
+  LightMutexHolder holder(get_global_lock());
 
   nassertr(!from_pos.is_nan(), BulletClosestHitRayResult::empty());
   nassertr(!to_pos.is_nan(), BulletClosestHitRayResult::empty());
@@ -631,6 +927,7 @@ ray_test_closest(const LPoint3 &from_pos, const LPoint3 &to_pos, const CollideMa
  */
 BulletAllHitsRayResult BulletWorld::
 ray_test_all(const LPoint3 &from_pos, const LPoint3 &to_pos, const CollideMask &mask) const {
+  LightMutexHolder holder(get_global_lock());
 
   nassertr(!from_pos.is_nan(), BulletAllHitsRayResult::empty());
   nassertr(!to_pos.is_nan(), BulletAllHitsRayResult::empty());
@@ -648,13 +945,16 @@ ray_test_all(const LPoint3 &from_pos, const LPoint3 &to_pos, const CollideMask &
  */
 BulletClosestHitSweepResult BulletWorld::
 sweep_test_closest(BulletShape *shape, const TransformState &from_ts, const TransformState &to_ts, const CollideMask &mask, PN_stdfloat penetration) const {
+  LightMutexHolder holder(get_global_lock());
 
   nassertr(shape, BulletClosestHitSweepResult::empty());
-  nassertr(shape->is_convex(), BulletClosestHitSweepResult::empty());
+
+  const btConvexShape *convex = (const btConvexShape *) shape->ptr();
+  nassertr(convex->isConvex(), BulletClosestHitSweepResult::empty());
+  
   nassertr(!from_ts.is_invalid(), BulletClosestHitSweepResult::empty());
   nassertr(!to_ts.is_invalid(), BulletClosestHitSweepResult::empty());
 
-  const btConvexShape *convex = (const btConvexShape *) shape->ptr();
   const btVector3 from_pos = LVecBase3_to_btVector3(from_ts.get_pos());
   const btVector3 to_pos = LVecBase3_to_btVector3(to_ts.get_pos());
   const btTransform from_trans = LMatrix4_to_btTrans(from_ts.get_mat());
@@ -671,6 +971,7 @@ sweep_test_closest(BulletShape *shape, const TransformState &from_ts, const Tran
  */
 bool BulletWorld::
 filter_test(PandaNode *node0, PandaNode *node1) const {
+  LightMutexHolder holder(get_global_lock());
 
   nassertr(node0, false);
   nassertr(node1, false);
@@ -702,6 +1003,7 @@ filter_test(PandaNode *node0, PandaNode *node1) const {
  */
 BulletContactResult BulletWorld::
 contact_test(PandaNode *node, bool use_filter) const {
+  LightMutexHolder holder(get_global_lock());
 
   btCollisionObject *obj = get_collision_object(node);
 
@@ -727,6 +1029,7 @@ contact_test(PandaNode *node, bool use_filter) const {
  */
 BulletContactResult BulletWorld::
 contact_test_pair(PandaNode *node0, PandaNode *node1) const {
+  LightMutexHolder holder(get_global_lock());
 
   btCollisionObject *obj0 = get_collision_object(node0);
   btCollisionObject *obj1 = get_collision_object(node1);
@@ -746,6 +1049,7 @@ contact_test_pair(PandaNode *node0, PandaNode *node1) const {
  */
 BulletPersistentManifold *BulletWorld::
 get_manifold(int idx) const {
+  LightMutexHolder holder(get_global_lock());
 
   nassertr(idx < get_num_manifolds(), NULL);
 
@@ -780,6 +1084,7 @@ get_collision_object(PandaNode *node) {
  */
 void BulletWorld::
 set_group_collision_flag(unsigned int group1, unsigned int group2, bool enable) {
+  LightMutexHolder holder(get_global_lock());
 
   if (bullet_filter_algorithm != FA_groups_mask) {
     bullet_cat.warning() << "filter algorithm is not 'groups-mask'" << endl;
@@ -794,6 +1099,7 @@ set_group_collision_flag(unsigned int group1, unsigned int group2, bool enable)
  */
 bool BulletWorld::
 get_group_collision_flag(unsigned int group1, unsigned int group2) const {
+  LightMutexHolder holder(get_global_lock());
 
   return _filter_cb2._collide[group1].get_bit(group2);
 }
@@ -803,6 +1109,7 @@ get_group_collision_flag(unsigned int group1, unsigned int group2) const {
  */
 void BulletWorld::
 set_contact_added_callback(CallbackObject *obj) {
+  LightMutexHolder holder(get_global_lock());
 
   _world->getSolverInfo().m_solverMode |= SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION;
   _world->getSolverInfo().m_solverMode |= SOLVER_USE_2_FRICTION_DIRECTIONS;
@@ -816,6 +1123,7 @@ set_contact_added_callback(CallbackObject *obj) {
  */
 void BulletWorld::
 clear_contact_added_callback() {
+  LightMutexHolder holder(get_global_lock());
 
   _world->getSolverInfo().m_solverMode &= ~SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION;
   _world->getSolverInfo().m_solverMode &= ~SOLVER_USE_2_FRICTION_DIRECTIONS;
@@ -829,6 +1137,7 @@ clear_contact_added_callback() {
  */
 void BulletWorld::
 set_tick_callback(CallbackObject *obj, bool is_pretick) {
+  LightMutexHolder holder(get_global_lock());
 
   nassertv(obj != NULL);
   _tick_callback_obj = obj;
@@ -840,6 +1149,7 @@ set_tick_callback(CallbackObject *obj, bool is_pretick) {
  */
 void BulletWorld::
 clear_tick_callback() {
+  LightMutexHolder holder(get_global_lock());
 
   _tick_callback_obj = NULL;
   _world->setInternalTickCallback(NULL);
@@ -866,6 +1176,7 @@ tick_callback(btDynamicsWorld *world, btScalar timestep) {
  */
 void BulletWorld::
 set_filter_callback(CallbackObject *obj) {
+  LightMutexHolder holder(get_global_lock());
 
   nassertv(obj != NULL);
 
@@ -881,6 +1192,7 @@ set_filter_callback(CallbackObject *obj) {
  */
 void BulletWorld::
 clear_filter_callback() {
+  LightMutexHolder holder(get_global_lock());
 
   _filter_cb3._filter_callback_obj = NULL;
 }

+ 42 - 23
panda/src/bullet/bulletWorld.h

@@ -37,6 +37,7 @@
 #include "callbackObject.h"
 #include "collideMask.h"
 #include "luse.h"
+#include "lightMutex.h"
 
 class BulletPersistentManifold;
 class BulletShape;
@@ -62,48 +63,43 @@ PUBLISHED:
   BulletSoftBodyWorldInfo get_world_info();
 
   // Debug
-  INLINE void set_debug_node(BulletDebugNode *node);
+  void set_debug_node(BulletDebugNode *node);
   void clear_debug_node();
   INLINE BulletDebugNode *get_debug_node() const;
   INLINE bool has_debug_node() const;
 
   // AttachRemove
   void attach(TypedObject *object);
-  void attach_constraint(BulletConstraint *constraint, bool linked_collision=false);
-
   void remove(TypedObject *object);
+  void attach_constraint(BulletConstraint *constraint, bool linked_collision=false);
 
   // Ghost object
-  INLINE int get_num_ghosts() const;
-  INLINE BulletGhostNode *get_ghost(int idx) const;
+  int get_num_ghosts() const;
+  BulletGhostNode *get_ghost(int idx) const;
   MAKE_SEQ(get_ghosts, get_num_ghosts, get_ghost);
 
   // Rigid body
-  INLINE int get_num_rigid_bodies() const;
-  INLINE BulletRigidBodyNode *get_rigid_body(int idx) const;
+  int get_num_rigid_bodies() const;
+  BulletRigidBodyNode *get_rigid_body(int idx) const;
   MAKE_SEQ(get_rigid_bodies, get_num_rigid_bodies, get_rigid_body);
 
   // Soft body
-  INLINE int get_num_soft_bodies() const;
-  INLINE BulletSoftBodyNode *get_soft_body(int idx) const;
+  int get_num_soft_bodies() const;
+  BulletSoftBodyNode *get_soft_body(int idx) const;
   MAKE_SEQ(get_soft_bodies, get_num_soft_bodies, get_soft_body);
 
   // Character controller
-  INLINE int get_num_characters() const;
-  INLINE BulletBaseCharacterControllerNode *get_character(int idx) const;
+  int get_num_characters() const;
+  BulletBaseCharacterControllerNode *get_character(int idx) const;
   MAKE_SEQ(get_characters, get_num_characters, get_character);
 
-  // Vehicle
-  void attach_vehicle(BulletVehicle *vehicle);
-  void remove_vehicle(BulletVehicle *vehicle);
-
-  INLINE int get_num_vehicles() const;
-  INLINE BulletVehicle *get_vehicle(int idx) const;
+  int get_num_vehicles() const;
+  BulletVehicle *get_vehicle(int idx) const;
   MAKE_SEQ(get_vehicles, get_num_vehicles, get_vehicle);
 
   // Constraint
-  INLINE int get_num_constraints() const;
-  INLINE BulletConstraint *get_constraint(int idx) const;
+  int get_num_constraints() const;
+  BulletConstraint *get_constraint(int idx) const;
   MAKE_SEQ(get_constraints, get_num_constraints, get_constraint);
 
   // Raycast and other queries
@@ -130,7 +126,7 @@ PUBLISHED:
   bool filter_test(PandaNode *node0, PandaNode *node1) const;
 
   // Manifolds
-  INLINE int get_num_manifolds() const;
+  int get_num_manifolds() const;
   BulletPersistentManifold *get_manifold(int idx) const;
   MAKE_SEQ(get_manifolds, get_num_manifolds, get_manifold);
 
@@ -171,7 +167,7 @@ PUBLISHED:
   MAKE_SEQ_PROPERTY(constraints, get_num_constraints, get_constraint);
   MAKE_SEQ_PROPERTY(manifolds, get_num_manifolds, get_manifold);
 
-PUBLISHED: // Deprecated methods, will become private soon
+PUBLISHED: // Deprecated methods, will be removed soon
   void attach_ghost(BulletGhostNode *node);
   void remove_ghost(BulletGhostNode *node);
 
@@ -184,6 +180,9 @@ PUBLISHED: // Deprecated methods, will become private soon
   void attach_character(BulletBaseCharacterControllerNode *node);
   void remove_character(BulletBaseCharacterControllerNode *node);
 
+  void attach_vehicle(BulletVehicle *vehicle);
+  void remove_vehicle(BulletVehicle *vehicle);
+
   void remove_constraint(BulletConstraint *constraint);
 
 public:
@@ -193,9 +192,29 @@ public:
   INLINE btBroadphaseInterface *get_broadphase() const;
   INLINE btDispatcher *get_dispatcher() const;
 
+  static LightMutex &get_global_lock();
+
 private:
-  void sync_p2b(PN_stdfloat dt, int num_substeps);
-  void sync_b2p();
+  void do_sync_p2b(PN_stdfloat dt, int num_substeps);
+  void do_sync_b2p();
+
+  void do_attach_ghost(BulletGhostNode *node);
+  void do_remove_ghost(BulletGhostNode *node);
+
+  void do_attach_rigid_body(BulletRigidBodyNode *node);
+  void do_remove_rigid_body(BulletRigidBodyNode *node);
+
+  void do_attach_soft_body(BulletSoftBodyNode *node);
+  void do_remove_soft_body(BulletSoftBodyNode *node);
+
+  void do_attach_character(BulletBaseCharacterControllerNode *node);
+  void do_remove_character(BulletBaseCharacterControllerNode *node);
+
+  void do_attach_vehicle(BulletVehicle *vehicle);
+  void do_remove_vehicle(BulletVehicle *vehicle);
+
+  void do_attach_constraint(BulletConstraint *constraint, bool linked_collision=false);
+  void do_remove_constraint(BulletConstraint *constraint);
 
   static void tick_callback(btDynamicsWorld *world, btScalar timestep);