| [1963] | 1 | /* | 
|---|
 | 2 | Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/ | 
|---|
 | 3 |  | 
|---|
 | 4 | This software is provided 'as-is', without any express or implied warranty. | 
|---|
 | 5 | In no event will the authors be held liable for any damages arising from the use of this software. | 
|---|
 | 6 | Permission is granted to anyone to use this software for any purpose,  | 
|---|
 | 7 | including commercial applications, and to alter it and redistribute it freely,  | 
|---|
 | 8 | subject to the following restrictions: | 
|---|
 | 9 |  | 
|---|
 | 10 | 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. | 
|---|
 | 11 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | 
|---|
 | 12 | 3. This notice may not be removed or altered from any source distribution. | 
|---|
 | 13 | */ | 
|---|
 | 14 |  | 
|---|
 | 15 |  | 
|---|
 | 16 |  | 
|---|
 | 17 | #ifndef SIMD__QUATERNION_H_ | 
|---|
 | 18 | #define SIMD__QUATERNION_H_ | 
|---|
 | 19 |  | 
|---|
| [2430] | 20 |  | 
|---|
| [1963] | 21 | #include "btVector3.h" | 
|---|
| [2882] | 22 | #include "btQuadWord.h" | 
|---|
| [1963] | 23 |  | 
|---|
| [2430] | 24 | /**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */ | 
|---|
| [1963] | 25 | class btQuaternion : public btQuadWord { | 
|---|
 | 26 | public: | 
|---|
| [2430] | 27 |   /**@brief No initialization constructor */ | 
|---|
| [1963] | 28 |         btQuaternion() {} | 
|---|
 | 29 |  | 
|---|
 | 30 |         //              template <typename btScalar> | 
|---|
 | 31 |         //              explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {} | 
|---|
| [2430] | 32 |   /**@brief Constructor from scalars */ | 
|---|
| [1963] | 33 |         btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w)  | 
|---|
 | 34 |                 : btQuadWord(x, y, z, w)  | 
|---|
 | 35 |         {} | 
|---|
| [2430] | 36 |   /**@brief Axis angle Constructor | 
|---|
 | 37 |    * @param axis The axis which the rotation is around | 
|---|
 | 38 |    * @param angle The magnitude of the rotation around the angle (Radians) */ | 
|---|
| [1963] | 39 |         btQuaternion(const btVector3& axis, const btScalar& angle)  | 
|---|
 | 40 |         {  | 
|---|
 | 41 |                 setRotation(axis, angle);  | 
|---|
 | 42 |         } | 
|---|
| [2430] | 43 |   /**@brief Constructor from Euler angles | 
|---|
 | 44 |    * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z | 
|---|
 | 45 |    * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y | 
|---|
 | 46 |    * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */ | 
|---|
| [1963] | 47 |         btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) | 
|---|
 | 48 |         {  | 
|---|
| [2430] | 49 | #ifndef BT_EULER_DEFAULT_ZYX | 
|---|
| [1963] | 50 |                 setEuler(yaw, pitch, roll);  | 
|---|
| [2430] | 51 | #else | 
|---|
 | 52 |                 setEulerZYX(yaw, pitch, roll);  | 
|---|
 | 53 | #endif  | 
|---|
| [1963] | 54 |         } | 
|---|
| [2430] | 55 |   /**@brief Set the rotation using axis angle notation  | 
|---|
 | 56 |    * @param axis The axis around which to rotate | 
|---|
 | 57 |    * @param angle The magnitude of the rotation in Radians */ | 
|---|
| [1963] | 58 |         void setRotation(const btVector3& axis, const btScalar& angle) | 
|---|
 | 59 |         { | 
|---|
 | 60 |                 btScalar d = axis.length(); | 
|---|
| [2882] | 61 |                 btAssert(d != btScalar(0.0)); | 
|---|
| [1963] | 62 |                 btScalar s = btSin(angle * btScalar(0.5)) / d; | 
|---|
 | 63 |                 setValue(axis.x() * s, axis.y() * s, axis.z() * s,  | 
|---|
 | 64 |                         btCos(angle * btScalar(0.5))); | 
|---|
 | 65 |         } | 
