00001
00002
00003
00004
00005
00006 #ifndef _GMTL_QUAT_OPS_H_
00007 #define _GMTL_QUAT_OPS_H_
00008
00009 #include <gmtl/Math.h>
00010 #include <gmtl/Quat.h>
00011
00012 namespace gmtl
00013 {
00025 template <typename DATA_TYPE>
00026 Quat<DATA_TYPE>& mult( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00027 {
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 Quat<DATA_TYPE> temporary;
00052 temporary[Xelt] = q1[Welt]*q2[Xelt] + q1[Xelt]*q2[Welt] + q1[Yelt]*q2[Zelt] - q1[Zelt]*q2[Yelt];
00053 temporary[Yelt] = q1[Welt]*q2[Yelt] + q1[Yelt]*q2[Welt] + q1[Zelt]*q2[Xelt] - q1[Xelt]*q2[Zelt];
00054 temporary[Zelt] = q1[Welt]*q2[Zelt] + q1[Zelt]*q2[Welt] + q1[Xelt]*q2[Yelt] - q1[Yelt]*q2[Xelt];
00055 temporary[Welt] = q1[Welt]*q2[Welt] - q1[Xelt]*q2[Xelt] - q1[Yelt]*q2[Yelt] - q1[Zelt]*q2[Zelt];
00056
00057
00058 result[Xelt] = temporary[Xelt];
00059 result[Yelt] = temporary[Yelt];
00060 result[Zelt] = temporary[Zelt];
00061 result[Welt] = temporary[Welt];
00062
00063
00064
00065 return result;
00066 }
00067
00074 template <typename DATA_TYPE>
00075 Quat<DATA_TYPE> operator*( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00076 {
00077
00078
00079
00080 return Quat<DATA_TYPE>( q1[Welt]*q2[Xelt] + q1[Xelt]*q2[Welt] + q1[Yelt]*q2[Zelt] - q1[Zelt]*q2[Yelt],
00081 q1[Welt]*q2[Yelt] + q1[Yelt]*q2[Welt] + q1[Zelt]*q2[Xelt] - q1[Xelt]*q2[Zelt],
00082 q1[Welt]*q2[Zelt] + q1[Zelt]*q2[Welt] + q1[Xelt]*q2[Yelt] - q1[Yelt]*q2[Xelt],
00083 q1[Welt]*q2[Welt] - q1[Xelt]*q2[Xelt] - q1[Yelt]*q2[Yelt] - q1[Zelt]*q2[Zelt] );
00084 }
00085
00090 template <typename DATA_TYPE>
00091 Quat<DATA_TYPE>& operator*=( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q2 )
00092 {
00093 return mult( result, result, q2 );
00094 }
00095
00101 template <typename DATA_TYPE>
00102 Quat<DATA_TYPE>& negate( Quat<DATA_TYPE>& result )
00103 {
00104 result[0] = -result[0];
00105 result[1] = -result[1];
00106 result[2] = -result[2];
00107 result[3] = -result[3];
00108 return result;
00109 }
00110
00116 template <typename DATA_TYPE>
00117 Quat<DATA_TYPE> operator-( const Quat<DATA_TYPE>& quat )
00118 {
00119 return Quat<DATA_TYPE>( -quat[0], -quat[1], -quat[2], -quat[3] );
00120 }
00121
00126 template <typename DATA_TYPE>
00127 Quat<DATA_TYPE>& mult( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q, DATA_TYPE s )
00128 {
00129 result[0] = q[0] * s;
00130 result[1] = q[1] * s;
00131 result[2] = q[2] * s;
00132 result[3] = q[3] * s;
00133 return result;
00134 }
00135
00140 template <typename DATA_TYPE>
00141 Quat<DATA_TYPE> operator*( const Quat<DATA_TYPE>& q, DATA_TYPE s )
00142 {
00143 Quat<DATA_TYPE> temporary;
00144 return mult( temporary, q, s );
00145 }
00146
00151 template <typename DATA_TYPE>
00152 Quat<DATA_TYPE>& operator*=( Quat<DATA_TYPE>& q, DATA_TYPE s )
00153 {
00154 return mult( q, q, s );
00155 }
00156
00161 template <typename DATA_TYPE>
00162 Quat<DATA_TYPE>& div( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q1, Quat<DATA_TYPE> q2 )
00163 {
00164
00165 return mult( result, q1, invert( q2 ) );
00166 }
00167
00172 template <typename DATA_TYPE>
00173 Quat<DATA_TYPE> operator/( const Quat<DATA_TYPE>& q1, Quat<DATA_TYPE> q2 )
00174 {
00175 return q1 * invert( q2 );
00176 }
00177
00182 template <typename DATA_TYPE>
00183 Quat<DATA_TYPE>& operator/=( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q2 )
00184 {
00185 return div( result, result, q2 );
00186 }
00187
00192 template <typename DATA_TYPE>
00193 Quat<DATA_TYPE>& div( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q, DATA_TYPE s )
00194 {
00195 result[0] = q[0] / s;
00196 result[1] = q[1] / s;
00197 result[2] = q[2] / s;
00198 result[3] = q[3] / s;
00199 return result;
00200 }
00201
00206 template <typename DATA_TYPE>
00207 Quat<DATA_TYPE> operator/( const Quat<DATA_TYPE>& q, DATA_TYPE s )
00208 {
00209 Quat<DATA_TYPE> temporary;
00210 return div( temporary, q, s );
00211 }
00212
00217 template <typename DATA_TYPE>
00218 Quat<DATA_TYPE>& operator/=( const Quat<DATA_TYPE>& q, DATA_TYPE s )
00219 {
00220 return div( q, q, s );
00221 }
00222
00226 template <typename DATA_TYPE>
00227 Quat<DATA_TYPE>& add( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00228 {
00229 result[0] = q1[0] + q2[0];
00230 result[1] = q1[1] + q2[1];
00231 result[2] = q1[2] + q2[2];
00232 result[3] = q1[3] + q2[3];
00233 return result;
00234 }
00235
00240 template <typename DATA_TYPE>
00241 Quat<DATA_TYPE> operator+( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00242 {
00243 Quat<DATA_TYPE> temporary;
00244 return add( temporary, q1, q2 );
00245 }
00246
00251 template <typename DATA_TYPE>
00252 Quat<DATA_TYPE>& operator+=( Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00253 {
00254 return add( q1, q1, q2 );
00255 }
00256
00260 template <typename DATA_TYPE>
00261 Quat<DATA_TYPE>& sub( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00262 {
00263 result[0] = q1[0] - q2[0];
00264 result[1] = q1[1] - q2[1];
00265 result[2] = q1[2] - q2[2];
00266 result[3] = q1[3] - q2[3];
00267 return result;
00268 }
00269
00274 template <typename DATA_TYPE>
00275 Quat<DATA_TYPE> operator-( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00276 {
00277 Quat<DATA_TYPE> temporary;
00278 return sub( temporary, q1, q2 );
00279 }
00280
00285 template <typename DATA_TYPE>
00286 Quat<DATA_TYPE>& operator-=( Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00287 {
00288 return sub( q1, q1, q2 );
00289 }
00290
00297 template <typename DATA_TYPE>
00298 DATA_TYPE dot( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00299 {
00300 return DATA_TYPE( (q1[0] * q2[0]) +
00301 (q1[1] * q2[1]) +
00302 (q1[2] * q2[2]) +
00303 (q1[3] * q2[3]) );
00304 }
00305
00313 template <typename DATA_TYPE>
00314 DATA_TYPE lengthSquared( const Quat<DATA_TYPE>& q )
00315 {
00316 return dot( q, q );
00317 }
00318
00325 template <typename DATA_TYPE>
00326 DATA_TYPE length( const Quat<DATA_TYPE>& q )
00327 {
00328 return Math::sqrt( lengthSquared( q ) );
00329 }
00330
00336 template <typename DATA_TYPE>
00337 Quat<DATA_TYPE>& normalize( Quat<DATA_TYPE>& result )
00338 {
00339 DATA_TYPE l = length( result );
00340
00341
00342 if (l < (DATA_TYPE)0.0001)
00343 return result;
00344
00345 DATA_TYPE l_inv = ((DATA_TYPE)1.0) / l;
00346 result[Xelt] *= l_inv;
00347 result[Yelt] *= l_inv;
00348 result[Zelt] *= l_inv;
00349 result[Welt] *= l_inv;
00350
00351 return result;
00352 }
00353
00363 template< typename DATA_TYPE >
00364 bool isNormalized( const Quat<DATA_TYPE>& q1, const DATA_TYPE eps = 0.0001f )
00365 {
00366 return Math::isEqual( lengthSquared( q1 ), DATA_TYPE(1), eps );
00367 }
00368
00375 template <typename DATA_TYPE>
00376 Quat<DATA_TYPE>& conj( Quat<DATA_TYPE>& result )
00377 {
00378 result[Xelt] = -result[Xelt];
00379 result[Yelt] = -result[Yelt];
00380 result[Zelt] = -result[Zelt];
00381 return result;
00382 }
00383
00389 template <typename DATA_TYPE>
00390 Quat<DATA_TYPE>& invert( Quat<DATA_TYPE>& result )
00391 {
00392
00393
00394 conj( result );
00395
00396
00397 DATA_TYPE l = lengthSquared( result );
00398 if (l < (DATA_TYPE)0.0001)
00399 return result;
00400
00401 DATA_TYPE l_inv = ((DATA_TYPE)1.0) / l;
00402 result[Xelt] *= l_inv;
00403 result[Yelt] *= l_inv;
00404 result[Zelt] *= l_inv;
00405 result[Welt] *= l_inv;
00406 return result;
00407 }
00408
00414 template <typename DATA_TYPE>
00415 Quat<DATA_TYPE>& exp( Quat<DATA_TYPE>& result )
00416 {
00417 DATA_TYPE len1, len2;
00418
00419 len1 = Math::sqrt( result[Xelt] * result[Xelt] +
00420 result[Yelt] * result[Yelt] +
00421 result[Zelt] * result[Zelt] );
00422 if (len1 > (DATA_TYPE)0.0)
00423 len2 = Math::sin( len1 ) / len1;
00424 else
00425 len2 = (DATA_TYPE)1.0;
00426
00427 result[Xelt] = result[Xelt] * len2;
00428 result[Yelt] = result[Yelt] * len2;
00429 result[Zelt] = result[Zelt] * len2;
00430 result[Welt] = Math::cos( len1 );
00431
00432 return result;
00433 }
00434
00439 template <typename DATA_TYPE>
00440 Quat<DATA_TYPE>& log( Quat<DATA_TYPE>& result )
00441 {
00442 DATA_TYPE length;
00443
00444 length = Math::sqrt( result[Xelt] * result[Xelt] +
00445 result[Yelt] * result[Yelt] +
00446 result[Zelt] * result[Zelt] );
00447
00448
00449 if (Math::isEqual( result[Welt], (DATA_TYPE)0.0, (DATA_TYPE)0.00001 ) == false)
00450 length = Math::aTan( length / result[Welt] );
00451 else
00452 length = Math::PI_OVER_2;
00453
00454 result[Welt] = (DATA_TYPE)0.0;
00455 result[Xelt] = result[Xelt] * length;
00456 result[Yelt] = result[Yelt] * length;
00457 result[Zelt] = result[Zelt] * length;
00458 return result;
00459 }
00460
00462 template <typename DATA_TYPE>
00463 void squad( Quat<DATA_TYPE>& result, DATA_TYPE t, const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2, const Quat<DATA_TYPE>& a, const Quat<DATA_TYPE>& b )
00464 {
00465 gmtlASSERT( false );
00466 }
00467
00469 template <typename DATA_TYPE>
00470 void meanTangent( Quat<DATA_TYPE>& result, const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2, const Quat<DATA_TYPE>& q3 )
00471 {
00472 gmtlASSERT( false );
00473 }
00474
00475
00476
00496 template <typename DATA_TYPE>
00497 Quat<DATA_TYPE>& slerp( Quat<DATA_TYPE>& result, const DATA_TYPE t, const Quat<DATA_TYPE>& from, const Quat<DATA_TYPE>& to, bool adjustSign=true)
00498 {
00499 const Quat<DATA_TYPE>& p = from;
00500
00501
00502 DATA_TYPE cosom = dot( from, to );
00503
00504
00505 Quat<DATA_TYPE> q;
00506 if (adjustSign && (cosom < (DATA_TYPE)0.0))
00507 {
00508 cosom = -cosom;
00509 q[0] = -to[0];
00510 q[1] = -to[1];
00511 q[2] = -to[2];
00512 q[3] = -to[3];
00513 }
00514 else
00515 {
00516 q = to;
00517 }
00518
00519
00520 DATA_TYPE sclp, sclq;
00521 if (((DATA_TYPE)1.0 - cosom) > (DATA_TYPE)0.0001)
00522 {
00523
00524 DATA_TYPE omega, sinom;
00525 omega = gmtl::Math::aCos( cosom );
00526 sinom = gmtl::Math::sin( omega );
00527 sclp = gmtl::Math::sin( ((DATA_TYPE)1.0 - t) * omega ) / sinom;
00528 sclq = gmtl::Math::sin( t * omega ) / sinom;
00529 }
00530 else
00531 {
00532
00533 sclp = (DATA_TYPE)1.0 - t;
00534 sclq = t;
00535 }
00536
00537 result[Xelt] = sclp * p[Xelt] + sclq * q[Xelt];
00538 result[Yelt] = sclp * p[Yelt] + sclq * q[Yelt];
00539 result[Zelt] = sclp * p[Zelt] + sclq * q[Zelt];
00540 result[Welt] = sclp * p[Welt] + sclq * q[Welt];
00541 return result;
00542 }
00543
00553 template <typename DATA_TYPE>
00554 Quat<DATA_TYPE>& lerp( Quat<DATA_TYPE>& result, const DATA_TYPE t, const Quat<DATA_TYPE>& from, const Quat<DATA_TYPE>& to)
00555 {
00556
00557 const Quat<DATA_TYPE>& p = from;
00558
00559
00560 DATA_TYPE cosom = dot( from, to );
00561
00562
00563 Quat<DATA_TYPE> q;
00564 if (cosom < (DATA_TYPE)0.0)
00565 {
00566 q[0] = -to[0];
00567 q[1] = -to[1];
00568 q[2] = -to[2];
00569 q[3] = -to[3];
00570 }
00571 else
00572 {
00573 q = to;
00574 }
00575
00576
00577 DATA_TYPE sclp, sclq;
00578 sclp = (DATA_TYPE)1.0 - t;
00579 sclq = t;
00580
00581 result[Xelt] = sclp * p[Xelt] + sclq * q[Xelt];
00582 result[Yelt] = sclp * p[Yelt] + sclq * q[Yelt];
00583 result[Zelt] = sclp * p[Zelt] + sclq * q[Zelt];
00584 result[Welt] = sclp * p[Welt] + sclq * q[Welt];
00585 return result;
00586 }
00587
00598 template <typename DATA_TYPE>
00599 inline bool operator==( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00600 {
00601 return bool( q1[0] == q2[0] &&
00602 q1[1] == q2[1] &&
00603 q1[2] == q2[2] &&
00604 q1[3] == q2[3] );
00605 }
00606
00610 template <typename DATA_TYPE>
00611 inline bool operator!=( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2 )
00612 {
00613 return !operator==( q1, q2 );
00614 }
00615
00618 template <typename DATA_TYPE>
00619 bool isEqual( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2, DATA_TYPE tol = 0.0 )
00620 {
00621 return bool( Math::isEqual( q1[0], q2[0], tol ) &&
00622 Math::isEqual( q1[1], q2[1], tol ) &&
00623 Math::isEqual( q1[2], q2[2], tol ) &&
00624 Math::isEqual( q1[3], q2[3], tol ) );
00625 }
00626
00632 template <typename DATA_TYPE>
00633 bool isEquiv( const Quat<DATA_TYPE>& q1, const Quat<DATA_TYPE>& q2, DATA_TYPE tol = 0.0 )
00634 {
00635 return bool( isEqual( q1, q2, tol ) || isEqual( q1, -q2, tol ) );
00636 }
00637
00639 }
00640
00641 #endif