369 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			369 lines
		
	
	
		
			14 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.
 | |
| */
 | |
| 
 | |
| /*
 | |
| Added by Roman Ponomarev (rponom@gmail.com)
 | |
| April 04, 2008
 | |
| 
 | |
| TODO:
 | |
|  - add clamping od accumulated impulse to improve stability
 | |
|  - add conversion for ODE constraint solver
 | |
| */
 | |
| 
 | |
| #ifndef BT_SLIDER_CONSTRAINT_H
 | |
| #define BT_SLIDER_CONSTRAINT_H
 | |
| 
 | |
| #include "LinearMath/btScalar.h"//for BT_USE_DOUBLE_PRECISION
 | |
| 
 | |
| #ifdef BT_USE_DOUBLE_PRECISION
 | |
| #define btSliderConstraintData2		btSliderConstraintDoubleData
 | |
| #define btSliderConstraintDataName  "btSliderConstraintDoubleData"
 | |
| #else
 | |
| #define btSliderConstraintData2		btSliderConstraintData 
 | |
| #define btSliderConstraintDataName	"btSliderConstraintData"
 | |
| #endif //BT_USE_DOUBLE_PRECISION
 | |
| 
 | |
| #include "LinearMath/btVector3.h"
 | |
| #include "btJacobianEntry.h"
 | |
| #include "btTypedConstraint.h"
 | |
| 
 | |
| 
 | |
| 
 | |
| class btRigidBody;
 | |
| 
 | |
| 
 | |
| 
 | |
| #define SLIDER_CONSTRAINT_DEF_SOFTNESS		(btScalar(1.0))
 | |
| #define SLIDER_CONSTRAINT_DEF_DAMPING		(btScalar(1.0))
 | |
| #define SLIDER_CONSTRAINT_DEF_RESTITUTION	(btScalar(0.7))
 | |
| #define SLIDER_CONSTRAINT_DEF_CFM			(btScalar(0.f))
 | |
| 
 | |
| 
 | |
| enum btSliderFlags
 | |
| {
 | |
| 	BT_SLIDER_FLAGS_CFM_DIRLIN = (1 << 0),
 | |
| 	BT_SLIDER_FLAGS_ERP_DIRLIN = (1 << 1),
 | |
| 	BT_SLIDER_FLAGS_CFM_DIRANG = (1 << 2),
 | |
| 	BT_SLIDER_FLAGS_ERP_DIRANG = (1 << 3),
 | |
| 	BT_SLIDER_FLAGS_CFM_ORTLIN = (1 << 4),
 | |
| 	BT_SLIDER_FLAGS_ERP_ORTLIN = (1 << 5),
 | |
| 	BT_SLIDER_FLAGS_CFM_ORTANG = (1 << 6),
 | |
| 	BT_SLIDER_FLAGS_ERP_ORTANG = (1 << 7),
 | |
| 	BT_SLIDER_FLAGS_CFM_LIMLIN = (1 << 8),
 | |
| 	BT_SLIDER_FLAGS_ERP_LIMLIN = (1 << 9),
 | |
| 	BT_SLIDER_FLAGS_CFM_LIMANG = (1 << 10),
 | |
| 	BT_SLIDER_FLAGS_ERP_LIMANG = (1 << 11)
 | |
| };
 | |
| 
 | |
| 
 | |
| ATTRIBUTE_ALIGNED16(class) btSliderConstraint : public btTypedConstraint
 | |
