504 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			504 lines
		
	
	
		
			15 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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Hinge Constraint by Dirk Gregorius. Limits added by Marcus Hennix at Starbreeze Studios */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BT_HINGECONSTRAINT_H
							 | 
						||
| 
								 | 
							
								#define BT_HINGECONSTRAINT_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define _BT_USE_CENTER_LIMIT_ 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btVector3.h"
							 | 
						||
| 
								 | 
							
								#include "btJacobianEntry.h"
							 | 
						||
| 
								 | 
							
								#include "btTypedConstraint.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class btRigidBody;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
								#define btHingeConstraintData	btHingeConstraintDoubleData2 //rename to 2 for backwards compatibility, so we can still load the 'btHingeConstraintDoubleData' version
							 | 
						||
| 
								 | 
							
								#define btHingeConstraintDataName	"btHingeConstraintDoubleData2" 
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define btHingeConstraintData	btHingeConstraintFloatData
							 | 
						||
| 
								 | 
							
								#define btHingeConstraintDataName	"btHingeConstraintFloatData"
							 | 
						||
| 
								 | 
							
								#endif //BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum btHingeFlags
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									BT_HINGE_FLAGS_CFM_STOP = 1,
							 | 
						||
| 
								 | 
							
									BT_HINGE_FLAGS_ERP_STOP = 2,
							 | 
						||
| 
								 | 
							
									BT_HINGE_FLAGS_CFM_NORM = 4,
							 | 
						||
| 
								 | 
							
									BT_HINGE_FLAGS_ERP_NORM = 8
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space
							 | 
						||
| 
								 | 
							
								/// axis defines the orientation of the hinge axis
							 | 
						||
| 
								 | 
							
								ATTRIBUTE_ALIGNED16(class) btHingeConstraint : public btTypedConstraint
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#ifdef IN_PARALLELL_SOLVER
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									btJacobianEntry	m_jac[3]; //3 orthogonal linear constraints
							 | 
						||
| 
								 | 
							
									btJacobianEntry	m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis.
							 | 
						||
| 
								 | 
							
									btTransform m_rbBFrame;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	m_motorTargetVelocity;
							 | 
						||
| 
								 | 
							
									btScalar	m_maxMotorImpulse;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
									btAngularLimit	m_limit;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									btScalar	m_lowerLimit;	
							 | 
						||
| 
								 | 
							
									btScalar	m_upperLimit;	
							 | 
						||
| 
								 | 
							
									btScalar	m_limitSign;
							 | 
						||
| 
								 | 
							
									btScalar	m_correction;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	m_limitSoftness; 
							 | 
						||
| 
								 | 
							
									btScalar	m_biasFactor; 
							 | 
						||
| 
								 | 
							
									btScalar	m_relaxationFactor; 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool		m_solveLimit;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	m_kHinge;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	m_accLimitImpulse;
							 | 
						||
| 
								 | 
							
									btScalar	m_hingeAngle;
							 | 
						||
| 
								 | 
							
									btScalar	m_referenceSign;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool		m_angularOnly;
							 | 
						||
| 
								 | 
							
									bool		m_enableAngularMotor;
							 | 
						||
| 
								 | 
							
									bool		m_useSolveConstraintObsolete;
							 | 
						||
| 
								 | 
							
									bool		m_useOffsetForConstraintFrame;
							 | 
						||
| 
								 | 
							
									bool		m_useReferenceFrameA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	m_accMotorImpulse;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int			m_flags;
							 | 
						||
| 
								 | 
							
									btScalar	m_normalCFM;
							 | 
						||
| 
								 | 
							
									btScalar	m_normalERP;
							 | 
						||
| 
								 | 
							
									btScalar	m_stopCFM;
							 | 
						||
| 
								 | 
							
									btScalar	m_stopERP;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_DECLARE_ALIGNED_ALLOCATOR();
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual void	buildJacobian();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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& angVelA,const btVector3& angVelB);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
							 | 
						||
| 
								 | 
							
									void	getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	updateRHS(btScalar	timeStep);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const btRigidBody& getRigidBodyA() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_rbA;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									const btRigidBody& getRigidBodyB() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_rbB;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btRigidBody& getRigidBodyA()	
							 | 
						||
| 
								 | 
							
									{		
							 | 
						||
| 
								 | 
							
										return m_rbA;	
							 | 
						||
| 
								 | 
							
									}	
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btRigidBody& getRigidBodyB()	
							 | 
						||
