Blender  V2.59
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/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