Blender V2.61 - r43446

btConeTwistConstraint.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios
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 Written by: Marcus Hennix
00016 */
00017 
00018 
00019 
00020 /*
00021 Overview:
00022 
00023 btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc).
00024 It is a fixed translation, 3 degree-of-freedom (DOF) rotational "joint".
00025 It divides the 3 rotational DOFs into swing (movement within a cone) and twist.
00026 Swing is divided into swing1 and swing2 which can have different limits, giving an elliptical shape.
00027 (Note: the cone's base isn't flat, so this ellipse is "embedded" on the surface of a sphere.)
00028 
00029 In the contraint's frame of reference:
00030 twist is along the x-axis,
00031 and swing 1 and 2 are along the z and y axes respectively.
00032 */
00033 
00034 
00035 
00036 #ifndef CONETWISTCONSTRAINT_H
00037 #define CONETWISTCONSTRAINT_H
00038 
00039 #include "LinearMath/btVector3.h"
00040 #include "btJacobianEntry.h"
00041 #include "btTypedConstraint.h"
00042 
00043 class btRigidBody;
00044 
00045 enum btConeTwistFlags
00046 {
00047     BT_CONETWIST_FLAGS_LIN_CFM = 1,
00048     BT_CONETWIST_FLAGS_LIN_ERP = 2,
00049     BT_CONETWIST_FLAGS_ANG_CFM = 4
00050 };
00051 
00053 class btConeTwistConstraint : public btTypedConstraint
00054 {
00055 #ifdef IN_PARALLELL_SOLVER
00056 public:
00057 #endif
00058     btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
00059 
00060     btTransform m_rbAFrame; 
00061     btTransform m_rbBFrame;
00062 
00063     btScalar    m_limitSoftness;
00064     btScalar    m_biasFactor;
00065     btScalar    m_relaxationFactor;
00066 
00067     btScalar    m_damping;
00068 
00069     btScalar    m_swingSpan1;
00070     btScalar    m_swingSpan2;
00071     btScalar    m_twistSpan;
00072 
00073     btScalar    m_fixThresh;
00074 
00075     btVector3   m_swingAxis;
00076     btVector3   m_twistAxis;
00077 
00078     btScalar    m_kSwing;
00079     btScalar    m_kTwist;
00080 
00081     btScalar    m_twistLimitSign;
00082     btScalar    m_swingCorrection;
00083     btScalar    m_twistCorrection;
00084 
00085     btScalar    m_twistAngle;
00086 
00087     btScalar    m_accSwingLimitImpulse;
00088     btScalar    m_accTwistLimitImpulse;
00089 
00090     bool        m_angularOnly;
00091     bool        m_solveTwistLimit;
00092     bool        m_solveSwingLimit;
00093 
00094     bool    m_useSolveConstraintObsolete;
00095 
00096     // not yet used...
00097     btScalar    m_swingLimitRatio;
00098     btScalar    m_twistLimitRatio;
00099     btVector3   m_twistAxisA;
00100 
00101     // motor
00102     bool         m_bMotorEnabled;
00103     bool         m_bNormalizedMotorStrength;
00104     btQuaternion m_qTarget;
00105     btScalar     m_maxMotorImpulse;
00106     btVector3    m_accMotorImpulse;
00107     
00108     // parameters
00109     int         m_flags;
00110     btScalar    m_linCFM;
00111     btScalar    m_linERP;
00112     btScalar    m_angCFM;
00113     
00114 protected:
00115 
00116     void init();
00117 
00118     void computeConeLimitInfo(const btQuaternion& qCone, // in
00119         btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs
00120 
00121     void computeTwistLimitInfo(const btQuaternion& qTwist, // in
00122         btScalar& twistAngle, btVector3& vTwistAxis); // all outs
00123 
00124     void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const;
00125 
00126 
00127 public:
00128 
00129     btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
00130     
00131     btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
00132 
00133     virtual void    buildJacobian();
00134 
00135     virtual void getInfo1 (btConstraintInfo1* info);
00136 
00137     void    getInfo1NonVirtual(btConstraintInfo1* info);
00138     
00139     virtual void getInfo2 (btConstraintInfo2* info);
00140     
00141     void    getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);
00142 
00143     virtual void    solveConstraintObsolete(btRigidBody& bodyA,btRigidBody& bodyB,btScalar  timeStep);
00144 
00145     void    updateRHS(btScalar  timeStep);
00146 
00147 
00148     const btRigidBody& getRigidBodyA() const
00149     {
00150         return m_rbA;
00151     }
00152     const btRigidBody& getRigidBodyB() const
00153     {
00154         return m_rbB;
00155     }
00156 
00157     void    setAngularOnly(bool angularOnly)
00158     {
00159         m_angularOnly = angularOnly;
00160     }
00161 
00162     void    setLimit(int limitIndex,btScalar limitValue)
00163     {
00164         switch (limitIndex)
00165         {
00166         case 3:
00167             {
00168                 m_twistSpan = limitValue;
00169                 break;
00170             }
00171         case 4:
00172             {
00173                 m_swingSpan2 = limitValue;
00174                 break;
00175             }
00176         case 5:
00177             {
00178                 m_swingSpan1 = limitValue;
00179                 break;
00180             }
00181         default:
00182             {
00183             }
00184         };
00185     }
00186 
00187     // setLimit(), a few notes:
00188     // _softness:
00189     //      0->1, recommend ~0.8->1.
00190     //      describes % of limits where movement is free.
00191     //      beyond this softness %, the limit is gradually enforced until the "hard" (1.0) limit is reached.
00192     // _biasFactor:
00193     //      0->1?, recommend 0.3 +/-0.3 or so.
00194     //      strength with which constraint resists zeroth order (angular, not angular velocity) limit violation.
00195     // __relaxationFactor:
00196     //      0->1, recommend to stay near 1.
00197     //      the lower the value, the less the constraint will fight velocities which violate the angular limits.
00198     void    setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
00199     {
00200         m_swingSpan1 = _swingSpan1;
00201         m_swingSpan2 = _swingSpan2;
00202         m_twistSpan  = _twistSpan;
00203 
00204         m_limitSoftness =  _softness;
00205         m_biasFactor = _biasFactor;
00206         m_relaxationFactor = _relaxationFactor;
00207     }
00208 
00209     const btTransform& getAFrame() { return m_rbAFrame; };  
00210     const btTransform& getBFrame() { return m_rbBFrame; };
00211 
00212     inline int getSolveTwistLimit()
00213     {
00214         return m_solveTwistLimit;
00215     }
00216 
00217     inline int getSolveSwingLimit()
00218     {
00219         return m_solveTwistLimit;
00220     }
00221 
00222     inline btScalar getTwistLimitSign()
00223     {
00224         return m_twistLimitSign;
00225     }
00226 
00227     void calcAngleInfo();
00228     void calcAngleInfo2(const btTransform& transA, const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);
00229 
00230     inline btScalar getSwingSpan1()
00231     {
00232         return m_swingSpan1;
00233     }
00234     inline btScalar getSwingSpan2()
00235     {
00236         return m_swingSpan2;
00237     }
00238     inline btScalar getTwistSpan()
00239     {
00240         return m_twistSpan;
00241     }
00242     inline btScalar getTwistAngle()
00243     {
00244         return m_twistAngle;
00245     }
00246     bool isPastSwingLimit() { return m_solveSwingLimit; }
00247 
00248     void setDamping(btScalar damping) { m_damping = damping; }
00249 
00250     void enableMotor(bool b) { m_bMotorEnabled = b; }
00251     void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; }
00252     void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; }
00253 
00254     btScalar getFixThresh() { return m_fixThresh; }
00255     void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; }
00256 
00257     // setMotorTarget:
00258     // q: the desired rotation of bodyA wrt bodyB.
00259     // note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability)
00260     // note: don't forget to enableMotor()
00261     void setMotorTarget(const btQuaternion &q);
00262 
00263     // same as above, but q is the desired rotation of frameA wrt frameB in constraint space
00264     void setMotorTargetInConstraintSpace(const btQuaternion &q);
00265 
00266     btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const;
00267 
00270     virtual void setParam(int num, btScalar value, int axis = -1);
00271 
00272     virtual void setFrames(const btTransform& frameA, const btTransform& frameB);
00273 
00274     const btTransform& getFrameOffsetA() const
00275     {
00276         return m_rbAFrame;
00277     }
00278 
00279     const btTransform& getFrameOffsetB() const
00280     {
00281         return m_rbBFrame;
00282     }
00283 
00284 
00286     virtual btScalar getParam(int num, int axis = -1) const;
00287 
00288     virtual int calculateSerializeBufferSize() const;
00289 
00291     virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
00292 
00293 };
00294 
00296 struct  btConeTwistConstraintData
00297 {
00298     btTypedConstraintData   m_typeConstraintData;
00299     btTransformFloatData m_rbAFrame;
00300     btTransformFloatData m_rbBFrame;
00301 
00302     //limits
00303     float   m_swingSpan1;
00304     float   m_swingSpan2;
00305     float   m_twistSpan;
00306     float   m_limitSoftness;
00307     float   m_biasFactor;
00308     float   m_relaxationFactor;
00309 
00310     float   m_damping;
00311         
00312     char m_pad[4];
00313 
00314 };
00315     
00316 
00317 
00318 SIMD_FORCE_INLINE int   btConeTwistConstraint::calculateSerializeBufferSize() const
00319 {
00320     return sizeof(btConeTwistConstraintData);
00321 
00322 }
00323 
00324 
00326 SIMD_FORCE_INLINE const char*   btConeTwistConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
00327 {
00328     btConeTwistConstraintData* cone = (btConeTwistConstraintData*) dataBuffer;
00329     btTypedConstraint::serialize(&cone->m_typeConstraintData,serializer);
00330 
00331     m_rbAFrame.serializeFloat(cone->m_rbAFrame);
00332     m_rbBFrame.serializeFloat(cone->m_rbBFrame);
00333     
00334     cone->m_swingSpan1 = float(m_swingSpan1);
00335     cone->m_swingSpan2 = float(m_swingSpan2);
00336     cone->m_twistSpan = float(m_twistSpan);
00337     cone->m_limitSoftness = float(m_limitSoftness);
00338     cone->m_biasFactor = float(m_biasFactor);
00339     cone->m_relaxationFactor = float(m_relaxationFactor);
00340     cone->m_damping = float(m_damping);
00341 
00342     return "btConeTwistConstraintData";
00343 }
00344 
00345 
00346 #endif //CONETWISTCONSTRAINT_H