| 
								 | 
							
									{		
							 | 
						||
| 
								 | 
							
										return m_rbB;	
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btTransform& getFrameOffsetA()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									return m_rbAFrame;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btTransform& getFrameOffsetB()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_rbBFrame;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void setFrames(const btTransform& frameA, const btTransform& frameB);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									void	setAngularOnly(bool angularOnly)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_angularOnly = angularOnly;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_enableAngularMotor  = enableMotor;
							 | 
						||
| 
								 | 
							
										m_motorTargetVelocity = targetVelocity;
							 | 
						||
| 
								 | 
							
										m_maxMotorImpulse = maxMotorImpulse;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// extra motor API, including ability to set a target rotation (as opposed to angular velocity)
							 | 
						||
| 
								 | 
							
									// note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to
							 | 
						||
| 
								 | 
							
									//       maintain a given angular target.
							 | 
						||
| 
								 | 
							
									void enableMotor(bool enableMotor) 	{ m_enableAngularMotor = enableMotor; }
							 | 
						||
| 
								 | 
							
									void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
							 | 
						||
| 
								 | 
							
									void setMotorTargetVelocity(btScalar motorTargetVelocity) { m_motorTargetVelocity = motorTargetVelocity; }
							 | 
						||
| 
								 | 
							
									void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B.
							 | 
						||
| 
								 | 
							
									void setMotorTarget(btScalar targetAngle, btScalar dt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
										m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										m_lowerLimit = btNormalizeAngle(low);
							 | 
						||
| 
								 | 
							
										m_upperLimit = btNormalizeAngle(high);
							 | 
						||
| 
								 | 
							
										m_limitSoftness =  _softness;
							 | 
						||
| 
								 | 
							
										m_biasFactor = _biasFactor;
							 | 
						||
| 
								 | 
							
										m_relaxationFactor = _relaxationFactor;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btScalar getLimitSoftness() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
										return m_limit.getSoftness();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										return m_limitSoftness;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar getLimitBiasFactor() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
										return m_limit.getBiasFactor();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										return m_biasFactor;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar getLimitRelaxationFactor() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
										return m_limit.getRelaxationFactor();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										return m_relaxationFactor;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	setAxis(btVector3& axisInA)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 rbAxisA1, rbAxisA2;
							 | 
						||
| 
								 | 
							
										btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
							 | 
						||
| 
								 | 
							
										btVector3 pivotInA = m_rbAFrame.getOrigin();
							 | 
						||
| 
								 | 
							
								//		m_rbAFrame.getOrigin() = pivotInA;
							 | 
						||
| 
								 | 
							
										m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
							 | 
						||
| 
								 | 
							
																		rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
							 | 
						||
| 
								 | 
							
																		rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
							 | 
						||
| 
								 | 
							
										btVector3 rbAxisB1 =  quatRotate(rotationArc,rbAxisA1);
							 | 
						||
| 
								 | 
							
										btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
							 | 
						||
| 
								 | 
							
																		rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
							 | 
						||
| 
								 | 
							
																		rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
							 | 
						||
| 
								 | 
							
										m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bool hasLimit() const {
							 | 
						||
| 
								 | 
							
								#ifdef  _BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
								        return m_limit.getHalfRange() > 0;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        return m_lowerLimit <= m_upperLimit;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	getLowerLimit() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
									return m_limit.getLow();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									return m_lowerLimit;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	getUpperLimit() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
									return m_limit.getHigh();
							 | 
						||
| 
								 | 
							
								#else		
							 | 
						||
| 
								 | 
							
									return m_upperLimit;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///The getHingeAngle gives the hinge angle in range [-PI,PI]
							 | 
						||
| 
								 | 
							
									btScalar getHingeAngle();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar getHingeAngle(const btTransform& transA,const btTransform& transB);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void testLimit(const btTransform& transA,const btTransform& transB);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const btTransform& getAFrame() const { return m_rbAFrame; };	
							 | 
						||
| 
								 | 
							
									const btTransform& getBFrame() const { return m_rbBFrame; };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btTransform& getAFrame() { return m_rbAFrame; };	
							 | 
						||
| 
								 | 
							
									btTransform& getBFrame() { return m_rbBFrame; };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline int getSolveLimit()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
									return m_limit.isLimit();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									return m_solveLimit;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline btScalar getLimitSign()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
									return m_limit.getSign();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										return m_limitSign;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline bool getAngularOnly() 
							 | 
						||
| 
								 | 
							
									{ 
							 | 
						||
| 
								 | 
							
										return m_angularOnly; 
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									inline bool getEnableAngularMotor() 
							 | 
						||
| 
								 | 
							
									{ 
							 | 
						||
| 
								 | 
							
										return m_enableAngularMotor; 
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									inline btScalar getMotorTargetVelocity() 
							 | 
						||
| 
								 | 
							
									{ 
							 | 
						||
| 
								 | 
							
										return m_motorTargetVelocity; 
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									inline btScalar getMaxMotorImpulse() 
							 | 
						||
| 
								 | 
							
									{ 
							 | 
						||
| 
								 | 
							
										return m_maxMotorImpulse; 
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// access for UseFrameOffset
							 | 
						||
| 
								 | 
							
									bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
							 | 
						||
| 
								 | 
							
									void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
							 | 
						||
| 
								 | 
							
									// access for UseReferenceFrameA
							 | 
						||
| 
								 | 
							
									bool getUseReferenceFrameA() const { return m_useReferenceFrameA; }
							 | 
						||
| 
								 | 
							
									void setUseReferenceFrameA(bool useReferenceFrameA) { m_useReferenceFrameA = useReferenceFrameA; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//only for backward compatibility
							 | 
						||
| 
								 | 
							
								#ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
							 | 
						||
| 
								 | 
							
								///this structure is not used, except for loading pre-2.82 .bullet files
							 | 
						||
| 
								 | 
							
								struct	btHingeConstraintDoubleData
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btTypedConstraintData	m_typeConstraintData;
							 | 
						||
| 
								 | 
							
									btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
							 | 
						||
| 
								 | 
							
									btTransformDoubleData m_rbBFrame;
							 | 
						||
| 
								 | 
							
									int			m_useReferenceFrameA;
							 | 
						||
| 
								 | 
							
									int			m_angularOnly;
							 | 
						||
| 
								 | 
							
									int			m_enableAngularMotor;
							 | 
						||
| 
								 | 
							
									float	m_motorTargetVelocity;
							 | 
						||
| 
								 | 
							
									float	m_maxMotorImpulse;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float	m_lowerLimit;
							 | 
						||
| 
								 | 
							
									float	m_upperLimit;
							 | 
						||
| 
								 | 
							
									float	m_limitSoftness;
							 | 
						||
| 
								 | 
							
									float	m_biasFactor;
							 | 
						||
| 
								 | 
							
									float	m_relaxationFactor;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///The getAccumulatedHingeAngle returns the accumulated hinge angle, taking rotation across the -PI/PI boundary into account
							 | 
						||
| 
								 | 
							
								ATTRIBUTE_ALIGNED16(class) btHingeAccumulatedAngleConstraint : public btHingeConstraint
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
									btScalar	m_accumulatedAngle;
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_DECLARE_ALIGNED_ALLOCATOR();
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btHingeAccumulatedAngleConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false)
							 | 
						||
| 
								 | 
							
									:btHingeConstraint(rbA,rbB,pivotInA,pivotInB, axisInA,axisInB, useReferenceFrameA )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_accumulatedAngle=getHingeAngle();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btHingeAccumulatedAngleConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false)
							 | 
						||
| 
								 | 
							
									:btHingeConstraint(rbA,pivotInA,axisInA, useReferenceFrameA)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_accumulatedAngle=getHingeAngle();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btHingeAccumulatedAngleConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false)
							 | 
						||
| 
								 | 
							
									:btHingeConstraint(rbA,rbB, rbAFrame, rbBFrame, useReferenceFrameA )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_accumulatedAngle=getHingeAngle();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btHingeAccumulatedAngleConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false)
							 | 
						||
| 
								 | 
							
									:btHingeConstraint(rbA,rbAFrame, useReferenceFrameA )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_accumulatedAngle=getHingeAngle();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									btScalar getAccumulatedHingeAngle();
							 | 
						||
| 
								 | 
							
									void	setAccumulatedHingeAngle(btScalar accAngle);
							 | 
						||
| 
								 | 
							
									virtual void getInfo1 (btConstraintInfo1* info);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct	btHingeConstraintFloatData
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btTypedConstraintData	m_typeConstraintData;
							 | 
						||
| 
								 | 
							
									btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
							 | 
						||
| 
								 | 
							
									btTransformFloatData m_rbBFrame;
							 | 
						||
| 
								 | 
							
									int			m_useReferenceFrameA;
							 | 
						||
| 
								 | 
							
									int			m_angularOnly;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int			m_enableAngularMotor;
							 | 
						||
| 
								 | 
							
									float	m_motorTargetVelocity;
							 | 
						||
| 
								 | 
							
									float	m_maxMotorImpulse;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float	m_lowerLimit;
							 | 
						||
| 
								 | 
							
									float	m_upperLimit;
							 | 
						||
| 
								 | 
							
									float	m_limitSoftness;
							 | 
						||
| 
								 | 
							
									float	m_biasFactor;
							 | 
						||
| 
								 | 
							
									float	m_relaxationFactor;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
							 | 
						||
| 
								 | 
							
								struct	btHingeConstraintDoubleData2
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btTypedConstraintDoubleData	m_typeConstraintData;
							 | 
						||
| 
								 | 
							
									btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
							 | 
						||
| 
								 | 
							
									btTransformDoubleData m_rbBFrame;
							 | 
						||
| 
								 | 
							
									int			m_useReferenceFrameA;
							 | 
						||
| 
								 | 
							
									int			m_angularOnly;
							 | 
						||
| 
								 | 
							
									int			m_enableAngularMotor;
							 | 
						||
| 
								 | 
							
									double		m_motorTargetVelocity;
							 | 
						||
| 
								 | 
							
									double		m_maxMotorImpulse;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									double		m_lowerLimit;
							 | 
						||
| 
								 | 
							
									double		m_upperLimit;
							 | 
						||
| 
								 | 
							
									double		m_limitSoftness;
							 | 
						||
| 
								 | 
							
									double		m_biasFactor;
							 | 
						||
| 
								 | 
							
									double		m_relaxationFactor;
							 | 
						||
| 
								 | 
							
									char	m_padding1[4];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SIMD_FORCE_INLINE	int	btHingeConstraint::calculateSerializeBufferSize() const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return sizeof(btHingeConstraintData);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///fills the dataBuffer and returns the struct name (and 0 on failure)
							 | 
						||
| 
								 | 
							
								SIMD_FORCE_INLINE	const char*	btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer;
							 | 
						||
| 
								 | 
							
									btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_rbAFrame.serialize(hingeData->m_rbAFrame);
							 | 
						||
| 
								 | 
							
									m_rbBFrame.serialize(hingeData->m_rbBFrame);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									hingeData->m_angularOnly = m_angularOnly;
							 | 
						||
| 
								 | 
							
									hingeData->m_enableAngularMotor = m_enableAngularMotor;
							 | 
						||
| 
								 | 
							
									hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse);
							 | 
						||
| 
								 | 
							
									hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity);
							 | 
						||
| 
								 | 
							
									hingeData->m_useReferenceFrameA = m_useReferenceFrameA;
							 | 
						||
| 
								 | 
							
								#ifdef	_BT_USE_CENTER_LIMIT_
							 | 
						||
| 
								 | 
							
									hingeData->m_lowerLimit = float(m_limit.getLow());
							 | 
						||
| 
								 | 
							
									hingeData->m_upperLimit = float(m_limit.getHigh());
							 | 
						||
| 
								 | 
							
									hingeData->m_limitSoftness = float(m_limit.getSoftness());
							 | 
						||
| 
								 | 
							
									hingeData->m_biasFactor = float(m_limit.getBiasFactor());
							 | 
						||
| 
								 | 
							
									hingeData->m_relaxationFactor = float(m_limit.getRelaxationFactor());
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									hingeData->m_lowerLimit = float(m_lowerLimit);
							 | 
						||
| 
								 | 
							
									hingeData->m_upperLimit = float(m_upperLimit);
							 | 
						||
| 
								 | 
							
									hingeData->m_limitSoftness = float(m_limitSoftness);
							 | 
						||
| 
								 | 
							
									hingeData->m_biasFactor = float(m_biasFactor);
							 | 
						||
| 
								 | 
							
									hingeData->m_relaxationFactor = float(m_relaxationFactor);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Fill padding with zeros to appease msan.
							 | 
						||
| 
								 | 
							
								#ifdef BT_USE_DOUBLE_PRECISION
							 | 
						||
| 
								 | 
							
									hingeData->m_padding1[0] = 0;
							 | 
						||
| 
								 | 
							
									hingeData->m_padding1[1] = 0;
							 | 
						||
| 
								 | 
							
									hingeData->m_padding1[2] = 0;
							 | 
						||
| 
								 | 
							
									hingeData->m_padding1[3] = 0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return btHingeConstraintDataName;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //BT_HINGECONSTRAINT_H
							 |