2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
5
This software is provided 'as-is', without any express or implied warranty.
6
In no event will the authors be held liable for any damages arising from the use of this software.
7
Permission is granted to anyone to use this software for any purpose,
8
including commercial applications, and to alter it and redistribute it freely,
9
subject to the following restrictions:
11
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
3. This notice may not be removed or altered from any source distribution.
17
#include "btDiscreteDynamicsWorld.h"
20
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
21
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
22
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
23
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
24
#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
25
#include "LinearMath/btTransformUtil.h"
26
#include "LinearMath/btQuickprof.h"
28
//rigidbody & constraints
29
#include "BulletDynamics/Dynamics/btRigidBody.h"
30
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
31
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
32
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
33
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
34
#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
35
#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
36
#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
37
#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
38
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
41
#include "LinearMath/btIDebugDraw.h"
42
#include "BulletCollision/CollisionShapes/btSphereShape.h"
45
#include "BulletDynamics/Dynamics/btActionInterface.h"
46
#include "LinearMath/btQuickprof.h"
47
#include "LinearMath/btMotionState.h"
49
#include "LinearMath/btSerializer.h"
52
btAlignedObjectArray<btVector3> debugContacts;
53
btAlignedObjectArray<btVector3> debugNormals;
55
int firstHit=startHit;
60
btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
61
:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
62
m_constraintSolver(constraintSolver),
65
m_synchronizeAllMotionStates(false),
68
if (!m_constraintSolver)
70
void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16);
71
m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver;
72
m_ownsConstraintSolver = true;
75
m_ownsConstraintSolver = false;
79
void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16);
80
m_islandManager = new (mem) btSimulationIslandManager();
83
m_ownsIslandManager = true;
87
btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld()
89
//only delete it when we created it
90
if (m_ownsIslandManager)
92
m_islandManager->~btSimulationIslandManager();
93
btAlignedFree( m_islandManager);
95
if (m_ownsConstraintSolver)
98
m_constraintSolver->~btConstraintSolver();
99
btAlignedFree(m_constraintSolver);
103
void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
105
///would like to iterate over m_nonStaticRigidBodies, but unfortunately old API allows
106
///to switch status _after_ adding kinematic objects to the world
107
///fix it for Bullet 3.x release
108
for (int i=0;i<m_collisionObjects.size();i++)
110
btCollisionObject* colObj = m_collisionObjects[i];
111
btRigidBody* body = btRigidBody::upcast(colObj);
112
if (body && body->getActivationState() != ISLAND_SLEEPING)
114
if (body->isKinematicObject())
116
//to calculate velocities next frame
117
body->saveKinematicState(timeStep);
124
void btDiscreteDynamicsWorld::debugDrawWorld()
126
BT_PROFILE("debugDrawWorld");
128
btCollisionWorld::debugDrawWorld();
130
bool drawConstraints = false;
131
if (getDebugDrawer())
133
int mode = getDebugDrawer()->getDebugMode();
134
if(mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits))
136
drawConstraints = true;
141
for(int i = getNumConstraints()-1; i>=0 ;i--)
143
btTypedConstraint* constraint = getConstraint(i);
144
debugDrawConstraint(constraint);
150
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
154
if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
156
for (i=0;i<m_actions.size();i++)
158
m_actions[i]->debugDraw(m_debugDrawer);
164
void btDiscreteDynamicsWorld::clearForces()
166
///@todo: iterate over awake simulation islands!
167
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
169
btRigidBody* body = m_nonStaticRigidBodies[i];
170
//need to check if next line is ok
171
//it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up
176
///apply gravity, call this once per timestep
177
void btDiscreteDynamicsWorld::applyGravity()
179
///@todo: iterate over awake simulation islands!
180
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
182
btRigidBody* body = m_nonStaticRigidBodies[i];
183
if (body->isActive())
185
body->applyGravity();
191
void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body)
195
if (body->getMotionState() && !body->isStaticOrKinematicObject())
197
//we need to call the update at least once, even for sleeping objects
198
//otherwise the 'graphics' transform never updates properly
199
///@todo: add 'dirty' flag
200
//if (body->getActivationState() != ISLAND_SLEEPING)
202
btTransform interpolatedTransform;
203
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
204
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
205
body->getMotionState()->setWorldTransform(interpolatedTransform);
211
void btDiscreteDynamicsWorld::synchronizeMotionStates()
213
BT_PROFILE("synchronizeMotionStates");
214
if (m_synchronizeAllMotionStates)
216
//iterate over all collision objects
217
for ( int i=0;i<m_collisionObjects.size();i++)
219
btCollisionObject* colObj = m_collisionObjects[i];
220
btRigidBody* body = btRigidBody::upcast(colObj);
222
synchronizeSingleMotionState(body);
226
//iterate over all active rigid bodies
227
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
229
btRigidBody* body = m_nonStaticRigidBodies[i];
230
if (body->isActive())
231
synchronizeSingleMotionState(body);
237
int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
239
startProfiling(timeStep);
241
BT_PROFILE("stepSimulation");
243
int numSimulationSubSteps = 0;
247
//fixed timestep with interpolation
248
m_localTime += timeStep;
249
if (m_localTime >= fixedTimeStep)
251
numSimulationSubSteps = int( m_localTime / fixedTimeStep);
252
m_localTime -= numSimulationSubSteps * fixedTimeStep;
257
fixedTimeStep = timeStep;
258
m_localTime = timeStep;
259
if (btFuzzyZero(timeStep))
261
numSimulationSubSteps = 0;
265
numSimulationSubSteps = 1;
270
//process some debugging flags
271
if (getDebugDrawer())
273
btIDebugDraw* debugDrawer = getDebugDrawer ();
274
gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
276
if (numSimulationSubSteps)
279
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
280
int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
282
saveKinematicState(fixedTimeStep*clampedSimulationSteps);
288
for (int i=0;i<clampedSimulationSteps;i++)
290
internalSingleStepSimulation(fixedTimeStep);
291
synchronizeMotionStates();
296
synchronizeMotionStates();
301
#ifndef BT_NO_PROFILE
302
CProfileManager::Increment_Frame_Counter();
303
#endif //BT_NO_PROFILE
305
return numSimulationSubSteps;
308
void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
311
BT_PROFILE("internalSingleStepSimulation");
313
if(0 != m_internalPreTickCallback) {
314
(*m_internalPreTickCallback)(this, timeStep);
317
///apply gravity, predict motion
318
predictUnconstraintMotion(timeStep);
320
btDispatcherInfo& dispatchInfo = getDispatchInfo();
322
dispatchInfo.m_timeStep = timeStep;
323
dispatchInfo.m_stepCount = 0;
324
dispatchInfo.m_debugDraw = getDebugDrawer();
327
///perform collision detection
328
performDiscreteCollisionDetection();
330
if (getDispatchInfo().m_useContinuous)
331
addSpeculativeContacts(timeStep);
334
calculateSimulationIslands();
337
getSolverInfo().m_timeStep = timeStep;
341
///solve contact and other joint constraints
342
solveConstraints(getSolverInfo());
344
///CallbackTriggers();
346
///integrate transforms
347
integrateTransforms(timeStep);
349
///update vehicle simulation
350
updateActions(timeStep);
352
updateActivationState( timeStep );
354
if(0 != m_internalTickCallback) {
355
(*m_internalTickCallback)(this, timeStep);
359
void btDiscreteDynamicsWorld::setGravity(const btVector3& gravity)
362
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
364
btRigidBody* body = m_nonStaticRigidBodies[i];
365
if (body->isActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
367
body->setGravity(gravity);
372
btVector3 btDiscreteDynamicsWorld::getGravity () const
377
void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
379
btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask);
382
void btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
384
btRigidBody* body = btRigidBody::upcast(collisionObject);
386
removeRigidBody(body);
388
btCollisionWorld::removeCollisionObject(collisionObject);
391
void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
393
m_nonStaticRigidBodies.remove(body);
394
btCollisionWorld::removeCollisionObject(body);
398
void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body)
400
if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
402
body->setGravity(m_gravity);
405
if (body->getCollisionShape())
407
if (!body->isStaticObject())
409
m_nonStaticRigidBodies.push_back(body);
412
body->setActivationState(ISLAND_SLEEPING);
415
bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
416
short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
417
short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
419
addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
423
void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
425
if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
427
body->setGravity(m_gravity);
430
if (body->getCollisionShape())
432
if (!body->isStaticObject())
434
m_nonStaticRigidBodies.push_back(body);
438
body->setActivationState(ISLAND_SLEEPING);
440
addCollisionObject(body,group,mask);
445
void btDiscreteDynamicsWorld::updateActions(btScalar timeStep)
447
BT_PROFILE("updateActions");
449
for ( int i=0;i<m_actions.size();i++)
451
m_actions[i]->updateAction( this, timeStep);
456
void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
458
BT_PROFILE("updateActivationState");
460
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
462
btRigidBody* body = m_nonStaticRigidBodies[i];
465
body->updateDeactivation(timeStep);
467
if (body->wantsSleeping())
469
if (body->isStaticOrKinematicObject())
471
body->setActivationState(ISLAND_SLEEPING);
474
if (body->getActivationState() == ACTIVE_TAG)
475
body->setActivationState( WANTS_DEACTIVATION );
476
if (body->getActivationState() == ISLAND_SLEEPING)
478
body->setAngularVelocity(btVector3(0,0,0));
479
body->setLinearVelocity(btVector3(0,0,0));
485
if (body->getActivationState() != DISABLE_DEACTIVATION)
486
body->setActivationState( ACTIVE_TAG );
492
void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
494
m_constraints.push_back(constraint);
495
if (disableCollisionsBetweenLinkedBodies)
497
constraint->getRigidBodyA().addConstraintRef(constraint);
498
constraint->getRigidBodyB().addConstraintRef(constraint);
502
void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
504
m_constraints.remove(constraint);
505
constraint->getRigidBodyA().removeConstraintRef(constraint);
506
constraint->getRigidBodyB().removeConstraintRef(constraint);
509
void btDiscreteDynamicsWorld::addAction(btActionInterface* action)
511
m_actions.push_back(action);
514
void btDiscreteDynamicsWorld::removeAction(btActionInterface* action)
516
m_actions.remove(action);
520
void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle)
525
void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle)
527
removeAction(vehicle);
530
void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character)
532
addAction(character);
535
void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character)
537
removeAction(character);
541
SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs)
545
const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
546
const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
547
islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag();
553
class btSortConstraintOnIslandPredicate
557
bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs )
559
int rIslandId0,lIslandId0;
560
rIslandId0 = btGetConstraintIslandId(rhs);
561
lIslandId0 = btGetConstraintIslandId(lhs);
562
return lIslandId0 < rIslandId0;
568
void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
570
BT_PROFILE("solveConstraints");
572
struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
575
btContactSolverInfo& m_solverInfo;
576
btConstraintSolver* m_solver;
577
btTypedConstraint** m_sortedConstraints;
578
int m_numConstraints;
579
btIDebugDraw* m_debugDrawer;
580
btStackAlloc* m_stackAlloc;
581
btDispatcher* m_dispatcher;
583
btAlignedObjectArray<btCollisionObject*> m_bodies;
584
btAlignedObjectArray<btPersistentManifold*> m_manifolds;
585
btAlignedObjectArray<btTypedConstraint*> m_constraints;
588
InplaceSolverIslandCallback(
589
btContactSolverInfo& solverInfo,
590
btConstraintSolver* solver,
591
btTypedConstraint** sortedConstraints,
593
btIDebugDraw* debugDrawer,
594
btStackAlloc* stackAlloc,
595
btDispatcher* dispatcher)
596
:m_solverInfo(solverInfo),
598
m_sortedConstraints(sortedConstraints),
599
m_numConstraints(numConstraints),
600
m_debugDrawer(debugDrawer),
601
m_stackAlloc(stackAlloc),
602
m_dispatcher(dispatcher)
608
InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other)
614
virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId)
618
if (numManifolds + m_numConstraints)
620
///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
621
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
625
//also add all non-contact constraints/joints for this island
626
btTypedConstraint** startConstraint = 0;
627
int numCurConstraints = 0;
630
//find the first constraint for this island
631
for (i=0;i<m_numConstraints;i++)
633
if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
635
startConstraint = &m_sortedConstraints[i];
639
//count the number of constraints in this island
640
for (;i<m_numConstraints;i++)
642
if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
648
if (m_solverInfo.m_minimumSolverBatchSize<=1)
650
///only call solveGroup if there is some work: avoid virtual function call, its overhead can be excessive
651
if (numManifolds + numCurConstraints)
653
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
658
for (i=0;i<numBodies;i++)
659
m_bodies.push_back(bodies[i]);
660
for (i=0;i<numManifolds;i++)
661
m_manifolds.push_back(manifolds[i]);
662
for (i=0;i<numCurConstraints;i++)
663
m_constraints.push_back(startConstraint[i]);
664
if ((m_constraints.size()+m_manifolds.size())>m_solverInfo.m_minimumSolverBatchSize)
666
processConstraints();
669
//printf("deferred\n");
674
void processConstraints()
676
if (m_manifolds.size() + m_constraints.size()>0)
678
m_solver->solveGroup( &m_bodies[0],m_bodies.size(), &m_manifolds[0], m_manifolds.size(), &m_constraints[0], m_constraints.size() ,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
681
m_manifolds.resize(0);
682
m_constraints.resize(0);
690
//sorted version of all btTypedConstraint, based on islandId
691
btAlignedObjectArray<btTypedConstraint*> sortedConstraints;
692
sortedConstraints.resize( m_constraints.size());
694
for (i=0;i<getNumConstraints();i++)
696
sortedConstraints[i] = m_constraints[i];
703
sortedConstraints.quickSort(btSortConstraintOnIslandPredicate());
705
btTypedConstraint** constraintsPtr = getNumConstraints() ? &sortedConstraints[0] : 0;
707
InplaceSolverIslandCallback solverCallback( solverInfo, m_constraintSolver, constraintsPtr,sortedConstraints.size(), m_debugDrawer,m_stackAlloc,m_dispatcher1);
709
m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
711
/// solve all the constraints for this island
712
m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
714
solverCallback.processConstraints();
716
m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
722
void btDiscreteDynamicsWorld::calculateSimulationIslands()
724
BT_PROFILE("calculateSimulationIslands");
726
getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher());
730
int numConstraints = int(m_constraints.size());
731
for (i=0;i< numConstraints ; i++ )
733
btTypedConstraint* constraint = m_constraints[i];
735
const btRigidBody* colObj0 = &constraint->getRigidBodyA();
736
const btRigidBody* colObj1 = &constraint->getRigidBodyB();
738
if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
739
((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
741
if (colObj0->isActive() || colObj1->isActive())
744
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),
745
(colObj1)->getIslandTag());
751
//Store the island id in each body
752
getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld());
760
class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
764
btCollisionObject* m_me;
765
btScalar m_allowedPenetration;
766
btOverlappingPairCache* m_pairCache;
767
btDispatcher* m_dispatcher;
770
btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
771
btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
773
m_allowedPenetration(0.0f),
774
m_pairCache(pairCache),
775
m_dispatcher(dispatcher)
779
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
781
if (convexResult.m_hitCollisionObject == m_me)
784
//ignore result if there is no contact response
785
if(!convexResult.m_hitCollisionObject->hasContactResponse())
788
btVector3 linVelA,linVelB;
789
linVelA = m_convexToWorld-m_convexFromWorld;
790
linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin();
792
btVector3 relativeVelocity = (linVelA-linVelB);
793
//don't report time of impact for motion away from the contact normal (or causes minor penetration)
794
if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration)
797
return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
800
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
802
//don't collide with itself
803
if (proxy0->m_clientObject == m_me)
806
///don't do CCD when the collision filters are not matching
807
if (!ClosestConvexResultCallback::needsCollision(proxy0))
810
btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
812
//call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
813
if (m_dispatcher->needsResponse(m_me,otherObj))
816
///don't do CCD when there are already contact points (touching contact/penetration)
817
btAlignedObjectArray<btPersistentManifold*> manifoldArray;
818
btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
821
if (collisionPair->m_algorithm)
823
manifoldArray.resize(0);
824
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
825
for (int j=0;j<manifoldArray.size();j++)
827
btPersistentManifold* manifold = manifoldArray[j];
828
if (manifold->getNumContacts()>0)
843
///internal debugging variable. this value shouldn't be too high
844
int gNumClampedCcdMotions=0;
846
void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
848
BT_PROFILE("integrateTransforms");
849
btTransform predictedTrans;
850
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
852
btRigidBody* body = m_nonStaticRigidBodies[i];
853
body->setHitFraction(1.f);
855
if (body->isActive() && (!body->isStaticOrKinematicObject()))
858
body->predictIntegratedTransform(timeStep, predictedTrans);
860
btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
864
if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
866
BT_PROFILE("CCD motion clamping");
867
if (body->getCollisionShape()->isConvex())
869
gNumClampedCcdMotions++;
870
#ifdef USE_STATIC_ONLY
871
class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
875
StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
876
btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
880
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
882
btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
883
if (!otherObj->isStaticOrKinematicObject())
885
return btClosestNotMeConvexResultCallback::needsCollision(proxy0);
889
StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
891
btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
893
//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
894
btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
895
sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
897
sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
898
sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
899
btTransform modifiedPredictedTrans = predictedTrans;
900
modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
902
convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
903
if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
906
//printf("clamped integration to hit fraction = %f\n",fraction);
907
body->setHitFraction(sweepResults.m_closestHitFraction);
908
body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
909
body->setHitFraction(0.f);
910
body->proceedToTransform( predictedTrans);
913
btVector3 linVel = body->getLinearVelocity();
915
btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep;
916
btScalar maxSpeedSqr = maxSpeed*maxSpeed;
917
if (linVel.length2()>maxSpeedSqr)
921
body->setLinearVelocity(linVel);
922
btScalar ms2 = body->getLinearVelocity().length2();
923
body->predictIntegratedTransform(timeStep, predictedTrans);
925
btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
926
btScalar smt = body->getCcdSquareMotionThreshold();
927
printf("sm2=%f\n",sm2);
930
//response between two dynamic objects without friction, assuming 0 penetration depth
931
btScalar appliedImpulse = 0.f;
932
btScalar depth = 0.f;
933
appliedImpulse = resolveSingleCollision(body,sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
944
body->proceedToTransform( predictedTrans);
949
void btDiscreteDynamicsWorld::addSpeculativeContacts(btScalar timeStep)
951
BT_PROFILE("addSpeculativeContacts");
952
btTransform predictedTrans;
953
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
955
btRigidBody* body = m_nonStaticRigidBodies[i];
956
body->setHitFraction(1.f);
958
if (body->isActive() && (!body->isStaticOrKinematicObject()))
960
body->predictIntegratedTransform(timeStep, predictedTrans);
961
btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
963
if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
965
BT_PROFILE("search speculative contacts");
966
if (body->getCollisionShape()->isConvex())
968
gNumClampedCcdMotions++;
970
btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
971
//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
972
btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
974
sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
975
sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
976
btTransform modifiedPredictedTrans;
977
modifiedPredictedTrans = predictedTrans;
978
modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
980
convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
981
if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
983
btBroadphaseProxy* proxy0 = body->getBroadphaseHandle();
984
btBroadphaseProxy* proxy1 = sweepResults.m_hitCollisionObject->getBroadphaseHandle();
985
btBroadphasePair* pair = sweepResults.m_pairCache->findPair(proxy0,proxy1);
988
if (pair->m_algorithm)
990
btManifoldArray contacts;
991
pair->m_algorithm->getAllContactManifolds(contacts);
994
btManifoldResult result(body,sweepResults.m_hitCollisionObject);
995
result.setPersistentManifold(contacts[0]);
997
btVector3 vec = (modifiedPredictedTrans.getOrigin()-body->getWorldTransform().getOrigin());
998
vec*=sweepResults.m_closestHitFraction;
1000
btScalar lenSqr = vec.length2();
1001
btScalar depth = 0.f;
1002
btVector3 pointWorld = sweepResults.m_hitPointWorld;
1003
if (lenSqr>SIMD_EPSILON)
1005
depth = btSqrt(lenSqr);
1010
if (contacts[0]->getBody0()==body)
1012
result.addContactPoint(sweepResults.m_hitNormalWorld,pointWorld,depth);
1014
debugContacts.push_back(sweepResults.m_hitPointWorld);//sweepResults.m_hitPointWorld);
1015
debugNormals.push_back(sweepResults.m_hitNormalWorld);
1020
result.addContactPoint(-sweepResults.m_hitNormalWorld,pointWorld,depth);
1021
//sweepResults.m_hitPointWorld,depth);
1024
if (1)//firstHit==1)
1027
debugNormals.push_back(sweepResults.m_hitNormalWorld);
1028
debugContacts.push_back(pointWorld);//sweepResults.m_hitPointWorld);
1029
debugNormals.push_back(sweepResults.m_hitNormalWorld);
1030
debugContacts.push_back(sweepResults.m_hitPointWorld);
1039
//no algorithm, use dispatcher to create one
1046
//add an overlapping pair
1047
//printf("pair missing\n");
1062
void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
1064
BT_PROFILE("predictUnconstraintMotion");
1065
for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
1067
btRigidBody* body = m_nonStaticRigidBodies[i];
1068
if (!body->isStaticOrKinematicObject())
1070
body->integrateVelocities( timeStep);
1072
body->applyDamping(timeStep);
1074
body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
1080
void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep)
1084
#ifndef BT_NO_PROFILE
1085
CProfileManager::Reset();
1086
#endif //BT_NO_PROFILE
1095
void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint)
1097
bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
1098
bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
1099
btScalar dbgDrawSize = constraint->getDbgDrawSize();
1100
if(dbgDrawSize <= btScalar(0.f))
1105
switch(constraint->getConstraintType())
1107
case POINT2POINT_CONSTRAINT_TYPE:
1109
btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
1112
btVector3 pivot = p2pC->getPivotInA();
1113
pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1114
tr.setOrigin(pivot);
1115
getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1116
// that ideally should draw the same frame
1117
pivot = p2pC->getPivotInB();
1118
pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1119
tr.setOrigin(pivot);
1120
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1123
case HINGE_CONSTRAINT_TYPE:
1125
btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
1126
btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1127
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1128
tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1129
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1130
btScalar minAng = pHinge->getLowerLimit();
1131
btScalar maxAng = pHinge->getUpperLimit();
1132
if(minAng == maxAng)
1136
bool drawSect = true;
1139
minAng = btScalar(0.f);
1145
btVector3& center = tr.getOrigin();
1146
btVector3 normal = tr.getBasis().getColumn(2);
1147
btVector3 axis = tr.getBasis().getColumn(0);
1148
getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
1152
case CONETWIST_CONSTRAINT_TYPE:
1154
btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
1155
btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1156
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1157
tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1158
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1161
//const btScalar length = btScalar(5);
1162
const btScalar length = dbgDrawSize;
1163
static int nSegments = 8*4;
1164
btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
1165
btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1167
for (int i=0; i<nSegments; i++)
1169
fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
1170
btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1172
getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
1174
if (i%(nSegments/8) == 0)
1175
getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
1179
btScalar tws = pCT->getTwistSpan();
1180
btScalar twa = pCT->getTwistAngle();
1181
bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1184
tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1188
tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1190
btVector3 pivot = tr.getOrigin();
1191
btVector3 normal = tr.getBasis().getColumn(0);
1192
btVector3 axis1 = tr.getBasis().getColumn(1);
1193
getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
1198
case D6_SPRING_CONSTRAINT_TYPE:
1199
case D6_CONSTRAINT_TYPE:
1201
btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
1202
btTransform tr = p6DOF->getCalculatedTransformA();
1203
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1204
tr = p6DOF->getCalculatedTransformB();
1205
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1208
tr = p6DOF->getCalculatedTransformA();
1209
const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1210
btVector3 up = tr.getBasis().getColumn(2);
1211
btVector3 axis = tr.getBasis().getColumn(0);
1212
btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1213
btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1214
btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1215
btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1216
getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
1217
axis = tr.getBasis().getColumn(1);
1218
btScalar ay = p6DOF->getAngle(1);
1219
btScalar az = p6DOF->getAngle(2);
1220
btScalar cy = btCos(ay);
1221
btScalar sy = btSin(ay);
1222
btScalar cz = btCos(az);
1223
btScalar sz = btSin(az);
1225
ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1226
ref[1] = -sz*axis[0] + cz*axis[1];
1227
ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1228
tr = p6DOF->getCalculatedTransformB();
1229
btVector3 normal = -tr.getBasis().getColumn(0);
1230
btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1231
btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1234
getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
1236
else if(minFi < maxFi)
1238
getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
1240
tr = p6DOF->getCalculatedTransformA();
1241
btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
1242
btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
1243
getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
1247
case SLIDER_CONSTRAINT_TYPE:
1249
btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
1250
btTransform tr = pSlider->getCalculatedTransformA();
1251
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1252
tr = pSlider->getCalculatedTransformB();
1253
if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1256
btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB();
1257
btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1258
btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1259
getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
1260
btVector3 normal = tr.getBasis().getColumn(0);
1261
btVector3 axis = tr.getBasis().getColumn(1);
1262
btScalar a_min = pSlider->getLowerAngLimit();
1263
btScalar a_max = pSlider->getUpperAngLimit();
1264
const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1265
getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
1279
void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
1281
if (m_ownsConstraintSolver)
1283
btAlignedFree( m_constraintSolver);
1285
m_ownsConstraintSolver = false;
1286
m_constraintSolver = solver;
1289
btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver()
1291
return m_constraintSolver;
1295
int btDiscreteDynamicsWorld::getNumConstraints() const
1297
return int(m_constraints.size());
1299
btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index)
1301
return m_constraints[index];
1303
const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const
1305
return m_constraints[index];
1310
void btDiscreteDynamicsWorld::serializeRigidBodies(btSerializer* serializer)
1313
//serialize all collision objects
1314
for (i=0;i<m_collisionObjects.size();i++)
1316
btCollisionObject* colObj = m_collisionObjects[i];
1317
if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY)
1319
int len = colObj->calculateSerializeBufferSize();
1320
btChunk* chunk = serializer->allocate(len,1);
1321
const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1322
serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
1326
for (i=0;i<m_constraints.size();i++)
1328
btTypedConstraint* constraint = m_constraints[i];
1329
int size = constraint->calculateSerializeBufferSize();
1330
btChunk* chunk = serializer->allocate(size,1);
1331
const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
1332
serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
1337
void btDiscreteDynamicsWorld::serialize(btSerializer* serializer)
1340
serializer->startSerialization();
1342
serializeRigidBodies(serializer);
1344
serializeCollisionObjects(serializer);
1346
serializer->finishSerialization();