diff --git a/ChangeLog.txt b/ChangeLog.txt index 4b8c94b83..0da02867c 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,12 @@ Bullet Continuous Collision Detection and Physics Library Erwin Coumans +2007 March 17 + - Added constraint solver optimizations, avoiding cross products during iterations, and gather rigidbody/constraint info in contiguous memory (btSolverBody/btSolverConstraint) + - These optimizations don't give large benefit yet, but it has good potential. Turned on by default. Can be switched off using solver->setSolverMode(SOLVER_RANDMIZE_ORDER). + - Enabled anti-jitter for rigid bodies. This is experimental, and can be switched off by setting a global (it is experimental so no proper interface) gJitterVelocityDampingFactor = 1.0; + - Fixed bug in islandmanifold.heapSort(btPersistentManifoldSortPredicate()); , thanks Noehrgel for reporting this (affected Sun Solaris) + 2007 March 12 - Added compile-time toggle between on 16-bit and 32-bit fixed-point SAP broadphase. This allows the number of bodies to exceed 32767 diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp index 52067d94e..c4f0cad78 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp @@ -252,6 +252,11 @@ void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) extern int gOverlappingPairs; + +void btAxisSweep3::refreshOverlappingPairs() +{ + +} void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) { @@ -269,6 +274,8 @@ void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair); m_invalidPair = 0; #endif + + int i; btBroadphasePair previousPair; diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h index 270b2c88a..28d6a1fa0 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h @@ -112,10 +112,7 @@ public: btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384); virtual ~btAxisSweep3(); - virtual void refreshOverlappingPairs() - { - //this is performed incrementally by sweep and prune (add pair), and during pair traversal (remove pair) - } + virtual void refreshOverlappingPairs(); BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask); void removeHandle(BP_FP_INT_TYPE handle); diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index 57becfd85..49f35c2cc 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -119,7 +119,7 @@ void btCollisionWorld::performDiscreteCollisionDetection() { btDispatcherInfo& dispatchInfo = getDispatchInfo(); - BEGIN_PROFILE("performDiscreteCollisionDetection"); + BEGIN_PROFILE("perform Broadphase Collision Detection"); //update aabb (of all moved objects) @@ -133,6 +133,11 @@ void btCollisionWorld::performDiscreteCollisionDetection() m_broadphasePairCache->refreshOverlappingPairs(); + + END_PROFILE("perform Broadphase Collision Detection"); + + BEGIN_PROFILE("performDiscreteCollisionDetection"); + btDispatcher* dispatcher = getDispatcher(); if (dispatcher) dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo); diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index 95100e9ed..8e1382a1c 100644 --- a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -46,8 +46,12 @@ struct btOrderIndex short int m_pointIndex; }; + + #define SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS 16384 static btOrderIndex gOrder[SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS]; + + static unsigned long btSeed2 = 0; unsigned long btRand2() { @@ -111,7 +115,7 @@ bool MyContactDestroyedCallback(void* userPersistentData) btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver() -:m_solverMode(SOLVER_RANDMIZE_ORDER)//SOLVER_USE_WARMSTARTING)//SOLVER_RANDMIZE_ORDER) //not using SOLVER_USE_WARMSTARTING +:m_solverMode(SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY) //not using SOLVER_USE_WARMSTARTING { gContactDestroyedCallback = &MyContactDestroyedCallback; @@ -138,7 +142,7 @@ void initSolverBody(btSolverBody* solverBody, btRigidBody* rigidbody) solverBody->m_angularVelocity = rigidbody->getAngularVelocity(); solverBody->m_centerOfMassPosition = rigidbody->getCenterOfMassPosition(); solverBody->m_friction = rigidbody->getFriction(); - solverBody->m_invInertiaWorld = rigidbody->getInvInertiaTensorWorld(); +// solverBody->m_invInertiaWorld = rigidbody->getInvInertiaTensorWorld(); solverBody->m_invMass = rigidbody->getInvMass(); solverBody->m_linearVelocity = rigidbody->getLinearVelocity(); solverBody->m_originalBody = rigidbody; @@ -342,12 +346,29 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio { if (!(numConstraints + numManifolds)) + { +// printf("empty\n"); return 0.f; + } + + BEGIN_PROFILE("refreshManifolds"); + + int i; + for (i=0;igetBody0(); + btRigidBody* rb1 = (btRigidBody*)manifold->getBody1(); + + manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); + + } + + END_PROFILE("refreshManifolds"); + BEGIN_PROFILE("gatherSolverData"); - - int sizeofSB = sizeof(btSolverBody); int sizeofSC = sizeof(btSolverConstraint); @@ -362,7 +383,10 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio // unsigned char* stackMemory = stackAlloc->allocate(memsize); - tmpSolverBodyPool.reserve(numManifolds*2); + //todo: use stack allocator for this temp memory + int minReservation = numManifolds*2; + + tmpSolverBodyPool.reserve(minReservation); { for (int i=0;igetBody0(); btRigidBody* rb1 = (btRigidBody*)manifold->getBody1(); - manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); - + int solverBodyIdA; int solverBodyIdB; @@ -591,6 +614,30 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio } } + btAlignedObjectArray gOrderTmpConstraintPool; + btAlignedObjectArray gOrderFrictionConstraintPool; + + int numConstraintPool = tmpSolverConstraintPool.size(); + int numFrictionPool = tmpSolverFrictionConstraintPool.size(); + + ///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints + gOrderTmpConstraintPool.resize(numConstraintPool); + gOrderFrictionConstraintPool.resize(numFrictionPool); + { + int i; + for (i=0;igetRigidBodyA().getIslandTag() >= 0) + { + tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity(); + } + if (constraint->getRigidBodyB().getIslandTag() >= 0) + { + tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity(); + } + constraint->solveConstraint(info.m_timeStep); + + if (constraint->getRigidBodyA().getIslandTag() >= 0) + { + tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity(); + } + if (constraint->getRigidBodyB().getIslandTag() >= 0) + { + tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity(); + } + } { int numPoolConstraints = tmpSolverConstraintPool.size(); for (j=0;jgetLinearVelocity(); + m_angularVelocity = m_originalBody->getAngularVelocity(); + } + } + + + inline void applyImpulse(const btVector3& impulse,const btVector3& rel_pos) { if (m_invMass) { m_linearVelocity += impulse * m_invMass; btVector3 torqueImpulse = rel_pos.cross(impulse); - m_angularVelocity += m_invInertiaWorld * torqueImpulse; +// m_angularVelocity += m_invInertiaWorld * torqueImpulse; } } diff --git a/src/BulletDynamics/ConstraintSolver/btsolverconstraint.h b/src/BulletDynamics/ConstraintSolver/btsolverconstraint.h index 01e11f0a5..8e651bf5e 100644 --- a/src/BulletDynamics/ConstraintSolver/btsolverconstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btsolverconstraint.h @@ -44,7 +44,7 @@ ATTRIBUTE_ALIGNED16 (struct btSolverConstraint) int m_constraintType; int m_frictionIndex; - int m_unusedPadding[2]; +// int m_unusedPadding[2]; enum btSolverConstraintType { diff --git a/src/BulletDynamics/Dynamics/btRigidBody.cpp b/src/BulletDynamics/Dynamics/btRigidBody.cpp index d8808cd12..8a3c7f58a 100644 --- a/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -112,7 +112,7 @@ btRigidBody::btRigidBody( btScalar mass,const btTransform& worldTransform,btColl -//#define EXPERIMENTAL_JITTER_REMOVAL 1 +#define EXPERIMENTAL_JITTER_REMOVAL 1 #ifdef EXPERIMENTAL_JITTER_REMOVAL //Bullet 2.20b has experimental damping code to reduce jitter just before objects fall asleep/deactivate //doesn't work very well yet (value 0 disabled this damping) @@ -121,7 +121,7 @@ btScalar gClippedAngvelThresholdSqr = btScalar(0.01); btScalar gClippedLinearThresholdSqr = btScalar(0.01); #endif //EXPERIMENTAL_JITTER_REMOVAL -btScalar gJitterVelocityDampingFactor = btScalar(0.9); +btScalar gJitterVelocityDampingFactor = btScalar(0.7); void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) {