btTransformUtil.h
Go to the documentation of this file.
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 BT_TRANSFORM_UTIL_H
00017 #define BT_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 //BT_TRANSFORM_UTIL_H
00228 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


bullet
Author(s): Erwin Coumans, ROS package maintained by Tully Foote
autogenerated on Wed Oct 31 2012 07:54:31