Blender V2.61 - r43446
|
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