Blender V2.61 - r43446
|
00001 /* 00002 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ 00003 00004 This software is provided 'as-is', without any express or implied warranty. 00005 In no event will the authors be held liable for any damages arising from the use of this software. 00006 Permission is granted to anyone to use this software for any purpose, 00007 including commercial applications, and to alter it and redistribute it freely, 00008 subject to the following restrictions: 00009 00010 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. 00011 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00012 3. This notice may not be removed or altered from any source distribution. 00013 */ 00014 00015 00016 #ifndef SIMD_TRANSFORM_UTIL_H 00017 #define SIMD_TRANSFORM_UTIL_H 00018 00019 #include "btTransform.h" 00020 #define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI 00021 00022 00023 00024 00025 SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) 00026 { 00027 return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), 00028 supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), 00029 supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); 00030 } 00031 00032 00033 00034 00035 00036 00038 class btTransformUtil 00039 { 00040 00041 public: 00042 00043 static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform) 00044 { 00045 predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); 00046 // #define QUATERNION_DERIVATIVE 00047 #ifdef QUATERNION_DERIVATIVE 00048 btQuaternion predictedOrn = curTrans.getRotation(); 00049 predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5)); 00050 predictedOrn.normalize(); 00051 #else 00052 //Exponential map 00053 //google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia 00054 00055 btVector3 axis; 00056 btScalar fAngle = angvel.length(); 00057 //limit the angular motion 00058 if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD) 00059 { 00060 fAngle = ANGULAR_MOTION_THRESHOLD / timeStep; 00061 } 00062 00063 if ( fAngle < btScalar(0.001) ) 00064 { 00065 // use Taylor's expansions of sync function 00066 axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle ); 00067 } 00068 else 00069 { 00070 // sync(fAngle) = sin(c*fAngle)/t 00071 axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle ); 00072 } 00073 btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) )); 00074 btQuaternion orn0 = curTrans.getRotation(); 00075 00076 btQuaternion predictedOrn = dorn * orn0; 00077 predictedOrn.normalize(); 00078 #endif 00079 predictedTransform.setRotation(predictedOrn); 00080 } 00081 00082 static void calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel) 00083 { 00084 linVel = (pos1 - pos0) / timeStep; 00085 btVector3 axis; 00086 btScalar angle; 00087 if (orn0 != orn1) 00088 { 00089 calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle); 00090 angVel = axis * angle / timeStep; 00091 } else 00092 { 00093 angVel.setValue(0,0,0); 00094 } 00095 } 00096 00097 static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle) 00098 { 00099 btQuaternion orn1 = orn0.nearest(orn1a); 00100 btQuaternion dorn = orn1 * orn0.inverse(); 00101 angle = dorn.getAngle(); 00102 axis = btVector3(dorn.x(),dorn.y(),dorn.z()); 00103 axis[3] = btScalar(0.); 00104 //check for axis length 00105 btScalar len = axis.length2(); 00106 if (len < SIMD_EPSILON*SIMD_EPSILON) 00107 axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); 00108 else 00109 axis /= btSqrt(len); 00110 } 00111 00112 static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel) 00113 { 00114 linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep; 00115 btVector3 axis; 00116 btScalar angle; 00117 calculateDiffAxisAngle(transform0,transform1,axis,angle); 00118 angVel = axis * angle / timeStep; 00119 } 00120 00121 static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle) 00122 { 00123 btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); 00124 btQuaternion dorn; 00125 dmat.getRotation(dorn); 00126 00128 dorn.normalize(); 00129 00130 angle = dorn.getAngle(); 00131 axis = btVector3(dorn.x(),dorn.y(),dorn.z()); 00132 axis[3] = btScalar(0.); 00133 //check for axis length 00134 btScalar len = axis.length2(); 00135 if (len < SIMD_EPSILON*SIMD_EPSILON) 00136 axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); 00137 else 00138 axis /= btSqrt(len); 00139 } 00140 00141 }; 00142 00143 00146 class btConvexSeparatingDistanceUtil 00147 { 00148 btQuaternion m_ornA; 00149 btQuaternion m_ornB; 00150 btVector3 m_posA; 00151 btVector3 m_posB; 00152 00153 btVector3 m_separatingNormal; 00154 00155 btScalar m_boundingRadiusA; 00156 btScalar m_boundingRadiusB; 00157 btScalar m_separatingDistance; 00158 00159 public: 00160 00161 btConvexSeparatingDistanceUtil(btScalar boundingRadiusA,btScalar boundingRadiusB) 00162 :m_boundingRadiusA(boundingRadiusA), 00163 m_boundingRadiusB(boundingRadiusB), 00164 m_separatingDistance(0.f) 00165 { 00166 } 00167 00168 btScalar getConservativeSeparatingDistance() 00169 { 00170 return m_separatingDistance; 00171 } 00172 00173 void updateSeparatingDistance(const btTransform& transA,const btTransform& transB) 00174 { 00175 const btVector3& toPosA = transA.getOrigin(); 00176 const btVector3& toPosB = transB.getOrigin(); 00177 btQuaternion toOrnA = transA.getRotation(); 00178 btQuaternion toOrnB = transB.getRotation(); 00179 00180 if (m_separatingDistance>0.f) 00181 { 00182 00183 00184 btVector3 linVelA,angVelA,linVelB,angVelB; 00185 btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA); 00186 btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB); 00187 btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB; 00188 btVector3 relLinVel = (linVelB-linVelA); 00189 btScalar relLinVelocLength = relLinVel.dot(m_separatingNormal); 00190 if (relLinVelocLength<0.f) 00191 { 00192 relLinVelocLength = 0.f; 00193 } 00194 00195 btScalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength; 00196 m_separatingDistance -= projectedMotion; 00197 } 00198 00199 m_posA = toPosA; 00200 m_posB = toPosB; 00201 m_ornA = toOrnA; 00202 m_ornB = toOrnB; 00203 } 00204 00205 void initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB) 00206 { 00207 m_separatingDistance = separatingDistance; 00208 00209 if (m_separatingDistance>0.f) 00210 { 00211 m_separatingNormal = separatingVector; 00212 00213 const btVector3& toPosA = transA.getOrigin(); 00214 const btVector3& toPosB = transB.getOrigin(); 00215 btQuaternion toOrnA = transA.getRotation(); 00216 btQuaternion toOrnB = transB.getRotation(); 00217 m_posA = toPosA; 00218 m_posB = toPosB; 00219 m_ornA = toOrnA; 00220 m_ornB = toOrnB; 00221 } 00222 } 00223 00224 }; 00225 00226 00227 #endif //SIMD_TRANSFORM_UTIL_H 00228