text:
/*
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


text:
/*
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.

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_HINGE2_CONSTRAINT_H
#define BT_HINGE2_CONSTRAINT_H

#include "LinearMath/btVector3.h"
#include "btTypedConstraint.h"
#include "btGeneric6DofSpring2Constraint.h"

// Constraint similar to ODE Hinge2 Joint
// has 3 degrees of frredom:
// 2 rotational degrees of freedom, similar to Euler rotations around Z (axis 1) and X (axis 2)
// 1 translational (along axis Z) with suspension spring

ATTRIBUTE_ALIGNED16(class) btHinge2Constraint : public btGeneric6DofSpring2Constraint
{
protected:
	btVector3	m_anchor;
	btVector3	m_axis1;
	btVector3	m_axis2;
public:
		BT_DECLARE_ALIGNED_ALLOCATOR();

	// constructor
	// anchor, axis1 and axis2 are in world coordinate system
	// axis1 must be orthogonal to axis2
    btHinge2Constraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2);
	// access
	const btVector3& getAnchor() { return m_calculatedTransformA.getOrigin(); }
	const btVector3& getAnchor2() { return m_calculatedTransformB.getOrigin(); }
	const btVector3& getAxis1() { return m_axis1; }
	const btVector3& getAxis2() { return m_axis2; }
	btScalar getAngle1() { return getAngle(2); }
	btScalar getAngle2() { return getAngle(0); }
	// limits
	void setUpperLimit(btScalar ang1max) { setAngularUpperLimit(btVector3(-1.f, 0.f, ang1max)); }
	void setLowerLimit(btScalar ang1min) { setAngularLowerLimit(btVector3( 1.f, 0.f, ang1min)); }
};

#endif // BT_HINGE2_CONSTRAINT_H

repo_name: JoshParnell/libphx

repo_language: C

mime_type: text/x-c++


text:
/*
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_CONTACT_SOLVER_INFO
#define BT_CONTACT_SOLVER_INFO

#include "LinearMath/btScalar.h"

enum	btSolverMode
{
	SOLVER_RANDMIZE_ORDER = 1,
	SOLVER_FRICTION_SEPARATE = 2,
	SOLVER_USE_WARMSTARTING = 4,
	SOLVER_USE_2_FRICTION_DIRECTIONS = 16,
	SOLVER_ENABLE_FRICTION_DIRECTION_CACHING = 32,
	SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64,
	SOLVER_CACHE_FRIENDLY = 128,
	SOLVER_SIMD = 256,
	SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS = 512,
	SOLVER_ALLOW_ZERO_LENGTH_FRICTION_DIRECTIONS = 1024
};

struct btContactSolverInfoData
{

	btScalar	m_tau;
	btScalar	m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'.
	btScalar	m_friction;
	btScalar	m_timeStep;
	btScalar	m_restitution;
	int		m_numIterations;
	btScalar	m_maxErrorReduction;
	btScalar	m_sor;//successive over-relaxation term
	btScalar	m_erp;//error reduction for non-contact constraints
	btScalar	m_erp2;//error reduction for contact constraints
	btScalar	m_globalCfm;//constraint force mixing for contacts and non-contacts
	btScalar	m_frictionERP;//error reduction for friction constraints
	btScalar	m_frictionCFM;//constraint force mixing for friction constraints

	int			m_splitImpulse;
	btScalar	m_splitImpulsePenetrationThreshold;
	btScalar	m_splitImpulseTurnErp;
	btScalar	m_linearSlop;
	btScalar	m_warmstartingFactor;

	int			m_solverMode;
	int	m_restingContactRestitutionThreshold;
	int			m_minimumSolverBatchSize;
	btScalar	m_maxGyroscopicForce;
	btScalar	m_singleAxisRollingFrictionThreshold;
	btScalar	m_leastSquaresResidualThreshold;
	btScalar	m_restitutionVelocityThreshold;

};

struct btContactSolverInfo : public btContactSolverInfoData
{

	inline btContactSolverInfo()
	{
		m_tau = btScalar(0.6);
		m_damping = btScalar(1.0);
		m_friction = btScalar(0.3);
		m_timeStep = btScalar(1.f/60.f);
		m_restitution = btScalar(0.);
		m_maxErrorReduction = btScalar(20.);
		m_numIterations = 10;
		m_erp = btScalar(0.2);
		m_erp2 = btScalar(0.2);
		m_globalCfm = btScalar(0.);
		m_frictionERP = btScalar(0.2);//positional friction 'anchors' are disabled by default
		m_frictionCFM = btScalar(0.);
		m_sor = btScalar(1.);
		m_splitImpulse = true;
		m_splitImpulsePenetrationThreshold = -.04f;
		m_splitImpulseTurnErp = 0.1f;
		m_linearSlop = btScalar(0.0);
		m_warmstartingFactor=btScalar(0.85);
		//m_solverMode =  SOLVER_USE_WARMSTARTING |  SOLVER_SIMD | SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION|SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;// | SOLVER_RANDMIZE_ORDER;
		m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD;// | SOLVER_RANDMIZE_ORDER;
		m_restingContactRestitutionThreshold = 2;//unused as of 2.81
		m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit
		m_maxGyroscopicForce = 100.f; ///it is only used for 'explicit' version of gyroscopic force
		m_singleAxisRollingFrictionThreshold = 1e30f;///if the velocity is above this threshold, it will use a single constraint row (axis), otherwise 3 rows.
		m_leastSquaresResidualThreshold = 0.f;
		m_restitutionVelocityThreshold = 0.2f;//if the relative velocity is below this threshold, there is zero restitution
	}
};

///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btContactSolverInfoDoubleData
{
	double		m_tau;
	double		m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'.
	double		m_friction;
	double		m_timeStep;
	double		m_restitution;
	double		m_maxErrorReduction;
	double		m_sor;
	double		m_erp;//used as Baumgarte factor
	double		m_erp2;//used in Split Impulse
	double		m_globalCfm;//constraint force mixing
	double		m_splitImpulsePenetrationThreshold;
	double		m_splitImpulseTurnErp;
	double		m_linearSlop;
	double		m_warmstartingFactor;
	double		m_maxGyroscopicForce;///it is only used for 'explicit' version of gyroscopic force
	double		m_singleAxisRollingFrictionThreshold;

	int			m_numIterations;
	int			m_solverMode;
	int			m_restingContactRestitutionThreshold;
	int			m_minimumSolverBatchSize;
	int			m_splitImpulse;
	char		m_padding[4];

};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btContactSolverInfoFloatData
{
	float		m_tau;
	float		m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'.
	float		m_friction;
	float		m_timeStep;

	float		m_restitution;
	float		m_maxErrorReduction;
	float		m_sor;
	float		m_erp;//used as Baumgarte factor

	float		m_erp2;//used in Split Impulse
	float		m_globalCfm;//constraint force mixing
	float		m_splitImpulsePenetrationThreshold;
	float		m_splitImpulseTurnErp;

	float		m_linearSlop;
	float		m_warmstartingFactor;
	float		m_maxGyroscopicForce;
	float		m_singleAxisRollingFrictionThreshold;

	int			m_numIterations;
	int			m_solverMode;
	int			m_restingContactRestitutionThreshold;
	int			m_minimumSolverBatchSize;

	int			m_splitImpulse;
	char		m_padding[4];
};

#endif //BT_CONTACT_SOLVER_INFO


text:
/*
Bullet Continuous Collision Detection and Physics Library
btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios

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.

Written by: Marcus Hennix
*/