| {
 | |
| protected:
 | |
| 	///for backwards compatibility during the transition to 'getInfo/getInfo2'
 | |
| 	bool		m_useSolveConstraintObsolete;
 | |
| 	bool		m_useOffsetForConstraintFrame;
 | |
| 	btTransform	m_frameInA;
 | |
|     btTransform	m_frameInB;
 | |
| 	// use frameA fo define limits, if true
 | |
| 	bool m_useLinearReferenceFrameA;
 | |
| 	// linear limits
 | |
| 	btScalar m_lowerLinLimit;
 | |
| 	btScalar m_upperLinLimit;
 | |
| 	// angular limits
 | |
| 	btScalar m_lowerAngLimit;
 | |
| 	btScalar m_upperAngLimit;
 | |
| 	// softness, restitution and damping for different cases
 | |
| 	// DirLin - moving inside linear limits
 | |
| 	// LimLin - hitting linear limit
 | |
| 	// DirAng - moving inside angular limits
 | |
| 	// LimAng - hitting angular limit
 | |
| 	// OrthoLin, OrthoAng - against constraint axis
 | |
| 	btScalar m_softnessDirLin;
 | |
| 	btScalar m_restitutionDirLin;
 | |
| 	btScalar m_dampingDirLin;
 | |
| 	btScalar m_cfmDirLin;
 | |
| 
 | |
| 	btScalar m_softnessDirAng;
 | |
| 	btScalar m_restitutionDirAng;
 | |
| 	btScalar m_dampingDirAng;
 | |
| 	btScalar m_cfmDirAng;
 | |
| 
 | |
| 	btScalar m_softnessLimLin;
 | |
| 	btScalar m_restitutionLimLin;
 | |
| 	btScalar m_dampingLimLin;
 | |
| 	btScalar m_cfmLimLin;
 | |
| 
 | |
| 	btScalar m_softnessLimAng;
 | |
| 	btScalar m_restitutionLimAng;
 | |
| 	btScalar m_dampingLimAng;
 | |
| 	btScalar m_cfmLimAng;
 | |
| 
 | |
| 	btScalar m_softnessOrthoLin;
 | |
| 	btScalar m_restitutionOrthoLin;
 | |
| 	btScalar m_dampingOrthoLin;
 | |
| 	btScalar m_cfmOrthoLin;
 | |
| 
 | |
| 	btScalar m_softnessOrthoAng;
 | |
| 	btScalar m_restitutionOrthoAng;
 | |
| 	btScalar m_dampingOrthoAng;
 | |
| 	btScalar m_cfmOrthoAng;
 | |
| 	
 | |
| 	// for interlal use
 | |
| 	bool m_solveLinLim;
 | |
| 	bool m_solveAngLim;
 | |
| 
 | |
| 	int m_flags;
 | |
| 
 | |
| 	btJacobianEntry	m_jacLin[3];
 | |
| 	btScalar		m_jacLinDiagABInv[3];
 | |
| 
 | |
|     btJacobianEntry	m_jacAng[3];
 | |
| 
 | |
| 	btScalar m_timeStep;
 | |
|     btTransform m_calculatedTransformA;
 | |
|     btTransform m_calculatedTransformB;
 | |
| 
 | |
| 	btVector3 m_sliderAxis;
 | |
| 	btVector3 m_realPivotAInW;
 | |
| 	btVector3 m_realPivotBInW;
 | |
| 	btVector3 m_projPivotInW;
 | |
| 	btVector3 m_delta;
 | |
| 	btVector3 m_depth;
 | |
| 	btVector3 m_relPosA;
 | |
| 	btVector3 m_relPosB;
 | |
| 
 | |
| 	btScalar m_linPos;
 | |
| 	btScalar m_angPos;
 | |
| 
 | |
| 	btScalar m_angDepth;
 | |
| 	btScalar m_kAngle;
 | |
| 
 | |
| 	bool	 m_poweredLinMotor;
 | |
|     btScalar m_targetLinMotorVelocity;
 | |
|     btScalar m_maxLinMotorForce;
 | |
|     btScalar m_accumulatedLinMotorImpulse;
 | |
| 	
 | |
| 	bool	 m_poweredAngMotor;
 | |
|     btScalar m_targetAngMotorVelocity;
 | |
|     btScalar m_maxAngMotorForce;
 | |
|     btScalar m_accumulatedAngMotorImpulse;
 | |
| 
 | |
| 	//------------------------    
 | |
| 	void initParams();
 | |
| public:
 | |
| 	BT_DECLARE_ALIGNED_ALLOCATOR();
 | |
| 	
 | |
| 	// constructors
 | |
|     btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
 | |
|     btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
 | |
| 
 | |
| 	// overrides
 | |
| 
 | |
|     virtual void getInfo1 (btConstraintInfo1* info);
 | |
| 
 | |
| 	void getInfo1NonVirtual(btConstraintInfo1* info);
 | |
| 	
 | |
| 	virtual void getInfo2 (btConstraintInfo2* info);
 | |
| 
 | |
| 	void getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB, btScalar rbAinvMass,btScalar rbBinvMass);
 | |
