forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			281 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| Bullet Continuous Collision Detection and Physics Library
 | |
| Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
 | |
| 
 | |
| This software is provided 'as-is', without any express or implied warranty.
 | |
| In no event will the authors be held liable for any damages arising from the use of this software.
 | |
| Permission is granted to anyone to use this software for any purpose, 
 | |
| including commercial applications, and to alter it and redistribute it freely, 
 | |
| subject to the following restrictions:
 | |
| 
 | |
| 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.
 | |
| 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
 | |
| 3. This notice may not be removed or altered from any source distribution.
 | |
| */
 | |
| 
 | |
| #include "btSimpleDynamicsWorld.h"
 | |
| #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
 | |
| #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
 | |
| #include "BulletCollision/CollisionShapes/btCollisionShape.h"
 | |
| #include "BulletDynamics/Dynamics/btRigidBody.h"
 | |
| #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
 | |
| #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Make sure this dummy function never changes so that it
 | |
|   can be used by probes that are checking whether the
 | |
|   library is actually installed.
 | |
| */
 | |
| extern "C" 
 | |
| {
 | |
| 	void btBulletDynamicsProbe ();
 | |
| 	void btBulletDynamicsProbe () {}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
 | |
| :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
 | |
| m_constraintSolver(constraintSolver),
 | |
| m_ownsConstraintSolver(false),
 | |
| m_gravity(0,0,-10)
 | |
| {
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| btSimpleDynamicsWorld::~btSimpleDynamicsWorld()
 | |
| {
 | |
| 	if (m_ownsConstraintSolver)
 | |
| 		btAlignedFree( m_constraintSolver);
 | |
| }
 | |
| 
 | |
| int		btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
 | |
| {
 | |
| 	(void)fixedTimeStep;
 | |
| 	(void)maxSubSteps;
 | |
| 
 | |
| 
 | |
| 	///apply gravity, predict motion
 | |
| 	predictUnconstraintMotion(timeStep);
 | |
| 
 | |
| 	btDispatcherInfo&	dispatchInfo = getDispatchInfo();
 | |
| 	dispatchInfo.m_timeStep = timeStep;
 | |
| 	dispatchInfo.m_stepCount = 0;
 | |
| 	dispatchInfo.m_debugDraw = getDebugDrawer();
 | |
| 
 | |
| 	///perform collision detection
 | |
| 	performDiscreteCollisionDetection();
 | |
| 
 | |
| 	///solve contact constraints
 | |
| 	int numManifolds = m_dispatcher1->getNumManifolds();
 | |
| 	if (numManifolds)
 | |
| 	{
 | |
| 		btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer();
 | |
| 		
 | |
| 		btContactSolverInfo infoGlobal;
 | |
| 		infoGlobal.m_timeStep = timeStep;
 | |
| 		m_constraintSolver->prepareSolve(0,numManifolds);
 | |
| 		m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_dispatcher1);
 | |
| 		m_constraintSolver->allSolved(infoGlobal,m_debugDrawer);
 | |
| 	}
 | |
| 
 | |
| 	///integrate transforms
 | |
| 	integrateTransforms(timeStep);
 | |
| 		
 | |
| 	updateAabbs();
 | |
| 
 | |
| 	synchronizeMotionStates();
 | |
| 
 | |
| 	clearForces();
 | |
| 
 | |
| 	return 1;
 | |
| 
 | |
| }
 | |
| 
 | |
| void	btSimpleDynamicsWorld::clearForces()
 | |
| {
 | |
| 	///@todo: iterate over awake simulation islands!
 | |
| 	for ( int i=0;i<m_collisionObjects.size();i++)
 | |
| 	{
 | |
| 		btCollisionObject* colObj = m_collisionObjects[i];
 | |
| 		
 | |
| 		btRigidBody* body = btRigidBody::upcast(colObj);
 | |
| 		if (body)
 | |
| 		{
 | |
| 			body->clearForces();
 | |
| 		}
 | |
| 	}
 | |
| }	
 | |
| 
 | |
| 
 | |
| void	btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
 | |
| {
 | |
| 	m_gravity = gravity;
 | |
| 	for ( int i=0;i<m_collisionObjects.size();i++)
 | |
| 	{
 | |
| 		btCollisionObject* colObj = m_collisionObjects[i];
 | |
| 		btRigidBody* body = btRigidBody::upcast(colObj);
 | |
| 		if (body)
 | |
| 		{
 | |
| 			body->setGravity(gravity);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| btVector3 btSimpleDynamicsWorld::getGravity () const
 | |
| {
 | |
| 	return m_gravity;
 | |
| }
 | |
| 
 | |
| void	btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body)
 | |
| {
 | |
| 	btCollisionWorld::removeCollisionObject(body);
 | |
| }
 | |
| 
 | |
| void	btSimpleDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
 | |
| {
 | |
| 	btRigidBody* body = btRigidBody::upcast(collisionObject);
 | |
| 	if (body)
 | |
| 		removeRigidBody(body);
 | |
| 	else
 | |
| 		btCollisionWorld::removeCollisionObject(collisionObject);
 | |
| }
 | |
| 
 | |
| 
 | |
| void	btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
 | |
| {
 | |
| 	body->setGravity(m_gravity);
 | |
| 
 | |
| 	if (body->getCollisionShape())
 | |
| 	{
 | |
| 		addCollisionObject(body);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void	btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask)
 | |
| {
 | |
| 	body->setGravity(m_gravity);
 | |
| 
 | |
| 	if (body->getCollisionShape())
 | |
| 	{
 | |
| 		addCollisionObject(body,group,mask);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| void	btSimpleDynamicsWorld::debugDrawWorld()
 | |
| {
 | |
| 
 | |
| }
 | |
| 				
 | |
| void	btSimpleDynamicsWorld::addAction(btActionInterface* action)
 | |
| {
 | |
| 
 | |
| }
 | |
| 
 | |
| void	btSimpleDynamicsWorld::removeAction(btActionInterface* action)
 | |
| {
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| void	btSimpleDynamicsWorld::updateAabbs()
 | |
| {
 | |
| 	btTransform predictedTrans;
 | |
| 	for ( int i=0;i<m_collisionObjects.size();i++)
 | |
| 	{
 | |
| 		btCollisionObject* colObj = m_collisionObjects[i];
 | |
| 		btRigidBody* body = btRigidBody::upcast(colObj);
 | |
| 		if (body)
 | |
| 		{
 | |
| 			if (body->isActive() && (!body->isStaticObject()))
 | |
| 			{
 | |
| 				btVector3 minAabb,maxAabb;
 | |
| 				colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
 | |
| 				btBroadphaseInterface* bp = getBroadphase();
 | |
| 				bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void	btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep)
 | |
| {
 | |
| 	btTransform predictedTrans;
 | |
| 	for ( int i=0;i<m_collisionObjects.size();i++)
 | |
| 	{
 | |
| 		btCollisionObject* colObj = m_collisionObjects[i];
 | |
| 		btRigidBody* body = btRigidBody::upcast(colObj);
 | |
| 		if (body)
 | |
| 		{
 | |
| 			if (body->isActive() && (!body->isStaticObject()))
 | |
| 			{
 | |
| 				body->predictIntegratedTransform(timeStep, predictedTrans);
 | |
| 				body->proceedToTransform( predictedTrans);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| void	btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
 | |
| {
 | |
| 	for ( int i=0;i<m_collisionObjects.size();i++)
 | |
| 	{
 | |
| 		btCollisionObject* colObj = m_collisionObjects[i];
 | |
| 		btRigidBody* body = btRigidBody::upcast(colObj);
 | |
| 		if (body)
 | |
| 		{
 | |
| 			if (!body->isStaticObject())
 | |
| 			{
 | |
| 				if (body->isActive())
 | |
| 				{
 | |
| 					body->applyGravity();
 | |
| 					body->integrateVelocities( timeStep);
 | |
| 					body->applyDamping(timeStep);
 | |
| 					body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| void	btSimpleDynamicsWorld::synchronizeMotionStates()
 | |
| {
 | |
| 	///@todo: iterate over awake simulation islands!
 | |
| 	for ( int i=0;i<m_collisionObjects.size();i++)
 | |
| 	{
 | |
| 		btCollisionObject* colObj = m_collisionObjects[i];
 | |
| 		btRigidBody* body = btRigidBody::upcast(colObj);
 | |
| 		if (body && body->getMotionState())
 | |
| 		{
 | |
| 			if (body->getActivationState() != ISLAND_SLEEPING)
 | |
| 			{
 | |
| 				body->getMotionState()->setWorldTransform(body->getWorldTransform());
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| void	btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
 | |
| {
 | |
| 	if (m_ownsConstraintSolver)
 | |
| 	{
 | |
| 		btAlignedFree(m_constraintSolver);
 | |
| 	}
 | |
| 	m_ownsConstraintSolver = false;
 | |
| 	m_constraintSolver = solver;
 | |
| }
 | |
| 
 | |
| btConstraintSolver* btSimpleDynamicsWorld::getConstraintSolver()
 | |
| {
 | |
| 	return m_constraintSolver;
 | |
| }
 |