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
 | 
						|
 |