2017-08-01 14:30:58 +02:00
/*
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 .
*/
/*
2014 May : btGeneric6DofSpring2Constraint is created from the original ( 2.82 .2712 ) btGeneric6DofConstraint by Gabor Puhr and Tamas Umenhoffer
Pros :
- Much more accurate and stable in a lot of situation . ( Especially when a sleeping chain of RBs connected with 6 dof2 is pulled )
- Stable and accurate spring with minimal energy loss that works with all of the solvers . ( latter is not true for the original 6 dof spring )
- Servo motor functionality
- Much more accurate bouncing . 0 really means zero bouncing ( not true for the original 6 odf ) and there is only a minimal energy loss when the value is 1 ( because of the solvers ' precision )
- Rotation order for the Euler system can be set . ( One axis ' freedom is still limited to pi / 2 )
Cons :
- It is slower than the original 6 dof . There is no exact ratio , but half speed is a good estimation .
- At bouncing the correct velocity is calculated , but not the correct position . ( it is because of the solver can correct position or velocity , but not both . )
*/
/// 2009 March: btGeneric6DofConstraint refactored by Roman Ponomarev
/// Added support for generic constraint solver through getInfo1/getInfo2 methods
/*
2007 - 09 - 09
btGeneric6DofConstraint Refactored by Francisco Le ? n
email : projectileman @ yahoo . com
http : //gimpact.sf.net
*/
# ifndef BT_GENERIC_6DOF_CONSTRAINT2_H
# define BT_GENERIC_6DOF_CONSTRAINT2_H
# include "LinearMath/btVector3.h"
# include "btJacobianEntry.h"
# include "btTypedConstraint.h"
class btRigidBody ;
# ifdef BT_USE_DOUBLE_PRECISION
2019-01-03 14:26:51 +01:00
# define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintDoubleData2
# define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintDoubleData2"
2017-08-01 14:30:58 +02:00
# else
2019-01-03 14:26:51 +01:00
# define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintData
# define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintData"
# endif //BT_USE_DOUBLE_PRECISION
2017-08-01 14:30:58 +02:00
enum RotateOrder
{
2019-01-03 14:26:51 +01:00
RO_XYZ = 0 ,
2017-08-01 14:30:58 +02:00
RO_XZY ,
RO_YXZ ,
RO_YZX ,
RO_ZXY ,
RO_ZYX
} ;
class btRotationalLimitMotor2
{
public :
2019-01-03 14:26:51 +01:00
// upper < lower means free
// upper == lower means locked
// upper > lower means limited
2017-08-01 14:30:58 +02:00
btScalar m_loLimit ;
btScalar m_hiLimit ;
btScalar m_bounce ;
btScalar m_stopERP ;
btScalar m_stopCFM ;
btScalar m_motorERP ;
btScalar m_motorCFM ;
2019-01-03 14:26:51 +01:00
bool m_enableMotor ;
2017-08-01 14:30:58 +02:00
btScalar m_targetVelocity ;
btScalar m_maxMotorForce ;
2019-01-03 14:26:51 +01:00
bool m_servoMotor ;
2017-08-01 14:30:58 +02:00
btScalar m_servoTarget ;
2019-01-03 14:26:51 +01:00
bool m_enableSpring ;
2017-08-01 14:30:58 +02:00
btScalar m_springStiffness ;
2019-01-03 14:26:51 +01:00
bool m_springStiffnessLimited ;
2017-08-01 14:30:58 +02:00
btScalar m_springDamping ;
2019-01-03 14:26:51 +01:00
bool m_springDampingLimited ;
2017-08-01 14:30:58 +02:00
btScalar m_equilibriumPoint ;
btScalar m_currentLimitError ;
btScalar m_currentLimitErrorHi ;
btScalar m_currentPosition ;
2019-01-03 14:26:51 +01:00
int m_currentLimit ;
2017-08-01 14:30:58 +02:00
btRotationalLimitMotor2 ( )
{
2019-01-03 14:26:51 +01:00
m_loLimit = 1.0f ;
m_hiLimit = - 1.0f ;
m_bounce = 0.0f ;
m_stopERP = 0.2f ;
m_stopCFM = 0.f ;
m_motorERP = 0.9f ;
m_motorCFM = 0.f ;
m_enableMotor = false ;
m_targetVelocity = 0 ;
m_maxMotorForce = 6.0f ;
m_servoMotor = false ;
m_servoTarget = 0 ;
m_enableSpring = false ;
m_springStiffness = 0 ;
2017-08-01 14:30:58 +02:00
m_springStiffnessLimited = false ;
2019-01-03 14:26:51 +01:00
m_springDamping = 0 ;
m_springDampingLimited = false ;
m_equilibriumPoint = 0 ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
m_currentLimitError = 0 ;
2017-08-01 14:30:58 +02:00
m_currentLimitErrorHi = 0 ;
2019-01-03 14:26:51 +01:00
m_currentPosition = 0 ;
m_currentLimit = 0 ;
2017-08-01 14:30:58 +02:00
}
2019-01-03 14:26:51 +01:00
btRotationalLimitMotor2 ( const btRotationalLimitMotor2 & limot )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
m_loLimit = limot . m_loLimit ;
m_hiLimit = limot . m_hiLimit ;
m_bounce = limot . m_bounce ;
m_stopERP = limot . m_stopERP ;
m_stopCFM = limot . m_stopCFM ;
m_motorERP = limot . m_motorERP ;
m_motorCFM = limot . m_motorCFM ;
m_enableMotor = limot . m_enableMotor ;
m_targetVelocity = limot . m_targetVelocity ;
m_maxMotorForce = limot . m_maxMotorForce ;
m_servoMotor = limot . m_servoMotor ;
m_servoTarget = limot . m_servoTarget ;
m_enableSpring = limot . m_enableSpring ;
m_springStiffness = limot . m_springStiffness ;
2017-08-01 14:30:58 +02:00
m_springStiffnessLimited = limot . m_springStiffnessLimited ;
2019-01-03 14:26:51 +01:00
m_springDamping = limot . m_springDamping ;
m_springDampingLimited = limot . m_springDampingLimited ;
m_equilibriumPoint = limot . m_equilibriumPoint ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
m_currentLimitError = limot . m_currentLimitError ;
2017-08-01 14:30:58 +02:00
m_currentLimitErrorHi = limot . m_currentLimitErrorHi ;
2019-01-03 14:26:51 +01:00
m_currentPosition = limot . m_currentPosition ;
m_currentLimit = limot . m_currentLimit ;
2017-08-01 14:30:58 +02:00
}
bool isLimited ( )
{
2019-01-03 14:26:51 +01:00
if ( m_loLimit > m_hiLimit ) return false ;
2017-08-01 14:30:58 +02:00
return true ;
}
void testLimitValue ( btScalar test_value ) ;
} ;
class btTranslationalLimitMotor2
{
public :
2019-01-03 14:26:51 +01:00
// upper < lower means free
// upper == lower means locked
// upper > lower means limited
2017-08-01 14:30:58 +02:00
btVector3 m_lowerLimit ;
btVector3 m_upperLimit ;
btVector3 m_bounce ;
btVector3 m_stopERP ;
btVector3 m_stopCFM ;
btVector3 m_motorERP ;
btVector3 m_motorCFM ;
2019-01-03 14:26:51 +01:00
bool m_enableMotor [ 3 ] ;
bool m_servoMotor [ 3 ] ;
bool m_enableSpring [ 3 ] ;
2017-08-01 14:30:58 +02:00
btVector3 m_servoTarget ;
btVector3 m_springStiffness ;
2019-01-03 14:26:51 +01:00
bool m_springStiffnessLimited [ 3 ] ;
2017-08-01 14:30:58 +02:00
btVector3 m_springDamping ;
2019-01-03 14:26:51 +01:00
bool m_springDampingLimited [ 3 ] ;
2017-08-01 14:30:58 +02:00
btVector3 m_equilibriumPoint ;
btVector3 m_targetVelocity ;
btVector3 m_maxMotorForce ;
btVector3 m_currentLimitError ;
btVector3 m_currentLimitErrorHi ;
btVector3 m_currentLinearDiff ;
2019-01-03 14:26:51 +01:00
int m_currentLimit [ 3 ] ;
2017-08-01 14:30:58 +02:00
btTranslationalLimitMotor2 ( )
{
2019-01-03 14:26:51 +01:00
m_lowerLimit . setValue ( 0.f , 0.f , 0.f ) ;
m_upperLimit . setValue ( 0.f , 0.f , 0.f ) ;
m_bounce . setValue ( 0.f , 0.f , 0.f ) ;
m_stopERP . setValue ( 0.2f , 0.2f , 0.2f ) ;
m_stopCFM . setValue ( 0.f , 0.f , 0.f ) ;
m_motorERP . setValue ( 0.9f , 0.9f , 0.9f ) ;
m_motorCFM . setValue ( 0.f , 0.f , 0.f ) ;
m_currentLimitError . setValue ( 0.f , 0.f , 0.f ) ;
m_currentLimitErrorHi . setValue ( 0.f , 0.f , 0.f ) ;
m_currentLinearDiff . setValue ( 0.f , 0.f , 0.f ) ;
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
m_enableMotor [ i ] = false ;
m_servoMotor [ i ] = false ;
m_enableSpring [ i ] = false ;
m_servoTarget [ i ] = btScalar ( 0.f ) ;
m_springStiffness [ i ] = btScalar ( 0.f ) ;
2017-08-01 14:30:58 +02:00
m_springStiffnessLimited [ i ] = false ;
2019-01-03 14:26:51 +01:00
m_springDamping [ i ] = btScalar ( 0.f ) ;
m_springDampingLimited [ i ] = false ;
m_equilibriumPoint [ i ] = btScalar ( 0.f ) ;
m_targetVelocity [ i ] = btScalar ( 0.f ) ;
m_maxMotorForce [ i ] = btScalar ( 0.f ) ;
m_currentLimit [ i ] = 0 ;
2017-08-01 14:30:58 +02:00
}
}
2019-01-03 14:26:51 +01:00
btTranslationalLimitMotor2 ( const btTranslationalLimitMotor2 & other )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
m_lowerLimit = other . m_lowerLimit ;
m_upperLimit = other . m_upperLimit ;
m_bounce = other . m_bounce ;
m_stopERP = other . m_stopERP ;
m_stopCFM = other . m_stopCFM ;
m_motorERP = other . m_motorERP ;
m_motorCFM = other . m_motorCFM ;
m_currentLimitError = other . m_currentLimitError ;
2017-08-01 14:30:58 +02:00
m_currentLimitErrorHi = other . m_currentLimitErrorHi ;
2019-01-03 14:26:51 +01:00
m_currentLinearDiff = other . m_currentLinearDiff ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
m_enableMotor [ i ] = other . m_enableMotor [ i ] ;
m_servoMotor [ i ] = other . m_servoMotor [ i ] ;
m_enableSpring [ i ] = other . m_enableSpring [ i ] ;
m_servoTarget [ i ] = other . m_servoTarget [ i ] ;
m_springStiffness [ i ] = other . m_springStiffness [ i ] ;
2017-08-01 14:30:58 +02:00
m_springStiffnessLimited [ i ] = other . m_springStiffnessLimited [ i ] ;
2019-01-03 14:26:51 +01:00
m_springDamping [ i ] = other . m_springDamping [ i ] ;
m_springDampingLimited [ i ] = other . m_springDampingLimited [ i ] ;
m_equilibriumPoint [ i ] = other . m_equilibriumPoint [ i ] ;
m_targetVelocity [ i ] = other . m_targetVelocity [ i ] ;
m_maxMotorForce [ i ] = other . m_maxMotorForce [ i ] ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
m_currentLimit [ i ] = other . m_currentLimit [ i ] ;
2017-08-01 14:30:58 +02:00
}
}
inline bool isLimited ( int limitIndex )
{
return ( m_upperLimit [ limitIndex ] > = m_lowerLimit [ limitIndex ] ) ;
}
void testLimitValue ( int limitIndex , btScalar test_value ) ;
} ;
enum bt6DofFlags2
{
BT_6DOF_FLAGS_CFM_STOP2 = 1 ,
BT_6DOF_FLAGS_ERP_STOP2 = 2 ,
BT_6DOF_FLAGS_CFM_MOTO2 = 4 ,
2019-01-03 14:26:51 +01:00
BT_6DOF_FLAGS_ERP_MOTO2 = 8 ,
2020-04-27 10:15:23 +02:00
BT_6DOF_FLAGS_USE_INFINITE_ERROR = ( 1 < < 16 )
2017-08-01 14:30:58 +02:00
} ;
2019-01-03 14:26:51 +01:00
# define BT_6DOF_FLAGS_AXIS_SHIFT2 4 // bits per axis
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
ATTRIBUTE_ALIGNED16 ( class )
btGeneric6DofSpring2Constraint : public btTypedConstraint
2017-08-01 14:30:58 +02:00
{
protected :
btTransform m_frameInA ;
btTransform m_frameInB ;
btJacobianEntry m_jacLinear [ 3 ] ;
btJacobianEntry m_jacAng [ 3 ] ;
btTranslationalLimitMotor2 m_linearLimits ;
btRotationalLimitMotor2 m_angularLimits [ 3 ] ;
RotateOrder m_rotateOrder ;
protected :
2019-01-03 14:26:51 +01:00
btTransform m_calculatedTransformA ;
btTransform m_calculatedTransformB ;
btVector3 m_calculatedAxisAngleDiff ;
btVector3 m_calculatedAxis [ 3 ] ;
btVector3 m_calculatedLinearDiff ;
btScalar m_factA ;
btScalar m_factB ;
bool m_hasStaticBody ;
int m_flags ;
2019-06-11 13:18:05 +02:00
btGeneric6DofSpring2Constraint & operator = ( const btGeneric6DofSpring2Constraint & )
2017-08-01 14:30:58 +02:00
{
btAssert ( 0 ) ;
return * this ;
}
2019-01-03 14:26:51 +01:00
int setAngularLimits ( btConstraintInfo2 * info , int row_offset , const btTransform & transA , const btTransform & transB , const btVector3 & linVelA , const btVector3 & linVelB , const btVector3 & angVelA , const btVector3 & angVelB ) ;
int setLinearLimits ( btConstraintInfo2 * info , int row , const btTransform & transA , const btTransform & transB , const btVector3 & linVelA , const btVector3 & linVelB , const btVector3 & angVelA , const btVector3 & angVelB ) ;
2017-08-01 14:30:58 +02:00
void calculateLinearInfo ( ) ;
void calculateAngleInfo ( ) ;
void testAngularLimitMotor ( int axis_index ) ;
2019-01-03 14:26:51 +01:00
void calculateJacobi ( btRotationalLimitMotor2 * limot , const btTransform & transA , const btTransform & transB , btConstraintInfo2 * info , int srow , btVector3 & ax1 , int rotational , int rotAllowed ) ;
int get_limit_motor_info2 ( btRotationalLimitMotor2 * limot ,
const btTransform & transA , const btTransform & transB , const btVector3 & linVelA , const btVector3 & linVelB , const btVector3 & angVelA , const btVector3 & angVelB ,
btConstraintInfo2 * info , int row , btVector3 & ax1 , int rotational , int rotAllowed = false ) ;
2017-08-01 14:30:58 +02:00
public :
BT_DECLARE_ALIGNED_ALLOCATOR ( ) ;
2019-01-03 14:26:51 +01:00
btGeneric6DofSpring2Constraint ( btRigidBody & rbA , btRigidBody & rbB , const btTransform & frameInA , const btTransform & frameInB , RotateOrder rotOrder = RO_XYZ ) ;
btGeneric6DofSpring2Constraint ( btRigidBody & rbB , const btTransform & frameInB , RotateOrder rotOrder = RO_XYZ ) ;
2017-08-01 14:30:58 +02:00
virtual void buildJacobian ( ) { }
2019-01-03 14:26:51 +01:00
virtual void getInfo1 ( btConstraintInfo1 * info ) ;
virtual void getInfo2 ( btConstraintInfo2 * info ) ;
2017-08-01 14:30:58 +02:00
virtual int calculateSerializeBufferSize ( ) const ;
virtual const char * serialize ( void * dataBuffer , btSerializer * serializer ) const ;
btRotationalLimitMotor2 * getRotationalLimitMotor ( int index ) { return & m_angularLimits [ index ] ; }
btTranslationalLimitMotor2 * getTranslationalLimitMotor ( ) { return & m_linearLimits ; }
// Calculates the global transform for the joint offset for body A an B, and also calculates the angle differences between the bodies.
2019-01-03 14:26:51 +01:00
void calculateTransforms ( const btTransform & transA , const btTransform & transB ) ;
2017-08-01 14:30:58 +02:00
void calculateTransforms ( ) ;
// Gets the global transform of the offset for body A
2019-01-03 14:26:51 +01:00
const btTransform & getCalculatedTransformA ( ) const { return m_calculatedTransformA ; }
2017-08-01 14:30:58 +02:00
// Gets the global transform of the offset for body B
2019-01-03 14:26:51 +01:00
const btTransform & getCalculatedTransformB ( ) const { return m_calculatedTransformB ; }
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
const btTransform & getFrameOffsetA ( ) const { return m_frameInA ; }
const btTransform & getFrameOffsetB ( ) const { return m_frameInB ; }
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
btTransform & getFrameOffsetA ( ) { return m_frameInA ; }
btTransform & getFrameOffsetB ( ) { return m_frameInB ; }
2017-08-01 14:30:58 +02:00
// Get the rotation axis in global coordinates ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
btVector3 getAxis ( int axis_index ) const { return m_calculatedAxis [ axis_index ] ; }
// Get the relative Euler angle ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
btScalar getAngle ( int axis_index ) const { return m_calculatedAxisAngleDiff [ axis_index ] ; }
// Get the relative position of the constraint pivot ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously )
btScalar getRelativePivotPosition ( int axis_index ) const { return m_calculatedLinearDiff [ axis_index ] ; }
2019-01-03 14:26:51 +01:00
void setFrames ( const btTransform & frameA , const btTransform & frameB ) ;
2017-08-01 14:30:58 +02:00
void setLinearLowerLimit ( const btVector3 & linearLower ) { m_linearLimits . m_lowerLimit = linearLower ; }
2019-01-03 14:26:51 +01:00
void getLinearLowerLimit ( btVector3 & linearLower ) { linearLower = m_linearLimits . m_lowerLimit ; }
2017-08-01 14:30:58 +02:00
void setLinearUpperLimit ( const btVector3 & linearUpper ) { m_linearLimits . m_upperLimit = linearUpper ; }
2019-01-03 14:26:51 +01:00
void getLinearUpperLimit ( btVector3 & linearUpper ) { linearUpper = m_linearLimits . m_upperLimit ; }
2017-08-01 14:30:58 +02:00
void setAngularLowerLimit ( const btVector3 & angularLower )
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
m_angularLimits [ i ] . m_loLimit = btNormalizeAngle ( angularLower [ i ] ) ;
}
void setAngularLowerLimitReversed ( const btVector3 & angularLower )
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
m_angularLimits [ i ] . m_hiLimit = btNormalizeAngle ( - angularLower [ i ] ) ;
}
2019-01-03 14:26:51 +01:00
void getAngularLowerLimit ( btVector3 & angularLower )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
angularLower [ i ] = m_angularLimits [ i ] . m_loLimit ;
}
2019-01-03 14:26:51 +01:00
void getAngularLowerLimitReversed ( btVector3 & angularLower )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
angularLower [ i ] = - m_angularLimits [ i ] . m_hiLimit ;
}
void setAngularUpperLimit ( const btVector3 & angularUpper )
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
m_angularLimits [ i ] . m_hiLimit = btNormalizeAngle ( angularUpper [ i ] ) ;
}
void setAngularUpperLimitReversed ( const btVector3 & angularUpper )
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
m_angularLimits [ i ] . m_loLimit = btNormalizeAngle ( - angularUpper [ i ] ) ;
}
2019-01-03 14:26:51 +01:00
void getAngularUpperLimit ( btVector3 & angularUpper )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
angularUpper [ i ] = m_angularLimits [ i ] . m_hiLimit ;
}
2019-01-03 14:26:51 +01:00
void getAngularUpperLimitReversed ( btVector3 & angularUpper )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
angularUpper [ i ] = - m_angularLimits [ i ] . m_loLimit ;
}
//first 3 are linear, next 3 are angular
void setLimit ( int axis , btScalar lo , btScalar hi )
{
2019-01-03 14:26:51 +01:00
if ( axis < 3 )
2017-08-01 14:30:58 +02:00
{
m_linearLimits . m_lowerLimit [ axis ] = lo ;
m_linearLimits . m_upperLimit [ axis ] = hi ;
}
else
{
lo = btNormalizeAngle ( lo ) ;
hi = btNormalizeAngle ( hi ) ;
2019-01-03 14:26:51 +01:00
m_angularLimits [ axis - 3 ] . m_loLimit = lo ;
m_angularLimits [ axis - 3 ] . m_hiLimit = hi ;
2017-08-01 14:30:58 +02:00
}
}
void setLimitReversed ( int axis , btScalar lo , btScalar hi )
{
2019-01-03 14:26:51 +01:00
if ( axis < 3 )
2017-08-01 14:30:58 +02:00
{
m_linearLimits . m_lowerLimit [ axis ] = lo ;
m_linearLimits . m_upperLimit [ axis ] = hi ;
}
else
{
lo = btNormalizeAngle ( lo ) ;
hi = btNormalizeAngle ( hi ) ;
2019-01-03 14:26:51 +01:00
m_angularLimits [ axis - 3 ] . m_hiLimit = - lo ;
m_angularLimits [ axis - 3 ] . m_loLimit = - hi ;
2017-08-01 14:30:58 +02:00
}
}
bool isLimited ( int limitIndex )
{
2019-01-03 14:26:51 +01:00
if ( limitIndex < 3 )
2017-08-01 14:30:58 +02:00
{
return m_linearLimits . isLimited ( limitIndex ) ;
}
2019-01-03 14:26:51 +01:00
return m_angularLimits [ limitIndex - 3 ] . isLimited ( ) ;
2017-08-01 14:30:58 +02:00
}
void setRotationOrder ( RotateOrder order ) { m_rotateOrder = order ; }
RotateOrder getRotationOrder ( ) { return m_rotateOrder ; }
2019-01-03 14:26:51 +01:00
void setAxis ( const btVector3 & axis1 , const btVector3 & axis2 ) ;
2017-08-01 14:30:58 +02:00
void setBounce ( int index , btScalar bounce ) ;
void enableMotor ( int index , bool onOff ) ;
2019-01-03 14:26:51 +01:00
void setServo ( int index , bool onOff ) ; // set the type of the motor (servo or not) (the motor has to be turned on for servo also)
2017-08-01 14:30:58 +02:00
void setTargetVelocity ( int index , btScalar velocity ) ;
void setServoTarget ( int index , btScalar target ) ;
void setMaxMotorForce ( int index , btScalar force ) ;
void enableSpring ( int index , bool onOff ) ;
2019-01-03 14:26:51 +01:00
void setStiffness ( int index , btScalar stiffness , bool limitIfNeeded = true ) ; // if limitIfNeeded is true the system will automatically limit the stiffness in necessary situations where otherwise the spring would move unrealistically too widely
void setDamping ( int index , btScalar damping , bool limitIfNeeded = true ) ; // if limitIfNeeded is true the system will automatically limit the damping in necessary situations where otherwise the spring would blow up
void setEquilibriumPoint ( ) ; // set the current constraint position/orientation as an equilibrium point for all DOF
void setEquilibriumPoint ( int index ) ; // set the current constraint position/orientation as an equilibrium point for given DOF
2017-08-01 14:30:58 +02:00
void setEquilibriumPoint ( int index , btScalar val ) ;
2019-01-03 14:26:51 +01:00
//override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5).
2017-08-01 14:30:58 +02:00
//If no axis is provided, it uses the default axis for this constraint.
virtual void setParam ( int num , btScalar value , int axis = - 1 ) ;
virtual btScalar getParam ( int num , int axis = - 1 ) const ;
2019-01-03 14:26:51 +01:00
static btScalar btGetMatrixElem ( const btMatrix3x3 & mat , int index ) ;
static bool matrixToEulerXYZ ( const btMatrix3x3 & mat , btVector3 & xyz ) ;
static bool matrixToEulerXZY ( const btMatrix3x3 & mat , btVector3 & xyz ) ;
static bool matrixToEulerYXZ ( const btMatrix3x3 & mat , btVector3 & xyz ) ;
static bool matrixToEulerYZX ( const btMatrix3x3 & mat , btVector3 & xyz ) ;
static bool matrixToEulerZXY ( const btMatrix3x3 & mat , btVector3 & xyz ) ;
static bool matrixToEulerZYX ( const btMatrix3x3 & mat , btVector3 & xyz ) ;
} ;
2017-08-01 14:30:58 +02:00
struct btGeneric6DofSpring2ConstraintData
{
btTypedConstraintData m_typeConstraintData ;
btTransformFloatData m_rbAFrame ;
btTransformFloatData m_rbBFrame ;
btVector3FloatData m_linearUpperLimit ;
btVector3FloatData m_linearLowerLimit ;
btVector3FloatData m_linearBounce ;
btVector3FloatData m_linearStopERP ;
btVector3FloatData m_linearStopCFM ;
btVector3FloatData m_linearMotorERP ;
btVector3FloatData m_linearMotorCFM ;
btVector3FloatData m_linearTargetVelocity ;
btVector3FloatData m_linearMaxMotorForce ;
btVector3FloatData m_linearServoTarget ;
btVector3FloatData m_linearSpringStiffness ;
btVector3FloatData m_linearSpringDamping ;
btVector3FloatData m_linearEquilibriumPoint ;
2019-01-03 14:26:51 +01:00
char m_linearEnableMotor [ 4 ] ;
char m_linearServoMotor [ 4 ] ;
char m_linearEnableSpring [ 4 ] ;
char m_linearSpringStiffnessLimited [ 4 ] ;
char m_linearSpringDampingLimited [ 4 ] ;
char m_padding1 [ 4 ] ;
2017-08-01 14:30:58 +02:00
btVector3FloatData m_angularUpperLimit ;
btVector3FloatData m_angularLowerLimit ;
btVector3FloatData m_angularBounce ;
btVector3FloatData m_angularStopERP ;
btVector3FloatData m_angularStopCFM ;
btVector3FloatData m_angularMotorERP ;
btVector3FloatData m_angularMotorCFM ;
btVector3FloatData m_angularTargetVelocity ;
btVector3FloatData m_angularMaxMotorForce ;
btVector3FloatData m_angularServoTarget ;
btVector3FloatData m_angularSpringStiffness ;
btVector3FloatData m_angularSpringDamping ;
btVector3FloatData m_angularEquilibriumPoint ;
2019-01-03 14:26:51 +01:00
char m_angularEnableMotor [ 4 ] ;
char m_angularServoMotor [ 4 ] ;
char m_angularEnableSpring [ 4 ] ;
char m_angularSpringStiffnessLimited [ 4 ] ;
char m_angularSpringDampingLimited [ 4 ] ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
int m_rotateOrder ;
2017-08-01 14:30:58 +02:00
} ;
struct btGeneric6DofSpring2ConstraintDoubleData2
{
btTypedConstraintDoubleData m_typeConstraintData ;
btTransformDoubleData m_rbAFrame ;
btTransformDoubleData m_rbBFrame ;
btVector3DoubleData m_linearUpperLimit ;
btVector3DoubleData m_linearLowerLimit ;
btVector3DoubleData m_linearBounce ;
btVector3DoubleData m_linearStopERP ;
btVector3DoubleData m_linearStopCFM ;
btVector3DoubleData m_linearMotorERP ;
btVector3DoubleData m_linearMotorCFM ;
btVector3DoubleData m_linearTargetVelocity ;
btVector3DoubleData m_linearMaxMotorForce ;
btVector3DoubleData m_linearServoTarget ;
btVector3DoubleData m_linearSpringStiffness ;
btVector3DoubleData m_linearSpringDamping ;
btVector3DoubleData m_linearEquilibriumPoint ;
2019-01-03 14:26:51 +01:00
char m_linearEnableMotor [ 4 ] ;
char m_linearServoMotor [ 4 ] ;
char m_linearEnableSpring [ 4 ] ;
char m_linearSpringStiffnessLimited [ 4 ] ;
char m_linearSpringDampingLimited [ 4 ] ;
char m_padding1 [ 4 ] ;
2017-08-01 14:30:58 +02:00
btVector3DoubleData m_angularUpperLimit ;
btVector3DoubleData m_angularLowerLimit ;
btVector3DoubleData m_angularBounce ;
btVector3DoubleData m_angularStopERP ;
btVector3DoubleData m_angularStopCFM ;
btVector3DoubleData m_angularMotorERP ;
btVector3DoubleData m_angularMotorCFM ;
btVector3DoubleData m_angularTargetVelocity ;
btVector3DoubleData m_angularMaxMotorForce ;
btVector3DoubleData m_angularServoTarget ;
btVector3DoubleData m_angularSpringStiffness ;
btVector3DoubleData m_angularSpringDamping ;
btVector3DoubleData m_angularEquilibriumPoint ;
2019-01-03 14:26:51 +01:00
char m_angularEnableMotor [ 4 ] ;
char m_angularServoMotor [ 4 ] ;
char m_angularEnableSpring [ 4 ] ;
char m_angularSpringStiffnessLimited [ 4 ] ;
char m_angularSpringDampingLimited [ 4 ] ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
int m_rotateOrder ;
2017-08-01 14:30:58 +02:00
} ;
SIMD_FORCE_INLINE int btGeneric6DofSpring2Constraint : : calculateSerializeBufferSize ( ) const
{
return sizeof ( btGeneric6DofSpring2ConstraintData2 ) ;
}
SIMD_FORCE_INLINE const char * btGeneric6DofSpring2Constraint : : serialize ( void * dataBuffer , btSerializer * serializer ) const
{
btGeneric6DofSpring2ConstraintData2 * dof = ( btGeneric6DofSpring2ConstraintData2 * ) dataBuffer ;
2019-01-03 14:26:51 +01:00
btTypedConstraint : : serialize ( & dof - > m_typeConstraintData , serializer ) ;
2017-08-01 14:30:58 +02:00
m_frameInA . serialize ( dof - > m_rbAFrame ) ;
m_frameInB . serialize ( dof - > m_rbBFrame ) ;
int i ;
2019-01-03 14:26:51 +01:00
for ( i = 0 ; i < 3 ; i + + )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
dof - > m_angularLowerLimit . m_floats [ i ] = m_angularLimits [ i ] . m_loLimit ;
dof - > m_angularUpperLimit . m_floats [ i ] = m_angularLimits [ i ] . m_hiLimit ;
dof - > m_angularBounce . m_floats [ i ] = m_angularLimits [ i ] . m_bounce ;
dof - > m_angularStopERP . m_floats [ i ] = m_angularLimits [ i ] . m_stopERP ;
dof - > m_angularStopCFM . m_floats [ i ] = m_angularLimits [ i ] . m_stopCFM ;
dof - > m_angularMotorERP . m_floats [ i ] = m_angularLimits [ i ] . m_motorERP ;
dof - > m_angularMotorCFM . m_floats [ i ] = m_angularLimits [ i ] . m_motorCFM ;
dof - > m_angularTargetVelocity . m_floats [ i ] = m_angularLimits [ i ] . m_targetVelocity ;
dof - > m_angularMaxMotorForce . m_floats [ i ] = m_angularLimits [ i ] . m_maxMotorForce ;
dof - > m_angularServoTarget . m_floats [ i ] = m_angularLimits [ i ] . m_servoTarget ;
dof - > m_angularSpringStiffness . m_floats [ i ] = m_angularLimits [ i ] . m_springStiffness ;
dof - > m_angularSpringDamping . m_floats [ i ] = m_angularLimits [ i ] . m_springDamping ;
2017-08-01 14:30:58 +02:00
dof - > m_angularEquilibriumPoint . m_floats [ i ] = m_angularLimits [ i ] . m_equilibriumPoint ;
}
2019-01-03 14:26:51 +01:00
dof - > m_angularLowerLimit . m_floats [ 3 ] = 0 ;
dof - > m_angularUpperLimit . m_floats [ 3 ] = 0 ;
dof - > m_angularBounce . m_floats [ 3 ] = 0 ;
dof - > m_angularStopERP . m_floats [ 3 ] = 0 ;
dof - > m_angularStopCFM . m_floats [ 3 ] = 0 ;
dof - > m_angularMotorERP . m_floats [ 3 ] = 0 ;
dof - > m_angularMotorCFM . m_floats [ 3 ] = 0 ;
dof - > m_angularTargetVelocity . m_floats [ 3 ] = 0 ;
dof - > m_angularMaxMotorForce . m_floats [ 3 ] = 0 ;
dof - > m_angularServoTarget . m_floats [ 3 ] = 0 ;
dof - > m_angularSpringStiffness . m_floats [ 3 ] = 0 ;
dof - > m_angularSpringDamping . m_floats [ 3 ] = 0 ;
2017-08-01 14:30:58 +02:00
dof - > m_angularEquilibriumPoint . m_floats [ 3 ] = 0 ;
2019-01-03 14:26:51 +01:00
for ( i = 0 ; i < 4 ; i + + )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
dof - > m_angularEnableMotor [ i ] = i < 3 ? ( m_angularLimits [ i ] . m_enableMotor ? 1 : 0 ) : 0 ;
dof - > m_angularServoMotor [ i ] = i < 3 ? ( m_angularLimits [ i ] . m_servoMotor ? 1 : 0 ) : 0 ;
dof - > m_angularEnableSpring [ i ] = i < 3 ? ( m_angularLimits [ i ] . m_enableSpring ? 1 : 0 ) : 0 ;
dof - > m_angularSpringStiffnessLimited [ i ] = i < 3 ? ( m_angularLimits [ i ] . m_springStiffnessLimited ? 1 : 0 ) : 0 ;
dof - > m_angularSpringDampingLimited [ i ] = i < 3 ? ( m_angularLimits [ i ] . m_springDampingLimited ? 1 : 0 ) : 0 ;
2017-08-01 14:30:58 +02:00
}
2019-01-03 14:26:51 +01:00
m_linearLimits . m_lowerLimit . serialize ( dof - > m_linearLowerLimit ) ;
m_linearLimits . m_upperLimit . serialize ( dof - > m_linearUpperLimit ) ;
m_linearLimits . m_bounce . serialize ( dof - > m_linearBounce ) ;
m_linearLimits . m_stopERP . serialize ( dof - > m_linearStopERP ) ;
m_linearLimits . m_stopCFM . serialize ( dof - > m_linearStopCFM ) ;
m_linearLimits . m_motorERP . serialize ( dof - > m_linearMotorERP ) ;
m_linearLimits . m_motorCFM . serialize ( dof - > m_linearMotorCFM ) ;
m_linearLimits . m_targetVelocity . serialize ( dof - > m_linearTargetVelocity ) ;
m_linearLimits . m_maxMotorForce . serialize ( dof - > m_linearMaxMotorForce ) ;
m_linearLimits . m_servoTarget . serialize ( dof - > m_linearServoTarget ) ;
m_linearLimits . m_springStiffness . serialize ( dof - > m_linearSpringStiffness ) ;
m_linearLimits . m_springDamping . serialize ( dof - > m_linearSpringDamping ) ;
m_linearLimits . m_equilibriumPoint . serialize ( dof - > m_linearEquilibriumPoint ) ;
for ( i = 0 ; i < 4 ; i + + )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
dof - > m_linearEnableMotor [ i ] = i < 3 ? ( m_linearLimits . m_enableMotor [ i ] ? 1 : 0 ) : 0 ;
dof - > m_linearServoMotor [ i ] = i < 3 ? ( m_linearLimits . m_servoMotor [ i ] ? 1 : 0 ) : 0 ;
dof - > m_linearEnableSpring [ i ] = i < 3 ? ( m_linearLimits . m_enableSpring [ i ] ? 1 : 0 ) : 0 ;
dof - > m_linearSpringStiffnessLimited [ i ] = i < 3 ? ( m_linearLimits . m_springStiffnessLimited [ i ] ? 1 : 0 ) : 0 ;
dof - > m_linearSpringDampingLimited [ i ] = i < 3 ? ( m_linearLimits . m_springDampingLimited [ i ] ? 1 : 0 ) : 0 ;
2017-08-01 14:30:58 +02:00
}
dof - > m_rotateOrder = m_rotateOrder ;
dof - > m_padding1 [ 0 ] = 0 ;
dof - > m_padding1 [ 1 ] = 0 ;
dof - > m_padding1 [ 2 ] = 0 ;
dof - > m_padding1 [ 3 ] = 0 ;
return btGeneric6DofSpring2ConstraintDataName ;
}
2019-01-03 14:26:51 +01:00
# endif //BT_GENERIC_6DOF_CONSTRAINT_H