Blender V2.61 - r43446

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