00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "btDiscreteDynamicsWorld.h"
00018
00019
00020 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
00021 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
00022 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
00023 #include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
00024 #include "LinearMath/btTransformUtil.h"
00025 #include "LinearMath/btQuickprof.h"
00026
00027
00028 #include "BulletDynamics/Dynamics/btRigidBody.h"
00029 #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
00030 #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
00031 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
00032 #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
00033 #include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
00034 #include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
00035 #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
00036 #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
00037
00038 #include "LinearMath/btIDebugDraw.h"
00039 #include "BulletCollision/CollisionShapes/btSphereShape.h"
00040
00041
00042 #include "BulletDynamics/Dynamics/btActionInterface.h"
00043 #include "LinearMath/btQuickprof.h"
00044 #include "LinearMath/btMotionState.h"
00045
00046 #include "LinearMath/btSerializer.h"
00047
00048
00049
00050 btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
00051 :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
00052 m_constraintSolver(constraintSolver),
00053 m_gravity(0,-10,0),
00054 m_localTime(btScalar(1.)/btScalar(60.)),
00055 m_synchronizeAllMotionStates(false),
00056 m_profileTimings(0)
00057 {
00058 if (!m_constraintSolver)
00059 {
00060 void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16);
00061 m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver;
00062 m_ownsConstraintSolver = true;
00063 } else
00064 {
00065 m_ownsConstraintSolver = false;
00066 }
00067
00068 {
00069 void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16);
00070 m_islandManager = new (mem) btSimulationIslandManager();
00071 }
00072
00073 m_ownsIslandManager = true;
00074 }
00075
00076
00077 btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld()
00078 {
00079
00080 if (m_ownsIslandManager)
00081 {
00082 m_islandManager->~btSimulationIslandManager();
00083 btAlignedFree( m_islandManager);
00084 }
00085 if (m_ownsConstraintSolver)
00086 {
00087
00088 m_constraintSolver->~btConstraintSolver();
00089 btAlignedFree(m_constraintSolver);
00090 }
00091 }
00092
00093 void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
00094 {
00098 for (int i=0;i<m_collisionObjects.size();i++)
00099 {
00100 btCollisionObject* colObj = m_collisionObjects[i];
00101 btRigidBody* body = btRigidBody::upcast(colObj);
00102 if (body && body->getActivationState() != ISLAND_SLEEPING)
00103 {
00104 if (body->isKinematicObject())
00105 {
00106
00107 body->saveKinematicState(timeStep);
00108 }
00109 }
00110 }
00111
00112 }
00113
00114 void btDiscreteDynamicsWorld::debugDrawWorld()
00115 {
00116 BT_PROFILE("debugDrawWorld");
00117
00118 btCollisionWorld::debugDrawWorld();
00119
00120 bool drawConstraints = false;
00121 if (getDebugDrawer())
00122 {
00123 int mode = getDebugDrawer()->getDebugMode();
00124 if(mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits))
00125 {
00126 drawConstraints = true;
00127 }
00128 }
00129 if(drawConstraints)
00130 {
00131 for(int i = getNumConstraints()-1; i>=0 ;i--)
00132 {
00133 btTypedConstraint* constraint = getConstraint(i);
00134 debugDrawConstraint(constraint);
00135 }
00136 }
00137
00138
00139
00140 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
00141 {
00142 int i;
00143
00144 if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
00145 {
00146 for (i=0;i<m_actions.size();i++)
00147 {
00148 m_actions[i]->debugDraw(m_debugDrawer);
00149 }
00150 }
00151 }
00152 }
00153
00154 void btDiscreteDynamicsWorld::clearForces()
00155 {
00157 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
00158 {
00159 btRigidBody* body = m_nonStaticRigidBodies[i];
00160
00161
00162 body->clearForces();
00163 }
00164 }
00165
00167 void btDiscreteDynamicsWorld::applyGravity()
00168 {
00170 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
00171 {
00172 btRigidBody* body = m_nonStaticRigidBodies[i];
00173 if (body->isActive())
00174 {
00175 body->applyGravity();
00176 }
00177 }
00178 }
00179
00180
00181 void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body)
00182 {
00183 btAssert(body);
00184
00185 if (body->getMotionState() && !body->isStaticOrKinematicObject())
00186 {
00187
00188
00190
00191 {
00192 btTransform interpolatedTransform;
00193 btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
00194 body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
00195 body->getMotionState()->setWorldTransform(interpolatedTransform);
00196 }
00197 }
00198 }
00199
00200
00201 void btDiscreteDynamicsWorld::synchronizeMotionStates()
00202 {
00203 BT_PROFILE("synchronizeMotionStates");
00204 if (m_synchronizeAllMotionStates)
00205 {
00206
00207 for ( int i=0;i<m_collisionObjects.size();i++)
00208 {
00209 btCollisionObject* colObj = m_collisionObjects[i];
00210 btRigidBody* body = btRigidBody::upcast(colObj);
00211 if (body)
00212 synchronizeSingleMotionState(body);
00213 }
00214 } else
00215 {
00216
00217 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
00218 {
00219 btRigidBody* body = m_nonStaticRigidBodies[i];
00220 if (body->isActive())
00221 synchronizeSingleMotionState(body);
00222 }
00223 }
00224 }
00225
00226
00227 int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
00228 {
00229 startProfiling(timeStep);
00230
00231 BT_PROFILE("stepSimulation");
00232
00233 int numSimulationSubSteps = 0;
00234
00235 if (maxSubSteps)
00236 {
00237
00238 m_localTime += timeStep;
00239 if (m_localTime >= fixedTimeStep)
00240 {
00241 numSimulationSubSteps = int( m_localTime / fixedTimeStep);
00242 m_localTime -= numSimulationSubSteps * fixedTimeStep;
00243 }
00244 } else
00245 {
00246
00247 fixedTimeStep = timeStep;
00248 m_localTime = timeStep;
00249 if (btFuzzyZero(timeStep))
00250 {
00251 numSimulationSubSteps = 0;
00252 maxSubSteps = 0;
00253 } else
00254 {
00255 numSimulationSubSteps = 1;
00256 maxSubSteps = 1;
00257 }
00258 }
00259
00260
00261 if (getDebugDrawer())
00262 {
00263 btIDebugDraw* debugDrawer = getDebugDrawer ();
00264 gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
00265 }
00266 if (numSimulationSubSteps)
00267 {
00268
00269 saveKinematicState(fixedTimeStep);
00270
00271 applyGravity();
00272
00273
00274 int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
00275
00276 for (int i=0;i<clampedSimulationSteps;i++)
00277 {
00278 internalSingleStepSimulation(fixedTimeStep);
00279 synchronizeMotionStates();
00280 }
00281
00282 } else
00283 {
00284 synchronizeMotionStates();
00285 }
00286
00287 clearForces();
00288
00289 #ifndef BT_NO_PROFILE
00290 CProfileManager::Increment_Frame_Counter();
00291 #endif //BT_NO_PROFILE
00292
00293 return numSimulationSubSteps;
00294 }
00295
00296 void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
00297 {
00298
00299 BT_PROFILE("internalSingleStepSimulation");
00300
00301 if(0 != m_internalPreTickCallback) {
00302 (*m_internalPreTickCallback)(this, timeStep);
00303 }
00304
00306 predictUnconstraintMotion(timeStep);
00307
00308 btDispatcherInfo& dispatchInfo = getDispatchInfo();
00309
00310 dispatchInfo.m_timeStep = timeStep;
00311 dispatchInfo.m_stepCount = 0;
00312 dispatchInfo.m_debugDraw = getDebugDrawer();
00313
00315 performDiscreteCollisionDetection();
00316
00317 calculateSimulationIslands();
00318
00319
00320 getSolverInfo().m_timeStep = timeStep;
00321
00322
00323
00325 solveConstraints(getSolverInfo());
00326
00328
00330 integrateTransforms(timeStep);
00331
00333 updateActions(timeStep);
00334
00335 updateActivationState( timeStep );
00336
00337 if(0 != m_internalTickCallback) {
00338 (*m_internalTickCallback)(this, timeStep);
00339 }
00340 }
00341
00342 void btDiscreteDynamicsWorld::setGravity(const btVector3& gravity)
00343 {
00344 m_gravity = gravity;
00345 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
00346 {
00347 btRigidBody* body = m_nonStaticRigidBodies[i];
00348 if (body->isActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
00349 {
00350 body->setGravity(gravity);
00351 }
00352 }
00353 }
00354
00355 btVector3 btDiscreteDynamicsWorld::getGravity () const
00356 {
00357 return m_gravity;
00358 }
00359
00360 void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
00361 {
00362 btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask);
00363 }
00364
00365 void btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
00366 {
00367 btRigidBody* body = btRigidBody::upcast(collisionObject);
00368 if (body)
00369 removeRigidBody(body);
00370 else
00371 btCollisionWorld::removeCollisionObject(collisionObject);
00372 }
00373
00374 void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
00375 {
00376 m_nonStaticRigidBodies.remove(body);
00377 btCollisionWorld::removeCollisionObject(body);
00378 }
00379
00380
00381 void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body)
00382 {
00383 if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
00384 {
00385 body->setGravity(m_gravity);
00386 }
00387
00388 if (body->getCollisionShape())
00389 {
00390 if (!body->isStaticObject())
00391 {
00392 m_nonStaticRigidBodies.push_back(body);
00393 } else
00394 {
00395 body->setActivationState(ISLAND_SLEEPING);
00396 }
00397
00398 bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
00399 short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
00400 short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
00401
00402 addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
00403 }
00404 }
00405
00406 void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
00407 {
00408 if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
00409 {
00410 body->setGravity(m_gravity);
00411 }
00412
00413 if (body->getCollisionShape())
00414 {
00415 if (!body->isStaticObject())
00416 {
00417 m_nonStaticRigidBodies.push_back(body);
00418 }
00419 else
00420 {
00421 body->setActivationState(ISLAND_SLEEPING);
00422 }
00423 addCollisionObject(body,group,mask);
00424 }
00425 }
00426
00427
00428 void btDiscreteDynamicsWorld::updateActions(btScalar timeStep)
00429 {
00430 BT_PROFILE("updateActions");
00431
00432 for ( int i=0;i<m_actions.size();i++)
00433 {
00434 m_actions[i]->updateAction( this, timeStep);
00435 }
00436 }
00437
00438
00439 void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
00440 {
00441 BT_PROFILE("updateActivationState");
00442
00443 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
00444 {
00445 btRigidBody* body = m_nonStaticRigidBodies[i];
00446 if (body)
00447 {
00448 body->updateDeactivation(timeStep);
00449
00450 if (body->wantsSleeping())
00451 {
00452 if (body->isStaticOrKinematicObject())
00453 {
00454 body->setActivationState(ISLAND_SLEEPING);
00455 } else
00456 {
00457 if (body->getActivationState() == ACTIVE_TAG)
00458 body->setActivationState( WANTS_DEACTIVATION );
00459 if (body->getActivationState() == ISLAND_SLEEPING)
00460 {
00461 body->setAngularVelocity(btVector3(0,0,0));
00462 body->setLinearVelocity(btVector3(0,0,0));
00463 }
00464
00465 }
00466 } else
00467 {
00468 if (body->getActivationState() != DISABLE_DEACTIVATION)
00469 body->setActivationState( ACTIVE_TAG );
00470 }
00471 }
00472 }
00473 }
00474
00475 void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
00476 {
00477 m_constraints.push_back(constraint);
00478 if (disableCollisionsBetweenLinkedBodies)
00479 {
00480 constraint->getRigidBodyA().addConstraintRef(constraint);
00481 constraint->getRigidBodyB().addConstraintRef(constraint);
00482 }
00483 }
00484
00485 void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
00486 {
00487 m_constraints.remove(constraint);
00488 constraint->getRigidBodyA().removeConstraintRef(constraint);
00489 constraint->getRigidBodyB().removeConstraintRef(constraint);
00490 }
00491
00492 void btDiscreteDynamicsWorld::addAction(btActionInterface* action)
00493 {
00494 m_actions.push_back(action);
00495 }
00496
00497 void btDiscreteDynamicsWorld::removeAction(btActionInterface* action)
00498 {
00499 m_actions.remove(action);
00500 }
00501
00502
00503 void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle)
00504 {
00505 addAction(vehicle);
00506 }
00507
00508 void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle)
00509 {
00510 removeAction(vehicle);
00511 }
00512
00513 void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character)
00514 {
00515 addAction(character);
00516 }
00517
00518 void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character)
00519 {
00520 removeAction(character);
00521 }
00522
00523
00524 SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs)
00525 {
00526 int islandId;
00527
00528 const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
00529 const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
00530 islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag();
00531 return islandId;
00532
00533 }
00534
00535
00536 class btSortConstraintOnIslandPredicate
00537 {
00538 public:
00539
00540 bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs )
00541 {
00542 int rIslandId0,lIslandId0;
00543 rIslandId0 = btGetConstraintIslandId(rhs);
00544 lIslandId0 = btGetConstraintIslandId(lhs);
00545 return lIslandId0 < rIslandId0;
00546 }
00547 };
00548
00549
00550
00551 void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
00552 {
00553 BT_PROFILE("solveConstraints");
00554
00555 struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
00556 {
00557
00558 btContactSolverInfo& m_solverInfo;
00559 btConstraintSolver* m_solver;
00560 btTypedConstraint** m_sortedConstraints;
00561 int m_numConstraints;
00562 btIDebugDraw* m_debugDrawer;
00563 btStackAlloc* m_stackAlloc;
00564 btDispatcher* m_dispatcher;
00565
00566 btAlignedObjectArray<btCollisionObject*> m_bodies;
00567 btAlignedObjectArray<btPersistentManifold*> m_manifolds;
00568 btAlignedObjectArray<btTypedConstraint*> m_constraints;
00569
00570
00571 InplaceSolverIslandCallback(
00572 btContactSolverInfo& solverInfo,
00573 btConstraintSolver* solver,
00574 btTypedConstraint** sortedConstraints,
00575 int numConstraints,
00576 btIDebugDraw* debugDrawer,
00577 btStackAlloc* stackAlloc,
00578 btDispatcher* dispatcher)
00579 :m_solverInfo(solverInfo),
00580 m_solver(solver),
00581 m_sortedConstraints(sortedConstraints),
00582 m_numConstraints(numConstraints),
00583 m_debugDrawer(debugDrawer),
00584 m_stackAlloc(stackAlloc),
00585 m_dispatcher(dispatcher)
00586 {
00587
00588 }
00589
00590
00591 InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other)
00592 {
00593 btAssert(0);
00594 (void)other;
00595 return *this;
00596 }
00597 virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId)
00598 {
00599 if (islandId<0)
00600 {
00601 if (numManifolds + m_numConstraints)
00602 {
00604 m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
00605 }
00606 } else
00607 {
00608
00609 btTypedConstraint** startConstraint = 0;
00610 int numCurConstraints = 0;
00611 int i;
00612
00613
00614 for (i=0;i<m_numConstraints;i++)
00615 {
00616 if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
00617 {
00618 startConstraint = &m_sortedConstraints[i];
00619 break;
00620 }
00621 }
00622
00623 for (;i<m_numConstraints;i++)
00624 {
00625 if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
00626 {
00627 numCurConstraints++;
00628 }
00629 }
00630
00631 if (m_solverInfo.m_minimumSolverBatchSize<=1)
00632 {
00634 if (numManifolds + numCurConstraints)
00635 {
00636 m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
00637 }
00638 } else
00639 {
00640
00641 for (i=0;i<numBodies;i++)
00642 m_bodies.push_back(bodies[i]);
00643 for (i=0;i<numManifolds;i++)
00644 m_manifolds.push_back(manifolds[i]);
00645 for (i=0;i<numCurConstraints;i++)
00646 m_constraints.push_back(startConstraint[i]);
00647 if ((m_constraints.size()+m_manifolds.size())>m_solverInfo.m_minimumSolverBatchSize)
00648 {
00649 processConstraints();
00650 } else
00651 {
00652
00653 }
00654 }
00655 }
00656 }
00657 void processConstraints()
00658 {
00659 if (m_manifolds.size() + m_constraints.size()>0)
00660 {
00661 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);
00662 }
00663 m_bodies.resize(0);
00664 m_manifolds.resize(0);
00665 m_constraints.resize(0);
00666
00667 }
00668
00669 };
00670
00671
00672
00673
00674 btAlignedObjectArray<btTypedConstraint*> sortedConstraints;
00675 sortedConstraints.resize( m_constraints.size());
00676 int i;
00677 for (i=0;i<getNumConstraints();i++)
00678 {
00679 sortedConstraints[i] = m_constraints[i];
00680 }
00681
00682
00683
00684
00685
00686 sortedConstraints.quickSort(btSortConstraintOnIslandPredicate());
00687
00688 btTypedConstraint** constraintsPtr = getNumConstraints() ? &sortedConstraints[0] : 0;
00689
00690 InplaceSolverIslandCallback solverCallback( solverInfo, m_constraintSolver, constraintsPtr,sortedConstraints.size(), m_debugDrawer,m_stackAlloc,m_dispatcher1);
00691
00692 m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
00693
00695 m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
00696
00697 solverCallback.processConstraints();
00698
00699 m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
00700 }
00701
00702
00703
00704
00705 void btDiscreteDynamicsWorld::calculateSimulationIslands()
00706 {
00707 BT_PROFILE("calculateSimulationIslands");
00708
00709 getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher());
00710
00711 {
00712 int i;
00713 int numConstraints = int(m_constraints.size());
00714 for (i=0;i< numConstraints ; i++ )
00715 {
00716 btTypedConstraint* constraint = m_constraints[i];
00717
00718 const btRigidBody* colObj0 = &constraint->getRigidBodyA();
00719 const btRigidBody* colObj1 = &constraint->getRigidBodyB();
00720
00721 if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
00722 ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
00723 {
00724 if (colObj0->isActive() || colObj1->isActive())
00725 {
00726
00727 getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),
00728 (colObj1)->getIslandTag());
00729 }
00730 }
00731 }
00732 }
00733
00734
00735 getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld());
00736
00737
00738 }
00739
00740
00741 #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
00742
00743 class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
00744 {
00745 btCollisionObject* m_me;
00746 btScalar m_allowedPenetration;
00747 btOverlappingPairCache* m_pairCache;
00748 btDispatcher* m_dispatcher;
00749
00750
00751 public:
00752 btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
00753 btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
00754 m_me(me),
00755 m_allowedPenetration(0.0f),
00756 m_pairCache(pairCache),
00757 m_dispatcher(dispatcher)
00758 {
00759 }
00760
00761 virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
00762 {
00763 if (convexResult.m_hitCollisionObject == m_me)
00764 return 1.0f;
00765
00766
00767 if(!convexResult.m_hitCollisionObject->hasContactResponse())
00768 return 1.0f;
00769
00770 btVector3 linVelA,linVelB;
00771 linVelA = m_convexToWorld-m_convexFromWorld;
00772 linVelB = btVector3(0,0,0);
00773
00774 btVector3 relativeVelocity = (linVelA-linVelB);
00775
00776 if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration)
00777 return 1.f;
00778
00779 return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
00780 }
00781
00782 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
00783 {
00784
00785 if (proxy0->m_clientObject == m_me)
00786 return false;
00787
00789 if (!ClosestConvexResultCallback::needsCollision(proxy0))
00790 return false;
00791
00792 btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
00793
00794
00795 if (m_dispatcher->needsResponse(m_me,otherObj))
00796 {
00798 btAlignedObjectArray<btPersistentManifold*> manifoldArray;
00799 btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
00800 if (collisionPair)
00801 {
00802 if (collisionPair->m_algorithm)
00803 {
00804 manifoldArray.resize(0);
00805 collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
00806 for (int j=0;j<manifoldArray.size();j++)
00807 {
00808 btPersistentManifold* manifold = manifoldArray[j];
00809 if (manifold->getNumContacts()>0)
00810 return false;
00811 }
00812 }
00813 }
00814 }
00815 return true;
00816 }
00817
00818
00819 };
00820
00822 int gNumClampedCcdMotions=0;
00823
00824
00825 void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
00826 {
00827 BT_PROFILE("integrateTransforms");
00828 btTransform predictedTrans;
00829 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
00830 {
00831 btRigidBody* body = m_nonStaticRigidBodies[i];
00832 body->setHitFraction(1.f);
00833
00834 if (body->isActive() && (!body->isStaticOrKinematicObject()))
00835 {
00836 body->predictIntegratedTransform(timeStep, predictedTrans);
00837 btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
00838
00839 if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
00840 {
00841 BT_PROFILE("CCD motion clamping");
00842 if (body->getCollisionShape()->isConvex())
00843 {
00844 gNumClampedCcdMotions++;
00845
00846 btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
00847
00848 btSphereShape tmpSphere(body->getCcdSweptSphereRadius());
00849
00850 sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
00851 sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
00852
00853 convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
00854 if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
00855 {
00856 body->setHitFraction(sweepResults.m_closestHitFraction);
00857 body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
00858 body->setHitFraction(0.f);
00859
00860 }
00861 }
00862 }
00863
00864 body->proceedToTransform( predictedTrans);
00865 }
00866 }
00867 }
00868
00869
00870
00871
00872
00873 void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
00874 {
00875 BT_PROFILE("predictUnconstraintMotion");
00876 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
00877 {
00878 btRigidBody* body = m_nonStaticRigidBodies[i];
00879 if (!body->isStaticOrKinematicObject())
00880 {
00881 body->integrateVelocities( timeStep);
00882
00883 body->applyDamping(timeStep);
00884
00885 body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
00886 }
00887 }
00888 }
00889
00890
00891 void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep)
00892 {
00893 (void)timeStep;
00894
00895 #ifndef BT_NO_PROFILE
00896 CProfileManager::Reset();
00897 #endif //BT_NO_PROFILE
00898
00899 }
00900
00901
00902
00903
00904
00905
00906 void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint)
00907 {
00908 bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
00909 bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
00910 btScalar dbgDrawSize = constraint->getDbgDrawSize();
00911 if(dbgDrawSize <= btScalar(0.f))
00912 {
00913 return;
00914 }
00915
00916 switch(constraint->getConstraintType())
00917 {
00918 case POINT2POINT_CONSTRAINT_TYPE:
00919 {
00920 btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
00921 btTransform tr;
00922 tr.setIdentity();
00923 btVector3 pivot = p2pC->getPivotInA();
00924 pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
00925 tr.setOrigin(pivot);
00926 getDebugDrawer()->drawTransform(tr, dbgDrawSize);
00927
00928 pivot = p2pC->getPivotInB();
00929 pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
00930 tr.setOrigin(pivot);
00931 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
00932 }
00933 break;
00934 case HINGE_CONSTRAINT_TYPE:
00935 {
00936 btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
00937 btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
00938 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
00939 tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
00940 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
00941 btScalar minAng = pHinge->getLowerLimit();
00942 btScalar maxAng = pHinge->getUpperLimit();
00943 if(minAng == maxAng)
00944 {
00945 break;
00946 }
00947 bool drawSect = true;
00948 if(minAng > maxAng)
00949 {
00950 minAng = btScalar(0.f);
00951 maxAng = SIMD_2_PI;
00952 drawSect = false;
00953 }
00954 if(drawLimits)
00955 {
00956 btVector3& center = tr.getOrigin();
00957 btVector3 normal = tr.getBasis().getColumn(2);
00958 btVector3 axis = tr.getBasis().getColumn(0);
00959 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
00960 }
00961 }
00962 break;
00963 case CONETWIST_CONSTRAINT_TYPE:
00964 {
00965 btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
00966 btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
00967 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
00968 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
00969 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
00970 if(drawLimits)
00971 {
00972
00973 const btScalar length = dbgDrawSize;
00974 static int nSegments = 8*4;
00975 btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
00976 btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
00977 pPrev = tr * pPrev;
00978 for (int i=0; i<nSegments; i++)
00979 {
00980 fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
00981 btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
00982 pCur = tr * pCur;
00983 getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
00984
00985 if (i%(nSegments/8) == 0)
00986 getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
00987
00988 pPrev = pCur;
00989 }
00990 btScalar tws = pCT->getTwistSpan();
00991 btScalar twa = pCT->getTwistAngle();
00992 bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
00993 if(useFrameB)
00994 {
00995 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
00996 }
00997 else
00998 {
00999 tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
01000 }
01001 btVector3 pivot = tr.getOrigin();
01002 btVector3 normal = tr.getBasis().getColumn(0);
01003 btVector3 axis1 = tr.getBasis().getColumn(1);
01004 getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
01005
01006 }
01007 }
01008 break;
01009 case D6_CONSTRAINT_TYPE:
01010 {
01011 btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
01012 btTransform tr = p6DOF->getCalculatedTransformA();
01013 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
01014 tr = p6DOF->getCalculatedTransformB();
01015 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
01016 if(drawLimits)
01017 {
01018 tr = p6DOF->getCalculatedTransformA();
01019 const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
01020 btVector3 up = tr.getBasis().getColumn(2);
01021 btVector3 axis = tr.getBasis().getColumn(0);
01022 btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
01023 btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
01024 btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
01025 btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
01026 getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
01027 axis = tr.getBasis().getColumn(1);
01028 btScalar ay = p6DOF->getAngle(1);
01029 btScalar az = p6DOF->getAngle(2);
01030 btScalar cy = btCos(ay);
01031 btScalar sy = btSin(ay);
01032 btScalar cz = btCos(az);
01033 btScalar sz = btSin(az);
01034 btVector3 ref;
01035 ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
01036 ref[1] = -sz*axis[0] + cz*axis[1];
01037 ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
01038 tr = p6DOF->getCalculatedTransformB();
01039 btVector3 normal = -tr.getBasis().getColumn(0);
01040 btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
01041 btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
01042 if(minFi > maxFi)
01043 {
01044 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
01045 }
01046 else if(minFi < maxFi)
01047 {
01048 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
01049 }
01050 tr = p6DOF->getCalculatedTransformA();
01051 btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
01052 btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
01053 getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
01054 }
01055 }
01056 break;
01057 case SLIDER_CONSTRAINT_TYPE:
01058 {
01059 btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
01060 btTransform tr = pSlider->getCalculatedTransformA();
01061 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
01062 tr = pSlider->getCalculatedTransformB();
01063 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
01064 if(drawLimits)
01065 {
01066 btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB();
01067 btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
01068 btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
01069 getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
01070 btVector3 normal = tr.getBasis().getColumn(0);
01071 btVector3 axis = tr.getBasis().getColumn(1);
01072 btScalar a_min = pSlider->getLowerAngLimit();
01073 btScalar a_max = pSlider->getUpperAngLimit();
01074 const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
01075 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
01076 }
01077 }
01078 break;
01079 default :
01080 break;
01081 }
01082 return;
01083 }
01084
01085
01086
01087
01088
01089 void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
01090 {
01091 if (m_ownsConstraintSolver)
01092 {
01093 btAlignedFree( m_constraintSolver);
01094 }
01095 m_ownsConstraintSolver = false;
01096 m_constraintSolver = solver;
01097 }
01098
01099 btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver()
01100 {
01101 return m_constraintSolver;
01102 }
01103
01104
01105 int btDiscreteDynamicsWorld::getNumConstraints() const
01106 {
01107 return int(m_constraints.size());
01108 }
01109 btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index)
01110 {
01111 return m_constraints[index];
01112 }
01113 const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const
01114 {
01115 return m_constraints[index];
01116 }
01117
01118
01119
01120 void btDiscreteDynamicsWorld::serializeRigidBodies(btSerializer* serializer)
01121 {
01122 int i;
01123
01124 for (i=0;i<m_collisionObjects.size();i++)
01125 {
01126 btCollisionObject* colObj = m_collisionObjects[i];
01127 if (colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
01128 {
01129 int len = colObj->calculateSerializeBufferSize();
01130 btChunk* chunk = serializer->allocate(len,1);
01131 const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
01132 serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
01133 }
01134 }
01135
01136 for (i=0;i<m_constraints.size();i++)
01137 {
01138 btTypedConstraint* constraint = m_constraints[i];
01139 int size = constraint->calculateSerializeBufferSize();
01140 btChunk* chunk = serializer->allocate(size,1);
01141 const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
01142 serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
01143 }
01144 }
01145
01146
01147 void btDiscreteDynamicsWorld::serialize(btSerializer* serializer)
01148 {
01149
01150 serializer->startSerialization();
01151
01152 serializeRigidBodies(serializer);
01153
01154 serializeCollisionObjects(serializer);
01155
01156 serializer->finishSerialization();
01157 }
01158