| 
 | |
| 
 | |
| 	// access
 | |
|     const btRigidBody& getRigidBodyA() const { return m_rbA; }
 | |
|     const btRigidBody& getRigidBodyB() const { return m_rbB; }
 | |
|     const btTransform & getCalculatedTransformA() const { return m_calculatedTransformA; }
 | |
|     const btTransform & getCalculatedTransformB() const { return m_calculatedTransformB; }
 | |
|     const btTransform & getFrameOffsetA() const { return m_frameInA; }
 | |
|     const btTransform & getFrameOffsetB() const { return m_frameInB; }
 | |
|     btTransform & getFrameOffsetA() { return m_frameInA; }
 | |
|     btTransform & getFrameOffsetB() { return m_frameInB; }
 | |
|     btScalar getLowerLinLimit() { return m_lowerLinLimit; }
 | |
|     void setLowerLinLimit(btScalar lowerLimit) { m_lowerLinLimit = lowerLimit; }
 | |
|     btScalar getUpperLinLimit() { return m_upperLinLimit; }
 | |
|     void setUpperLinLimit(btScalar upperLimit) { m_upperLinLimit = upperLimit; }
 | |
|     btScalar getLowerAngLimit() { return m_lowerAngLimit; }
 | |
|     void setLowerAngLimit(btScalar lowerLimit) { m_lowerAngLimit = btNormalizeAngle(lowerLimit); }
 | |
|     btScalar getUpperAngLimit() { return m_upperAngLimit; }
 | |
|     void setUpperAngLimit(btScalar upperLimit) { m_upperAngLimit = btNormalizeAngle(upperLimit); }
 | |
| 	bool getUseLinearReferenceFrameA() { return m_useLinearReferenceFrameA; }
 | |
| 	btScalar getSoftnessDirLin() { return m_softnessDirLin; }
 | |
| 	btScalar getRestitutionDirLin() { return m_restitutionDirLin; }
 | |
| 	btScalar getDampingDirLin() { return m_dampingDirLin ; }
 | |
| 	btScalar getSoftnessDirAng() { return m_softnessDirAng; }
 | |
| 	btScalar getRestitutionDirAng() { return m_restitutionDirAng; }
 | |
| 	btScalar getDampingDirAng() { return m_dampingDirAng; }
 | |
| 	btScalar getSoftnessLimLin() { return m_softnessLimLin; }
 | |
| 	btScalar getRestitutionLimLin() { return m_restitutionLimLin; }
 | |
| 	btScalar getDampingLimLin() { return m_dampingLimLin; }
 | |
| 	btScalar getSoftnessLimAng() { return m_softnessLimAng; }
 | |
| 	btScalar getRestitutionLimAng() { return m_restitutionLimAng; }
 | |
| 	btScalar getDampingLimAng() { return m_dampingLimAng; }
 | |
| 	btScalar getSoftnessOrthoLin() { return m_softnessOrthoLin; }
 | |
| 	btScalar getRestitutionOrthoLin() { return m_restitutionOrthoLin; }
 | |
| 	btScalar getDampingOrthoLin() { return m_dampingOrthoLin; }
 | |
| 	btScalar getSoftnessOrthoAng() { return m_softnessOrthoAng; }
 | |
| 	btScalar getRestitutionOrthoAng() { return m_restitutionOrthoAng; }
 | |
| 	btScalar getDampingOrthoAng() { return m_dampingOrthoAng; }
 | |
| 	void setSoftnessDirLin(btScalar softnessDirLin) { m_softnessDirLin = softnessDirLin; }
 | |
| 	void setRestitutionDirLin(btScalar restitutionDirLin) { m_restitutionDirLin = restitutionDirLin; }
 | |
| 	void setDampingDirLin(btScalar dampingDirLin) { m_dampingDirLin = dampingDirLin; }
 | |
| 	void setSoftnessDirAng(btScalar softnessDirAng) { m_softnessDirAng = softnessDirAng; }
 | |