|---|
| [2430] | 66 |   /**@brief Set the quaternion using Euler angles | 
|---|
 | 67 |    * @param yaw Angle around Y | 
|---|
 | 68 |    * @param pitch Angle around X | 
|---|
 | 69 |    * @param roll Angle around Z */ | 
|---|
| [1963] | 70 |         void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) | 
|---|
 | 71 |         { | 
|---|
 | 72 |                 btScalar halfYaw = btScalar(yaw) * btScalar(0.5);   | 
|---|
 | 73 |                 btScalar halfPitch = btScalar(pitch) * btScalar(0.5);   | 
|---|
 | 74 |                 btScalar halfRoll = btScalar(roll) * btScalar(0.5);   | 
|---|
 | 75 |                 btScalar cosYaw = btCos(halfYaw); | 
|---|
 | 76 |                 btScalar sinYaw = btSin(halfYaw); | 
|---|
 | 77 |                 btScalar cosPitch = btCos(halfPitch); | 
|---|
 | 78 |                 btScalar sinPitch = btSin(halfPitch); | 
|---|
 | 79 |                 btScalar cosRoll = btCos(halfRoll); | 
|---|
 | 80 |                 btScalar sinRoll = btSin(halfRoll); | 
|---|
 | 81 |                 setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, | 
|---|
 | 82 |                         cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, | 
|---|
 | 83 |                         sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, | 
|---|
 | 84 |                         cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); | 
|---|
 | 85 |         } | 
|---|
| [2430] | 86 |   /**@brief Set the quaternion using euler angles  | 
|---|
 | 87 |    * @param yaw Angle around Z | 
|---|
 | 88 |    * @param pitch Angle around Y | 
|---|
 | 89 |    * @param roll Angle around X */ | 
|---|
 | 90 |         void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) | 
|---|
| [1963] | 91 |         { | 
|---|
| [2430] | 92 |                 btScalar halfYaw = btScalar(yaw) * btScalar(0.5);   | 
|---|
 | 93 |                 btScalar halfPitch = btScalar(pitch) * btScalar(0.5);   | 
|---|
 | 94 |                 btScalar halfRoll = btScalar(roll) * btScalar(0.5);   | 
|---|
 | 95 |                 btScalar cosYaw = btCos(halfYaw); | 
|---|
 | 96 |                 btScalar sinYaw = btSin(halfYaw); | 
|---|
 | 97 |                 btScalar cosPitch = btCos(halfPitch); | 
|---|
 | 98 |                 btScalar sinPitch = btSin(halfPitch); | 
|---|
 | 99 |                 btScalar cosRoll = btCos(halfRoll); | 
|---|
 | 100 |                 btScalar sinRoll = btSin(halfRoll); | 
|---|
 | 101 |                 setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x | 
|---|
 | 102 |                          cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y | 
|---|
 | 103 |                          cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z | 
|---|
 | 104 |                          cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx | 
|---|
 | 105 |         } | 
|---|
 | 106 |   /**@brief Add two quaternions | 
|---|
 | 107 |    * @param q The quaternion to add to this one */ | 
|---|
 | 108 |         SIMD_FORCE_INLINE       btQuaternion& operator+=(const btQuaternion& q) | 
|---|
 | 109 |         { | 
|---|
 | 110 |                 m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3]; | 
|---|
| [1963] | 111 |                 return *this; | 
|---|
 | 112 |         } | 
|---|
 | 113 |  | 
|---|
| [2430] | 114 |   /**@brief Subtract out a quaternion | 
|---|
 | 115 |    * @param q The quaternion to subtract from this one */ | 
|---|
| [1963] | 116 |         btQuaternion& operator-=(const btQuaternion& q)  | 
|---|
 | 117 |         { | 
|---|
| [2430] | 118 |                 m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3]; | 
|---|
| [1963] | 119 |                 return *this; | 
|---|
 | 120 |         } | 
|---|
 | 121 |  | 
|---|
| [2430] | 122 |   /**@brief Scale this quaternion | 
|---|
 | 123 |    * @param s The scalar to scale by */ | 