/*
Overview:

btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc).
It is a fixed translation, 3 degree-of-freedom (DOF) rotational "joint".
It divides the 3 rotational DOFs into swing (movement within a cone) and twist.
Swing is divided into swing1 and swing2 which can have different limits, giving an elliptical shape.
(Note: the cone's base isn't flat, so this ellipse is "embedded" on the surface of a sphere.)

In the contraint's frame of reference:
twist is along the x-axis,
and swing 1 and 2 are along the z and y axes respectively.
*/

#ifndef BT_CONETWISTCONSTRAINT_H
#define BT_CONETWISTCONSTRAINT_H

#include "LinearMath/btVector3.h"
#include "btJacobianEntry.h"
#include "btTypedConstraint.h"

#ifdef BT_USE_DOUBLE_PRECISION
#define btConeTwistConstraintData2	btConeTwistConstraintDoubleData
#define btConeTwistConstraintDataName	"btConeTwistConstraintDoubleData"
#else
#define btConeTwistConstraintData2	btConeTwistConstraintData
#define btConeTwistConstraintDataName	"btConeTwistConstraintData"
#endif //BT_USE_DOUBLE_PRECISION

class btRigidBody;

enum btConeTwistFlags
{
	BT_CONETWIST_FLAGS_LIN_CFM = 1,
	BT_CONETWIST_FLAGS_LIN_ERP = 2,
	BT_CONETWIST_FLAGS_ANG_CFM = 4
};

///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc)
ATTRIBUTE_ALIGNED16(class) btConeTwistConstraint : public btTypedConstraint
{
#ifdef IN_PARALLELL_SOLVER
public:
#endif
	btJacobianEntry	m_jac[3]; //3 orthogonal linear constraints

	btTransform m_rbAFrame;
	btTransform m_rbBFrame;

	btScalar	m_limitSoftness;
	btScalar	m_biasFactor;
	btScalar	m_relaxationFactor;

	btScalar	m_damping;

	btScalar	m_swingSpan1;
	btScalar	m_swingSpan2;
	btScalar	m_twistSpan;

	btScalar	m_fixThresh;

	btVector3   m_swingAxis;
	btVector3	m_twistAxis;

	btScalar	m_kSwing;
	btScalar	m_kTwist;

	btScalar	m_twistLimitSign;
	btScalar	m_swingCorrection;
	btScalar	m_twistCorrection;

	btScalar	m_twistAngle;

	btScalar	m_accSwingLimitImpulse;
	btScalar	m_accTwistLimitImpulse;

	bool		m_angularOnly;
	bool		m_solveTwistLimit;
	bool		m_solveSwingLimit;

	bool	m_useSolveConstraintObsolete;

	// not yet used...
	btScalar	m_swingLimitRatio;
	btScalar	m_twistLimitRatio;
	btVector3   m_twistAxisA;

	// motor
	bool		 m_bMotorEnabled;
	bool		 m_bNormalizedMotorStrength;
	btQuaternion m_qTarget;
	btScalar	 m_maxMotorImpulse;
	btVector3	 m_accMotorImpulse;

	// parameters
	int			m_flags;
	btScalar	m_linCFM;
	btScalar	m_linERP;
	btScalar	m_angCFM;

protected:

	void init();

	void computeConeLimitInfo(const btQuaternion& qCone, // in
		btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs

	void computeTwistLimitInfo(const btQuaternion& qTwist, // in
		btScalar& twistAngle, btVector3& vTwistAxis); // all outs

	void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const;

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);

	btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);

	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 btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);

	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);

	void	updateRHS(btScalar	timeStep);

	const btRigidBody& getRigidBodyA() const
	{
		return m_rbA;
	}
	const btRigidBody& getRigidBodyB() const
	{
		return m_rbB;
	}

	void	setAngularOnly(bool angularOnly)
	{
		m_angularOnly = angularOnly;
	}

	bool    getAngularOnly() const
	{
	    return m_angularOnly;
	}

	void	setLimit(int limitIndex,btScalar limitValue)
	{
		switch (limitIndex)
		{
		case 3:
			{
				m_twistSpan = limitValue;
				break;
			}
		case 4:
			{
				m_swingSpan2 = limitValue;
				break;
			}
		case 5:
			{
				m_swingSpan1 = limitValue;
				break;
			}
		default:
			{
			}
		};
	}

    btScalar getLimit(int limitIndex) const
	{
		switch (limitIndex)
		{
		case 3:
			{
				return m_twistSpan;
				break;
			}
		case 4:
			{
				return m_swingSpan2;
				break;
			}
		case 5:
			{
				return m_swingSpan1;
				break;
			}
		default:
			{
			    btAssert(0 && "Invalid limitIndex specified for btConeTwistConstraint");
			    return 0.0;
			}
		};
	}

	// setLimit(), a few notes:
	// _softness:
	//		0->1, recommend ~0.8->1.
	//		describes % of limits where movement is free.
	//		beyond this softness %, the limit is gradually enforced until the "hard" (1.0) limit is reached.
	// _biasFactor:
	//		0->1?, recommend 0.3 +/-0.3 or so.
	//		strength with which constraint resists zeroth order (angular, not angular velocity) limit violation.
	// __relaxationFactor:
	//		0->1, recommend to stay near 1.
	//		the lower the value, the less the constraint will fight velocities which violate the angular limits.
	void	setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
	{
		m_swingSpan1 = _swingSpan1;
		m_swingSpan2 = _swingSpan2;
		m_twistSpan  = _twistSpan;

		m_limitSoftness =  _softness;
		m_biasFactor = _biasFactor;
		m_relaxationFactor = _relaxationFactor;
	}

	const btTransform& getAFrame() const { return m_rbAFrame; };
	const btTransform& getBFrame() const { return m_rbBFrame; };

	inline int getSolveTwistLimit()
	{
		return m_solveTwistLimit;
	}

	inline int getSolveSwingLimit()
	{
		return m_solveSwingLimit;
	}

	inline btScalar getTwistLimitSign()
	{
		return m_twistLimitSign;
	}

	void calcAngleInfo();
	void calcAngleInfo2(const btTransform& transA, const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);

	inline btScalar getSwingSpan1() const
	{
		return m_swingSpan1;
	}
	inline btScalar getSwingSpan2() const
	{
		return m_swingSpan2;
	}
	inline btScalar getTwistSpan() const
	{
		return m_twistSpan;
	}
	inline btScalar getLimitSoftness() const
	{
		return m_limitSoftness;
	}
	inline btScalar getBiasFactor() const
	{
		return m_biasFactor;
	}
	inline btScalar getRelaxationFactor() const
	{
		return m_relaxationFactor;
	}
	inline btScalar getTwistAngle() const
	{
		return m_twistAngle;
	}
	bool isPastSwingLimit() { return m_solveSwingLimit; }

	btScalar getDamping() const { return m_damping; }
	void setDamping(btScalar damping) { m_damping = damping; }

	void enableMotor(bool b) { m_bMotorEnabled = b; }
	bool isMotorEnabled() const { return m_bMotorEnabled; }
	btScalar getMaxMotorImpulse() const { return m_maxMotorImpulse; }
	bool isMaxMotorImpulseNormalized() const { return m_bNormalizedMotorStrength; }
	void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; }
	void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; }

	btScalar getFixThresh() { return m_fixThresh; }
	void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; }

	// setMotorTarget:
	// q: the desired rotation of bodyA wrt bodyB.
	// note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability)
	// note: don't forget to enableMotor()
	void setMotorTarget(const btQuaternion &q);
	const btQuaternion& getMotorTarget() const { return m_qTarget; }

	// same as above, but q is the desired rotation of frameA wrt frameB in constraint space
	void setMotorTargetInConstraintSpace(const btQuaternion &q);

	btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const;

	///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);

	virtual void setFrames(const btTransform& frameA, const btTransform& frameB);

	const btTransform& getFrameOffsetA() const
	{
		return m_rbAFrame;
	}

	const btTransform& getFrameOffsetB() const
	{
		return m_rbBFrame;
	}

	///return the local value of parameter
	virtual	btScalar getParam(int num, int axis = -1) const;

	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;

};

