197 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			197 lines
		
	
	
		
			11 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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
							 | 
						||
| 
								 | 
							
								#define BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class btIDebugDraw;
							 | 
						||
| 
								 | 
							
								class btPersistentManifold;
							 | 
						||
| 
								 | 
							
								class btDispatcher;
							 | 
						||
| 
								 | 
							
								class btCollisionObject;
							 | 
						||
| 
								 | 
							
								#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
							 | 
						||
| 
								 | 
							
								#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
							 | 
						||
| 
								 | 
							
								#include "BulletDynamics/ConstraintSolver/btSolverBody.h"
							 | 
						||
| 
								 | 
							
								#include "BulletDynamics/ConstraintSolver/btSolverConstraint.h"
							 | 
						||
| 
								 | 
							
								#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
							 | 
						||
| 
								 | 
							
								#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef btSimdScalar(*btSingleConstraintRowSolver)(btSolverBody&, btSolverBody&, const btSolverConstraint&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
							 | 
						||
| 
								 | 
							
								ATTRIBUTE_ALIGNED16(class) btSequentialImpulseConstraintSolver : public btConstraintSolver
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btSolverBody>      m_tmpSolverBodyPool;
							 | 
						||
| 
								 | 
							
									btConstraintArray			m_tmpSolverContactConstraintPool;
							 | 
						||
| 
								 | 
							
									btConstraintArray			m_tmpSolverNonContactConstraintPool;
							 | 
						||
| 
								 | 
							
									btConstraintArray			m_tmpSolverContactFrictionConstraintPool;
							 | 
						||
| 
								 | 
							
									btConstraintArray			m_tmpSolverContactRollingFrictionConstraintPool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<int>	m_orderTmpConstraintPool;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<int>	m_orderNonContactConstraintPool;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<int>	m_orderFrictionConstraintPool;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
							 | 
						||
| 
								 | 
							
									int							m_maxOverrideNumSolverIterations;
							 | 
						||
| 
								 | 
							
									int m_fixedBodyId;
							 | 
						||
| 
								 | 
							
								    // When running solvers on multiple threads, a race condition exists for Kinematic objects that
							 | 
						||
| 
								 | 
							
								    // participate in more than one solver.
							 | 
						||
| 
								 | 
							
								    // The getOrInitSolverBody() function writes the companionId of each body (storing the index of the solver body
							 | 
						||
| 
								 | 
							
								    // for the current solver). For normal dynamic bodies it isn't an issue because they can only be in one island
							 | 
						||
| 
								 | 
							
								    // (and therefore one thread) at a time. But kinematic bodies can be in multiple islands at once.
							 | 
						||
| 
								 | 
							
								    // To avoid this race condition, this solver does not write the companionId, instead it stores the solver body
							 | 
						||
| 
								 | 
							
								    // index in this solver-local table, indexed by the uniqueId of the body.
							 | 
						||
| 
								 | 
							
								    btAlignedObjectArray<int>	m_kinematicBodyUniqueIdToSolverBodyTable;  // only used for multithreading
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver m_resolveSingleConstraintRowGeneric;
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver m_resolveSingleConstraintRowLowerLimit;
							 | 
						||
| 
								 | 
							
								    btSingleConstraintRowSolver m_resolveSplitPenetrationImpulse;
							 | 
						||
| 
								 | 
							
								    int m_cachedSolverMode;  // used to check if SOLVER_SIMD flag has been changed
							 | 
						||
| 
								 | 
							
								    void setupSolverFunctions( bool useSimd );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	m_leastSquaresResidual;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void setupFrictionConstraint(	btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int  solverBodyIdB,
							 | 
						||
| 
								 | 
							
																	btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
							 | 
						||
| 
								 | 
							
																	btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, 
							 | 
						||
| 
								 | 
							
																	const btContactSolverInfo& infoGlobal,
							 | 
						||
| 
								 | 
							
																	btScalar desiredVelocity=0., btScalar cfmSlip=0.);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void setupTorsionalFrictionConstraint(	btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int  solverBodyIdB,
							 | 
						||
| 
								 | 
							
																	btManifoldPoint& cp,btScalar combinedTorsionalFriction, const btVector3& rel_pos1,const btVector3& rel_pos2,
							 | 
						||
| 
								 | 
							
																	btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, 
							 | 
						||
| 
								 | 
							
																	btScalar desiredVelocity=0., btScalar cfmSlip=0.);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btSolverConstraint&	addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity=0., btScalar cfmSlip=0.);
							 | 
						||
