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