struct	btConeTwistConstraintDoubleData
{
	btTypedConstraintDoubleData	m_typeConstraintData;
	btTransformDoubleData m_rbAFrame;
	btTransformDoubleData m_rbBFrame;

	//limits
	double	m_swingSpan1;
	double	m_swingSpan2;
	double	m_twistSpan;
	double	m_limitSoftness;
	double	m_biasFactor;
	double	m_relaxationFactor;

	double	m_damping;

};

#ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
///this structure is not used, except for loading pre-2.82 .bullet files
struct	btConeTwistConstraintData
{
	btTypedConstraintData	m_typeConstraintData;
	btTransformFloatData m_rbAFrame;
	btTransformFloatData m_rbBFrame;

	//limits
	float	m_swingSpan1;
	float	m_swingSpan2;
	float	m_twistSpan;
	float	m_limitSoftness;
	float	m_biasFactor;
	float	m_relaxationFactor;

	float	m_damping;

	char m_pad[4];

};
#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
//

SIMD_FORCE_INLINE int	btConeTwistConstraint::calculateSerializeBufferSize() const
{
	return sizeof(btConeTwistConstraintData2);

}

	///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE const char*	btConeTwistConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
{
	btConeTwistConstraintData2* cone = (btConeTwistConstraintData2*) dataBuffer;
	btTypedConstraint::serialize(&cone->m_typeConstraintData,serializer);

	m_rbAFrame.serialize(cone->m_rbAFrame);
	m_rbBFrame.serialize(cone->m_rbBFrame);

	cone->m_swingSpan1 = m_swingSpan1;
	cone->m_swingSpan2 = m_swingSpan2;
	cone->m_twistSpan = m_twistSpan;
	cone->m_limitSoftness = m_limitSoftness;
	cone->m_biasFactor = m_biasFactor;
	cone->m_relaxationFactor = m_relaxationFactor;
	cone->m_damping = m_damping;

	return btConeTwistConstraintDataName;
}

#endif //BT_CONETWISTCONSTRAINT_H


text:
/*
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_CONSTRAINT_SOLVER_H
#define BT_CONSTRAINT_SOLVER_H

#include "LinearMath/btScalar.h"

class btPersistentManifold;
class btRigidBody;
class btCollisionObject;
class btTypedConstraint;
struct btContactSolverInfo;
struct btBroadphaseProxy;
class btIDebugDraw;
class btStackAlloc;
class	btDispatcher;
/// btConstraintSolver provides solver interface

enum btConstraintSolverType
{
	BT_SEQUENTIAL_IMPULSE_SOLVER=1,
	BT_MLCP_SOLVER=2,
	BT_NNCG_SOLVER=4
};

class btConstraintSolver
{

public:

	virtual ~btConstraintSolver() {}

	virtual void prepareSolve (int /* numBodies */, int /* numManifolds */) {;}

	///solve a group of constraints
	virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer,btDispatcher* dispatcher) = 0;

	virtual void allSolved (const btContactSolverInfo& /* info */,class btIDebugDraw* /* debugDrawer */) {;}

	///clear internal cached data and reset random seed
	virtual	void	reset() = 0;

	virtual btConstraintSolverType	getSolverType() const=0;

};

#endif //BT_CONSTRAINT_SOLVER_H