| 
								 | 
							
									btSolverConstraint&	addTorsionalFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,btScalar torsionalFriction, const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0, btScalar cfmSlip=0.f);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									void setupContactConstraint(btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, 
							 | 
						||
| 
								 | 
							
																const btContactSolverInfo& infoGlobal,btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static void	applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, int solverBodyIdA,int solverBodyIdB, 
							 | 
						||
| 
								 | 
							
																		 btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
							 | 
						||
| 
								 | 
							
									unsigned long	m_btSeed2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btScalar restitutionCurve(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual void convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btSimdScalar	resolveSplitPenetrationSIMD(btSolverBody& bodyA,btSolverBody& bodyB, const btSolverConstraint& contactConstraint)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_resolveSplitPenetrationImpulse( bodyA, bodyB, contactConstraint );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btSimdScalar	resolveSplitPenetrationImpulseCacheFriendly(btSolverBody& bodyA,btSolverBody& bodyB, const btSolverConstraint& contactConstraint)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_resolveSplitPenetrationImpulse( bodyA, bodyB, contactConstraint );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//internal method
							 | 
						||
| 
								 | 
							
									int		getOrInitSolverBody(btCollisionObject& body,btScalar timeStep);
							 | 
						||
| 
								 | 
							
									void	initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btSimdScalar	resolveSingleConstraintRowGeneric(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
							 | 
						||
| 
								 | 
							
									btSimdScalar	resolveSingleConstraintRowGenericSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
							 | 
						||
| 
								 | 
							
									btSimdScalar	resolveSingleConstraintRowLowerLimit(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
							 | 
						||
| 
								 | 
							
									btSimdScalar	resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
							 | 
						||
| 
								 | 
							
									btSimdScalar	resolveSplitPenetrationImpulse(btSolverBody& bodyA,btSolverBody& bodyB, const btSolverConstraint& contactConstraint)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_resolveSplitPenetrationImpulse( bodyA, bodyB, contactConstraint );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
							 | 
						||
| 
								 | 
							
									virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal);
							 | 
						||
| 
								 | 
							
									virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
							 | 
						||
| 
								 | 
							
									virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_DECLARE_ALIGNED_ALLOCATOR();
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btSequentialImpulseConstraintSolver();
							 | 
						||
| 
								 | 
							
									virtual ~btSequentialImpulseConstraintSolver();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher);
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
									///clear internal cached data and reset random seed
							 | 
						||
| 
								 | 
							
									virtual	void	reset();
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									unsigned long btRand2();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int btRandInt2 (int n);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	setRandSeed(unsigned long seed)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_btSeed2 = seed;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									unsigned long	getRandSeed() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_btSeed2;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									virtual btConstraintSolverType	getSolverType() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return BT_SEQUENTIAL_IMPULSE_SOLVER;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getActiveConstraintRowSolverGeneric()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_resolveSingleConstraintRowGeneric;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									void setConstraintRowSolverGeneric(btSingleConstraintRowSolver rowSolver)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_resolveSingleConstraintRowGeneric = rowSolver;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getActiveConstraintRowSolverLowerLimit()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_resolveSingleConstraintRowLowerLimit;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									void setConstraintRowSolverLowerLimit(btSingleConstraintRowSolver rowSolver)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_resolveSingleConstraintRowLowerLimit = rowSolver;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///Various implementations of solving a single constraint row using a generic equality constraint, using scalar reference, SSE2 or SSE4
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getScalarConstraintRowSolverGeneric();
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getSSE2ConstraintRowSolverGeneric();
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getSSE4_1ConstraintRowSolverGeneric();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///Various implementations of solving a single constraint row using an inequality (lower limit) constraint, using scalar reference, SSE2 or SSE4
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getScalarConstraintRowSolverLowerLimit();
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getSSE2ConstraintRowSolverLowerLimit();
							 | 
						||
| 
								 | 
							
									btSingleConstraintRowSolver	getSSE4_1ConstraintRowSolverLowerLimit();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
							 | 
						||
| 
								 | 
							
								
							 |