btDiscreteDynamicsWorld.cpp

Go to the documentation of this file.
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/CollisionShapes/btCollisionShape.h"
00023 #include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
00024 #include "LinearMath/btTransformUtil.h"
00025 #include "LinearMath/btQuickprof.h"
00026 
00027 //rigidbody & constraints
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         //only delete it when we created it
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                                 //to calculate velocities next frame
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                 //need to check if next line is ok
00161                 //it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up
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                 //we need to call the update at least once, even for sleeping objects
00188                 //otherwise the 'graphics' transform never updates properly
00190                 //if (body->getActivationState() != ISLAND_SLEEPING)
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                 //iterate  over all collision objects
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                 //iterate over all active rigid bodies
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                 //fixed timestep with interpolation
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                 //variable timestep
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         //process some debugging flags
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                 //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
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                                         //also add all non-contact constraints/joints for this island
00609                                 btTypedConstraint** startConstraint = 0;
00610                                 int numCurConstraints = 0;
00611                                 int i;
00612                                 
00613                                 //find the first constraint for this island
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                                 //count the number of constraints in this island
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                                                 //printf("deferred\n");
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         //sorted version of all btTypedConstraint, based on islandId
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 //      btAssert(0);
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         //Store the island id in each body
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                 //ignore result if there is no contact response
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);//toB.getOrigin()-fromB.getOrigin();
00773 
00774                 btVector3 relativeVelocity = (linVelA-linVelB);
00775                 //don't report time of impact for motion away from the contact normal (or causes minor penetration)
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                 //don't collide with itself
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                 //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
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 //#include "stdio.h"
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                                         //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
00848                                         btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
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 //                                                      printf("clamped integration to hit fraction = %f\n",fraction);
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                         //damping
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                                 // that ideally should draw the same frame      
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                                         //const btScalar length = btScalar(5);
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         //serialize all collision objects
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 

Generated on Mon Feb 15 22:17:03 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1