From eaabf1a2c8a46cef7028a8dc2ea0627fab740f4b Mon Sep 17 00:00:00 2001 From: "erwin.coumans" Date: Fri, 5 Oct 2012 21:15:11 +0000 Subject: [PATCH] Expose btManifoldResult::calculateCombinedRestitution and btManifoldResult::calculateCombinedFriction as static member functions, so it can be reused for speculative contacts Add speculative contact restitution, but disabled by default, not well tested (btDiscreteDynamicsWorld::setApplySpeculativeContactRestitution) Add --with-double-precision option to premake build system --- build/premake4.lua | 10 ++++ .../CollisionDispatch/btManifoldResult.cpp | 4 +- .../CollisionDispatch/btManifoldResult.h | 5 +- .../Dynamics/btDiscreteDynamicsWorld.cpp | 51 ++++++++++++++++--- .../Dynamics/btDiscreteDynamicsWorld.h | 11 ++++ 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/build/premake4.lua b/build/premake4.lua index 6436d8035..ed80bb589 100644 --- a/build/premake4.lua +++ b/build/premake4.lua @@ -13,6 +13,12 @@ solution "0BulletSolution" description = "Disable demos and extras" } + newoption { + trigger = "with-double-precision", + description = "Enable double precision build" + } + + newoption { trigger = "with-nacl", description = "Enable Native Client build" @@ -59,6 +65,10 @@ solution "0BulletSolution" postfix=""; + if _OPTIONS["with-double-precision"] then + defines {"BT_USE_DOUBLE_PRECISION"} + end + if _ACTION == "xcode4" then if _OPTIONS["ios"] then postfix = "ios"; diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp index 88f4a3f20..4b2986a00 100644 --- a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp +++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp @@ -40,7 +40,7 @@ inline btScalar calculateCombinedRollingFriction(const btCollisionObject* body0, ///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; -inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1) { btScalar friction = body0->getFriction() * body1->getFriction(); @@ -53,7 +53,7 @@ inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const b } -inline btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1) { return body0->getRestitution() * body1->getRestitution(); } diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/src/BulletCollision/CollisionDispatch/btManifoldResult.h index ec45524e9..977b9a02f 100644 --- a/src/BulletCollision/CollisionDispatch/btManifoldResult.h +++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.h @@ -141,7 +141,10 @@ public: { return m_body1Wrap->getCollisionObject(); } - + + /// in the future we can let the user override the methods to combine restitution and friction + static btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1); + static btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1); }; #endif //BT_MANIFOLD_RESULT_H diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index 58f83b9eb..bbb114144 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -209,6 +209,7 @@ m_constraintSolver(constraintSolver), m_gravity(0,-10,0), m_localTime(0), m_synchronizeAllMotionStates(false), +m_applySpeculativeContactRestitution(false) m_profileTimings(0) { @@ -486,7 +487,6 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) ///perform collision detection performDiscreteCollisionDetection(); - calculateSimulationIslands(); @@ -962,6 +962,8 @@ void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep) bool isPredictive = true; int index = manifold->addManifoldPoint(newPoint, isPredictive); btManifoldPoint& pt = manifold->getContactPoint(index); + pt.m_combinedRestitution = 0; + pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject); pt.m_positionWorldOnA = body->getWorldTransform().getOrigin(); pt.m_positionWorldOnB = worldPointB; @@ -1055,11 +1057,12 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) printf("sm2=%f\n",sm2); } #else - //response between two dynamic objects without friction, assuming 0 penetration depth - btScalar appliedImpulse = 0.f; - btScalar depth = 0.f; - - appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); + + //don't apply the collision response right now, it will happen next frame + //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution. + //btScalar appliedImpulse = 0.f; + //btScalar depth = 0.f; + //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); #endif @@ -1075,6 +1078,42 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) } } + + ///this should probably be switched on by default, but it is not well tested yet + if (m_applySpeculativeContactRestitution) + { + BT_PROFILE("apply speculative contact restitution"); + for (int i=0;igetBody0()); + btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1()); + + for (int p=0;pgetNumContacts();p++) + { + const btManifoldPoint& pt = manifold->getContactPoint(p); + btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1); + + if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f) + //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f) + { + btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution; + + const btVector3& pos1 = pt.getPositionWorldOnA(); + const btVector3& pos2 = pt.getPositionWorldOnB(); + + btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin(); + btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin(); + + if (body0) + body0->applyImpulse(imp,rel_pos0); + if (body1) + body1->applyImpulse(-imp,rel_pos1); + } + } + } + } + } diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h index 9875a915b..fa934c49d 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -58,6 +58,7 @@ protected: bool m_ownsIslandManager; bool m_ownsConstraintSolver; bool m_synchronizeAllMotionStates; + bool m_applySpeculativeContactRestitution; btAlignedObjectArray m_actions; @@ -202,6 +203,16 @@ public: return m_synchronizeAllMotionStates; } + void setApplySpeculativeContactRestitution(bool enable) + { + m_applySpeculativeContactRestitution = enable; + } + + bool getApplySpeculativeContactRestitution() const + { + return m_applySpeculativeContactRestitution; + } + ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo) virtual void serialize(btSerializer* serializer);