From 8c56528a79ed8284b591d794a596924611d0bb7f Mon Sep 17 00:00:00 2001 From: "erwin.coumans" Date: Tue, 11 Sep 2012 03:12:32 +0000 Subject: [PATCH] Avoid using restitution for ccd motion clamping. Restitution for fast moving objects should be handled by btDiscreteDynamicsWorld::createPredictiveContacts (make sure to merge islands based on those predictive contacts too, added some check in the solver) This fixes Issue 356. Use same solver settings for AllBulletDemos Make sure to embed the setCcdSweptSphereRadius inside the actual collision shape (for shoot box) --- Demos/AllBulletDemos/Main.cpp | 6 ++-- Demos/OpenGL/DemoApplication.cpp | 8 ++--- .../ConstraintSolver/btContactConstraint.cpp | 4 +-- .../btSequentialImpulseConstraintSolver.cpp | 33 +++++++++++++++++++ .../Dynamics/btDiscreteDynamicsWorld.cpp | 27 +++++++++++++-- 5 files changed, 67 insertions(+), 11 deletions(-) diff --git a/Demos/AllBulletDemos/Main.cpp b/Demos/AllBulletDemos/Main.cpp index cec0ff1c0..c59e18d3b 100644 --- a/Demos/AllBulletDemos/Main.cpp +++ b/Demos/AllBulletDemos/Main.cpp @@ -100,12 +100,12 @@ void setDefaultSettings() gDrawClusters=0; gDebugNoDeactivation = 0; - gUseSplitImpulse = 0; + gUseSplitImpulse = 1; gUseWarmstarting = 1; - gRandomizeConstraints = 1; + gRandomizeConstraints = 0; gErp = 0.2f; gSlop=0.0f; - gErp2 = 0.1f; + gErp2 = 0.81f; gWarmStartingParameter = 0.85f; } diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp index 18d8b21ff..d72dc3049 100644 --- a/Demos/OpenGL/DemoApplication.cpp +++ b/Demos/OpenGL/DemoApplication.cpp @@ -534,8 +534,8 @@ void DemoApplication::setShootBoxShape () { if (!m_shootBoxShape) { - btBoxShape* box = new btBoxShape(btVector3(.15f,.15f,.15f)); - box->initializePolyhedralFeatures(); + btBoxShape* box = new btBoxShape(btVector3(0.5,0.5,0.5)); + box->initializePolyhedralFeatures(); m_shootBoxShape = box; } } @@ -565,8 +565,8 @@ void DemoApplication::shootBox(const btVector3& destination) body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); body->setLinearVelocity(linVel); body->setAngularVelocity(btVector3(0,0,0)); - body->setCcdMotionThreshold(0.1); - body->setCcdSweptSphereRadius(0.1f); + body->setCcdMotionThreshold(0.5); + body->setCcdSweptSphereRadius(0.4f);//value should be smaller (embedded) than the half extends of the box (see ::setShootBoxShape) // printf("shootBox uid=%d\n", body->getBroadphaseHandle()->getUid()); // printf("camPos=%f,%f,%f\n",camPos.getX(),camPos.getY(),camPos.getZ()); // printf("destination=%f,%f,%f\n",destination.getX(),destination.getY(),destination.getZ()); diff --git a/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp index 888591829..9d60d9957 100644 --- a/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp @@ -70,7 +70,7 @@ void btContactConstraint::buildJacobian() -//response between two dynamic objects without friction, assuming 0 penetration depth +//response between two dynamic objects without friction and no restitution, assuming 0 penetration depth btScalar resolveSingleCollision( btRigidBody* body1, btCollisionObject* colObj2, @@ -93,7 +93,7 @@ btScalar resolveSingleCollision( btScalar rel_vel; rel_vel = normal.dot(vel); - btScalar combinedRestitution = body1->getRestitution() * colObj2->getRestitution(); + btScalar combinedRestitution = 0.f; btScalar restitution = combinedRestitution* -rel_vel; btScalar positionalError = solverInfo.m_erp *-distance /solverInfo.m_timeStep ; diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index 7090e8f4e..8a0042aef 100644 --- a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -781,6 +781,39 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol m_maxOverrideNumSolverIterations = 0; +#ifdef BT_DEBUG + //make sure that dynamic bodies exist for all contact manifolds + for (int i=0;igetBody0()->isStaticOrKinematicObject()) + { + bool found=false; + for (int b=0;bgetBody0()==bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject()) + { + bool found=false; + for (int b=0;bgetBody1()==bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + } +#endif //BT_DEBUG for (int i = 0; i < numBodies; i++) diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index b7a32edc0..bd6c74b28 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -481,10 +481,11 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) dispatchInfo.m_debugDraw = getDebugDrawer(); + createPredictiveContacts(timeStep); + ///perform collision detection performDiscreteCollisionDetection(); - createPredictiveContacts(timeStep); calculateSimulationIslands(); @@ -733,6 +734,28 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands() getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); + { + //merge islands based on speculative contact manifolds too + for (int i=0;im_predictiveManifolds.size();i++) + { + btPersistentManifold* manifold = m_predictiveManifolds[i]; + + const btCollisionObject* colObj0 = manifold->getBody0(); + const btCollisionObject* colObj1 = manifold->getBody1(); + + if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && + ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) + { + if (colObj0->isActive() || colObj1->isActive()) + { + + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), + (colObj1)->getIslandTag()); + } + } + } + } + { int i; int numConstraints = int(m_constraints.size()); @@ -912,7 +935,7 @@ void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep) btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); #endif //btConvexShape* convexShape = static_cast(body->getCollisionShape()); - btSphereShape tmpSphere(0.1);//body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast(body->getCollisionShape()); + btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast(body->getCollisionShape()); sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;