btHingeConstraint.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 /* Hinge Constraint by Dirk Gregorius. Limits added by Marcus Hennix at Starbreeze Studios */
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 class btHingeConstraint : public btTypedConstraint
00047 {
00048 #ifdef IN_PARALLELL_SOLVER
00049 public:
00050 #endif
00051         btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
00052         btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
00053 
00054         btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis.
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         // extra motor API, including ability to set a target rotation (as opposed to angular velocity)
00150         // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to
00151         //       maintain a given angular target.
00152         void enableMotor(bool enableMotor)      { m_enableAngularMotor = enableMotor; }
00153         void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
00154         void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B.
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 //              m_rbAFrame.getOrigin() = pivotInA;
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         // access for UseFrameOffset
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; // constraint axii. Assumes z is hinge axis.
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; // constraint axii. Assumes z is hinge axis.
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

Generated on Mon Feb 15 22:17:04 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1