text:
/*
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_NNCG_CONSTRAINT_SOLVER_H
#define BT_NNCG_CONSTRAINT_SOLVER_H

#include "btSequentialImpulseConstraintSolver.h"

ATTRIBUTE_ALIGNED16(class) btNNCGConstraintSolver : public btSequentialImpulseConstraintSolver
{
protected:

	btScalar m_deltafLengthSqrPrev;

	btAlignedObjectArray<btScalar> m_pNC;  // p for None Contact constraints
	btAlignedObjectArray<btScalar> m_pC;   // p for Contact constraints
	btAlignedObjectArray<btScalar> m_pCF;  // p for ContactFriction constraints
	btAlignedObjectArray<btScalar> m_pCRF; // p for ContactRollingFriction constraints

	//These are recalculated in every iterations. We just keep these to prevent reallocation in each iteration.
	btAlignedObjectArray<btScalar> m_deltafNC;  // deltaf for NoneContact constraints
	btAlignedObjectArray<btScalar> m_deltafC;   // deltaf for Contact constraints
	btAlignedObjectArray<btScalar> m_deltafCF;  // deltaf for ContactFriction constraints
	btAlignedObjectArray<btScalar> m_deltafCRF; // deltaf for ContactRollingFriction constraints

protected:

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

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	btNNCGConstraintSolver() : btSequentialImpulseConstraintSolver(), m_onlyForNoneContact(false) {}

	virtual btConstraintSolverType getSolverType() const
	{
		return BT_NNCG_SOLVER;
	}

	bool m_onlyForNoneContact;
};

#endif //BT_NNCG_CONSTRAINT_SOLVER_H


text:
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2010 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_TYPED_CONSTRAINT_H
#define BT_TYPED_CONSTRAINT_H

#include "LinearMath/btScalar.h"
#include "btSolverConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"

#ifdef BT_USE_DOUBLE_PRECISION
#define btTypedConstraintData2		btTypedConstraintDoubleData
#define btTypedConstraintDataName	"btTypedConstraintDoubleData"
#else
#define btTypedConstraintData2 		btTypedConstraintFloatData
#define btTypedConstraintDataName  "btTypedConstraintFloatData"
#endif //BT_USE_DOUBLE_PRECISION

class btSerializer;

//Don't change any of the existing enum values, so add enum types at the end for serialization compatibility
enum btTypedConstraintType
{
	POINT2POINT_CONSTRAINT_TYPE=3,
	HINGE_CONSTRAINT_TYPE,
	CONETWIST_CONSTRAINT_TYPE,
	D6_CONSTRAINT_TYPE,
	SLIDER_CONSTRAINT_TYPE,
	CONTACT_CONSTRAINT_TYPE,
	D6_SPRING_CONSTRAINT_TYPE,
	GEAR_CONSTRAINT_TYPE,
	FIXED_CONSTRAINT_TYPE,
	D6_SPRING_2_CONSTRAINT_TYPE,
	MAX_CONSTRAINT_TYPE
};

enum btConstraintParams
{
	BT_CONSTRAINT_ERP=1,
	BT_CONSTRAINT_STOP_ERP,
	BT_CONSTRAINT_CFM,
	BT_CONSTRAINT_STOP_CFM
};

#if 1
	#define btAssertConstrParams(_par) btAssert(_par)
#else
	#define btAssertConstrParams(_par)
#endif

ATTRIBUTE_ALIGNED16(struct)	btJointFeedback
{
	BT_DECLARE_ALIGNED_ALLOCATOR();
	btVector3	m_appliedForceBodyA;
	btVector3	m_appliedTorqueBodyA;
	btVector3	m_appliedForceBodyB;
	btVector3	m_appliedTorqueBodyB;
};

///TypedConstraint is the baseclass for Bullet constraints and vehicles
ATTRIBUTE_ALIGNED16(class) btTypedConstraint : public btTypedObject
{
	int	m_userConstraintType;

	union
	{
		int	m_userConstraintId;
		void* m_userConstraintPtr;
	};

	btScalar	m_breakingImpulseThreshold;
	bool		m_isEnabled;
	bool		m_needsFeedback;
	int			m_overrideNumSolverIterations;

	btTypedConstraint&	operator=(btTypedConstraint&	other)
	{
		btAssert(0);
		(void) other;
		return *this;
	}

protected:
	btRigidBody&	m_rbA;
	btRigidBody&	m_rbB;
	btScalar	m_appliedImpulse;
	btScalar	m_dbgDrawSize;
	btJointFeedback*	m_jointFeedback;

	///internal method used by the constraint solver, don't use them directly
	btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	virtual ~btTypedConstraint() {};
	btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
	btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB);

	struct btConstraintInfo1 {
		int m_numConstraintRows,nub;
	};

	static btRigidBody& getFixedBody();

	struct btConstraintInfo2 {
		// integrator parameters: frames per second (1/stepsize), default error
		// reduction parameter (0..1).
		btScalar fps,erp;

		// for the first and second body, pointers to two (linear and angular)
		// n*3 jacobian sub matrices, stored by rows. these matrices will have
		// been initialized to 0 on entry. if the second body is zero then the
		// J2xx pointers may be 0.
		btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;

		// elements to jump from one row to the next in J's
		int rowskip;

		// right hand sides of the equation J*v = c + cfm * lambda. cfm is the
		// "constraint force mixing" vector. c is set to zero on entry, cfm is
		// set to a constant value (typically very small or zero) value on entry.
		btScalar *m_constraintError,*cfm;

		// lo and hi limits for variables (set to -/+ infinity on entry).
		btScalar *m_lowerLimit,*m_upperLimit;

		// number of solver iterations
		int m_numIterations;

		//damping of the velocity
		btScalar	m_damping;
	};

	int	getOverrideNumSolverIterations() const
	{
		return m_overrideNumSolverIterations;
	}

	///override the number of constraint solver iterations used to solve this constraint
	///-1 will use the default number of iterations, as specified in SolverInfo.m_numIterations
	void setOverrideNumSolverIterations(int overideNumIterations)
	{
		m_overrideNumSolverIterations = overideNumIterations;
	}

	///internal method used by the constraint solver, don't use them directly
	virtual void	buildJacobian() {};

	///internal method used by the constraint solver, don't use them directly
	virtual	void	setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
	{
        (void)ca;
        (void)solverBodyA;
        (void)solverBodyB;
        (void)timeStep;
	}

	///internal method used by the constraint solver, don't use them directly
	virtual void getInfo1 (btConstraintInfo1* info)=0;

	///internal method used by the constraint solver, don't use them directly
	virtual void getInfo2 (btConstraintInfo2* info)=0;

	///internal method used by the constraint solver, don't use them directly
	void	internalSetAppliedImpulse(btScalar appliedImpulse)
	{
		m_appliedImpulse = appliedImpulse;
	}
	///internal method used by the constraint solver, don't use them directly
	btScalar	internalGetAppliedImpulse()
	{
		return m_appliedImpulse;
	}

	btScalar	getBreakingImpulseThreshold() const
	{
		return 	m_breakingImpulseThreshold;
	}

	void	setBreakingImpulseThreshold(btScalar threshold)
	{
		m_breakingImpulseThreshold = threshold;
	}

	bool	isEnabled() const
	{
		return m_isEnabled;
	}

	void	setEnabled(bool enabled)
	{
		m_isEnabled=enabled;
	}

	///internal method used by the constraint solver, don't use them directly
	virtual	void	solveConstraintObsolete(btSolverBody& /*bodyA*/,btSolverBody& /*bodyB*/,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;
	}

	int getUserConstraintType() const
	{
		return m_userConstraintType ;
	}

	void	setUserConstraintType(int userConstraintType)
	{
		m_userConstraintType = userConstraintType;
	};

	void	setUserConstraintId(int uid)
	{
		m_userConstraintId = uid;
	}

	int getUserConstraintId() const
	{
		return m_userConstraintId;
	}

	void	setUserConstraintPtr(void* ptr)
	{
		m_userConstraintPtr = ptr;
	}

	void*	getUserConstraintPtr()
	{
		return m_userConstraintPtr;
	}

	void	setJointFeedback(btJointFeedback* jointFeedback)
	{
		m_jointFeedback = jointFeedback;
	}

	const btJointFeedback* getJointFeedback() const
	{
		return m_jointFeedback;
	}

	btJointFeedback* getJointFeedback()
	{
		return m_jointFeedback;
	}

	int getUid() const
	{
		return m_userConstraintId;
	}

	bool	needsFeedback() const
	{
		return m_needsFeedback;
	}

	///enableFeedback will allow to read the applied linear and angular impulse
	///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information
	void	enableFeedback(bool needsFeedback)
	{
		m_needsFeedback = needsFeedback;
	}

	///getAppliedImpulse is an estimated total applied impulse.
	///This feedback could be used to determine breaking constraints or playing sounds.
	btScalar	getAppliedImpulse() const
	{
		btAssert(m_needsFeedback);
		return m_appliedImpulse;
	}

	btTypedConstraintType getConstraintType () const
	{
		return btTypedConstraintType(m_objectType);
	}

	void setDbgDrawSize(btScalar dbgDrawSize)
	{
		m_dbgDrawSize = dbgDrawSize;
	}
	btScalar getDbgDrawSize()
	{
		return m_dbgDrawSize;
	}

	///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) = 0;

	///return the local value of parameter
	virtual	btScalar getParam(int num, int axis = -1) const = 0;

	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;

};

// returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits
// all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI])
SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
{
	if(angleLowerLimitInRadians >= angleUpperLimitInRadians)
	{
		return angleInRadians;
	}
	else if(angleInRadians < angleLowerLimitInRadians)
	{
		btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians));
		btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians));
		return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI);
	}
	else if(angleInRadians > angleUpperLimitInRadians)
	{
		btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians));
		btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians));
		return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians;
	}
	else
	{
		return angleInRadians;
	}
}

///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct	btTypedConstraintFloatData
{
	btRigidBodyFloatData		*m_rbA;
	btRigidBodyFloatData		*m_rbB;
	char	*m_name;

	int	m_objectType;
	int	m_userConstraintType;
	int	m_userConstraintId;
	int	m_needsFeedback;

	float	m_appliedImpulse;
	float	m_dbgDrawSize;

	int	m_disableCollisionsBetweenLinkedBodies;
	int	m_overrideNumSolverIterations;

	float	m_breakingImpulseThreshold;
	int		m_isEnabled;

};

///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64

#define BT_BACKWARDS_COMPATIBLE_SERIALIZATION
#ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
///this structure is not used, except for loading pre-2.82 .bullet files
struct	btTypedConstraintData
{
	btRigidBodyData		*m_rbA;
	btRigidBodyData		*m_rbB;
	char	*m_name;

	int	m_objectType;
	int	m_userConstraintType;
	int	m_userConstraintId;
	int	m_needsFeedback;

	float	m_appliedImpulse;
	float	m_dbgDrawSize;

	int	m_disableCollisionsBetweenLinkedBodies;
	int	m_overrideNumSolverIterations;

	float	m_breakingImpulseThreshold;
	int		m_isEnabled;

};
#endif //BACKWARDS_COMPATIBLE

struct	btTypedConstraintDoubleData
{
	btRigidBodyDoubleData		*m_rbA;
	btRigidBodyDoubleData		*m_rbB;
	char	*m_name;

	int	m_objectType;
	int	m_userConstraintType;
	int	m_userConstraintId;
	int	m_needsFeedback;

	double	m_appliedImpulse;
	double	m_dbgDrawSize;