|---|
| [1963] | 124 |         btQuaternion& operator*=(const btScalar& s) | 
|---|
 | 125 |         { | 
|---|
| [2430] | 126 |                 m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s; | 
|---|
| [1963] | 127 |                 return *this; | 
|---|
 | 128 |         } | 
|---|
 | 129 |  | 
|---|
| [2430] | 130 |   /**@brief Multiply this quaternion by q on the right | 
|---|
 | 131 |    * @param q The other quaternion  | 
|---|
 | 132 |    * Equivilant to this = this * q */ | 
|---|
| [1963] | 133 |         btQuaternion& operator*=(const btQuaternion& q) | 
|---|
 | 134 |         { | 
|---|
| [2430] | 135 |                 setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(), | 
|---|
 | 136 |                         m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(), | 
|---|
 | 137 |                         m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(), | 
|---|
 | 138 |                         m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z()); | 
|---|
| [1963] | 139 |                 return *this; | 
|---|
 | 140 |         } | 
|---|
| [2430] | 141 |   /**@brief Return the dot product between this quaternion and another | 
|---|
 | 142 |    * @param q The other quaternion */ | 
|---|
| [1963] | 143 |         btScalar dot(const btQuaternion& q) const | 
|---|
 | 144 |         { | 
|---|
| [2430] | 145 |                 return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3]; | 
|---|
| [1963] | 146 |         } | 
|---|
 | 147 |  | 
|---|
| [2430] | 148 |   /**@brief Return the length squared of the quaternion */ | 
|---|
| [1963] | 149 |         btScalar length2() const | 
|---|
 | 150 |         { | 
|---|
 | 151 |                 return dot(*this); | 
|---|
 | 152 |         } | 
|---|
 | 153 |  | 
|---|
| [2430] | 154 |   /**@brief Return the length of the quaternion */ | 
|---|
| [1963] | 155 |         btScalar length() const | 
|---|
 | 156 |         { | 
|---|
 | 157 |                 return btSqrt(length2()); | 
|---|
 | 158 |         } | 
|---|
 | 159 |  | 
|---|
| [2430] | 160 |   /**@brief Normalize the quaternion  | 
|---|
 | 161 |    * Such that x^2 + y^2 + z^2 +w^2 = 1 */ | 
|---|
| [1963] | 162 |         btQuaternion& normalize()  | 
|---|
 | 163 |         { | 
|---|
 | 164 |                 return *this /= length(); | 
|---|
 | 165 |         } | 
|---|
 | 166 |  | 
|---|
| [2430] | 167 |   /**@brief Return a scaled version of this quaternion | 
|---|
 | 168 |    * @param s The scale factor */ | 
|---|
| [1963] | 169 |         SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 170 |         operator*(const btScalar& s) const | 
|---|
 | 171 |         { | 
|---|
| [2430] | 172 |                 return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s); | 
|---|
| [1963] | 173 |         } | 
|---|
 | 174 |  | 
|---|
 | 175 |  | 
|---|
| [2430] | 176 |   /**@brief Return an inversely scaled versionof this quaternion | 
|---|
 | 177 |    * @param s The inverse scale factor */ | 
|---|
| [1963] | 178 |         btQuaternion operator/(const btScalar& s) const | 
|---|
 | 179 |         { | 
|---|
| [2882] | 180 |                 btAssert(s != btScalar(0.0)); | 
|---|
| [1963] | 181 |                 return *this * (btScalar(1.0) / s); | 
|---|
 | 182 |         } | 
|---|
 | 183 |  | 
|---|
| [2430] | 184 |   /**@brief Inversely scale this quaternion | 
|---|
 | 185 |    * @param s The scale factor */ | 
|---|
| [1963] | 186 |         btQuaternion& operator/=(const btScalar& s)  | 
|---|
 | 187 |         { | 
|---|
| [2882] | 188 |                 btAssert(s != btScalar(0.0)); | 
|---|
| [1963] | 189 |                 return *this *= btScalar(1.0) / s; | 
|---|
 | 190 |         } | 
|---|
 | 191 |  | 
