I have read the other posts about making Bullet deterministic. While there were great suggestions, still I can not make it work.
So far I have avoided destroying and recreating the world, due to its high computational cost and the complexity of the code. Instead, I have tried the following and got slightly better deterministic behavior, but not fully there. The following is mostly taken from Bullet own reset function.
Code: Select all
void PhysicsMediator::reset()
{
if (m_dynamicsWorld)
{
numObjects = m_dynamicsWorld->getNumCollisionObjects();
///create a copy of the array, not a reference!
btCollisionObjectArray copyArray = m_dynamicsWorld->getCollisionObjectArray();
for (i = 0;i < numObjects;i++)
{
btCollisionObject* colObj = copyArray[i];
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
if (body->getMotionState())
{
btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
myMotionState->m_graphicsWorldTrans = myMotionState->m_startWorldTrans;
body->setCenterOfMassTransform(myMotionState->m_graphicsWorldTrans);
colObj->setInterpolationWorldTransform(myMotionState->m_startWorldTrans);
colObj->forceActivationState(ACTIVE_TAG);
colObj->activate();
colObj->setActivationState(DISABLE_DEACTIVATION);
colObj->setDeactivationTime(btScalar(2e7));
}
//removed cached contact points (this is not necessary if all objects have been removed from the dynamics world)
m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle(),m_dynamicsWorld->getDispatcher());
btRigidBody* body = btRigidBody::upcast(colObj);
if (body && !body->isStaticObject())
{
btRigidBody::upcast(colObj)->setLinearVelocity(btVector3(0, 0, 0));
btRigidBody::upcast(colObj)->setAngularVelocity(btVector3(0, 0, 0));
btRigidBody::upcast(colObj)->clearForces();
}
}
}
///reset some internal cached data in the broad phase
m_dynamicsWorld->getBroadphase()->resetPool(m_dynamicsWorld->getDispatcher());
m_dynamicsWorld->getConstraintSolver()->reset();
}
}
Thanks
Shahin