Blender V2.61 - r43446
|
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 #define _BT_USE_CENTER_LIMIT_ 1 00021 00022 00023 #include "LinearMath/btVector3.h" 00024 #include "btJacobianEntry.h" 00025 #include "btTypedConstraint.h" 00026 00027 class btRigidBody; 00028 00029 #ifdef BT_USE_DOUBLE_PRECISION 00030 #define btHingeConstraintData btHingeConstraintDoubleData 00031 #define btHingeConstraintDataName "btHingeConstraintDoubleData" 00032 #else 00033 #define btHingeConstraintData btHingeConstraintFloatData 00034 #define btHingeConstraintDataName "btHingeConstraintFloatData" 00035 #endif //BT_USE_DOUBLE_PRECISION 00036 00037 00038 00039 enum btHingeFlags 00040 { 00041 BT_HINGE_FLAGS_CFM_STOP = 1, 00042 BT_HINGE_FLAGS_ERP_STOP = 2, 00043 BT_HINGE_FLAGS_CFM_NORM = 4 00044 }; 00045 00046 00049 ATTRIBUTE_ALIGNED16(class) btHingeConstraint : public btTypedConstraint 00050 { 00051 #ifdef IN_PARALLELL_SOLVER 00052 public: 00053 #endif 00054 btJacobianEntry m_jac[3]; //3 orthogonal linear constraints 00055 btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor 00056 00057 btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis. 00058 btTransform m_rbBFrame; 00059 00060 btScalar m_motorTargetVelocity; 00061 btScalar m_maxMotorImpulse; 00062 00063 00064 #ifdef _BT_USE_CENTER_LIMIT_ 00065 btAngularLimit m_limit; 00066 #else 00067 btScalar m_lowerLimit; 00068 btScalar m_upperLimit; 00069 btScalar m_limitSign; 00070 btScalar m_correction; 00071 00072 btScalar m_limitSoftness; 00073 btScalar m_biasFactor; 00074 btScalar m_relaxationFactor; 00075 00076 bool m_solveLimit; 00077 #endif 00078 00079 btScalar m_kHinge; 00080 00081 00082 btScalar m_accLimitImpulse; 00083 btScalar m_hingeAngle; 00084 btScalar m_referenceSign; 00085 00086 bool m_angularOnly; 00087 bool m_enableAngularMotor; 00088 bool m_useSolveConstraintObsolete; 00089 bool m_useOffsetForConstraintFrame; 00090 bool m_useReferenceFrameA; 00091 00092 btScalar m_accMotorImpulse; 00093 00094 int m_flags; 00095 btScalar m_normalCFM; 00096 btScalar m_stopCFM; 00097 btScalar m_stopERP; 00098 00099 00100 public: 00101 00102 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false); 00103 00104 btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false); 00105 00106 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false); 00107 00108 btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false); 00109 00110 00111 virtual void buildJacobian(); 00112 00113 virtual void getInfo1 (btConstraintInfo1* info); 00114 00115 void getInfo1NonVirtual(btConstraintInfo1* info); 00116 00117 virtual void getInfo2 (btConstraintInfo2* info); 00118 00119 void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); 00120 00121 void getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); 00122 void getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); 00123 00124 00125 void updateRHS(btScalar timeStep); 00126 00127 const btRigidBody& getRigidBodyA() const 00128 { 00129 return m_rbA; 00130 } 00131 const btRigidBody& getRigidBodyB() const 00132 { 00133 return m_rbB; 00134 } 00135 00136 btRigidBody& getRigidBodyA() 00137 { 00138 return m_rbA; 00139 } 00140 00141 btRigidBody& getRigidBodyB() 00142 { 00143 return m_rbB; 00144 } 00145 00146 btTransform& getFrameOffsetA() 00147 { 00148 return m_rbAFrame; 00149 } 00150 00151 btTransform& getFrameOffsetB() 00152 { 00153 return m_rbBFrame; 00154 } 00155 00156 void setFrames(const btTransform& frameA, const btTransform& frameB); 00157 00158 void setAngularOnly(bool angularOnly) 00159 { 00160 m_angularOnly = angularOnly; 00161 } 00162 00163 void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse) 00164 { 00165 m_enableAngularMotor = enableMotor; 00166 m_motorTargetVelocity = targetVelocity; 00167 m_maxMotorImpulse = maxMotorImpulse; 00168 } 00169 00170 // extra motor API, including ability to set a target rotation (as opposed to angular velocity) 00171 // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to 00172 // maintain a given angular target. 00173 void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; } 00174 void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; } 00175 void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B. 00176 void setMotorTarget(btScalar targetAngle, btScalar dt); 00177 00178 00179 void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) 00180 { 00181 #ifdef _BT_USE_CENTER_LIMIT_ 00182 m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor); 00183 #else 00184 m_lowerLimit = btNormalizeAngle(low); 00185 m_upperLimit = btNormalizeAngle(high); 00186 m_limitSoftness = _softness; 00187 m_biasFactor = _biasFactor; 00188 m_relaxationFactor = _relaxationFactor; 00189 #endif 00190 } 00191 00192 void setAxis(btVector3& axisInA) 00193 { 00194 btVector3 rbAxisA1, rbAxisA2; 00195 btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2); 00196 btVector3 pivotInA = m_rbAFrame.getOrigin(); 00197 // m_rbAFrame.getOrigin() = pivotInA; 00198 m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), 00199 rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), 00200 rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); 00201 00202 btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA; 00203 00204 btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); 00205 btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); 00206 btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); 00207 00208 m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA)); 00209 00210 m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), 00211 rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), 00212 rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); 00213 m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis(); 00214 00215 } 00216 00217 btScalar getLowerLimit() const 00218 { 00219 #ifdef _BT_USE_CENTER_LIMIT_ 00220 return m_limit.getLow(); 00221 #else 00222 return m_lowerLimit; 00223 #endif 00224 } 00225 00226 btScalar getUpperLimit() const 00227 { 00228 #ifdef _BT_USE_CENTER_LIMIT_ 00229 return m_limit.getHigh(); 00230 #else 00231 return m_upperLimit; 00232 #endif 00233 } 00234 00235 00236 btScalar getHingeAngle(); 00237 00238 btScalar getHingeAngle(const btTransform& transA,const btTransform& transB); 00239 00240 void testLimit(const btTransform& transA,const btTransform& transB); 00241 00242 00243 const btTransform& getAFrame() const { return m_rbAFrame; }; 00244 const btTransform& getBFrame() const { return m_rbBFrame; }; 00245 00246 btTransform& getAFrame() { return m_rbAFrame; }; 00247 btTransform& getBFrame() { return m_rbBFrame; }; 00248 00249 inline int getSolveLimit() 00250 { 00251 #ifdef _BT_USE_CENTER_LIMIT_ 00252 return m_limit.isLimit(); 00253 #else 00254 return m_solveLimit; 00255 #endif 00256 } 00257 00258 inline btScalar getLimitSign() 00259 { 00260 #ifdef _BT_USE_CENTER_LIMIT_ 00261 return m_limit.getSign(); 00262 #else 00263 return m_limitSign; 00264 #endif 00265 } 00266 00267 inline bool getAngularOnly() 00268 { 00269 return m_angularOnly; 00270 } 00271 inline bool getEnableAngularMotor() 00272 { 00273 return m_enableAngularMotor; 00274 } 00275 inline btScalar getMotorTargetVelosity() 00276 { 00277 return m_motorTargetVelocity; 00278 } 00279 inline btScalar getMaxMotorImpulse() 00280 { 00281 return m_maxMotorImpulse; 00282 } 00283 // access for UseFrameOffset 00284 bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; } 00285 void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; } 00286 00287 00290 virtual void setParam(int num, btScalar value, int axis = -1); 00292 virtual btScalar getParam(int num, int axis = -1) const; 00293 00294 virtual int calculateSerializeBufferSize() const; 00295 00297 virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; 00298 00299 00300 }; 00301 00303 struct btHingeConstraintDoubleData 00304 { 00305 btTypedConstraintData m_typeConstraintData; 00306 btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. 00307 btTransformDoubleData m_rbBFrame; 00308 int m_useReferenceFrameA; 00309 int m_angularOnly; 00310 int m_enableAngularMotor; 00311 float m_motorTargetVelocity; 00312 float m_maxMotorImpulse; 00313 00314 float m_lowerLimit; 00315 float m_upperLimit; 00316 float m_limitSoftness; 00317 float m_biasFactor; 00318 float m_relaxationFactor; 00319 00320 }; 00322 struct btHingeConstraintFloatData 00323 { 00324 btTypedConstraintData m_typeConstraintData; 00325 btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. 00326 btTransformFloatData m_rbBFrame; 00327 int m_useReferenceFrameA; 00328 int m_angularOnly; 00329 00330 int m_enableAngularMotor; 00331 float m_motorTargetVelocity; 00332 float m_maxMotorImpulse; 00333 00334 float m_lowerLimit; 00335 float m_upperLimit; 00336 float m_limitSoftness; 00337 float m_biasFactor; 00338 float m_relaxationFactor; 00339 00340 }; 00341 00342 00343 00344 SIMD_FORCE_INLINE int btHingeConstraint::calculateSerializeBufferSize() const 00345 { 00346 return sizeof(btHingeConstraintData); 00347 } 00348 00350 SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const 00351 { 00352 btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer; 00353 btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer); 00354 00355 m_rbAFrame.serialize(hingeData->m_rbAFrame); 00356 m_rbBFrame.serialize(hingeData->m_rbBFrame); 00357 00358 hingeData->m_angularOnly = m_angularOnly; 00359 hingeData->m_enableAngularMotor = m_enableAngularMotor; 00360 hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse); 00361 hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity); 00362 hingeData->m_useReferenceFrameA = m_useReferenceFrameA; 00363 #ifdef _BT_USE_CENTER_LIMIT_ 00364 hingeData->m_lowerLimit = float(m_limit.getLow()); 00365 hingeData->m_upperLimit = float(m_limit.getHigh()); 00366 hingeData->m_limitSoftness = float(m_limit.getSoftness()); 00367 hingeData->m_biasFactor = float(m_limit.getBiasFactor()); 00368 hingeData->m_relaxationFactor = float(m_limit.getRelaxationFactor()); 00369 #else 00370 hingeData->m_lowerLimit = float(m_lowerLimit); 00371 hingeData->m_upperLimit = float(m_upperLimit); 00372 hingeData->m_limitSoftness = float(m_limitSoftness); 00373 hingeData->m_biasFactor = float(m_biasFactor); 00374 hingeData->m_relaxationFactor = float(m_relaxationFactor); 00375 #endif 00376 00377 return btHingeConstraintDataName; 00378 } 00379 00380 #endif //HINGECONSTRAINT_H