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