	int	m_disableCollisionsBetweenLinkedBodies;
	int	m_overrideNumSolverIterations;

	double	m_breakingImpulseThreshold;
	int		m_isEnabled;
	char	padding[4];

};

SIMD_FORCE_INLINE	int	btTypedConstraint::calculateSerializeBufferSize() const
{
	return sizeof(btTypedConstraintData2);
}

class btAngularLimit
{
private:
	btScalar
		m_center,
		m_halfRange,
		m_softness,
		m_biasFactor,
		m_relaxationFactor,
		m_correction,
		m_sign;

	bool
		m_solveLimit;

public:
	/// Default constructor initializes limit as inactive, allowing free constraint movement
	btAngularLimit()
		:m_center(0.0f),
		m_halfRange(-1.0f),
		m_softness(0.9f),
		m_biasFactor(0.3f),
		m_relaxationFactor(1.0f),
		m_correction(0.0f),
		m_sign(0.0f),
		m_solveLimit(false)
	{}

	/// Sets all limit's parameters.
	/// When low > high limit becomes inactive.
	/// When high - low > 2PI limit is ineffective too becouse no angle can exceed the limit
	void set(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f);

	/// Checks conastaint angle against limit. If limit is active and the angle violates the limit
	/// correction is calculated.
	void test(const btScalar angle);

	/// Returns limit's softness
	inline btScalar getSoftness() const
	{
		return m_softness;
	}

	/// Returns limit's bias factor
	inline btScalar getBiasFactor() const
	{
		return m_biasFactor;
	}

	/// Returns limit's relaxation factor
	inline btScalar getRelaxationFactor() const
	{
		return m_relaxationFactor;
	}

	/// Returns correction value evaluated when test() was invoked
	inline btScalar getCorrection() const
	{
		return m_correction;
	}

	/// Returns sign value evaluated when test() was invoked
	inline btScalar getSign() const
	{
		return m_sign;
	}

	/// Gives half of the distance between min and max limit angle
	inline btScalar getHalfRange() const
	{
		return m_halfRange;
	}

	/// Returns true when the last test() invocation recognized limit violation
	inline bool isLimit() const
	{
		return m_solveLimit;
	}

	/// Checks given angle against limit. If limit is active and angle doesn't fit it, the angle
	/// returned is modified so it equals to the limit closest to given angle.
	void fit(btScalar& angle) const;

	/// Returns correction value multiplied by sign value
	btScalar getError() const;

	btScalar getLow() const;

	btScalar getHigh() const;

};

#endif //BT_TYPED_CONSTRAINT_H


text:
/*
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_JACOBIAN_ENTRY_H
#define BT_JACOBIAN_ENTRY_H

#include "LinearMath/btMatrix3x3.h"

//notes:
// Another memory optimization would be to store m_1MinvJt in the remaining 3 w components
// which makes the btJacobianEntry memory layout 16 bytes
// if you only are interested in angular part, just feed massInvA and massInvB zero

/// Jacobian entry is an abstraction that allows to describe constraints
/// it can be used in combination with a constraint solver
/// Can be used to relate the effect of an impulse to the constraint error
ATTRIBUTE_ALIGNED16(class) btJacobianEntry
{
public:
	btJacobianEntry() {};
	//constraint between two different rigidbodies
	btJacobianEntry(
		const btMatrix3x3& world2A,
		const btMatrix3x3& world2B,
		const btVector3& rel_pos1,const btVector3& rel_pos2,
		const btVector3& jointAxis,
		const btVector3& inertiaInvA,
		const btScalar massInvA,
		const btVector3& inertiaInvB,
		const btScalar massInvB)
		:m_linearJointAxis(jointAxis)
	{
		m_aJ = world2A*(rel_pos1.cross(m_linearJointAxis));
		m_bJ = world2B*(rel_pos2.cross(-m_linearJointAxis));
		m_0MinvJt	= inertiaInvA * m_aJ;
		m_1MinvJt = inertiaInvB * m_bJ;
		m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ);

		btAssert(m_Adiag > btScalar(0.0));
	}

	//angular constraint between two different rigidbodies
	btJacobianEntry(const btVector3& jointAxis,
		const btMatrix3x3& world2A,
		const btMatrix3x3& world2B,
		const btVector3& inertiaInvA,
		const btVector3& inertiaInvB)
		:m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.)))
	{
		m_aJ= world2A*jointAxis;
		m_bJ = world2B*-jointAxis;
		m_0MinvJt	= inertiaInvA * m_aJ;
		m_1MinvJt = inertiaInvB * m_bJ;
		m_Adiag =  m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ);

		btAssert(m_Adiag > btScalar(0.0));
	}

	//angular constraint between two different rigidbodies
	btJacobianEntry(const btVector3& axisInA,
		const btVector3& axisInB,
		const btVector3& inertiaInvA,
		const btVector3& inertiaInvB)
		: m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.)))
		, m_aJ(axisInA)
		, m_bJ(-axisInB)
	{
		m_0MinvJt	= inertiaInvA * m_aJ;
		m_1MinvJt = inertiaInvB * m_bJ;
		m_Adiag =  m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ);

		btAssert(m_Adiag > btScalar(0.0));
	}

	//constraint on one rigidbody
	btJacobianEntry(
		const btMatrix3x3& world2A,
		const btVector3& rel_pos1,const btVector3& rel_pos2,
		const btVector3& jointAxis,
		const btVector3& inertiaInvA,
		const btScalar massInvA)
		:m_linearJointAxis(jointAxis)
	{
		m_aJ= world2A*(rel_pos1.cross(jointAxis));
		m_bJ = world2A*(rel_pos2.cross(-jointAxis));
		m_0MinvJt	= inertiaInvA * m_aJ;
		m_1MinvJt = btVector3(btScalar(0.),btScalar(0.),btScalar(0.));
		m_Adiag = massInvA + m_0MinvJt.dot(m_aJ);

		btAssert(m_Adiag > btScalar(0.0));
	}

	btScalar	getDiagonal() const { return m_Adiag; }

	// for two constraints on the same rigidbody (for example vehicle friction)
	btScalar	getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA) const
	{
		const btJacobianEntry& jacA = *this;
		btScalar lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis);
		btScalar ang = jacA.m_0MinvJt.dot(jacB.m_aJ);
		return lin + ang;
	}

	// for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies)
	btScalar	getNonDiagonal(const btJacobianEntry& jacB,const btScalar massInvA,const btScalar massInvB) const
	{
		const btJacobianEntry& jacA = *this;
		btVector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis;
		btVector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ;
		btVector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ;
		btVector3 lin0 = massInvA * lin ;
		btVector3 lin1 = massInvB * lin;
		btVector3 sum = ang0+ang1+lin0+lin1;
		return sum[0]+sum[1]+sum[2];
	}

	btScalar getRelativeVelocity(const btVector3& linvelA,const btVector3& angvelA,const btVector3& linvelB,const btVector3& angvelB)
	{
		btVector3 linrel = linvelA - linvelB;
		btVector3 angvela  = angvelA * m_aJ;
		btVector3 angvelb  = angvelB * m_bJ;
		linrel *= m_linearJointAxis;
		angvela += angvelb;
		angvela += linrel;
		btScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2];
		return rel_vel2 + SIMD_EPSILON;
	}
//private:

	btVector3	m_linearJointAxis;
	btVector3	m_aJ;
	btVector3	m_bJ;
	btVector3	m_0MinvJt;
	btVector3	m_1MinvJt;
	//Optimization: can be stored in the w/last component of one of the vectors
	btScalar	m_Adiag;

};

#endif //BT_JACOBIAN_ENTRY_H


text:
/*
 * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies.
 * Erwin Coumans makes no representations about the suitability
 * of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
*/
#ifndef BT_WHEEL_INFO_H
#define BT_WHEEL_INFO_H