|---|
| [2430] | 192 |   /**@brief Return a normalized version of this quaternion */ | 
|---|
| [1963] | 193 |         btQuaternion normalized() const  | 
|---|
 | 194 |         { | 
|---|
 | 195 |                 return *this / length(); | 
|---|
 | 196 |         }  | 
|---|
| [2430] | 197 |   /**@brief Return the angle between this quaternion and the other  | 
|---|
 | 198 |    * @param q The other quaternion */ | 
|---|
| [1963] | 199 |         btScalar angle(const btQuaternion& q) const  | 
|---|
 | 200 |         { | 
|---|
 | 201 |                 btScalar s = btSqrt(length2() * q.length2()); | 
|---|
| [2882] | 202 |                 btAssert(s != btScalar(0.0)); | 
|---|
| [1963] | 203 |                 return btAcos(dot(q) / s); | 
|---|
 | 204 |         } | 
|---|
| [2430] | 205 |   /**@brief Return the angle of rotation represented by this quaternion */ | 
|---|
| [1963] | 206 |         btScalar getAngle() const  | 
|---|
 | 207 |         { | 
|---|
| [2430] | 208 |                 btScalar s = btScalar(2.) * btAcos(m_floats[3]); | 
|---|
| [1963] | 209 |                 return s; | 
|---|
 | 210 |         } | 
|---|
 | 211 |  | 
|---|
 | 212 |  | 
|---|
| [2430] | 213 |   /**@brief Return the inverse of this quaternion */ | 
|---|
| [1963] | 214 |         btQuaternion inverse() const | 
|---|
 | 215 |         { | 
|---|
| [2430] | 216 |                 return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]); | 
|---|
| [1963] | 217 |         } | 
|---|
 | 218 |  | 
|---|
| [2430] | 219 |   /**@brief Return the sum of this quaternion and the other  | 
|---|
 | 220 |    * @param q2 The other quaternion */ | 
|---|
| [1963] | 221 |         SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 222 |         operator+(const btQuaternion& q2) const | 
|---|
 | 223 |         { | 
|---|
 | 224 |                 const btQuaternion& q1 = *this; | 
|---|
| [2430] | 225 |                 return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]); | 
|---|
| [1963] | 226 |         } | 
|---|
 | 227 |  | 
|---|
| [2430] | 228 |   /**@brief Return the difference between this quaternion and the other  | 
|---|
 | 229 |    * @param q2 The other quaternion */ | 
|---|
| [1963] | 230 |         SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 231 |         operator-(const btQuaternion& q2) const | 
|---|
 | 232 |         { | 
|---|
 | 233 |                 const btQuaternion& q1 = *this; | 
|---|
| [2430] | 234 |                 return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]); | 
|---|
| [1963] | 235 |         } | 
|---|
 | 236 |  | 
|---|
| [2430] | 237 |   /**@brief Return the negative of this quaternion  | 
|---|
 | 238 |    * This simply negates each element */ | 
|---|
| [1963] | 239 |         SIMD_FORCE_INLINE btQuaternion operator-() const | 
|---|
 | 240 |         { | 
|---|
 | 241 |                 const btQuaternion& q2 = *this; | 
|---|
| [2430] | 242 |                 return btQuaternion( - q2.x(), - q2.y(),  - q2.z(),  - q2.m_floats[3]); | 
|---|
| [1963] | 243 |         } | 
|---|
| [2430] | 244 |   /**@todo document this and it's use */ | 
|---|
| [1963] | 245 |         SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const  | 
|---|
 | 246 |         { | 
|---|
 | 247 |                 btQuaternion diff,sum; | 
|---|
 | 248 |                 diff = *this - qd; | 
|---|
 | 249 |                 sum = *this + qd; | 
|---|
 | 250 |                 if( diff.dot(diff) > sum.dot(sum) ) | 
|---|
 | 251 |                         return qd; | 
|---|
 | 252 |                 return (-qd); | 
|---|
 | 253 |         } | 
|---|
 | 254 |  | 
|---|
| [2430] | 255 |   /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion | 
|---|
 | 256 |    * @param q The other quaternion to interpolate with  | 
|---|
 | 257 |    * @param t The ratio between this and q to interpolate.  If t = 0 the result is this, if t=1 the result is q. | 
