diff --git a/panda/src/bullet/bulletBodyNode.I b/panda/src/bullet/bulletBodyNode.I index 376c8061b5..2071f9a945 100644 --- a/panda/src/bullet/bulletBodyNode.I +++ b/panda/src/bullet/bulletBodyNode.I @@ -225,3 +225,29 @@ get_shape(int idx) const { return _shapes[idx]; } +//////////////////////////////////////////////////////////////////// +// Function: BulletBodyNode::set_debug_enabled +// Access: Published +// Description: Enables or disables the debug visualisation for +// this collision object. By default the debug +// visualisation is enabled. +//////////////////////////////////////////////////////////////////// +INLINE void BulletBodyNode:: +set_debug_enabled(const bool enabled) { + + set_collision_flag(btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT, !enabled); +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletBodyNode::is_debug_enabled +// Access: Published +// Description: Returns TRUE if the debug visualisation is enabled +// for this collision object, and FALSE if the debug +// visualisation is disabled. +//////////////////////////////////////////////////////////////////// +INLINE bool BulletBodyNode:: +is_debug_enabled() const { + + return !get_collision_flag(btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT); +} + diff --git a/panda/src/bullet/bulletBodyNode.cxx b/panda/src/bullet/bulletBodyNode.cxx index b805d9ef4c..bcff220281 100644 --- a/panda/src/bullet/bulletBodyNode.cxx +++ b/panda/src/bullet/bulletBodyNode.cxx @@ -35,9 +35,6 @@ BulletBodyNode(const char *name) : PandaNode(name) { // Shape _shape = new btEmptyShape(); - // Transform changed callback - _disable_transform_changed = false; - // Default collide mask set_into_collide_mask(CollideMask::all_on()); } @@ -162,22 +159,6 @@ output(ostream &out) const { if (is_kinematic()) out << " kinematic"; } -//////////////////////////////////////////////////////////////////// -// Function: BulletBodyNode::transform_changed -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -void BulletBodyNode:: -transform_changed() { - - // Apply scale to collision shape - CPT(TransformState) ts = this->get_transform(); - if (ts->has_scale()) { - LVecBase3f scale = ts->get_scale(); - _shape->setLocalScaling(LVecBase3f_to_btVector3(scale)); - } -} - //////////////////////////////////////////////////////////////////// // Function: BulletBodyNode::add_shape // Access: Published @@ -194,7 +175,7 @@ add_shape(BulletShape *shape, CPT(TransformState) ts) { // Transform btTransform trans = btTransform::getIdentity(); if (ts) { - trans = LMatrix4f_to_btTrans(ts->get_mat()); + trans = TransformState_to_btTrans(ts); } // Root shape @@ -447,14 +428,14 @@ set_active(bool active, bool force) { } //////////////////////////////////////////////////////////////////// -// Function: BulletBodyNode::set_disable_deactivation +// Function: BulletBodyNode::set_deactivation_enabled // Access: Published // Description: //////////////////////////////////////////////////////////////////// void BulletBodyNode:: -set_disable_deactivation(bool disable, bool force) { +set_deactivation_enabled(const bool enabled, const bool force) { - int state = (disable) ? DISABLE_DEACTIVATION : WANTS_DEACTIVATION; + int state = (enabled) ? WANTS_DEACTIVATION : DISABLE_DEACTIVATION; if (force) { get_object()->forceActivationState(state); @@ -465,14 +446,14 @@ set_disable_deactivation(bool disable, bool force) { } //////////////////////////////////////////////////////////////////// -// Function: BulletBodyNode::get_disable_deactivation +// Function: BulletBodyNode::is_deactivation_enabled // Access: Published // Description: //////////////////////////////////////////////////////////////////// bool BulletBodyNode:: -get_disable_deactivation() const { +is_deactivation_enabled() const { - return (get_object()->getActivationState() & DISABLE_DEACTIVATION) != 0; + return (get_object()->getActivationState() & DISABLE_DEACTIVATION) == 0; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/bullet/bulletBodyNode.h b/panda/src/bullet/bulletBodyNode.h index 8d659c8436..c31bc109ee 100644 --- a/panda/src/bullet/bulletBodyNode.h +++ b/panda/src/bullet/bulletBodyNode.h @@ -78,8 +78,12 @@ PUBLISHED: void set_deactivation_time(float dt); float get_deactivation_time() const; - void set_disable_deactivation(bool disable, bool force=false); - bool get_disable_deactivation() const; + void set_deactivation_enabled(const bool enabled, const bool force=false); + bool is_deactivation_enabled() const; + + // Debug Visualistion + INLINE void set_debug_enabled(const bool enabled); + INLINE bool is_debug_enabled() const; // Friction and Restitution INLINE float get_restitution() const; @@ -121,9 +125,6 @@ protected: typedef PTA(PT(BulletShape)) BulletShapes; BulletShapes _shapes; - bool _disable_transform_changed; - virtual void transform_changed(); - private: virtual void shape_changed(); diff --git a/panda/src/bullet/bulletCharacterControllerNode.cxx b/panda/src/bullet/bulletCharacterControllerNode.cxx index 03b67aa537..a1acbe3a8c 100644 --- a/panda/src/bullet/bulletCharacterControllerNode.cxx +++ b/panda/src/bullet/bulletCharacterControllerNode.cxx @@ -24,17 +24,21 @@ TypeHandle BulletCharacterControllerNode::_type_handle; BulletCharacterControllerNode:: BulletCharacterControllerNode(BulletShape *shape, float step_height, const char *name) : PandaNode(name) { - // Setup initial transform + // Synchronised transform + _sync = TransformState::make_identity(); + _sync_disable = false; + + // Initial transform btTransform trans = btTransform::getIdentity(); - // Get convex shape + // Get convex shape (for ghost object) if (!shape->is_convex()) { bullet_cat.error() << "a convex shape is required!" << endl; } btConvexShape *convex = dynamic_cast(shape->ptr()); - // Setup ghost object + // Ghost object _ghost = new btPairCachingGhostObject(); _ghost->setUserPointer(this); @@ -43,25 +47,21 @@ BulletCharacterControllerNode(BulletShape *shape, float step_height, const char _ghost->setCollisionShape(convex); _ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); - // Setup up axis + // Up axis _up = get_default_up_axis(); - // Movement + // Initialise movement _linear_velocity_is_local = false; _linear_velocity.set(0.0f, 0.0f, 0.0f); _angular_velocity = 0.0f; - // Setup character controller + // Character controller _character = new btKinematicCharacterController(_ghost, convex, step_height, _up); _character->setGravity((btScalar)9.81f); // Retain a pointer to the shape _shape = shape; - // The 'transform changed' hook has to be disabled when updating the node's - // transform from inside the post_step method! - _disable_transform_changed = false; - // Default collide mask set_into_collide_mask(CollideMask::all_on()); } @@ -196,14 +196,17 @@ set_angular_velocity(float omega) { } //////////////////////////////////////////////////////////////////// -// Function: BulletCharacterControllerNode::pre_step +// Function: BulletCharacterControllerNode::sync_p2b // Access: Public // Description: //////////////////////////////////////////////////////////////////// void BulletCharacterControllerNode:: -pre_step(float dt) { +sync_p2b(float dt) { - // Angular rotation + // Synchronise global transform + transform_changed(); + + // Angular rotation btScalar angle = dt * deg_2_rad(_angular_velocity); btMatrix3x3 m = _ghost->getWorldTransform().getBasis(); @@ -225,28 +228,32 @@ pre_step(float dt) { } _character->setVelocityForTimeInterval(v, dt); - //_character->setWalkDirection(v * dt); - _angular_velocity = 0.0f; } //////////////////////////////////////////////////////////////////// -// Function: BulletCharacterControllerNode::post_step +// Function: BulletCharacterControllerNode::sync_b2p // Access: Public // Description: //////////////////////////////////////////////////////////////////// void BulletCharacterControllerNode:: -post_step() { - - btTransform trans = _ghost->getWorldTransform(); - CPT(TransformState) ts = btTrans_to_TransformState(trans); - - _disable_transform_changed = true; +sync_b2p() { NodePath np = NodePath::any_path((PandaNode *)this); - np.set_transform(np.get_top(), ts); + LVecBase3f scale = np.get_net_transform()->get_scale(); - _disable_transform_changed = false; + btTransform trans = _ghost->getWorldTransform(); + CPT(TransformState) ts = btTrans_to_TransformState(trans, scale); + + LMatrix4f m_sync = _sync->get_mat(); + LMatrix4f m_ts = ts->get_mat(); + + if (!m_sync.almost_equal(m_ts)) { + _sync = ts; + _sync_disable = true; + np.set_transform(NodePath(), ts); + _sync_disable = false; + } } //////////////////////////////////////////////////////////////////// @@ -257,25 +264,36 @@ post_step() { void BulletCharacterControllerNode:: transform_changed() { - if (_disable_transform_changed) return; + if (_sync_disable) return; - // Get translation and heading NodePath np = NodePath::any_path((PandaNode *)this); - CPT(TransformState) ts = np.get_transform(np.get_top()); + CPT(TransformState) ts = np.get_net_transform(); - LPoint3f pos = ts->get_pos(); - float heading = ts->get_hpr().get_x(); + LMatrix4f m_sync = _sync->get_mat(); + LMatrix4f m_ts = ts->get_mat(); - // Set translation - _character->warp(LVecBase3f_to_btVector3(pos)); + if (!m_sync.almost_equal(m_ts)) { + _sync = ts; - // Set Heading - btMatrix3x3 m = _ghost->getWorldTransform().getBasis(); - btVector3 up = m[_up]; + // Get translation, heading and scale + LPoint3f pos = ts->get_pos(); + float heading = ts->get_hpr().get_x(); + LVecBase3f scale = ts->get_scale(); - m = btMatrix3x3(btQuaternion(up, heading)); + // Set translation + _character->warp(LVecBase3f_to_btVector3(pos)); - _ghost->getWorldTransform().setBasis(m); + // Set Heading + btMatrix3x3 m = _ghost->getWorldTransform().getBasis(); + btVector3 up = m[_up]; + + m = btMatrix3x3(btQuaternion(up, heading)); + + _ghost->getWorldTransform().setBasis(m); + + // Set scale + _shape->set_local_scale(scale); + } } //////////////////////////////////////////////////////////////////// @@ -408,25 +426,3 @@ set_use_ghost_sweep_test(bool value) { return _character->setUseGhostSweepTest(value); } -/* -//////////////////////////////////////////////////////////////////// -// Function: BulletCharacterControllerNode::parents_changed -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -void BulletCharacterControllerNode:: -parents_changed() { - -} - -//////////////////////////////////////////////////////////////////// -// Function: BulletCharacterControllerNode::children_changed -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -void BulletCharacterControllerNode:: -children_changed() { - -} -*/ - diff --git a/panda/src/bullet/bulletCharacterControllerNode.h b/panda/src/bullet/bulletCharacterControllerNode.h index 1568024d60..b774148d59 100644 --- a/panda/src/bullet/bulletCharacterControllerNode.h +++ b/panda/src/bullet/bulletCharacterControllerNode.h @@ -69,15 +69,16 @@ public: INLINE btPairCachingGhostObject *get_ghost() const; INLINE btKinematicCharacterController *get_character() const; - void pre_step(float dt); - void post_step(); + void sync_p2b(float dt); + void sync_b2p(); protected: - //virtual void parents_changed(); - //virtual void children_changed(); virtual void transform_changed(); private: + CPT(TransformState) _sync; + bool _sync_disable; + BulletUpAxis _up; btKinematicCharacterController *_character; @@ -89,8 +90,6 @@ private: bool _linear_velocity_is_local; float _angular_velocity; - bool _disable_transform_changed; - //////////////////////////////////////////////////////////////////// public: static TypeHandle get_class_type() { diff --git a/panda/src/bullet/bulletDebugNode.cxx b/panda/src/bullet/bulletDebugNode.cxx index 4a29d0be0c..b886482aed 100644 --- a/panda/src/bullet/bulletDebugNode.cxx +++ b/panda/src/bullet/bulletDebugNode.cxx @@ -186,12 +186,12 @@ draw_mask_changed() { } //////////////////////////////////////////////////////////////////// -// Function: BulletDebugNode::post_step +// Function: BulletDebugNode::sync_b2p // Access: Private // Description: //////////////////////////////////////////////////////////////////// void BulletDebugNode:: -post_step(btDynamicsWorld *world) { +sync_b2p(btDynamicsWorld *world) { if (is_overall_hidden()) return; @@ -199,7 +199,7 @@ post_step(btDynamicsWorld *world) { world->debugDrawWorld(); // Get inverse of this node's net transform - NodePath np = NodePath::any_path(this); + NodePath np = NodePath::any_path((PandaNode *)this); LMatrix4f m = np.get_net_transform()->get_mat(); m.invert_in_place(); @@ -348,7 +348,6 @@ drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, cons void BulletDebugNode::DebugDraw:: drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &n0, const btVector3 &n1, const btVector3 &n2, const btVector3 &color, btScalar alpha) { - // TODO bullet_cat.debug() << "drawTriangle(2) - not yet implemented!" << endl; } @@ -374,7 +373,6 @@ drawContactPoint(const btVector3 &point, const btVector3 &normal, btScalar dista void BulletDebugNode::DebugDraw:: draw3dText(const btVector3 &location, const char *text) { - // TODO bullet_cat.debug() << "draw3dText - not yet implemented!" << endl; } diff --git a/panda/src/bullet/bulletDebugNode.h b/panda/src/bullet/bulletDebugNode.h index 497530583e..167f8cc4cd 100644 --- a/panda/src/bullet/bulletDebugNode.h +++ b/panda/src/bullet/bulletDebugNode.h @@ -49,7 +49,7 @@ public: virtual bool safe_to_flatten_below() const; private: - void post_step(btDynamicsWorld *world); + void sync_b2p(btDynamicsWorld *world); struct Line { LVecBase3f _p0; diff --git a/panda/src/bullet/bulletGhostNode.cxx b/panda/src/bullet/bulletGhostNode.cxx index 90f42caaa5..79ae5f3ea4 100644 --- a/panda/src/bullet/bulletGhostNode.cxx +++ b/panda/src/bullet/bulletGhostNode.cxx @@ -25,19 +25,20 @@ TypeHandle BulletGhostNode::_type_handle; BulletGhostNode:: BulletGhostNode(const char *name) : BulletBodyNode(name) { - // Setup initial transform + // Synchronised transform + _sync = TransformState::make_identity(); + _sync_disable = false; + + // Initial transform btTransform trans = btTransform::getIdentity(); - // Setup ghost object + // Ghost object _ghost = new btPairCachingGhostObject(); _ghost->setUserPointer(this); _ghost->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE); _ghost->setWorldTransform(trans); _ghost->setInterpolationWorldTransform(trans); _ghost->setCollisionShape(_shape); - - // Autosync is off by default - _sync_transform = false; } //////////////////////////////////////////////////////////////////// @@ -51,35 +52,6 @@ get_object() const { return _ghost; } -//////////////////////////////////////////////////////////////////// -// Function: BulletGhostNode::parents_changed -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -void BulletGhostNode:: -parents_changed() { - - // Enable autosync if one of the parents is suited for this - Parents parents = get_parents(); - for (int i=0; i < parents.get_num_parents(); ++i) { - PandaNode *parent = parents.get_parent(i); - TypeHandle type = parent->get_type(); - - if (BulletRigidBodyNode::get_class_type() == type || - BulletSoftBodyNode::get_class_type() == type || - BulletGhostNode::get_class_type() == type || - BulletCharacterControllerNode::get_class_type() == type) { - _sync_transform = true; - return; - } - } - - // None of the parents is suited for autosync - _sync_transform = false; - - transform_changed(); -} - //////////////////////////////////////////////////////////////////// // Function: BulletGhostNode::transform_changed // Access: Protected @@ -88,26 +60,64 @@ parents_changed() { void BulletGhostNode:: transform_changed() { - if (_disable_transform_changed) return; + if (_sync_disable) return; - btTransform trans = btTransform::getIdentity(); - get_node_transform(trans, this); - _ghost->setWorldTransform(trans); - _ghost->setInterpolationWorldTransform(trans); + NodePath np = NodePath::any_path((PandaNode *)this); + CPT(TransformState) ts = np.get_net_transform(); - BulletBodyNode::transform_changed(); + LMatrix4f m_sync = _sync->get_mat(); + LMatrix4f m_ts = ts->get_mat(); + + if (!m_sync.almost_equal(m_ts)) { + _sync = ts; + + btTransform trans = TransformState_to_btTrans(ts); + _ghost->setWorldTransform(trans); + _ghost->setInterpolationWorldTransform(trans); + + if (ts->has_scale()) { + LVecBase3f scale = ts->get_scale(); + for (int i=0; iset_local_scale(scale); + } + } + } } //////////////////////////////////////////////////////////////////// -// Function: BulletGhostNode::pre_step +// Function: BulletGhostNode::sync_p2b // Access: Public // Description: //////////////////////////////////////////////////////////////////// void BulletGhostNode:: -pre_step() { +sync_p2b() { - if (_sync_transform) { - transform_changed(); + transform_changed(); +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletGhostNode::sync_b2p +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void BulletGhostNode:: +sync_b2p() { + + NodePath np = NodePath::any_path((PandaNode *)this); + LVecBase3f scale = np.get_net_transform()->get_scale(); + + btTransform trans = _ghost->getWorldTransform(); + CPT(TransformState) ts = btTrans_to_TransformState(trans, scale); + + LMatrix4f m_sync = _sync->get_mat(); + LMatrix4f m_ts = ts->get_mat(); + + if (!m_sync.almost_equal(m_ts)) { + _sync = ts; + _sync_disable = true; + np.set_transform(NodePath(), ts); + _sync_disable = false; } } diff --git a/panda/src/bullet/bulletGhostNode.h b/panda/src/bullet/bulletGhostNode.h index b3c66e9f8c..5a91478448 100644 --- a/panda/src/bullet/bulletGhostNode.h +++ b/panda/src/bullet/bulletGhostNode.h @@ -44,16 +44,17 @@ PUBLISHED: public: virtual btCollisionObject *get_object() const; - void pre_step(); + void sync_p2b(); + void sync_b2p(); protected: - virtual void parents_changed(); virtual void transform_changed(); private: - btPairCachingGhostObject *_ghost; + CPT(TransformState) _sync; + bool _sync_disable; - bool _sync_transform; + btPairCachingGhostObject *_ghost; //////////////////////////////////////////////////////////////////// public: diff --git a/panda/src/bullet/bulletRigidBodyNode.I b/panda/src/bullet/bulletRigidBodyNode.I index 519f2b1b5c..c4ee21dcb4 100644 --- a/panda/src/bullet/bulletRigidBodyNode.I +++ b/panda/src/bullet/bulletRigidBodyNode.I @@ -21,8 +21,8 @@ INLINE BulletRigidBodyNode:: ~BulletRigidBodyNode() { - delete _body; - delete _motion; + delete _rigid->getMotionState(); + delete _rigid; } //////////////////////////////////////////////////////////////////// @@ -33,7 +33,7 @@ INLINE BulletRigidBodyNode:: INLINE void BulletRigidBodyNode:: set_linear_damping(float value) { - _body->setDamping(value, _body->getAngularDamping()); + _rigid->setDamping(value, _rigid->getAngularDamping()); } //////////////////////////////////////////////////////////////////// @@ -44,7 +44,7 @@ set_linear_damping(float value) { INLINE void BulletRigidBodyNode:: set_angular_damping(float value) { - _body->setDamping(_body->getLinearDamping(), value); + _rigid->setDamping(_rigid->getLinearDamping(), value); } //////////////////////////////////////////////////////////////////// @@ -55,7 +55,7 @@ set_angular_damping(float value) { INLINE float BulletRigidBodyNode:: get_linear_damping() const { - return _body->getLinearDamping(); + return _rigid->getLinearDamping(); } //////////////////////////////////////////////////////////////////// @@ -66,6 +66,6 @@ get_linear_damping() const { INLINE float BulletRigidBodyNode:: get_angular_damping() const { - return _body->getAngularDamping(); + return _rigid->getAngularDamping(); } diff --git a/panda/src/bullet/bulletRigidBodyNode.cxx b/panda/src/bullet/bulletRigidBodyNode.cxx index c34d775cfa..93eddedc99 100644 --- a/panda/src/bullet/bulletRigidBodyNode.cxx +++ b/panda/src/bullet/bulletRigidBodyNode.cxx @@ -25,16 +25,19 @@ TypeHandle BulletRigidBodyNode::_type_handle; BulletRigidBodyNode:: BulletRigidBodyNode(const char *name) : BulletBodyNode(name) { - // Setup motion state - _motion = new MotionState(this); + // Synchronised transform + _sync = TransformState::make_identity(); + _sync_disable = false; - // Setup mass properties + // Mass properties btScalar mass(0.0); btVector3 inertia(0, 0, 0); - btRigidBody::btRigidBodyConstructionInfo ci(mass, _motion, _shape, inertia); + // Motion state and construction info + btDefaultMotionState *motion = new btDefaultMotionState(); + btRigidBody::btRigidBodyConstructionInfo ci(mass, motion, _shape, inertia); - // Enable additional damping + // Additional damping if (bullet_additional_damping) { ci.m_additionalDamping = true; ci.m_additionalDampingFactor = bullet_additional_damping_linear_factor; @@ -43,9 +46,9 @@ BulletRigidBodyNode(const char *name) : BulletBodyNode(name) { ci.m_additionalAngularDampingThresholdSqr = bullet_additional_damping_angular_threshold; } - // Setup rigid body - _body = new btRigidBody(ci); - _body->setUserPointer(this); + // Rigid body + _rigid = new btRigidBody(ci); + _rigid->setUserPointer(this); } //////////////////////////////////////////////////////////////////// @@ -69,7 +72,7 @@ output(ostream &out) const { btCollisionObject *BulletRigidBodyNode:: get_object() const { - return _body; + return _rigid; } //////////////////////////////////////////////////////////////////// @@ -97,10 +100,10 @@ set_mass(float mass) { btVector3 inertia(0.0f, 0.0f, 0.0f); if (mass > 0.0f) { - _body->getCollisionShape()->calculateLocalInertia(mass, inertia); + _rigid->getCollisionShape()->calculateLocalInertia(mass, inertia); } - _body->setMassProps(mass, inertia); + _rigid->setMassProps(mass, inertia); } //////////////////////////////////////////////////////////////////// @@ -111,7 +114,7 @@ set_mass(float mass) { float BulletRigidBodyNode:: get_mass() const { - btScalar invMass = _body->getInvMass(); + btScalar invMass = _rigid->getInvMass(); if (invMass == 0.0f) { return 0.0f; @@ -132,7 +135,7 @@ apply_force(const LVector3f &force, const LPoint3f &pos) { nassertv_always(!force.is_nan()); nassertv_always(!pos.is_nan()); - _body->applyForce(LVecBase3f_to_btVector3(force), + _rigid->applyForce(LVecBase3f_to_btVector3(force), LVecBase3f_to_btVector3(pos)); } @@ -146,7 +149,7 @@ apply_central_force(const LVector3f &force) { nassertv_always(!force.is_nan()); - _body->applyCentralForce(LVecBase3f_to_btVector3(force)); + _rigid->applyCentralForce(LVecBase3f_to_btVector3(force)); } //////////////////////////////////////////////////////////////////// @@ -159,7 +162,7 @@ apply_torque(const LVector3f &torque) { nassertv_always(!torque.is_nan()); - _body->applyTorque(LVecBase3f_to_btVector3(torque)); + _rigid->applyTorque(LVecBase3f_to_btVector3(torque)); } //////////////////////////////////////////////////////////////////// @@ -172,7 +175,7 @@ apply_torque_impulse(const LVector3f &torque) { nassertv_always(!torque.is_nan()); - _body->applyTorqueImpulse(LVecBase3f_to_btVector3(torque)); + _rigid->applyTorqueImpulse(LVecBase3f_to_btVector3(torque)); } //////////////////////////////////////////////////////////////////// @@ -186,7 +189,7 @@ apply_impulse(const LVector3f &impulse, const LPoint3f &pos) { nassertv_always(!impulse.is_nan()); nassertv_always(!pos.is_nan()); - _body->applyImpulse(LVecBase3f_to_btVector3(impulse), + _rigid->applyImpulse(LVecBase3f_to_btVector3(impulse), LVecBase3f_to_btVector3(pos)); } @@ -200,18 +203,7 @@ apply_central_impulse(const LVector3f &impulse) { nassertv_always(!impulse.is_nan()); - _body->applyCentralImpulse(LVecBase3f_to_btVector3(impulse)); -} - -//////////////////////////////////////////////////////////////////// -// Function: BulletRigidBodyNode::parents_changed -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -void BulletRigidBodyNode:: -parents_changed() { - - transform_changed(); + _rigid->applyCentralImpulse(LVecBase3f_to_btVector3(impulse)); } //////////////////////////////////////////////////////////////////// @@ -222,56 +214,65 @@ parents_changed() { void BulletRigidBodyNode:: transform_changed() { - if (_disable_transform_changed) return; + if (_sync_disable) return; - btTransform trans = btTransform::getIdentity(); - get_node_transform(trans, this); - _body->setWorldTransform(trans); - _body->setInterpolationWorldTransform(trans); + NodePath np = NodePath::any_path((PandaNode *)this); + CPT(TransformState) ts = np.get_net_transform(); - BulletBodyNode::transform_changed(); -} + LMatrix4f m_sync = _sync->get_mat(); + LMatrix4f m_ts = ts->get_mat(); -//////////////////////////////////////////////////////////////////// -// Function: BulletRigidBodyNode::MotionState::getWorldTransform -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void BulletRigidBodyNode::MotionState:: -getWorldTransform(btTransform &trans) const { + if (!m_sync.almost_equal(m_ts)) { + _sync = ts; - get_node_transform(trans, _node); -} + btTransform trans = TransformState_to_btTrans(ts); + _rigid->setWorldTransform(trans); + _rigid->setInterpolationWorldTransform(trans); -//////////////////////////////////////////////////////////////////// -// Function: BulletRigidBodyNode::MotionState::setWorldTransform -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void BulletRigidBodyNode::MotionState:: -setWorldTransform(const btTransform &trans) { - - if (trans.getOrigin().getX() != trans.getOrigin().getX()) { - bullet_cat.error() << "setWorldTransform: trans is NAN!" << endl; - return; + if (ts->has_scale()) { + LVecBase3f scale = ts->get_scale(); + for (int i=0; iset_local_scale(scale); + } + } } +} - LVecBase3f scale = _node->get_transform()->get_scale(); +//////////////////////////////////////////////////////////////////// +// Function: BulletRigidBodyNode::sync_p2b +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void BulletRigidBodyNode:: +sync_p2b() { + + transform_changed(); +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletRigidBodyNode::sync_b2p +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void BulletRigidBodyNode:: +sync_b2p() { + + NodePath np = NodePath::any_path((PandaNode *)this); + LVecBase3f scale = np.get_net_transform()->get_scale(); + + btTransform trans = _rigid->getWorldTransform(); CPT(TransformState) ts = btTrans_to_TransformState(trans, scale); - // Disable transform_changed callback - _node->_disable_transform_changed = true; + LMatrix4f m_sync = _sync->get_mat(); + LMatrix4f m_ts = ts->get_mat(); - if (_node->get_num_parents() == 0) { - _node->set_transform(ts); + if (!m_sync.almost_equal(m_ts)) { + _sync = ts; + _sync_disable = true; + np.set_transform(NodePath(), ts); + _sync_disable = false; } - else { - NodePath np = NodePath::any_path(_node); - np.set_transform(np.get_top(), ts); - } - - // Re-enable transform_changed callback again - _node->_disable_transform_changed = false; } //////////////////////////////////////////////////////////////////// @@ -284,11 +285,10 @@ set_center_of_mass_pos(const LPoint3f &pos) { nassertv_always(!pos.is_nan()); - btTransform xform = btTransform::getIdentity(); - xform.setIdentity(); - xform.setOrigin(LVecBase3f_to_btVector3(pos)); + btTransform trans = btTransform::getIdentity(); + trans.setOrigin(LVecBase3f_to_btVector3(pos)); - _body->setCenterOfMassTransform(xform); + _rigid->setCenterOfMassTransform(trans); } //////////////////////////////////////////////////////////////////// @@ -299,7 +299,7 @@ set_center_of_mass_pos(const LPoint3f &pos) { LPoint3f BulletRigidBodyNode:: get_center_of_mass_pos() const { - return btVector3_to_LPoint3f(_body->getCenterOfMassPosition()); + return btVector3_to_LPoint3f(_rigid->getCenterOfMassPosition()); } //////////////////////////////////////////////////////////////////// @@ -310,7 +310,7 @@ get_center_of_mass_pos() const { LVector3f BulletRigidBodyNode:: get_linear_velocity() const { - return btVector3_to_LVector3f(_body->getLinearVelocity()); + return btVector3_to_LVector3f(_rigid->getLinearVelocity()); } //////////////////////////////////////////////////////////////////// @@ -321,7 +321,7 @@ get_linear_velocity() const { LVector3f BulletRigidBodyNode:: get_angular_velocity() const { - return btVector3_to_LVector3f(_body->getAngularVelocity()); + return btVector3_to_LVector3f(_rigid->getAngularVelocity()); } //////////////////////////////////////////////////////////////////// @@ -334,7 +334,7 @@ set_linear_velocity(const LVector3f &velocity) { nassertv_always(!velocity.is_nan()); - _body->setLinearVelocity(LVecBase3f_to_btVector3(velocity)); + _rigid->setLinearVelocity(LVecBase3f_to_btVector3(velocity)); } //////////////////////////////////////////////////////////////////// @@ -347,7 +347,7 @@ set_angular_velocity(const LVector3f &velocity) { nassertv_always(!velocity.is_nan()); - _body->setAngularVelocity(LVecBase3f_to_btVector3(velocity)); + _rigid->setAngularVelocity(LVecBase3f_to_btVector3(velocity)); } //////////////////////////////////////////////////////////////////// @@ -358,7 +358,7 @@ set_angular_velocity(const LVector3f &velocity) { void BulletRigidBodyNode:: clear_forces() { - _body->clearForces(); + _rigid->clearForces(); } //////////////////////////////////////////////////////////////////// @@ -369,7 +369,7 @@ clear_forces() { float BulletRigidBodyNode:: get_linear_sleep_threshold() const { - return _body->getLinearSleepingThreshold(); + return _rigid->getLinearSleepingThreshold(); } //////////////////////////////////////////////////////////////////// @@ -380,7 +380,7 @@ get_linear_sleep_threshold() const { float BulletRigidBodyNode:: get_angular_sleep_threshold() const { - return _body->getAngularSleepingThreshold(); + return _rigid->getAngularSleepingThreshold(); } //////////////////////////////////////////////////////////////////// @@ -391,7 +391,7 @@ get_angular_sleep_threshold() const { void BulletRigidBodyNode:: set_linear_sleep_threshold(float threshold) { - _body->setSleepingThresholds(_body->getLinearSleepingThreshold(), threshold); + _rigid->setSleepingThresholds(_rigid->getLinearSleepingThreshold(), threshold); } //////////////////////////////////////////////////////////////////// @@ -402,7 +402,7 @@ set_linear_sleep_threshold(float threshold) { void BulletRigidBodyNode:: set_angular_sleep_threshold(float threshold) { - _body->setSleepingThresholds(threshold, _body->getAngularSleepingThreshold()); + _rigid->setSleepingThresholds(threshold, _rigid->getAngularSleepingThreshold()); } //////////////////////////////////////////////////////////////////// @@ -415,7 +415,7 @@ set_gravity(const LVector3f &gravity) { nassertv_always(!gravity.is_nan()); - _body->setGravity(LVecBase3f_to_btVector3(gravity)); + _rigid->setGravity(LVecBase3f_to_btVector3(gravity)); } //////////////////////////////////////////////////////////////////// @@ -426,7 +426,7 @@ set_gravity(const LVector3f &gravity) { LVector3f BulletRigidBodyNode:: get_gravity() const { - return btVector3_to_LVector3f(_body->getGravity()); + return btVector3_to_LVector3f(_rigid->getGravity()); } //////////////////////////////////////////////////////////////////// @@ -437,7 +437,7 @@ get_gravity() const { void BulletRigidBodyNode:: set_linear_factor(const LVector3f &factor) { - _body->setLinearFactor(LVecBase3f_to_btVector3(factor)); + _rigid->setLinearFactor(LVecBase3f_to_btVector3(factor)); } //////////////////////////////////////////////////////////////////// @@ -448,6 +448,6 @@ set_linear_factor(const LVector3f &factor) { void BulletRigidBodyNode:: set_angular_factor(const LVector3f &factor) { - _body->setAngularFactor(LVecBase3f_to_btVector3(factor)); + _rigid->setAngularFactor(LVecBase3f_to_btVector3(factor)); } diff --git a/panda/src/bullet/bulletRigidBodyNode.h b/panda/src/bullet/bulletRigidBodyNode.h index 5dc2699940..1935fb413e 100644 --- a/panda/src/bullet/bulletRigidBodyNode.h +++ b/panda/src/bullet/bulletRigidBodyNode.h @@ -82,28 +82,19 @@ public: virtual void output(ostream &out) const; + void sync_p2b(); + void sync_b2p(); + protected: - virtual void parents_changed(); virtual void transform_changed(); private: virtual void shape_changed(); - class MotionState : public btMotionState { + CPT(TransformState) _sync; + bool _sync_disable; - public: - MotionState(BulletRigidBodyNode *node) : _node(node) {}; - ~MotionState() {}; - - virtual void getWorldTransform(btTransform &trans) const; - virtual void setWorldTransform(const btTransform &trans); - - private: - BulletRigidBodyNode *_node; - }; - - btRigidBody *_body; - MotionState *_motion; + btRigidBody *_rigid; //////////////////////////////////////////////////////////////////// public: diff --git a/panda/src/bullet/bulletSoftBodyNode.I b/panda/src/bullet/bulletSoftBodyNode.I index 0624c1f0e8..9844afc8a6 100644 --- a/panda/src/bullet/bulletSoftBodyNode.I +++ b/panda/src/bullet/bulletSoftBodyNode.I @@ -21,7 +21,7 @@ INLINE BulletSoftBodyNode:: ~BulletSoftBodyNode() { - delete _body; + delete _soft; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/bullet/bulletSoftBodyNode.cxx b/panda/src/bullet/bulletSoftBodyNode.cxx index 5500e26dd5..b22554c5b3 100644 --- a/panda/src/bullet/bulletSoftBodyNode.cxx +++ b/panda/src/bullet/bulletSoftBodyNode.cxx @@ -32,12 +32,16 @@ TypeHandle BulletSoftBodyNode::_type_handle; BulletSoftBodyNode:: BulletSoftBodyNode(btSoftBody *body, const char *name) : BulletBodyNode(name) { - // Setup body - _body = body; - _body->setUserPointer(this); + // Synchronised transform + _sync = TransformState::make_identity(); + _sync_disable = false; + + // Softbody + _soft = body; + _soft->setUserPointer(this); // Shape - btCollisionShape *shape_ptr = _body->getCollisionShape(); + btCollisionShape *shape_ptr = _soft->getCollisionShape(); nassertv(shape_ptr != NULL); nassertv(shape_ptr->getShapeType() == SOFTBODY_SHAPE_PROXYTYPE); @@ -58,7 +62,7 @@ BulletSoftBodyNode(btSoftBody *body, const char *name) : BulletBodyNode(name) { btCollisionObject *BulletSoftBodyNode:: get_object() const { - return _body; + return _soft; } //////////////////////////////////////////////////////////////////// @@ -69,7 +73,7 @@ get_object() const { BulletSoftBodyConfig BulletSoftBodyNode:: get_cfg() { - return BulletSoftBodyConfig(_body->m_cfg); + return BulletSoftBodyConfig(_soft->m_cfg); } //////////////////////////////////////////////////////////////////// @@ -80,7 +84,7 @@ get_cfg() { BulletSoftBodyWorldInfo BulletSoftBodyNode:: get_world_info() { - return BulletSoftBodyWorldInfo(*(_body->m_worldInfo)); + return BulletSoftBodyWorldInfo(*(_soft->m_worldInfo)); } //////////////////////////////////////////////////////////////////// @@ -91,7 +95,7 @@ get_world_info() { int BulletSoftBodyNode:: get_num_materials() const { - return _body->m_materials.size(); + return _soft->m_materials.size(); } //////////////////////////////////////////////////////////////////// @@ -104,7 +108,21 @@ get_material(int idx) const { nassertr(idx >= 0 && idx < get_num_materials(), BulletSoftBodyMaterial::empty()); - btSoftBody::Material *material = _body->m_materials[idx]; + btSoftBody::Material *material = _soft->m_materials[idx]; + return BulletSoftBodyMaterial(*material); +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletSoftBodyNode::append_material +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +BulletSoftBodyMaterial BulletSoftBodyNode:: +append_material() { + + btSoftBody::Material *material = _soft->appendMaterial(); + nassertr(material, BulletSoftBodyMaterial::empty()); + return BulletSoftBodyMaterial(*material); } @@ -116,7 +134,7 @@ get_material(int idx) const { int BulletSoftBodyNode:: get_num_nodes() const { - return _body->m_nodes.size(); + return _soft->m_nodes.size(); } //////////////////////////////////////////////////////////////////// @@ -128,21 +146,7 @@ BulletSoftBodyNodeElement BulletSoftBodyNode:: get_node(int idx) const { nassertr(idx >=0 && idx < get_num_nodes(), BulletSoftBodyNodeElement::empty()); - return BulletSoftBodyNodeElement(_body->m_nodes[idx]); -} - -//////////////////////////////////////////////////////////////////// -// Function: BulletSoftBodyNode::append_material -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -BulletSoftBodyMaterial BulletSoftBodyNode:: -append_material() { - - btSoftBody::Material *material = _body->appendMaterial(); - nassertr(material, BulletSoftBodyMaterial::empty()); - - return BulletSoftBodyMaterial(*material); + return BulletSoftBodyNodeElement(_soft->m_nodes[idx]); } //////////////////////////////////////////////////////////////////// @@ -154,10 +158,10 @@ void BulletSoftBodyNode:: generate_bending_constraints(int distance, BulletSoftBodyMaterial *material) { if (material) { - _body->generateBendingConstraints(distance, &(material->get_material())); + _soft->generateBendingConstraints(distance, &(material->get_material())); } else { - _body->generateBendingConstraints(distance); + _soft->generateBendingConstraints(distance); } } @@ -169,18 +173,7 @@ generate_bending_constraints(int distance, BulletSoftBodyMaterial *material) { void BulletSoftBodyNode:: randomize_constraints() { - _body->randomizeConstraints(); -} - -//////////////////////////////////////////////////////////////////// -// Function: BulletSoftBodyNode::parents_changed -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -void BulletSoftBodyNode:: -parents_changed() { - - transform_changed(); + _soft->randomizeConstraints(); } //////////////////////////////////////////////////////////////////// @@ -191,24 +184,52 @@ parents_changed() { void BulletSoftBodyNode:: transform_changed() { - if (_disable_transform_changed) return; + if (_sync_disable) return; - btTransform trans = btTransform::getIdentity(); - get_node_transform(trans, this); - trans *= _body->m_initialWorldTransform.inverse(); - _body->transform(trans); + NodePath np = NodePath::any_path((PandaNode *)this); + CPT(TransformState) ts = np.get_net_transform(); - BulletBodyNode::transform_changed(); + LMatrix4f m_sync = _sync->get_mat(); + LMatrix4f m_ts = ts->get_mat(); + + if (!m_sync.almost_equal(m_ts)) { + _sync = ts; + + btTransform trans = TransformState_to_btTrans(ts); + + trans *= _soft->m_initialWorldTransform.inverse(); + _soft->transform(trans); + + if (ts->has_scale()) { + LVecBase3f scale = ts->get_scale(); + for (int i=0; iset_local_scale(scale); + } + } + } } //////////////////////////////////////////////////////////////////// -// Function: BulletSoftBodyNode::post_step +// Function: BulletSoftBodyNode::sync_p2b // Access: Public // Description: //////////////////////////////////////////////////////////////////// void BulletSoftBodyNode:: -post_step() { +sync_p2b() { + transform_changed(); +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletSoftBodyNode::sync_b2p +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void BulletSoftBodyNode:: +sync_b2p() { + + // Render softbody if (_geom) { btTransform trans = btTransform::getIdentity(); get_node_transform(trans, this); @@ -221,7 +242,7 @@ post_step() { GeomVertexReader flips(vdata, BulletHelper::get_sb_flip()); while (!vertices.is_at_end()) { - btSoftBody::Node node = _body->m_nodes[indices.get_data1i()]; + btSoftBody::Node node = _soft->m_nodes[indices.get_data1i()]; btVector3 v = trans.invXform(node.m_x); btVector3 n = node.m_n; @@ -233,7 +254,7 @@ post_step() { } if (_curve) { - btSoftBody::tNodeArray &nodes(_body->m_nodes); + btSoftBody::tNodeArray &nodes(_soft->m_nodes); for (int i=0; i < nodes.size(); i++) { btVector3 pos = nodes[i].m_x; @@ -242,7 +263,7 @@ post_step() { } if (_surface) { - btSoftBody::tNodeArray &nodes(_body->m_nodes); + btSoftBody::tNodeArray &nodes(_soft->m_nodes); int num_u = _surface->get_num_u_vertices(); int num_v = _surface->get_num_v_vertices(); @@ -260,11 +281,18 @@ post_step() { // set_bounds does not store the pointer - it makes a copy using // volume->make_copy(). BoundingBox bb = this->get_aabb(); - CPT(TransformState) xform = TransformState::make_pos(bb.get_approx_center()); + LVecBase3f pos = bb.get_approx_center(); - _disable_transform_changed = true; - this->set_transform(xform); - _disable_transform_changed = false; + NodePath np = NodePath::any_path((PandaNode *)this); + LVecBase3f scale = np.get_net_transform()->get_scale(); + + CPT(TransformState) ts = TransformState::make_pos(pos); + ts = ts->set_scale(scale); + + _sync = ts; + _sync_disable = true; + np.set_transform(NodePath(), ts); + _sync_disable = false; Thread *current_thread = Thread::get_current_thread(); this->r_mark_geom_bounds_stale(current_thread); @@ -289,7 +317,7 @@ get_closest_node_index(LVecBase3f point, bool local) { get_node_transform(trans, this); } - btSoftBody::tNodeArray &nodes(_body->m_nodes); + btSoftBody::tNodeArray &nodes(_soft->m_nodes); int node_idx = 0; for (int i=0; iget_vertex_data()->has_column(InternalName::get_vertex())); nassertv(geom->get_vertex_data()->has_column(InternalName::get_normal())); + sync_p2b(); + _geom = geom; PT(GeomVertexData) vdata = _geom->modify_vertex_data(); @@ -362,7 +392,7 @@ unlink_geom() { void BulletSoftBodyNode:: link_curve(NurbsCurveEvaluator *curve) { - nassertv(curve->get_num_vertices() == _body->m_nodes.size()); + nassertv(curve->get_num_vertices() == _soft->m_nodes.size()); _curve = curve; } @@ -386,7 +416,7 @@ unlink_curve() { void BulletSoftBodyNode:: link_surface(NurbsSurfaceEvaluator *surface) { - nassertv(surface->get_num_u_vertices() * surface->get_num_v_vertices() == _body->m_nodes.size()); + nassertv(surface->get_num_u_vertices() * surface->get_num_v_vertices() == _soft->m_nodes.size()); _surface = surface; } @@ -413,7 +443,7 @@ get_aabb() const { btVector3 pMin; btVector3 pMax; - _body->getAabb(pMin, pMax); + _soft->getAabb(pMin, pMax); return BoundingBox( btVector3_to_LPoint3f(pMin), @@ -429,7 +459,7 @@ get_aabb() const { void BulletSoftBodyNode:: set_volume_mass(float mass) { - _body->setVolumeMass(mass); + _soft->setVolumeMass(mass); } //////////////////////////////////////////////////////////////////// @@ -440,7 +470,7 @@ set_volume_mass(float mass) { void BulletSoftBodyNode:: set_total_mass(float mass, bool fromfaces) { - _body->setTotalMass(mass, fromfaces); + _soft->setTotalMass(mass, fromfaces); } //////////////////////////////////////////////////////////////////// @@ -451,7 +481,7 @@ set_total_mass(float mass, bool fromfaces) { void BulletSoftBodyNode:: set_volume_density(float density) { - _body->setVolumeDensity(density); + _soft->setVolumeDensity(density); } //////////////////////////////////////////////////////////////////// @@ -462,7 +492,7 @@ set_volume_density(float density) { void BulletSoftBodyNode:: set_total_density(float density) { - _body->setTotalDensity(density); + _soft->setTotalDensity(density); } //////////////////////////////////////////////////////////////////// @@ -473,7 +503,7 @@ set_total_density(float density) { void BulletSoftBodyNode:: set_mass(int node, float mass) { - _body->setMass(node, mass); + _soft->setMass(node, mass); } //////////////////////////////////////////////////////////////////// @@ -484,7 +514,7 @@ set_mass(int node, float mass) { float BulletSoftBodyNode:: get_mass(int node) const { - return _body->getMass(node); + return _soft->getMass(node); } //////////////////////////////////////////////////////////////////// @@ -495,7 +525,7 @@ get_mass(int node) const { float BulletSoftBodyNode:: get_total_mass() const { - return _body->getTotalMass(); + return _soft->getTotalMass(); } //////////////////////////////////////////////////////////////////// @@ -506,7 +536,7 @@ get_total_mass() const { float BulletSoftBodyNode:: get_volume() const { - return _body->getVolume(); + return _soft->getVolume(); } //////////////////////////////////////////////////////////////////// @@ -518,7 +548,7 @@ void BulletSoftBodyNode:: add_force(const LVector3f &force) { nassertv(!force.is_nan()); - _body->addForce(LVecBase3f_to_btVector3(force)); + _soft->addForce(LVecBase3f_to_btVector3(force)); } //////////////////////////////////////////////////////////////////// @@ -530,7 +560,7 @@ void BulletSoftBodyNode:: add_force(const LVector3f &force, int node) { nassertv(!force.is_nan()); - _body->addForce(LVecBase3f_to_btVector3(force), node); + _soft->addForce(LVecBase3f_to_btVector3(force), node); } //////////////////////////////////////////////////////////////////// @@ -542,7 +572,7 @@ void BulletSoftBodyNode:: set_velocity(const LVector3f &velocity) { nassertv(!velocity.is_nan()); - _body->setVelocity(LVecBase3f_to_btVector3(velocity)); + _soft->setVelocity(LVecBase3f_to_btVector3(velocity)); } //////////////////////////////////////////////////////////////////// @@ -554,7 +584,7 @@ void BulletSoftBodyNode:: add_velocity(const LVector3f &velocity) { nassertv(!velocity.is_nan()); - _body->addVelocity(LVecBase3f_to_btVector3(velocity)); + _soft->addVelocity(LVecBase3f_to_btVector3(velocity)); } //////////////////////////////////////////////////////////////////// @@ -566,7 +596,7 @@ void BulletSoftBodyNode:: add_velocity(const LVector3f &velocity, int node) { nassertv(!velocity.is_nan()); - _body->addVelocity(LVecBase3f_to_btVector3(velocity), node); + _soft->addVelocity(LVecBase3f_to_btVector3(velocity), node); } //////////////////////////////////////////////////////////////////// @@ -577,7 +607,7 @@ add_velocity(const LVector3f &velocity, int node) { void BulletSoftBodyNode:: generate_clusters(int k, int maxiterations) { - _body->generateClusters(k, maxiterations); + _soft->generateClusters(k, maxiterations); } //////////////////////////////////////////////////////////////////// @@ -588,7 +618,7 @@ generate_clusters(int k, int maxiterations) { void BulletSoftBodyNode:: release_clusters() { - _body->releaseClusters(); + _soft->releaseClusters(); } //////////////////////////////////////////////////////////////////// @@ -599,7 +629,7 @@ release_clusters() { void BulletSoftBodyNode:: release_cluster(int index) { - _body->releaseCluster(index); + _soft->releaseCluster(index); } //////////////////////////////////////////////////////////////////// @@ -610,7 +640,7 @@ release_cluster(int index) { int BulletSoftBodyNode:: get_num_clusters() const { - return _body->clusterCount(); + return _soft->clusterCount(); } //////////////////////////////////////////////////////////////////// @@ -621,7 +651,7 @@ get_num_clusters() const { LVecBase3f BulletSoftBodyNode:: cluster_com(int cluster) const { - return btVector3_to_LVecBase3f(_body->clusterCom(cluster)); + return btVector3_to_LVecBase3f(_soft->clusterCom(cluster)); } //////////////////////////////////////////////////////////////////// @@ -632,7 +662,7 @@ cluster_com(int cluster) const { void BulletSoftBodyNode:: set_pose(bool bvolume, bool bframe) { - _body->setPose(bvolume, bframe); + _soft->setPose(bvolume, bframe); } //////////////////////////////////////////////////////////////////// @@ -643,11 +673,13 @@ set_pose(bool bvolume, bool bframe) { void BulletSoftBodyNode:: append_anchor(int node, BulletRigidBodyNode *body, bool disable) { - nassertv(node < _body->m_nodes.size()) + nassertv(node < _soft->m_nodes.size()) nassertv(body); + body->sync_p2b(); + btRigidBody *ptr =(btRigidBody *)body->get_object(); - _body->appendAnchor(node, ptr, disable); + _soft->appendAnchor(node, ptr, disable); } //////////////////////////////////////////////////////////////////// @@ -658,12 +690,14 @@ append_anchor(int node, BulletRigidBodyNode *body, bool disable) { void BulletSoftBodyNode:: append_anchor(int node, BulletRigidBodyNode *body, const LVector3f &pivot, bool disable) { - nassertv(node < _body->m_nodes.size()) + nassertv(node < _soft->m_nodes.size()) nassertv(body); nassertv(!pivot.is_nan()); + body->sync_p2b(); + btRigidBody *ptr =(btRigidBody *)body->get_object(); - _body->appendAnchor(node, ptr, LVecBase3f_to_btVector3(pivot), disable); + _soft->appendAnchor(node, ptr, LVecBase3f_to_btVector3(pivot), disable); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/bullet/bulletSoftBodyNode.h b/panda/src/bullet/bulletSoftBodyNode.h index 649e4f5e82..41d464dd7d 100644 --- a/panda/src/bullet/bulletSoftBodyNode.h +++ b/panda/src/bullet/bulletSoftBodyNode.h @@ -188,14 +188,17 @@ PUBLISHED: public: virtual btCollisionObject *get_object() const; - void post_step(); + void sync_p2b(); + void sync_b2p(); protected: - virtual void parents_changed(); virtual void transform_changed(); private: - btSoftBody *_body; + btSoftBody *_soft; + + CPT(TransformState) _sync; + bool _sync_disable; PT(Geom) _geom; PT(NurbsCurveEvaluator) _curve; diff --git a/panda/src/bullet/bulletVehicle.cxx b/panda/src/bullet/bulletVehicle.cxx index 62a8427514..a78d58f3e0 100644 --- a/panda/src/bullet/bulletVehicle.cxx +++ b/panda/src/bullet/bulletVehicle.cxx @@ -218,12 +218,12 @@ get_wheel(int idx) const { } //////////////////////////////////////////////////////////////////// -// Function: BulletVehicle::post_step +// Function: BulletVehicle::sync_b2p // Access: Public // Description: //////////////////////////////////////////////////////////////////// void BulletVehicle:: -post_step() { +sync_b2p() { for (int i=0; i < get_num_wheels(); i++) { btWheelInfo info = _vehicle->getWheelInfo(i); diff --git a/panda/src/bullet/bulletVehicle.h b/panda/src/bullet/bulletVehicle.h index ff0415626f..f35d02ab61 100644 --- a/panda/src/bullet/bulletVehicle.h +++ b/panda/src/bullet/bulletVehicle.h @@ -91,7 +91,7 @@ PUBLISHED: public: INLINE btRaycastVehicle *get_vehicle() const; - void post_step(); + void sync_b2p(); private: btRaycastVehicle *_vehicle; diff --git a/panda/src/bullet/bulletWorld.cxx b/panda/src/bullet/bulletWorld.cxx index 50821b3a5e..0bccb85a61 100644 --- a/panda/src/bullet/bulletWorld.cxx +++ b/panda/src/bullet/bulletWorld.cxx @@ -24,7 +24,8 @@ TypeHandle BulletWorld::_type_handle; PStatCollector BulletWorld::_pstat_physics("App:Bullet:DoPhysics"); PStatCollector BulletWorld::_pstat_simulation("App:Bullet:DoPhysics:Simulation"); PStatCollector BulletWorld::_pstat_debug("App:Bullet:DoPhysics:Debug"); -PStatCollector BulletWorld::_pstat_sb("App:Bullet:DoPhysics:SoftBodies"); +PStatCollector BulletWorld::_pstat_p2b("App:Bullet:DoPhysics:SyncP2B"); +PStatCollector BulletWorld::_pstat_b2p("App:Bullet:DoPhysics:SyncB2P"); //////////////////////////////////////////////////////////////////// // Function: BulletWorld::Constructor @@ -140,49 +141,86 @@ do_physics(float dt, int substeps, float stepsize) { _pstat_physics.start(); - // Preprocess characters - for (int i=0; i < get_num_characters(); i++) { - get_character(i)->pre_step(dt); - } - - // Preprocess ghosts (autosync) - for (int i=0; i < get_num_ghosts(); i++) { - get_ghost(i)->pre_step(); - } + // Synchronize Panda to Bullet + _pstat_p2b.start(); + sync_p2b(dt); + _pstat_p2b.stop(); // Simulation _pstat_simulation.start(); _world->stepSimulation(dt, substeps, stepsize); _pstat_simulation.stop(); - // Postprocess characters - for (int i=0; i < get_num_characters(); i++) { - get_character(i)->post_step(); - } - - // Postprocess vehicles - for (int i=0; i < get_num_vehicles(); i++) { - get_vehicle(i)->post_step(); - } + // Synchronize Bullet to Panda + _pstat_b2p.start(); + sync_b2p(); + _info.m_sparsesdf.GarbageCollect(bullet_gc_lifetime); + _pstat_b2p.stop(); // Render debug - _pstat_debug.start(); if (_debug) { - _debug->post_step(_world); + _pstat_debug.start(); + _debug->sync_b2p(_world); + _pstat_debug.stop(); } - _pstat_debug.stop(); - - // Render soft bodies - _pstat_sb.start(); - for (int i=0; i < get_num_soft_bodies(); i++) { - get_soft_body(i)->post_step(); - } - _info.m_sparsesdf.GarbageCollect(bullet_gc_lifetime); - _pstat_sb.stop(); _pstat_physics.stop(); } +//////////////////////////////////////////////////////////////////// +// Function: BulletWorld::sync_p2b +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void BulletWorld:: +sync_p2b(float dt) { + + for (int i=0; i < get_num_rigid_bodies(); i++) { + get_rigid_body(i)->sync_p2b(); + } + + for (int i=0; i < get_num_soft_bodies(); i++) { + get_soft_body(i)->sync_p2b(); + } + + for (int i=0; i < get_num_ghosts(); i++) { + get_ghost(i)->sync_p2b(); + } + + for (int i=0; i < get_num_characters(); i++) { + get_character(i)->sync_p2b(dt); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletWorld::sync_b2p +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void BulletWorld:: +sync_b2p() { + + for (int i=0; i < get_num_vehicles(); i++) { + get_vehicle(i)->sync_b2p(); + } + + for (int i=0; i < get_num_rigid_bodies(); i++) { + get_rigid_body(i)->sync_b2p(); + } + + for (int i=0; i < get_num_soft_bodies(); i++) { + get_soft_body(i)->sync_b2p(); + } + + for (int i=0; i < get_num_ghosts(); i++) { + get_ghost(i)->sync_b2p(); + } + + for (int i=0; i < get_num_characters(); i++) { + get_character(i)->sync_b2p(); + } +} + //////////////////////////////////////////////////////////////////// // Function: BulletWorld::set_debug_node // Access: Published @@ -325,7 +363,7 @@ attach_ghost(BulletGhostNode *node) { // TODO group/filter settings... /* -enum CollisionFilterGroups { +enum CollisionFilterGroups { DefaultFilter = 1, StaticFilter = 2, KinematicFilter = 4, diff --git a/panda/src/bullet/bulletWorld.h b/panda/src/bullet/bulletWorld.h index 15de6f5a4d..19d3140bd9 100644 --- a/panda/src/bullet/bulletWorld.h +++ b/panda/src/bullet/bulletWorld.h @@ -151,6 +151,9 @@ public: INLINE btDispatcher *get_dispatcher() const; private: + void sync_p2b(float dt); + void sync_b2p(); + typedef PTA(PT(BulletRigidBodyNode)) BulletRigidBodies; typedef PTA(PT(BulletSoftBodyNode)) BulletSoftBodies; typedef PTA(PT(BulletGhostNode)) BulletGhosts; @@ -161,7 +164,8 @@ private: static PStatCollector _pstat_physics; static PStatCollector _pstat_simulation; static PStatCollector _pstat_debug; - static PStatCollector _pstat_sb; + static PStatCollector _pstat_p2b; + static PStatCollector _pstat_b2p; struct btFilterCallback : public btOverlapFilterCallback { virtual bool needBroadphaseCollision(