Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/LinearMath/btTransformUtil.h @ 2122

Last change on this file since 2122 was 2119, checked in by rgrieder, 16 years ago

Merged physics branch into physics_new branch.

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1/*
2Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
3
4This software is provided 'as-is', without any express or implied warranty.
5In no event will the authors be held liable for any damages arising from the use of this software.
6Permission is granted to anyone to use this software for any purpose,
7including commercial applications, and to alter it and redistribute it freely,
8subject to the following restrictions:
9
101. 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.
112. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
123. This notice may not be removed or altered from any source distribution.
13*/
14
15
16#ifndef SIMD_TRANSFORM_UTIL_H
17#define SIMD_TRANSFORM_UTIL_H
18
19#include "btTransform.h"
20#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI
21
22
23
24#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
25
26#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x))))          /* reciprocal square root */
27
28SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir)
29{
30        return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
31      supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
32      supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); 
33}
34
35
36SIMD_FORCE_INLINE void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q)
37{
38  if (btFabs(n.z()) > SIMDSQRT12) {
39    // choose p in y-z plane
40    btScalar a = n[1]*n[1] + n[2]*n[2];
41    btScalar k = btRecipSqrt (a);
42    p.setValue(0,-n[2]*k,n[1]*k);
43    // set q = n x p
44    q.setValue(a*k,-n[0]*p[2],n[0]*p[1]);
45  }
46  else {
47    // choose p in x-y plane
48    btScalar a = n.x()*n.x() + n.y()*n.y();
49    btScalar k = btRecipSqrt (a);
50    p.setValue(-n.y()*k,n.x()*k,0);
51    // set q = n x p
52    q.setValue(-n.z()*p.y(),n.z()*p.x(),a*k);
53  }
54}
55
56
57
58/// Utils related to temporal transforms
59class btTransformUtil
60{
61
62public:
63
64        static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform)
65        {
66                predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
67//      #define QUATERNION_DERIVATIVE
68        #ifdef QUATERNION_DERIVATIVE
69                btQuaternion predictedOrn = curTrans.getRotation();
70                predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5));
71                predictedOrn.normalize();
72        #else
73                //Exponential map
74                //google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
75
76                btVector3 axis;
77                btScalar        fAngle = angvel.length(); 
78                //limit the angular motion
79                if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD)
80                {
81                        fAngle = ANGULAR_MOTION_THRESHOLD / timeStep;
82                }
83
84                if ( fAngle < btScalar(0.001) )
85                {
86                        // use Taylor's expansions of sync function
87                        axis   = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle );
88                }
89                else
90                {
91                        // sync(fAngle) = sin(c*fAngle)/t
92                        axis   = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle );
93                }
94                btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) ));
95                btQuaternion orn0 = curTrans.getRotation();
96
97                btQuaternion predictedOrn = dorn * orn0;
98                predictedOrn.normalize();
99        #endif
100                predictedTransform.setRotation(predictedOrn);
101        }
102
103        static void     calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
104        {
105                linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
106                btVector3 axis;
107                btScalar  angle;
108                calculateDiffAxisAngle(transform0,transform1,axis,angle);
109                angVel = axis * angle / timeStep;
110        }
111
112        static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle)
113        {
114       
115        #ifdef USE_QUATERNION_DIFF
116                btQuaternion orn0 = transform0.getRotation();
117                btQuaternion orn1a = transform1.getRotation();
118                btQuaternion orn1 = orn0.farthest(orn1a);
119                btQuaternion dorn = orn1 * orn0.inverse();
120#else
121                btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
122                btQuaternion dorn;
123                dmat.getRotation(dorn);
124#endif//USE_QUATERNION_DIFF
125       
126                ///floating point inaccuracy can lead to w component > 1..., which breaks
127
128                dorn.normalize();
129               
130                angle = dorn.getAngle();
131                axis = btVector3(dorn.x(),dorn.y(),dorn.z());
132                axis[3] = btScalar(0.);
133                //check for axis length
134                btScalar len = axis.length2();
135                if (len < SIMD_EPSILON*SIMD_EPSILON)
136                        axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
137                else
138                        axis /= btSqrt(len);
139        }
140
141};
142
143#endif //SIMD_TRANSFORM_UTIL_H
144
Note: See TracBrowser for help on using the repository browser.