|---|
 | 258 |    * Slerp interpolates assuming constant velocity.  */ | 
|---|
| [1963] | 259 |         btQuaternion slerp(const btQuaternion& q, const btScalar& t) const | 
|---|
 | 260 |         { | 
|---|
 | 261 |                 btScalar theta = angle(q); | 
|---|
 | 262 |                 if (theta != btScalar(0.0)) | 
|---|
 | 263 |                 { | 
|---|
 | 264 |                         btScalar d = btScalar(1.0) / btSin(theta); | 
|---|
 | 265 |                         btScalar s0 = btSin((btScalar(1.0) - t) * theta); | 
|---|
 | 266 |                         btScalar s1 = btSin(t * theta);    | 
|---|
| [2430] | 267 |                         return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d, | 
|---|
 | 268 |                                 (m_floats[1] * s0 + q.y() * s1) * d, | 
|---|
 | 269 |                                 (m_floats[2] * s0 + q.z() * s1) * d, | 
|---|
 | 270 |                                 (m_floats[3] * s0 + q.m_floats[3] * s1) * d); | 
|---|
| [1963] | 271 |                 } | 
|---|
 | 272 |                 else | 
|---|
 | 273 |                 { | 
|---|
 | 274 |                         return *this; | 
|---|
 | 275 |                 } | 
|---|
 | 276 |         } | 
|---|
 | 277 |  | 
|---|
| [2882] | 278 |         static const btQuaternion&      getIdentity() | 
|---|
 | 279 |         { | 
|---|
 | 280 |                 static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.)); | 
|---|
 | 281 |                 return identityQuat; | 
|---|
 | 282 |         } | 
|---|
 | 283 |  | 
|---|
| [2430] | 284 |         SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; } | 
|---|
| [1963] | 285 |  | 
|---|
 | 286 |          | 
|---|
 | 287 | }; | 
|---|
 | 288 |  | 
|---|
 | 289 |  | 
|---|
| [2430] | 290 | /**@brief Return the negative of a quaternion */ | 
|---|
| [1963] | 291 | SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 292 | operator-(const btQuaternion& q) | 
|---|
 | 293 | { | 
|---|
 | 294 |         return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w()); | 
|---|
 | 295 | } | 
|---|
 | 296 |  | 
|---|
 | 297 |  | 
|---|
 | 298 |  | 
|---|
| [2430] | 299 | /**@brief Return the product of two quaternions */ | 
|---|
| [1963] | 300 | SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 301 | operator*(const btQuaternion& q1, const btQuaternion& q2) { | 
|---|
 | 302 |         return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), | 
|---|
 | 303 |                 q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), | 
|---|
 | 304 |                 q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), | 
|---|
 | 305 |                 q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());  | 
|---|
 | 306 | } | 
|---|
 | 307 |  | 
|---|
 | 308 | SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 309 | operator*(const btQuaternion& q, const btVector3& w) | 
|---|
 | 310 | { | 
|---|
 | 311 |         return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), | 
|---|
 | 312 |                 q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), | 
|---|
 | 313 |                 q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), | 
|---|
 | 314 |                 -q.x() * w.x() - q.y() * w.y() - q.z() * w.z());  | 
|---|
 | 315 | } | 
|---|
 | 316 |  | 
|---|
 | 317 | SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 318 | operator*(const btVector3& w, const btQuaternion& q) | 
|---|
 | 319 | { | 
|---|
 | 320 |         return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), | 
|---|
 | 321 |                 w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), | 
|---|
 | 322 |                 w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), | 
|---|
 | 323 |                 -w.x() * q.x() - w.y() * q.y() - w.z() * q.z());  | 
|---|
 | 324 | } | 
|---|
 | 325 |  | 
|---|
| [2430] | 326 | /**@brief Calculate the dot product between two quaternions */ | 
|---|
| [1963] | 327 | SIMD_FORCE_INLINE btScalar  | 
|---|
 | 328 | dot(const btQuaternion& q1, const btQuaternion& q2)  | 
|---|
 | 329 | {  | 
|---|
 | 330 |         return q1.dot(q2);  | 
|---|
 | 331 | } | 
