forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			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
 | ||
|  | 
 |