| 	void setRestitutionDirAng(btScalar restitutionDirAng) { m_restitutionDirAng = restitutionDirAng; }
 | |
| 	void setDampingDirAng(btScalar dampingDirAng) { m_dampingDirAng = dampingDirAng; }
 | |
| 	void setSoftnessLimLin(btScalar softnessLimLin) { m_softnessLimLin = softnessLimLin; }
 | |
| 	void setRestitutionLimLin(btScalar restitutionLimLin) { m_restitutionLimLin = restitutionLimLin; }
 | |
| 	void setDampingLimLin(btScalar dampingLimLin) { m_dampingLimLin = dampingLimLin; }
 | |
| 	void setSoftnessLimAng(btScalar softnessLimAng) { m_softnessLimAng = softnessLimAng; }
 | |
| 	void setRestitutionLimAng(btScalar restitutionLimAng) { m_restitutionLimAng = restitutionLimAng; }
 | |
| 	void setDampingLimAng(btScalar dampingLimAng) { m_dampingLimAng = dampingLimAng; }
 | |
| 	void setSoftnessOrthoLin(btScalar softnessOrthoLin) { m_softnessOrthoLin = softnessOrthoLin; }
 | |
| 	void setRestitutionOrthoLin(btScalar restitutionOrthoLin) { m_restitutionOrthoLin = restitutionOrthoLin; }
 | |
| 	void setDampingOrthoLin(btScalar dampingOrthoLin) { m_dampingOrthoLin = dampingOrthoLin; }
 | |
| 	void setSoftnessOrthoAng(btScalar softnessOrthoAng) { m_softnessOrthoAng = softnessOrthoAng; }
 | |
| 	void setRestitutionOrthoAng(btScalar restitutionOrthoAng) { m_restitutionOrthoAng = restitutionOrthoAng; }
 | |
| 	void setDampingOrthoAng(btScalar dampingOrthoAng) { m_dampingOrthoAng = dampingOrthoAng; }
 | |
| 	void setPoweredLinMotor(bool onOff) { m_poweredLinMotor = onOff; }
 | |
| 	bool getPoweredLinMotor() { return m_poweredLinMotor; }
 | |
| 	void setTargetLinMotorVelocity(btScalar targetLinMotorVelocity) { m_targetLinMotorVelocity = targetLinMotorVelocity; }
 | |
| 	btScalar getTargetLinMotorVelocity() { return m_targetLinMotorVelocity; }
 | |
| 	void setMaxLinMotorForce(btScalar maxLinMotorForce) { m_maxLinMotorForce = maxLinMotorForce; }
 | |
| 	btScalar getMaxLinMotorForce() { return m_maxLinMotorForce; }
 | |
| 	void setPoweredAngMotor(bool onOff) { m_poweredAngMotor = onOff; }
 | |
| 	bool getPoweredAngMotor() { return m_poweredAngMotor; }
 | |
| 	void setTargetAngMotorVelocity(btScalar targetAngMotorVelocity) { m_targetAngMotorVelocity = targetAngMotorVelocity; }
 | |
| 	btScalar getTargetAngMotorVelocity() { return m_targetAngMotorVelocity; }
 | |
| 	void setMaxAngMotorForce(btScalar maxAngMotorForce) { m_maxAngMotorForce = maxAngMotorForce; }
 | |
| 	btScalar getMaxAngMotorForce() { return m_maxAngMotorForce; }
 | |
| 
 | |
| 	btScalar getLinearPos() const { return m_linPos; }
 | |
| 	btScalar getAngularPos() const { return m_angPos; }
 | |
| 	
 | |
| 	
 | |
| 
 | |
| 	// access for ODE solver
 | |
| 	bool getSolveLinLimit() { return m_solveLinLim; }
 | |
| 	btScalar getLinDepth() { return m_depth[0]; }
 | |
| 	bool getSolveAngLimit() { return m_solveAngLim; }
 | |
| 	btScalar getAngDepth() { return m_angDepth; }
 | |
| 	// shared code used by ODE solver
 | |
| 	void	calculateTransforms(const btTransform& transA,const btTransform& transB);
 | |
| 	void	testLinLimits();
 | |
| 	void	testAngLimits();
 | |
| 	// access for PE Solver
 | |
