mirror of https://github.com/axmolengine/axmol.git
350 lines
14 KiB
C++
350 lines
14 KiB
C++
/*
|
|
Bullet Continuous Collision Detection and Physics Library
|
|
Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
|
|
|
|
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
|