#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"

class btRigidBody;

struct btWheelInfoConstructionInfo
{
	btVector3	m_chassisConnectionCS;
	btVector3	m_wheelDirectionCS;
	btVector3	m_wheelAxleCS;
	btScalar	m_suspensionRestLength;
	btScalar	m_maxSuspensionTravelCm;
	btScalar	m_wheelRadius;

	btScalar		m_suspensionStiffness;
	btScalar		m_wheelsDampingCompression;
	btScalar		m_wheelsDampingRelaxation;
	btScalar		m_frictionSlip;
	btScalar		m_maxSuspensionForce;
	bool m_bIsFrontWheel;

};

/// btWheelInfo contains information per wheel about friction and suspension.
struct btWheelInfo
{
	struct RaycastInfo
	{
		//set by raycaster
		btVector3	m_contactNormalWS;//contactnormal
		btVector3	m_contactPointWS;//raycast hitpoint
		btScalar	m_suspensionLength;
		btVector3	m_hardPointWS;//raycast starting point
		btVector3	m_wheelDirectionWS; //direction in worldspace
		btVector3	m_wheelAxleWS; // axle in worldspace
		bool		m_isInContact;
		void*		m_groundObject; //could be general void* ptr
	};

	RaycastInfo	m_raycastInfo;

	btTransform	m_worldTransform;

	btVector3	m_chassisConnectionPointCS; //const
	btVector3	m_wheelDirectionCS;//const
	btVector3	m_wheelAxleCS; // const or modified by steering
	btScalar	m_suspensionRestLength1;//const
	btScalar	m_maxSuspensionTravelCm;
	btScalar getSuspensionRestLength() const;
	btScalar	m_wheelsRadius;//const
	btScalar	m_suspensionStiffness;//const
	btScalar	m_wheelsDampingCompression;//const
	btScalar	m_wheelsDampingRelaxation;//const
	btScalar	m_frictionSlip;
	btScalar	m_steering;
	btScalar	m_rotation;
	btScalar	m_deltaRotation;
	btScalar	m_rollInfluence;
	btScalar	m_maxSuspensionForce;

	btScalar	m_engineForce;

	btScalar	m_brake;

	bool m_bIsFrontWheel;

	void*		m_clientInfo;//can be used to store pointer to sync transforms...

	btWheelInfo() {}

	btWheelInfo(btWheelInfoConstructionInfo& ci)

	{

		m_suspensionRestLength1 = ci.m_suspensionRestLength;
		m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm;

		m_wheelsRadius = ci.m_wheelRadius;
		m_suspensionStiffness = ci.m_suspensionStiffness;
		m_wheelsDampingCompression = ci.m_wheelsDampingCompression;
		m_wheelsDampingRelaxation = ci.m_wheelsDampingRelaxation;
		m_chassisConnectionPointCS = ci.m_chassisConnectionCS;
		m_wheelDirectionCS = ci.m_wheelDirectionCS;
		m_wheelAxleCS = ci.m_wheelAxleCS;
		m_frictionSlip = ci.m_frictionSlip;
		m_steering = btScalar(0.);
		m_engineForce = btScalar(0.);
		m_rotation = btScalar(0.);
		m_deltaRotation = btScalar(0.);
		m_brake = btScalar(0.);
		m_rollInfluence = btScalar(0.1);
		m_bIsFrontWheel = ci.m_bIsFrontWheel;
		m_maxSuspensionForce = ci.m_maxSuspensionForce;

	}

	void	updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo);

	btScalar	m_clippedInvContactDotSuspension;
	btScalar	m_suspensionRelativeVelocity;
	//calculated by suspension
	btScalar	m_wheelsSuspensionForce;
	btScalar	m_skidInfo;

};

#endif //BT_WHEEL_INFO_H


text:
/*
 * Copyright (c) 2005 Erwin Coumans http://bulletphysics.org
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies.
 * Erwin Coumans makes no representations about the suitability
 * of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
*/
#ifndef BT_VEHICLE_RAYCASTER_H
#define BT_VEHICLE_RAYCASTER_H

#include "LinearMath/btVector3.h"

/// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting
struct btVehicleRaycaster
{
virtual ~btVehicleRaycaster()
{
}
	struct btVehicleRaycasterResult
	{
		btVehicleRaycasterResult() :m_distFraction(btScalar(-1.)){};
		btVector3	m_hitPointInWorld;
		btVector3	m_hitNormalInWorld;
		btScalar	m_distFraction;
	};

	virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) = 0;

};

#endif //BT_VEHICLE_RAYCASTER_H


text:
/*
 * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies.
 * Erwin Coumans makes no representations about the suitability
 * of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
*/
#ifndef BT_RAYCASTVEHICLE_H
#define BT_RAYCASTVEHICLE_H

#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "btVehicleRaycaster.h"
class btDynamicsWorld;
#include "LinearMath/btAlignedObjectArray.h"
#include "btWheelInfo.h"
#include "BulletDynamics/Dynamics/btActionInterface.h"

//class btVehicleTuning;

///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle.
class btRaycastVehicle : public btActionInterface
{

		btAlignedObjectArray<btVector3>	m_forwardWS;
		btAlignedObjectArray<btVector3>	m_axle;
		btAlignedObjectArray<btScalar>	m_forwardImpulse;
		btAlignedObjectArray<btScalar>	m_sideImpulse;

		///backwards compatibility
		int	m_userConstraintType;
		int	m_userConstraintId;

public:
	class btVehicleTuning
		{
			public:

			btVehicleTuning()
				:m_suspensionStiffness(btScalar(5.88)),
				m_suspensionCompression(btScalar(0.83)),
				m_suspensionDamping(btScalar(0.88)),
				m_maxSuspensionTravelCm(btScalar(500.)),
				m_frictionSlip(btScalar(10.5)),
				m_maxSuspensionForce(btScalar(6000.))
			{
			}
			btScalar	m_suspensionStiffness;
			btScalar	m_suspensionCompression;
			btScalar	m_suspensionDamping;
			btScalar	m_maxSuspensionTravelCm;
			btScalar	m_frictionSlip;
			btScalar	m_maxSuspensionForce;

		};
private:

	btVehicleRaycaster*	m_vehicleRaycaster;
	btScalar		m_pitchControl;
	btScalar	m_steeringValue;
	btScalar m_currentVehicleSpeedKmHour;

	btRigidBody* m_chassisBody;

	int m_indexRightAxis;
	int m_indexUpAxis;
	int	m_indexForwardAxis;

	void defaultInit(const btVehicleTuning& tuning);

public:

	//constructor to create a car from an existing rigidbody
	btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis,	btVehicleRaycaster* raycaster );

	virtual ~btRaycastVehicle() ;

	///btActionInterface interface
	virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step)
	{
        (void) collisionWorld;
		updateVehicle(step);
	}

	///btActionInterface interface
	void	debugDraw(btIDebugDraw* debugDrawer);

	const btTransform& getChassisWorldTransform() const;

	btScalar rayCast(btWheelInfo& wheel);

	virtual void updateVehicle(btScalar step);

	void resetSuspension();

	btScalar	getSteeringValue(int wheel) const;

	void	setSteeringValue(btScalar steering,int wheel);

	void	applyEngineForce(btScalar force, int wheel);

	const btTransform&	getWheelTransformWS( int wheelIndex ) const;

	void	updateWheelTransform( int wheelIndex, bool interpolatedTransform = true );