| 	btVector3 getAncorInA();
 | |
| 	btVector3 getAncorInB();
 | |
| 	// access for UseFrameOffset
 | |
| 	bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
 | |
| 	void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
 | |
| 
 | |
| 	void setFrames(const btTransform& frameA, const btTransform& frameB) 
 | |
| 	{ 
 | |
| 		m_frameInA=frameA; 
 | |
| 		m_frameInB=frameB;
 | |
| 		calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
 | |
| 		buildJacobian();
 | |
| 	} 
 | |
| 
 | |
| 
 | |
| 	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
 | |
| 	///If no axis is provided, it uses the default axis for this constraint.
 | |
| 	virtual	void	setParam(int num, btScalar value, int axis = -1);
 | |
| 	///return the local value of parameter
 | |
| 	virtual	btScalar getParam(int num, int axis = -1) const;
 | |
| 	
 | |
| 	virtual	int getFlags() const
 | |
|     	{
 | |
| 		return m_flags;
 | |
| 	}
 | |
| 
 | |
| 	virtual	int	calculateSerializeBufferSize() const;
 | |
| 
 | |
| 	///fills the dataBuffer and returns the struct name (and 0 on failure)
 | |
| 	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;
 | |
| 
 | |
| 
 | |
| };
 | |
| 
 | |
| 
 | |
| ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
 | |
| 
 | |
| 
 | |
| struct btSliderConstraintData
 | |
| {
 | |
| 	btTypedConstraintData	m_typeConstraintData;
 | |
| 	btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
 | |
| 	btTransformFloatData m_rbBFrame;
 | |
| 	
 | |
| 	float	m_linearUpperLimit;
 | |
| 	float	m_linearLowerLimit;
 | |
| 
 | |
| 	float	m_angularUpperLimit;
 | |
| 	float	m_angularLowerLimit;
 | |
| 
 | |
| 	int	m_useLinearReferenceFrameA;
 | |
| 	int m_useOffsetForConstraintFrame;
 | |
| 
 | |
| };
 | |
| 
 | |
| 
 | |
| struct btSliderConstraintDoubleData
 | |
| {
 | |
| 	btTypedConstraintDoubleData	m_typeConstraintData;
 | |
| 	btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
 | |
| 	btTransformDoubleData m_rbBFrame;
 | |
| 	
 | |
| 	double	m_linearUpperLimit;
 | |
| 	double	m_linearLowerLimit;
 | |
| 
 | |
| 	double	m_angularUpperLimit;
 | |
| 	double	m_angularLowerLimit;
 | |
| 
 | |
| 	int	m_useLinearReferenceFrameA;
 | |
| 	int m_useOffsetForConstraintFrame;
 | |
| 
 | |
| };
 | |
| 
 | |
| SIMD_FORCE_INLINE		int	btSliderConstraint::calculateSerializeBufferSize() const
 | |
| {
 | |
| 	return sizeof(btSliderConstraintData2);
 | |
| }
 | |
| 
 | |
| 	///fills the dataBuffer and returns the struct name (and 0 on failure)
 | |
| SIMD_FORCE_INLINE	const char*	btSliderConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
 | |
| {
 | |
| 
 | |
| 	btSliderConstraintData2* sliderData = (btSliderConstraintData2*) dataBuffer;
 | |
| 	btTypedConstraint::serialize(&sliderData->m_typeConstraintData,serializer);
 | |
| 
 | |
| 	m_frameInA.serialize(sliderData->m_rbAFrame);
 | |
| 	m_frameInB.serialize(sliderData->m_rbBFrame);
 | |
| 
 | |
| 	sliderData->m_linearUpperLimit = m_upperLinLimit;
 | |
| 	sliderData->m_linearLowerLimit = m_lowerLinLimit;
 | |
| 
 | |
| 	sliderData->m_angularUpperLimit = m_upperAngLimit;
 | |
| 	sliderData->m_angularLowerLimit = m_lowerAngLimit;
 | |
| 
 | |
| 	sliderData->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA;
 | |
| 	sliderData->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame;
 | |
| 
 | |
| 	return btSliderConstraintDataName;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #endif //BT_SLIDER_CONSTRAINT_H
 | |
| 
 |