Home | History | Annotate | Download | only in Dynamics
      1 /*
      2 Bullet Continuous Collision Detection and Physics Library
      3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
      4 
      5 This software is provided 'as-is', without any express or implied warranty.
      6 In no event will the authors be held liable for any damages arising from the use of this software.
      7 Permission is granted to anyone to use this software for any purpose,
      8 including commercial applications, and to alter it and redistribute it freely,
      9 subject to the following restrictions:
     10 
     11 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.
     12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
     13 3. This notice may not be removed or altered from any source distribution.
     14 */
     15 
     16 #include "btSimpleDynamicsWorld.h"
     17 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
     18 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
     19 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
     20 #include "BulletDynamics/Dynamics/btRigidBody.h"
     21 #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
     22 #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
     23 
     24 
     25 /*
     26   Make sure this dummy function never changes so that it
     27   can be used by probes that are checking whether the
     28   library is actually installed.
     29 */
     30 extern "C"
     31 {
     32 	void btBulletDynamicsProbe ();
     33 	void btBulletDynamicsProbe () {}
     34 }
     35 
     36 
     37 
     38 
     39 btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
     40 :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
     41 m_constraintSolver(constraintSolver),
     42 m_ownsConstraintSolver(false),
     43 m_gravity(0,0,-10)
     44 {
     45 
     46 }
     47 
     48 
     49 btSimpleDynamicsWorld::~btSimpleDynamicsWorld()
     50 {
     51 	if (m_ownsConstraintSolver)
     52 		btAlignedFree( m_constraintSolver);
     53 }
     54 
     55 int		btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
     56 {
     57 	(void)fixedTimeStep;
     58 	(void)maxSubSteps;
     59 
     60 
     61 	///apply gravity, predict motion
     62 	predictUnconstraintMotion(timeStep);
     63 
     64 	btDispatcherInfo&	dispatchInfo = getDispatchInfo();
     65 	dispatchInfo.m_timeStep = timeStep;
     66 	dispatchInfo.m_stepCount = 0;
     67 	dispatchInfo.m_debugDraw = getDebugDrawer();
     68 
     69 	///perform collision detection
     70 	performDiscreteCollisionDetection();
     71 
     72 	///solve contact constraints
     73 	int numManifolds = m_dispatcher1->getNumManifolds();
     74 	if (numManifolds)
     75 	{
     76 		btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer();
     77 
     78 		btContactSolverInfo infoGlobal;
     79 		infoGlobal.m_timeStep = timeStep;
     80 		m_constraintSolver->prepareSolve(0,numManifolds);
     81 		m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_dispatcher1);
     82 		m_constraintSolver->allSolved(infoGlobal,m_debugDrawer);
     83 	}
     84 
     85 	///integrate transforms
     86 	integrateTransforms(timeStep);
     87 
     88 	updateAabbs();
     89 
     90 	synchronizeMotionStates();
     91 
     92 	clearForces();
     93 
     94 	return 1;
     95 
     96 }
     97 
     98 void	btSimpleDynamicsWorld::clearForces()
     99 {
    100 	///@todo: iterate over awake simulation islands!
    101 	for ( int i=0;i<m_collisionObjects.size();i++)
    102 	{
    103 		btCollisionObject* colObj = m_collisionObjects[i];
    104 
    105 		btRigidBody* body = btRigidBody::upcast(colObj);
    106 		if (body)
    107 		{
    108 			body->clearForces();
    109 		}
    110 	}
    111 }
    112 
    113 
    114 void	btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
    115 {
    116 	m_gravity = gravity;
    117 	for ( int i=0;i<m_collisionObjects.size();i++)
    118 	{
    119 		btCollisionObject* colObj = m_collisionObjects[i];
    120 		btRigidBody* body = btRigidBody::upcast(colObj);
    121 		if (body)
    122 		{
    123 			body->setGravity(gravity);
    124 		}
    125 	}
    126 }
    127 
    128 btVector3 btSimpleDynamicsWorld::getGravity () const
    129 {
    130 	return m_gravity;
    131 }
    132 
    133 void	btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body)
    134 {
    135 	btCollisionWorld::removeCollisionObject(body);
    136 }
    137 
    138 void	btSimpleDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
    139 {
    140 	btRigidBody* body = btRigidBody::upcast(collisionObject);
    141 	if (body)
    142 		removeRigidBody(body);
    143 	else
    144 		btCollisionWorld::removeCollisionObject(collisionObject);
    145 }
    146 
    147 
    148 void	btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
    149 {
    150 	body->setGravity(m_gravity);
    151 
    152 	if (body->getCollisionShape())
    153 	{
    154 		addCollisionObject(body);
    155 	}
    156 }
    157 
    158 void	btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
    159 {
    160 	body->setGravity(m_gravity);
    161 
    162 	if (body->getCollisionShape())
    163 	{
    164 		addCollisionObject(body,group,mask);
    165 	}
    166 }
    167 
    168 
    169 void	btSimpleDynamicsWorld::debugDrawWorld()
    170 {
    171 
    172 }
    173 
    174 void	btSimpleDynamicsWorld::addAction(btActionInterface* action)
    175 {
    176 
    177 }
    178 
    179 void	btSimpleDynamicsWorld::removeAction(btActionInterface* action)
    180 {
    181 
    182 }
    183 
    184 
    185 void	btSimpleDynamicsWorld::updateAabbs()
    186 {
    187 	btTransform predictedTrans;
    188 	for ( int i=0;i<m_collisionObjects.size();i++)
    189 	{
    190 		btCollisionObject* colObj = m_collisionObjects[i];
    191 		btRigidBody* body = btRigidBody::upcast(colObj);
    192 		if (body)
    193 		{
    194 			if (body->isActive() && (!body->isStaticObject()))
    195 			{
    196 				btVector3 minAabb,maxAabb;
    197 				colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
    198 				btBroadphaseInterface* bp = getBroadphase();
    199 				bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
    200 			}
    201 		}
    202 	}
    203 }
    204 
    205 void	btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep)
    206 {
    207 	btTransform predictedTrans;
    208 	for ( int i=0;i<m_collisionObjects.size();i++)
    209 	{
    210 		btCollisionObject* colObj = m_collisionObjects[i];
    211 		btRigidBody* body = btRigidBody::upcast(colObj);
    212 		if (body)
    213 		{
    214 			if (body->isActive() && (!body->isStaticObject()))
    215 			{
    216 				body->predictIntegratedTransform(timeStep, predictedTrans);
    217 				body->proceedToTransform( predictedTrans);
    218 			}
    219 		}
    220 	}
    221 }
    222 
    223 
    224 
    225 void	btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
    226 {
    227 	for ( int i=0;i<m_collisionObjects.size();i++)
    228 	{
    229 		btCollisionObject* colObj = m_collisionObjects[i];
    230 		btRigidBody* body = btRigidBody::upcast(colObj);
    231 		if (body)
    232 		{
    233 			if (!body->isStaticObject())
    234 			{
    235 				if (body->isActive())
    236 				{
    237 					body->applyGravity();
    238 					body->integrateVelocities( timeStep);
    239 					body->applyDamping(timeStep);
    240 					body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
    241 				}
    242 			}
    243 		}
    244 	}
    245 }
    246 
    247 
    248 void	btSimpleDynamicsWorld::synchronizeMotionStates()
    249 {
    250 	///@todo: iterate over awake simulation islands!
    251 	for ( int i=0;i<m_collisionObjects.size();i++)
    252 	{
    253 		btCollisionObject* colObj = m_collisionObjects[i];
    254 		btRigidBody* body = btRigidBody::upcast(colObj);
    255 		if (body && body->getMotionState())
    256 		{
    257 			if (body->getActivationState() != ISLAND_SLEEPING)
    258 			{
    259 				body->getMotionState()->setWorldTransform(body->getWorldTransform());
    260 			}
    261 		}
    262 	}
    263 
    264 }
    265 
    266 
    267 void	btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
    268 {
    269 	if (m_ownsConstraintSolver)
    270 	{
    271 		btAlignedFree(m_constraintSolver);
    272 	}
    273 	m_ownsConstraintSolver = false;
    274 	m_constraintSolver = solver;
    275 }
    276 
    277 btConstraintSolver* btSimpleDynamicsWorld::getConstraintSolver()
    278 {
    279 	return m_constraintSolver;
    280 }
    281