//	void	setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth);

	btWheelInfo&	addWheel( const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS,btScalar suspensionRestLength,btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel);

	inline int		getNumWheels() const {
		return int (m_wheelInfo.size());
	}

	btAlignedObjectArray<btWheelInfo>	m_wheelInfo;

	const btWheelInfo&	getWheelInfo(int index) const;

	btWheelInfo&	getWheelInfo(int index);

	void	updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform = true);

	void setBrake(btScalar brake,int wheelIndex);

	void	setPitchControl(btScalar pitch)
	{
		m_pitchControl = pitch;
	}

	void	updateSuspension(btScalar deltaTime);

	virtual void	updateFriction(btScalar	timeStep);

	inline btRigidBody* getRigidBody()
	{
		return m_chassisBody;
	}

	const btRigidBody* getRigidBody() const
	{
		return m_chassisBody;
	}

	inline int	getRightAxis() const
	{
		return m_indexRightAxis;
	}
	inline int getUpAxis() const
	{
		return m_indexUpAxis;
	}

	inline int getForwardAxis() const
	{
		return m_indexForwardAxis;
	}

	///Worldspace forward vector
	btVector3 getForwardVector() const
	{
		const btTransform& chassisTrans = getChassisWorldTransform();

		btVector3 forwardW (
			  chassisTrans.getBasis()[0][m_indexForwardAxis],
			  chassisTrans.getBasis()[1][m_indexForwardAxis],
			  chassisTrans.getBasis()[2][m_indexForwardAxis]);

		return forwardW;
	}

	///Velocity of vehicle (positive if velocity vector has same direction as foward vector)
	btScalar	getCurrentSpeedKmHour() const
	{
		return m_currentVehicleSpeedKmHour;
	}

	virtual void	setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex)
	{
		m_indexRightAxis = rightIndex;
		m_indexUpAxis = upIndex;
		m_indexForwardAxis = forwardIndex;
	}

	///backwards compatibility
	int getUserConstraintType() const
	{
		return m_userConstraintType ;
	}

	void	setUserConstraintType(int userConstraintType)
	{
		m_userConstraintType = userConstraintType;
	};

	void	setUserConstraintId(int uid)
	{
		m_userConstraintId = uid;
	}

	int getUserConstraintId() const
	{
		return m_userConstraintId;
	}

};

class btDefaultVehicleRaycaster : public btVehicleRaycaster
{
	btDynamicsWorld*	m_dynamicsWorld;
public:
	btDefaultVehicleRaycaster(btDynamicsWorld* world)
		:m_dynamicsWorld(world)
	{
	}

	virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result);

};

#endif //BT_RAYCASTVEHICLE_H


text:
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com

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_CHARACTER_CONTROLLER_INTERFACE_H
#define BT_CHARACTER_CONTROLLER_INTERFACE_H

#include "LinearMath/btVector3.h"
#include "BulletDynamics/Dynamics/btActionInterface.h"

class btCollisionShape;
class btRigidBody;
class btCollisionWorld;

class btCharacterControllerInterface : public btActionInterface
{
public:
	btCharacterControllerInterface () {};
	virtual ~btCharacterControllerInterface () {};

	virtual void	setWalkDirection(const btVector3& walkDirection) = 0;
	virtual void	setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0;
	virtual void	reset ( btCollisionWorld* collisionWorld ) = 0;
	virtual void	warp (const btVector3& origin) = 0;

	virtual void	preStep ( btCollisionWorld* collisionWorld) = 0;
	virtual void	playerStep (btCollisionWorld* collisionWorld, btScalar dt) = 0;
	virtual bool	canJump () const = 0;
	virtual void	jump(const btVector3& dir = btVector3()) = 0;

	virtual bool	onGround () const = 0;
	virtual void	setUpInterpolate (bool value) = 0;
};

#endif //BT_CHARACTER_CONTROLLER_INTERFACE_H


text:
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com

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_KINEMATIC_CHARACTER_CONTROLLER_H
#define BT_KINEMATIC_CHARACTER_CONTROLLER_H

#include "LinearMath/btVector3.h"

#include "btCharacterControllerInterface.h"

#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"

class btCollisionShape;
class btConvexShape;
class btRigidBody;
class btCollisionWorld;
class btCollisionDispatcher;
class btPairCachingGhostObject;

///btKinematicCharacterController is an object that supports a sliding motion in a world.
///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterControllerInterface
{
protected:

	btScalar m_halfHeight;

	btPairCachingGhostObject* m_ghostObject;
	btConvexShape*	m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast

	btScalar m_maxPenetrationDepth;
	btScalar m_verticalVelocity;
	btScalar m_verticalOffset;
	btScalar m_fallSpeed;
	btScalar m_jumpSpeed;
	btScalar m_SetjumpSpeed;
	btScalar m_maxJumpHeight;
	btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value)
	btScalar m_maxSlopeCosine;  // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization)
	btScalar m_gravity;

	btScalar m_turnAngle;

	btScalar m_stepHeight;

	btScalar	m_addedMargin;//@todo: remove this and fix the code

	///this is the desired walk direction, set by the user
	btVector3	m_walkDirection;
	btVector3	m_normalizedDirection;
	btVector3	m_AngVel;

	btVector3	m_jumpPosition;

	//some internal variables
	btVector3 m_currentPosition;
	btScalar  m_currentStepOffset;
	btVector3 m_targetPosition;

	btQuaternion m_currentOrientation;
	btQuaternion m_targetOrientation;

	///keep track of the contact manifolds
	btManifoldArray	m_manifoldArray;

	bool m_touchingContact;
	btVector3 m_touchingNormal;

	btScalar m_linearDamping;
	btScalar m_angularDamping;

	bool  m_wasOnGround;
	bool  m_wasJumping;
	bool	m_useGhostObjectSweepTest;
	bool	m_useWalkDirection;
	btScalar	m_velocityTimeInterval;
	btVector3 m_up;
	btVector3 m_jumpAxis;

	static btVector3* getUpAxisDirections();
	bool  m_interpolateUp;
	bool  full_drop;
	bool  bounce_fix;

	btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
	btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
	btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal);

	bool recoverFromPenetration ( btCollisionWorld* collisionWorld);
	void stepUp (btCollisionWorld* collisionWorld);
	void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0));
	void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove);
	void stepDown (btCollisionWorld* collisionWorld, btScalar dt);

	virtual bool needsCollision(const btCollisionObject* body0, const btCollisionObject* body1);

	void setUpVector(const btVector3& up);

	btQuaternion getRotation(btVector3& v0, btVector3& v1) const;

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up = btVector3(1.0,0.0,0.0));
	~btKinematicCharacterController ();

	///btActionInterface interface
	virtual void updateAction( btCollisionWorld* collisionWorld,btScalar deltaTime)
	{
		preStep ( collisionWorld);
		playerStep (collisionWorld, deltaTime);
	}

	///btActionInterface interface
	void	debugDraw(btIDebugDraw* debugDrawer);

	void setUp(const btVector3& up);

	const btVector3& getUp() { return m_up; }

	/// This should probably be called setPositionIncrementPerSimulatorStep.
	/// This is neither a direction nor a velocity, but the amount to
	///	increment the position each simulation iteration, regardless
	///	of dt.
	/// This call will reset any velocity set by setVelocityForTimeInterval().
	virtual void	setWalkDirection(const btVector3& walkDirection);

	/// Caller provides a velocity with which the character should move for
	///	the given time period.  After the time period, velocity is reset
	///	to zero.
	/// This call will reset any walk direction set by setWalkDirection().
	/// Negative time intervals will result in no motion.
	virtual void setVelocityForTimeInterval(const btVector3& velocity,
				btScalar timeInterval);

	virtual void setAngularVelocity(const btVector3& velocity);
	virtual const btVector3& getAngularVelocity() const;

	virtual void setLinearVelocity(const btVector3& velocity);
	virtual btVector3 getLinearVelocity() const;

	void setLinearDamping(btScalar d) { m_linearDamping = btClamped(d, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); }
	btScalar getLinearDamping() const { return  m_linearDamping; }
	void setAngularDamping(btScalar d) { m_angularDamping = btClamped(d, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); }
	btScalar getAngularDamping() const { return  m_angularDamping; }

	void reset ( btCollisionWorld* collisionWorld );
	void warp (const btVector3& origin);

	void preStep (  btCollisionWorld* collisionWorld);
	void playerStep ( btCollisionWorld* collisionWorld, btScalar dt);

	void setStepHeight(btScalar h);
	btScalar getStepHeight() const { return m_stepHeight; }
	void setFallSpeed (btScalar fallSpeed);
	btScalar getFallSpeed() const { return m_fallSpeed; }
	void setJumpSpeed (btScalar jumpSpeed);
	btScalar getJumpSpeed() const { return m_jumpSpeed; }
	void setMaxJumpHeight (btScalar maxJumpHeight);
	bool canJump () const;

	void jump(const btVector3& v = btVector3());

	void applyImpulse(const btVector3& v) { jump(v); }

	void setGravity(const btVector3& gravity);
	btVector3 getGravity() const;

	/// The max slope determines the maximum angle that the controller can walk up.
	/// The slope angle is measured in radians.
	void setMaxSlope(btScalar slopeRadians);
	btScalar getMaxSlope() const;

	void setMaxPenetrationDepth(btScalar d);
	btScalar getMaxPenetrationDepth() const;

	btPairCachingGhostObject* getGhostObject();
	void	setUseGhostSweepTest(bool useGhostObjectSweepTest)
	{
		m_useGhostObjectSweepTest = useGhostObjectSweepTest;
	}

	bool onGround () const;
	void setUpInterpolate (bool value);
};

#endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H


text:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Author: Oros
# 2016/10/06
# License : CC0 1.0 Universal

"""
Display SDCCH, Subchannel, Timeslot, HoppingChannel, ARFCN
"""
from scapy.all import sniff
from optparse import OptionParser

def find_assignment(x):
	"""

	0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
	0010   00 43 b1 be 40 00 40 11 8a e9 7f 00 00 01 7f 00
	0020   00 01 b9 11 12 79 00 2f fe 42 02 04 01 00 00 00
	0030   e6 00 00 08 d4 7a 02 00 06 00 2d 06 3f 10 0e 03
	0040   df 7b a3 71 01 00 ce 01 81 59 d7 2b 2b 2b 2b 2b
	0050   2b

	Dedicated mode or TBF
	0000   10
		0001 .... = Dedicated mode or TBF: This message assigns an uplink TBF or is the second message of two in a two-message assignment of an uplink or downlink TBF (1)
	Packet Channel Description
	0000   0e 03 df
		0000 1... = Channel Type: 1
		.... .110 = Timeslot: 6
		000. .... = Training Sequence: 0
		.... .0.. = Spare: 0x00
		.... ..11  1101 1111 = Single channel ARFCN: 991

	Dedicated mode or TBF
	0000   30
		0011 .... = Dedicated mode or TBF: This message assigns a downlink TBF to the mobile station identified in the IA Rest Octets IE (3)

	GSMTAP	81	(CCCH) (RR) Immediate Assignment
	0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
	0010   00 43 07 02 40 00 40 11 35 a6 7f 00 00 01 7f 00
	0020   00 01 b7 29 12 79 00 2f fe 42 02 04 01 00 00 00
	0030   e6 00 00 16 ab ce 02 00 07 00 2d 06 3f 03 41 c0
	0040   09 00 03 b1 01 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
	0050   2b

	0x3e = 0x41
	0100 0... = SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8): 8
	Subchannel: 0
	.... .001 = Timeslot: 1

	0x3f = 0xc0
	110. .... = Training Sequence: 6
	...0 .... = Hopping Channel: No
	..00 .... = Spare: 0x00

	0x40 = 0x09
	Single channel ARFCN: 9

			0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

	0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
	0010   00 43 c8 7f 40 00 40 11 74 28 7f 00 00 01 7f 00
	0020   00 01 9c c8 12 79 00 2f fe 42 02 04 01 00 00 00
	0030   e4 00 00 09 0a e7 02 00 08 00 2d 06 3f 00 41 03
	0040   df 92 f4 2a 01 00 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
	0050   2b

	Dedicated mode or TBF
	0000   00
		0000 .... = Dedicated mode or TBF: This message assigns a dedicated mode resource (0)
	Channel Description
	0000   41 03 df
		0100 0... = SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8): 8
		Subchannel: 0
		.... .001 = Timeslot: 1
		000. .... = Training Sequence: 0
		...0 .... = Hopping Channel: No
		..00 .... = Spare: 0x00
		Single channel ARFCN: 991

	79
	0111 1... = SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8): 15
	Subchannel: 7
	.... .001 = Timeslot: 1

	ARFCN calcul :
	https://en.wikipedia.org/wiki/ARFCN
	http://www.telecomabc.com/a/arfcn.html
	http://niviuk.free.fr/gsm_band.php

	"""
	p=str(x)
	if ord(p[0x36]) != 0x1: # Channel Type != BCCH (0)
		if ord(p[0x3c]) == 0x3f: # Message Type: Immediate Assignment
			if ord(p[0x3d]) >> 4 == 0: # 0000 .... = Dedicated mode or TBF: This message assigns a dedicated mode resource (0)
				sdcch=ord(p[0x3e]) >> 3 # 0100 0... = SDCCH/8 + SACCH/C8 or CBCH (SDCCH/8): 8
				subchannel=ord(p[0x3e])
				timeslot=ord(p[0x3e]) & 0x07 # .... .001 = Timeslot: 1
				hopping_channel="yes" if (ord(p[0x3f]) >> 4) & 1 == 1 else "no" # ...0 .... = Hopping Channel: No
				arfcn=(ord(p[0x3f]) & 0x03)*256 + ord(p[0x40]) # .... ..11  1101 1111 = Single channel ARFCN: 991
				print("{}\t; {}\t\t; {}\t\t; {}\t\t\t; {}".format(sdcch, subchannel, timeslot, hopping_channel, arfcn))
			else:
				# Dedicated mode or TBF: This message assigns an uplink TBF or is the second message of two in a two-message assignment of an uplink or downlink TBF (1)
				sdcch="-"
				subchannel="-"
				timeslot=ord(p[0x3e]) & 0x07 # .... .001 = Timeslot: 1
				hopping_channel="-"
				arfcn=(ord(p[0x3f]) & 0x03)*256 + ord(p[0x40]) # .... ..11  1101 1111 = Single channel ARFCN: 991
				print("{}\t; {}\t\t; {}\t\t; {}\t\t\t; {}".format(sdcch, subchannel, timeslot, hopping_channel, arfcn))
				pass

parser = OptionParser(usage="%prog: [options]")
parser.add_option("-i", "--iface", dest="iface", default="lo", help="Interface (default : lo)")
parser.add_option("-p", "--port", dest="port", default="4729", type="int", help="Port (default : 4729)")
(options, args) = parser.parse_args()

print("SDCCH\t; Subchannel\t; Timeslot\t; HoppingChannel\t; ARFCN")
sniff(iface=options.iface, filter="port {} and not icmp and udp".format(options.port), prn=find_assignment, store=0)

repo_language: Python