btQuaternion.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 
00017 #ifndef SIMD__QUATERNION_H_
00018 #define SIMD__QUATERNION_H_
00019 
00020 
00021 #include "btVector3.h"
00022 #include "btQuadWord.h"
00023 
00025 class btQuaternion : public btQuadWord {
00026 public:
00028         btQuaternion() {}
00029 
00030         //              template <typename btScalar>
00031         //              explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
00033         btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) 
00034                 : btQuadWord(x, y, z, w) 
00035         {}
00039         btQuaternion(const btVector3& axis, const btScalar& angle) 
00040         { 
00041                 setRotation(axis, angle); 
00042         }
00047   btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) __attribute__((deprecated))
00048         { 
00049 #ifndef BT_EULER_DEFAULT_ZYX
00050                 setEuler(yaw, pitch, roll); 
00051 #else
00052                 setRPY(roll, pitch, yaw);
00053 #endif 
00054         }
00058         void setRotation(const btVector3& axis, const btScalar& angle)
00059         {
00060                 btScalar d = axis.length();
00061                 btAssert(d != btScalar(0.0));
00062                 btScalar s = btSin(angle * btScalar(0.5)) / d;
00063                 setValue(axis.x() * s, axis.y() * s, axis.z() * s, 
00064                         btCos(angle * btScalar(0.5)));
00065         }
00070         void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
00071         {
00072                 btScalar halfYaw = btScalar(yaw) * btScalar(0.5);  
00073                 btScalar halfPitch = btScalar(pitch) * btScalar(0.5);  
00074                 btScalar halfRoll = btScalar(roll) * btScalar(0.5);  
00075                 btScalar cosYaw = btCos(halfYaw);
00076                 btScalar sinYaw = btSin(halfYaw);
00077                 btScalar cosPitch = btCos(halfPitch);
00078                 btScalar sinPitch = btSin(halfPitch);
00079                 btScalar cosRoll = btCos(halfRoll);
00080                 btScalar sinRoll = btSin(halfRoll);
00081                 setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
00082                         cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
00083                         sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
00084                         cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
00085         }
00090   void setRPY(const btScalar& roll, const btScalar& pitch, const btScalar& yaw)
00091         {
00092                 btScalar halfYaw = btScalar(yaw) * btScalar(0.5);  
00093                 btScalar halfPitch = btScalar(pitch) * btScalar(0.5);  
00094                 btScalar halfRoll = btScalar(roll) * btScalar(0.5);  
00095                 btScalar cosYaw = btCos(halfYaw);
00096                 btScalar sinYaw = btSin(halfYaw);
00097                 btScalar cosPitch = btCos(halfPitch);
00098                 btScalar sinPitch = btSin(halfPitch);
00099                 btScalar cosRoll = btCos(halfRoll);
00100                 btScalar sinRoll = btSin(halfRoll);
00101                 setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x
00102                          cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y
00103                          cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z
00104                          cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx
00105         }
00110   void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) __attribute__((deprecated))
00111         {
00112           setRPY(roll, pitch, yaw);
00113         }
00116         SIMD_FORCE_INLINE       btQuaternion& operator+=(const btQuaternion& q)
00117         {
00118                 m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3];
00119                 return *this;
00120         }
00121 
00124         btQuaternion& operator-=(const btQuaternion& q) 
00125         {
00126                 m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3];
00127                 return *this;
00128         }
00129 
00132         btQuaternion& operator*=(const btScalar& s)
00133         {
00134                 m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s;
00135                 return *this;
00136         }
00137 
00141         btQuaternion& operator*=(const btQuaternion& q)
00142         {
00143                 setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
00144                         m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(),
00145                         m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(),
00146                         m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z());
00147                 return *this;
00148         }
00151         btScalar dot(const btQuaternion& q) const
00152         {
00153                 return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3];
00154         }
00155 
00157         btScalar length2() const
00158         {
00159                 return dot(*this);
00160         }
00161 
00163         btScalar length() const
00164         {
00165                 return btSqrt(length2());
00166         }
00167 
00170         btQuaternion& normalize() 
00171         {
00172                 return *this /= length();
00173         }
00174 
00177         SIMD_FORCE_INLINE btQuaternion
00178         operator*(const btScalar& s) const
00179         {
00180                 return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s);
00181         }
00182 
00183 
00186         btQuaternion operator/(const btScalar& s) const
00187         {
00188                 btAssert(s != btScalar(0.0));
00189                 return *this * (btScalar(1.0) / s);
00190         }
00191 
00194         btQuaternion& operator/=(const btScalar& s) 
00195         {
00196                 btAssert(s != btScalar(0.0));
00197                 return *this *= btScalar(1.0) / s;
00198         }
00199 
00201         btQuaternion normalized() const 
00202         {
00203                 return *this / length();
00204         } 
00207         btScalar angle(const btQuaternion& q) const 
00208         {
00209                 btScalar s = btSqrt(length2() * q.length2());
00210                 btAssert(s != btScalar(0.0));
00211                 return btAcos(dot(q) / s);
00212         }
00215         btScalar angleShortestPath(const btQuaternion& q) const 
00216         {
00217                 btScalar s = btSqrt(length2() * q.length2());
00218                 btAssert(s != btScalar(0.0));
00219                 if (dot(q) < 0) // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp
00220                         return btAcos(dot(-q) / s) * btScalar(2.0);
00221                 else 
00222                         return btAcos(dot(q) / s) * btScalar(2.0);
00223         }
00225         btScalar getAngle() const 
00226         {
00227                 btScalar s = btScalar(2.) * btAcos(m_floats[3]);
00228                 return s;
00229         }
00230 
00232         btScalar getAngleShortestPath() const 
00233         {
00234         btScalar s;
00235                 if (dot(*this) < 0)
00236                         s = btScalar(2.) * btAcos(m_floats[3]);
00237                 else
00238                         s = btScalar(2.) * btAcos(-m_floats[3]);
00239 
00240                 return s;
00241         }
00242 
00244         btVector3 getAxis() const
00245         {
00246                 btScalar s_squared = btScalar(1.) - btPow(m_floats[3], btScalar(2.));
00247                 if (s_squared < btScalar(10.) * SIMD_EPSILON) //Check for divide by zero
00248                         return btVector3(1.0, 0.0, 0.0);  // Arbitrary
00249                 btScalar s = btSqrt(s_squared);
00250                 return btVector3(m_floats[0] / s, m_floats[1] / s, m_floats[2] / s);
00251         }
00252 
00254         btQuaternion inverse() const
00255         {
00256                 return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]);
00257         }
00258 
00261         SIMD_FORCE_INLINE btQuaternion
00262         operator+(const btQuaternion& q2) const
00263         {
00264                 const btQuaternion& q1 = *this;
00265                 return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]);
00266         }
00267 
00270         SIMD_FORCE_INLINE btQuaternion
00271         operator-(const btQuaternion& q2) const
00272         {
00273                 const btQuaternion& q1 = *this;
00274                 return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]);
00275         }
00276 
00279         SIMD_FORCE_INLINE btQuaternion operator-() const
00280         {
00281                 const btQuaternion& q2 = *this;
00282                 return btQuaternion( - q2.x(), - q2.y(),  - q2.z(),  - q2.m_floats[3]);
00283         }
00285         SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const 
00286         {
00287                 btQuaternion diff,sum;
00288                 diff = *this - qd;
00289                 sum = *this + qd;
00290                 if( diff.dot(diff) > sum.dot(sum) )
00291                         return qd;
00292                 return (-qd);
00293         }
00294 
00296         SIMD_FORCE_INLINE btQuaternion nearest( const btQuaternion& qd) const 
00297         {
00298                 btQuaternion diff,sum;
00299                 diff = *this - qd;
00300                 sum = *this + qd;
00301                 if( diff.dot(diff) < sum.dot(sum) )
00302                         return qd;
00303                 return (-qd);
00304         }
00305 
00306 
00311         btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
00312         {
00313           btScalar theta = angleShortestPath(q) / btScalar(2.0);
00314                 if (theta != btScalar(0.0))
00315                 {
00316                         btScalar d = btScalar(1.0) / btSin(theta);
00317                         btScalar s0 = btSin((btScalar(1.0) - t) * theta);
00318                         btScalar s1 = btSin(t * theta);   
00319                         if (dot(q) < 0) // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp
00320                           return btQuaternion((m_floats[0] * s0 + -q.x() * s1) * d,
00321                                               (m_floats[1] * s0 + -q.y() * s1) * d,
00322                                               (m_floats[2] * s0 + -q.z() * s1) * d,
00323                                               (m_floats[3] * s0 + -q.m_floats[3] * s1) * d);
00324                         else
00325                           return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
00326                                               (m_floats[1] * s0 + q.y() * s1) * d,
00327                                               (m_floats[2] * s0 + q.z() * s1) * d,
00328                                               (m_floats[3] * s0 + q.m_floats[3] * s1) * d);
00329                         
00330                 }
00331                 else
00332                 {
00333                         return *this;
00334                 }
00335         }
00336 
00337         static const btQuaternion&      getIdentity()
00338         {
00339                 static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.));
00340                 return identityQuat;
00341         }
00342 
00343         SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; }
00344 
00345         
00346 };
00347 
00348 
00350 SIMD_FORCE_INLINE btQuaternion
00351 operator-(const btQuaternion& q)
00352 {
00353         return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w());
00354 }
00355 
00356 
00357 
00359 SIMD_FORCE_INLINE btQuaternion
00360 operator*(const btQuaternion& q1, const btQuaternion& q2) {
00361         return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
00362                 q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
00363                 q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
00364                 q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); 
00365 }
00366 
00367 SIMD_FORCE_INLINE btQuaternion
00368 operator*(const btQuaternion& q, const btVector3& w)
00369 {
00370         return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
00371                 q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
00372                 q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
00373                 -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); 
00374 }
00375 
00376 SIMD_FORCE_INLINE btQuaternion
00377 operator*(const btVector3& w, const btQuaternion& q)
00378 {
00379         return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(),
00380                 w.y() * q.w() + w.z() * q.x() - w.x() * q.z(),
00381                 w.z() * q.w() + w.x() * q.y() - w.y() * q.x(),
00382                 -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); 
00383 }
00384 
00386 SIMD_FORCE_INLINE btScalar 
00387 dot(const btQuaternion& q1, const btQuaternion& q2) 
00388 { 
00389         return q1.dot(q2); 
00390 }
00391 
00392 
00394 SIMD_FORCE_INLINE btScalar
00395 length(const btQuaternion& q) 
00396 { 
00397         return q.length(); 
00398 }
00399 
00401 SIMD_FORCE_INLINE btScalar
00402 angle(const btQuaternion& q1, const btQuaternion& q2) 
00403 { 
00404         return q1.angle(q2); 
00405 }
00406 
00408 SIMD_FORCE_INLINE btScalar
00409 angleShortestPath(const btQuaternion& q1, const btQuaternion& q2) 
00410 { 
00411         return q1.angleShortestPath(q2); 
00412 }
00413 
00415 SIMD_FORCE_INLINE btQuaternion
00416 inverse(const btQuaternion& q) 
00417 {
00418         return q.inverse();
00419 }
00420 
00426 SIMD_FORCE_INLINE btQuaternion
00427 slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) 
00428 {
00429         return q1.slerp(q2, t);
00430 }
00431 
00432 SIMD_FORCE_INLINE btVector3 
00433 quatRotate(const btQuaternion& rotation, const btVector3& v) 
00434 {
00435         btQuaternion q = rotation * v;
00436         q *= rotation.inverse();
00437         return btVector3(q.getX(),q.getY(),q.getZ());
00438 }
00439 
00440 SIMD_FORCE_INLINE btQuaternion 
00441 shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized
00442 {
00443         btVector3 c = v0.cross(v1);
00444         btScalar  d = v0.dot(v1);
00445 
00446         if (d < -1.0 + SIMD_EPSILON)
00447         {
00448                 btVector3 n,unused;
00449                 btPlaneSpace1(v0,n,unused);
00450                 return btQuaternion(n.x(),n.y(),n.z(),0.0f); // just pick any vector that is orthogonal to v0
00451         }
00452 
00453         btScalar  s = btSqrt((1.0f + d) * 2.0f);
00454         btScalar rs = 1.0f / s;
00455 
00456         return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f);
00457 }
00458 
00459 SIMD_FORCE_INLINE btQuaternion 
00460 shortestArcQuatNormalize2(btVector3& v0,btVector3& v1)
00461 {
00462         v0.normalize();
00463         v1.normalize();
00464         return shortestArcQuat(v0,v1);
00465 }
00466 
00467 #endif
00468 
00469 
00470 
00471 


tf2
Author(s): Tully Foote, Eitan Marder-Eppstein, Wim Meeussen
autogenerated on Mon Oct 6 2014 00:12:43