00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef HINGECONSTRAINT_H
00019 #define HINGECONSTRAINT_H
00020
00021 #include "LinearMath/btVector3.h"
00022 #include "btJacobianEntry.h"
00023 #include "btTypedConstraint.h"
00024
00025 class btRigidBody;
00026
00027 #ifdef BT_USE_DOUBLE_PRECISION
00028 #define btHingeConstraintData btHingeConstraintDoubleData
00029 #define btHingeConstraintDataName "btHingeConstraintDoubleData"
00030 #else
00031 #define btHingeConstraintData btHingeConstraintFloatData
00032 #define btHingeConstraintDataName "btHingeConstraintFloatData"
00033 #endif //BT_USE_DOUBLE_PRECISION
00034
00035
00036 enum btHingeFlags
00037 {
00038 BT_HINGE_FLAGS_CFM_STOP = 1,
00039 BT_HINGE_FLAGS_ERP_STOP = 2,
00040 BT_HINGE_FLAGS_CFM_NORM = 4
00041 };
00042
00043
00046 ATTRIBUTE_ALIGNED16(class) btHingeConstraint : public btTypedConstraint
00047 {
00048 #ifdef IN_PARALLELL_SOLVER
00049 public:
00050 #endif
00051 btJacobianEntry m_jac[3];
00052 btJacobianEntry m_jacAng[3];
00053
00054 btTransform m_rbAFrame;
00055 btTransform m_rbBFrame;
00056
00057 btScalar m_motorTargetVelocity;
00058 btScalar m_maxMotorImpulse;
00059
00060 btScalar m_limitSoftness;
00061 btScalar m_biasFactor;
00062 btScalar m_relaxationFactor;
00063
00064 btScalar m_lowerLimit;
00065 btScalar m_upperLimit;
00066
00067 btScalar m_kHinge;
00068
00069 btScalar m_limitSign;
00070 btScalar m_correction;
00071
00072 btScalar m_accLimitImpulse;
00073 btScalar m_hingeAngle;
00074 btScalar m_referenceSign;
00075
00076 bool m_angularOnly;
00077 bool m_enableAngularMotor;
00078 bool m_solveLimit;
00079 bool m_useSolveConstraintObsolete;
00080 bool m_useOffsetForConstraintFrame;
00081 bool m_useReferenceFrameA;
00082
00083 btScalar m_accMotorImpulse;
00084
00085 int m_flags;
00086 btScalar m_normalCFM;
00087 btScalar m_stopCFM;
00088 btScalar m_stopERP;
00089
00090
00091 public:
00092
00093 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB, bool useReferenceFrameA = false);
00094
00095 btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA, bool useReferenceFrameA = false);
00096
00097 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
00098
00099 btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
00100
00101
00102 virtual void buildJacobian();
00103
00104 virtual void getInfo1 (btConstraintInfo1* info);
00105
00106 void getInfo1NonVirtual(btConstraintInfo1* info);
00107
00108 virtual void getInfo2 (btConstraintInfo2* info);
00109
00110 void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
00111
00112 void getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
00113 void getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
00114
00115
00116 void updateRHS(btScalar timeStep);
00117
00118 const btRigidBody& getRigidBodyA() const
00119 {
00120 return m_rbA;
00121 }
00122 const btRigidBody& getRigidBodyB() const
00123 {
00124 return m_rbB;
00125 }
00126
00127 btRigidBody& getRigidBodyA()
00128 {
00129 return m_rbA;
00130 }
00131
00132 btRigidBody& getRigidBodyB()
00133 {
00134 return m_rbB;
00135 }
00136
00137 void setAngularOnly(bool angularOnly)
00138 {
00139 m_angularOnly = angularOnly;
00140 }
00141
00142 void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse)
00143 {
00144 m_enableAngularMotor = enableMotor;
00145 m_motorTargetVelocity = targetVelocity;
00146 m_maxMotorImpulse = maxMotorImpulse;
00147 }
00148
00149
00150
00151
00152 void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; }
00153 void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
00154 void setMotorTarget(const btQuaternion& qAinB, btScalar dt);
00155 void setMotorTarget(btScalar targetAngle, btScalar dt);
00156
00157
00158 void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
00159 {
00160 m_lowerLimit = btNormalizeAngle(low);
00161 m_upperLimit = btNormalizeAngle(high);
00162
00163 m_limitSoftness = _softness;
00164 m_biasFactor = _biasFactor;
00165 m_relaxationFactor = _relaxationFactor;
00166
00167 }
00168
00169 void setAxis(btVector3& axisInA)
00170 {
00171 btVector3 rbAxisA1, rbAxisA2;
00172 btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
00173 btVector3 pivotInA = m_rbAFrame.getOrigin();
00174
00175 m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
00176 rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
00177 rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
00178
00179 btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA;
00180
00181 btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
00182 btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1);
00183 btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
00184
00185
00186 m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(pivotInA);
00187 m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
00188 rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
00189 rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
00190 }
00191
00192 btScalar getLowerLimit() const
00193 {
00194 return m_lowerLimit;
00195 }
00196
00197 btScalar getUpperLimit() const
00198 {
00199 return m_upperLimit;
00200 }
00201
00202
00203 btScalar getHingeAngle();
00204
00205 btScalar getHingeAngle(const btTransform& transA,const btTransform& transB);
00206
00207 void testLimit(const btTransform& transA,const btTransform& transB);
00208
00209
00210 const btTransform& getAFrame() const { return m_rbAFrame; };
00211 const btTransform& getBFrame() const { return m_rbBFrame; };
00212
00213 btTransform& getAFrame() { return m_rbAFrame; };
00214 btTransform& getBFrame() { return m_rbBFrame; };
00215
00216 inline int getSolveLimit()
00217 {
00218 return m_solveLimit;
00219 }
00220
00221 inline btScalar getLimitSign()
00222 {
00223 return m_limitSign;
00224 }
00225
00226 inline bool getAngularOnly()
00227 {
00228 return m_angularOnly;
00229 }
00230 inline bool getEnableAngularMotor()
00231 {
00232 return m_enableAngularMotor;
00233 }
00234 inline btScalar getMotorTargetVelosity()
00235 {
00236 return m_motorTargetVelocity;
00237 }
00238 inline btScalar getMaxMotorImpulse()
00239 {
00240 return m_maxMotorImpulse;
00241 }
00242
00243 bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
00244 void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
00245
00246
00249 virtual void setParam(int num, btScalar value, int axis = -1);
00251 virtual btScalar getParam(int num, int axis = -1) const;
00252
00253 virtual int calculateSerializeBufferSize() const;
00254
00256 virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
00257
00258
00259 };
00260
00262 struct btHingeConstraintDoubleData
00263 {
00264 btTypedConstraintData m_typeConstraintData;
00265 btTransformDoubleData m_rbAFrame;
00266 btTransformDoubleData m_rbBFrame;
00267 int m_useReferenceFrameA;
00268 int m_angularOnly;
00269 int m_enableAngularMotor;
00270 float m_motorTargetVelocity;
00271 float m_maxMotorImpulse;
00272
00273 float m_lowerLimit;
00274 float m_upperLimit;
00275 float m_limitSoftness;
00276 float m_biasFactor;
00277 float m_relaxationFactor;
00278
00279 };
00281 struct btHingeConstraintFloatData
00282 {
00283 btTypedConstraintData m_typeConstraintData;
00284 btTransformFloatData m_rbAFrame;
00285 btTransformFloatData m_rbBFrame;
00286 int m_useReferenceFrameA;
00287 int m_angularOnly;
00288
00289 int m_enableAngularMotor;
00290 float m_motorTargetVelocity;
00291 float m_maxMotorImpulse;
00292
00293 float m_lowerLimit;
00294 float m_upperLimit;
00295 float m_limitSoftness;
00296 float m_biasFactor;
00297 float m_relaxationFactor;
00298
00299 };
00300
00301
00302
00303 SIMD_FORCE_INLINE int btHingeConstraint::calculateSerializeBufferSize() const
00304 {
00305 return sizeof(btHingeConstraintData);
00306 }
00307
00309 SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
00310 {
00311 btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer;
00312 btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer);
00313
00314 m_rbAFrame.serialize(hingeData->m_rbAFrame);
00315 m_rbBFrame.serialize(hingeData->m_rbBFrame);
00316
00317 hingeData->m_angularOnly = m_angularOnly;
00318 hingeData->m_enableAngularMotor = m_enableAngularMotor;
00319 hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse);
00320 hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity);
00321 hingeData->m_useReferenceFrameA = m_useReferenceFrameA;
00322
00323 hingeData->m_lowerLimit = float(m_lowerLimit);
00324 hingeData->m_upperLimit = float(m_upperLimit);
00325 hingeData->m_limitSoftness = float(m_limitSoftness);
00326 hingeData->m_biasFactor = float(m_biasFactor);
00327 hingeData->m_relaxationFactor = float(m_relaxationFactor);
00328
00329 return btHingeConstraintDataName;
00330 }
00331
00332 #endif //HINGECONSTRAINT_H