|---|
 | 332 |  | 
|---|
 | 333 |  | 
|---|
| [2430] | 334 | /**@brief Return the length of a quaternion */ | 
|---|
| [1963] | 335 | SIMD_FORCE_INLINE btScalar | 
|---|
 | 336 | length(const btQuaternion& q)  | 
|---|
 | 337 | {  | 
|---|
 | 338 |         return q.length();  | 
|---|
 | 339 | } | 
|---|
 | 340 |  | 
|---|
| [2430] | 341 | /**@brief Return the angle between two quaternions*/ | 
|---|
| [1963] | 342 | SIMD_FORCE_INLINE btScalar | 
|---|
 | 343 | angle(const btQuaternion& q1, const btQuaternion& q2)  | 
|---|
 | 344 | {  | 
|---|
 | 345 |         return q1.angle(q2);  | 
|---|
 | 346 | } | 
|---|
 | 347 |  | 
|---|
| [2430] | 348 | /**@brief Return the inverse of a quaternion*/ | 
|---|
| [1963] | 349 | SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 350 | inverse(const btQuaternion& q)  | 
|---|
 | 351 | { | 
|---|
 | 352 |         return q.inverse(); | 
|---|
 | 353 | } | 
|---|
 | 354 |  | 
|---|
| [2430] | 355 | /**@brief Return the result of spherical linear interpolation betwen two quaternions  | 
|---|
 | 356 |  * @param q1 The first quaternion | 
|---|
 | 357 |  * @param q2 The second quaternion  | 
|---|
 | 358 |  * @param t The ration between q1 and q2.  t = 0 return q1, t=1 returns q2  | 
|---|
 | 359 |  * Slerp assumes constant velocity between positions. */ | 
|---|
| [1963] | 360 | SIMD_FORCE_INLINE btQuaternion | 
|---|
 | 361 | slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)  | 
|---|
 | 362 | { | 
|---|
 | 363 |         return q1.slerp(q2, t); | 
|---|
 | 364 | } | 
|---|
 | 365 |  | 
|---|
 | 366 | SIMD_FORCE_INLINE btVector3  | 
|---|
 | 367 | quatRotate(const btQuaternion& rotation, const btVector3& v)  | 
|---|
 | 368 | { | 
|---|
 | 369 |         btQuaternion q = rotation * v; | 
|---|
 | 370 |         q *= rotation.inverse(); | 
|---|
 | 371 |         return btVector3(q.getX(),q.getY(),q.getZ()); | 
|---|
 | 372 | } | 
|---|
 | 373 |  | 
|---|
 | 374 | SIMD_FORCE_INLINE btQuaternion  | 
|---|
 | 375 | shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized | 
|---|
 | 376 | { | 
|---|
 | 377 |         btVector3 c = v0.cross(v1); | 
|---|
 | 378 |         btScalar  d = v0.dot(v1); | 
|---|
 | 379 |  | 
|---|
 | 380 |         if (d < -1.0 + SIMD_EPSILON) | 
|---|
 | 381 |                 return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector | 
|---|
 | 382 |  | 
|---|
 | 383 |         btScalar  s = btSqrt((1.0f + d) * 2.0f); | 
|---|
 | 384 |         btScalar rs = 1.0f / s; | 
|---|
 | 385 |  | 
|---|
 | 386 |         return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f); | 
|---|
 | 387 | } | 
|---|
 | 388 |  | 
|---|
 | 389 | SIMD_FORCE_INLINE btQuaternion  | 
|---|
 | 390 | shortestArcQuatNormalize2(btVector3& v0,btVector3& v1) | 
|---|
 | 391 | { | 
|---|
 | 392 |         v0.normalize(); | 
|---|
 | 393 |         v1.normalize(); | 
|---|
 | 394 |         return shortestArcQuat(v0,v1); | 
|---|
 | 395 | } | 
|---|
 | 396 |  | 
|---|
 | 397 | #endif | 
|---|
 | 398 |  | 
|---|
 | 399 |  | 
|---|
 | 400 |  | 
|---|
 | 401 |  | 
|---|