00001
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "K3dQuaternion.h"
00035
00036 #define EQUIVALENT(a,b) (((a < b + K3dMath::EPSILON) && (a > b - K3dMath::EPSILON)) ? true : false)
00037
00038
00039
00040
00041
00042 K3dQuaternion::K3dQuaternion ( void )
00043 {
00044 }
00045
00046 K3dQuaternion::~K3dQuaternion ( void )
00047 {
00048 }
00049
00050 K3dQuaternion::K3dQuaternion ( float fX, float fY, float fZ, float fW )
00051 {
00052 m_afTuple[0] = fX;
00053 m_afTuple[1] = fY;
00054 m_afTuple[2] = fZ;
00055 m_afTuple[3] = fW;
00056 }
00057
00058 K3dQuaternion::K3dQuaternion ( K3dVector4 kVec4 )
00059 {
00060 m_afTuple[0] = kVec4[0];
00061 m_afTuple[1] = kVec4[1];
00062 m_afTuple[2] = kVec4[2];
00063 m_afTuple[3] = kVec4[3];
00064 }
00065
00066 K3dQuaternion::K3dQuaternion ( float afVector[4] )
00067 {
00068 for ( int i=0; i<4; i++ )
00069 {
00070 m_afTuple[i] = afVector[i];
00071 }
00072 }
00073
00074 K3dQuaternion::K3dQuaternion ( K3dQuaternion& rkQ )
00075 {
00076 memcpy ( m_afTuple,rkQ.m_afTuple,4*sizeof ( float ) );
00077 }
00078
00079 K3dQuaternion::K3dQuaternion ( K3dMatrix& rkRot )
00080 {
00081 FromRotationMatrix ( rkRot );
00082 }
00083
00084 K3dQuaternion::K3dQuaternion ( K3dVector3& rkAxis, float fAngle )
00085 {
00086 FromAxisAngle ( rkAxis,fAngle );
00087 }
00088
00089 K3dQuaternion::K3dQuaternion ( K3dVector3 akRotColumn[3] )
00090 {
00091 FromRotationMatrix ( akRotColumn );
00092 }
00093
00094 K3dQuaternion::operator const float* () const
00095 {
00096 return m_afTuple;
00097 }
00098
00099 K3dQuaternion::operator float* ()
00100 {
00101 return m_afTuple;
00102 }
00103
00104 float& K3dQuaternion::operator[] ( int i )
00105 {
00106 if ( ! ( 0 <= i && i < 4 ) )
00107 {
00108 cerr << "float K3dQuaternion::operator[] (int i) const -- Error index" << endl;
00109 }
00110 return m_afTuple[i];
00111 }
00112
00113 float K3dQuaternion::W () const
00114 {
00115 return m_afTuple[3];
00116 }
00117
00118 float& K3dQuaternion::W ()
00119 {
00120 return m_afTuple[3];
00121 }
00122
00123 float K3dQuaternion::X () const
00124 {
00125 return m_afTuple[0];
00126 }
00127
00128 float& K3dQuaternion::X ()
00129 {
00130 return m_afTuple[0];
00131 }
00132
00133 float K3dQuaternion::Y () const
00134 {
00135 return m_afTuple[1];
00136 }
00137
00138 float& K3dQuaternion::Y ()
00139 {
00140 return m_afTuple[1];
00141 }
00142
00143 float K3dQuaternion::Z () const
00144 {
00145 return m_afTuple[2];
00146 }
00147
00148 float& K3dQuaternion::Z ()
00149 {
00150 return m_afTuple[2];
00151 }
00152
00153 K3dQuaternion& K3dQuaternion::operator= ( K3dQuaternion& rkQ )
00154 {
00155 memcpy ( m_afTuple,rkQ.m_afTuple,4*sizeof ( float ) );
00156 return *this;
00157 }
00158
00159 bool K3dQuaternion::operator== ( K3dQuaternion& rkQ )
00160 {
00161 for ( int i = 0; i < 4; i++ )
00162 {
00163 if ( m_afTuple[i] != rkQ.m_afTuple[i] )
00164 return false;
00165 }
00166 return true;
00167 }
00168
00169 bool K3dQuaternion::operator!= ( K3dQuaternion& rkQ )
00170 {
00171 return !operator== ( rkQ );
00172 }
00173
00174 int K3dQuaternion::CompareArrays ( K3dQuaternion& rkQ )
00175 {
00176 for ( int i = 0; i < 4; i++ )
00177 {
00178 unsigned int uiTest0 = * ( unsigned int* ) &m_afTuple[i];
00179 unsigned int uiTest1 = * ( unsigned int* ) &rkQ.m_afTuple[i];
00180 if ( uiTest0 < uiTest1 )
00181 return -1;
00182 if ( uiTest0 > uiTest1 )
00183 return +1;
00184 }
00185 return 0;
00186 }
00187
00188 bool K3dQuaternion::operator< ( K3dQuaternion& rkQ )
00189 {
00190 return CompareArrays ( rkQ ) < 0;
00191 }
00192
00193 bool K3dQuaternion::operator<= ( K3dQuaternion& rkQ )
00194 {
00195 return CompareArrays ( rkQ ) <= 0;
00196 }
00197
00198 bool K3dQuaternion::operator> ( K3dQuaternion& rkQ )
00199 {
00200 return CompareArrays ( rkQ ) > 0;
00201 }
00202
00203 bool K3dQuaternion::operator>= ( K3dQuaternion& rkQ )
00204 {
00205 return CompareArrays ( rkQ ) >= 0;
00206 }
00207
00208 K3dQuaternion& K3dQuaternion::operator+ ( K3dQuaternion& rkQ )
00209 {
00210 for ( int i = 0; i < 4; i++ )
00211 m_afTuple[i] = m_afTuple[i] + rkQ.m_afTuple[i];
00212 return *this;
00213 }
00214
00215 K3dQuaternion& K3dQuaternion::operator- ( K3dQuaternion& rkQ )
00216 {
00217 for ( int i = 0; i < 4; i++ )
00218 m_afTuple[i] = m_afTuple[i] - rkQ.m_afTuple[i];
00219 return *this;
00220 }
00221
00223 K3dQuaternion& K3dQuaternion::operator* ( K3dQuaternion& rkQ )
00224 {
00225 K3dQuaternion kProd;
00226
00227 kProd.m_afTuple[0] =
00228 m_afTuple[0]*rkQ.m_afTuple[0] -
00229 m_afTuple[1]*rkQ.m_afTuple[1] -
00230 m_afTuple[2]*rkQ.m_afTuple[2] -
00231 m_afTuple[3]*rkQ.m_afTuple[3];
00232
00233 kProd.m_afTuple[1] =
00234 m_afTuple[0]*rkQ.m_afTuple[1] +
00235 m_afTuple[1]*rkQ.m_afTuple[0] +
00236 m_afTuple[2]*rkQ.m_afTuple[3] -
00237 m_afTuple[3]*rkQ.m_afTuple[2];
00238
00239 kProd.m_afTuple[2] =
00240 m_afTuple[0]*rkQ.m_afTuple[2] +
00241 m_afTuple[2]*rkQ.m_afTuple[0] +
00242 m_afTuple[3]*rkQ.m_afTuple[1] -
00243 m_afTuple[1]*rkQ.m_afTuple[3];
00244
00245 kProd.m_afTuple[3] =
00246 m_afTuple[0]*rkQ.m_afTuple[3] +
00247 m_afTuple[3]*rkQ.m_afTuple[0] +
00248 m_afTuple[1]*rkQ.m_afTuple[2] -
00249 m_afTuple[2]*rkQ.m_afTuple[1];
00250
00251 *this = kProd;
00252
00253 return *this;
00254 }
00255
00256 K3dQuaternion& K3dQuaternion::operator* ( float fScalar )
00257 {
00258 for ( int i = 0; i < 4; i++ )
00259 m_afTuple[i] = fScalar*m_afTuple[i];
00260 return *this;
00261 }
00262
00263 K3dQuaternion& K3dQuaternion::operator/ ( float fScalar )
00264 {
00265 int i;
00266
00267 if ( fScalar != ( float ) 0.0 )
00268 {
00269 float fInvScalar = ( ( float ) 1.0 ) /fScalar;
00270 for ( i = 0; i < 4; i++ )
00271 m_afTuple[i] = fInvScalar*m_afTuple[i];
00272 }
00273 else
00274 {
00275 for ( i = 0; i < 4; i++ )
00276 m_afTuple[i] = K3dMath::MAX_REAL;
00277 }
00278
00279 return *this;
00280 }
00281
00282 K3dQuaternion& K3dQuaternion::operator- ()
00283 {
00284 for ( int i = 0; i < 4; i++ )
00285 m_afTuple[i] = -m_afTuple[i];
00286 return *this;
00287 }
00288
00289 K3dQuaternion& K3dQuaternion::operator+= ( K3dQuaternion& rkQ )
00290 {
00291 for ( int i = 0; i < 4; i++ )
00292 m_afTuple[i] += rkQ.m_afTuple[i];
00293 return *this;
00294 }
00295
00296 K3dQuaternion& K3dQuaternion::operator-= ( K3dQuaternion& rkQ )
00297 {
00298 for ( int i = 0; i < 4; i++ )
00299 m_afTuple[i] -= rkQ.m_afTuple[i];
00300 return *this;
00301 }
00302
00303 K3dQuaternion& K3dQuaternion::operator*= ( float fScalar )
00304 {
00305 for ( int i = 0; i < 4; i++ )
00306 m_afTuple[i] *= fScalar;
00307 return *this;
00308 }
00309
00310 K3dQuaternion& K3dQuaternion::operator/= ( float fScalar )
00311 {
00312 int i;
00313
00314 if ( fScalar != ( float ) 0.0 )
00315 {
00316 float fInvScalar = ( ( float ) 1.0 ) /fScalar;
00317 for ( i = 0; i < 4; i++ )
00318 m_afTuple[i] *= fInvScalar;
00319 }
00320 else
00321 {
00322 for ( i = 0; i < 4; i++ )
00323 m_afTuple[i] = K3dMath::MAX_REAL;
00324 }
00325
00326 return *this;
00327 }
00328
00329 void K3dQuaternion::FromRotationMatrix ( K3dMatrix& rkRot )
00330 {
00331
00332
00333
00334 float fTrace = rkRot ( 0,0 ) + rkRot ( 1,1 ) + rkRot ( 2,2 );
00335 float fRoot;
00336
00337 if ( fTrace > ( float ) 0.0 )
00338 {
00339
00340 fRoot = K3dMath::Sqrt ( fTrace + ( float ) 1.0 );
00341 m_afTuple[0] = ( ( float ) 0.5 ) *fRoot;
00342 fRoot = ( ( float ) 0.5 ) /fRoot;
00343 m_afTuple[1] = ( rkRot ( 2,1 )-rkRot ( 1,2 ) ) *fRoot;
00344 m_afTuple[2] = ( rkRot ( 0,2 )-rkRot ( 2,0 ) ) *fRoot;
00345 m_afTuple[3] = ( rkRot ( 1,0 )-rkRot ( 0,1 ) ) *fRoot;
00346 }
00347 else
00348 {
00349
00350 int i = 0;
00351 if ( rkRot ( 1,1 ) > rkRot ( 0,0 ) )
00352 i = 1;
00353 if ( rkRot ( 2,2 ) > rkRot ( i,i ) )
00354 i = 2;
00355 int j = NEXT[i];
00356 int k = NEXT[j];
00357
00358 fRoot = K3dMath::Sqrt ( rkRot ( i,i )-rkRot ( j,j )-rkRot ( k,k ) + ( float ) 1.0 );
00359 float* apfQuat[3] = { &m_afTuple[1], &m_afTuple[2], &m_afTuple[3] };
00360 *apfQuat[i] = ( ( float ) 0.5 ) *fRoot;
00361 fRoot = ( ( float ) 0.5 ) /fRoot;
00362 m_afTuple[0] = ( rkRot ( k,j )-rkRot ( j,k ) ) *fRoot;
00363 *apfQuat[j] = ( rkRot ( j,i ) +rkRot ( i,j ) ) *fRoot;
00364 *apfQuat[k] = ( rkRot ( k,i ) +rkRot ( i,k ) ) *fRoot;
00365 }
00366 }
00367
00369 void K3dQuaternion::ToRotationMatrix ( K3dMatrix& _rkRot )
00370 {
00371 _rkRot[0] = ( 1.0f - 2.0f * m_afTuple[1] * m_afTuple[1] - 2.0f * m_afTuple[2] * m_afTuple[2] );
00372 _rkRot[1] = ( 2.0f * m_afTuple[0] * m_afTuple[1] + 2.0f * m_afTuple[3] * m_afTuple[2] );
00373 _rkRot[2] = ( 2.0f * m_afTuple[0] * m_afTuple[2] - 2.0f * m_afTuple[3] * m_afTuple[1] );
00374
00375 _rkRot[4] = ( 2.0f * m_afTuple[0] * m_afTuple[1] - 2.0f * m_afTuple[3] * m_afTuple[2] );
00376 _rkRot[5] = ( 1.0f - 2.0f * m_afTuple[0] * m_afTuple[0] - 2.0f * m_afTuple[2] * m_afTuple[2] );
00377 _rkRot[6] = ( 2.0f * m_afTuple[1] * m_afTuple[2] + 2.0f * m_afTuple[3] * m_afTuple[0] );
00378
00379 _rkRot[8] = ( 2.0f * m_afTuple[0] * m_afTuple[2] + 2.0f * m_afTuple[3] * m_afTuple[1] );
00380 _rkRot[9] = ( 2.0f * m_afTuple[1] * m_afTuple[2] - 2.0f * m_afTuple[3] * m_afTuple[0] );
00381 _rkRot[10] = ( 1.0f - 2.0f * m_afTuple[0] * m_afTuple[0] - 2.0f * m_afTuple[1] * m_afTuple[1] );
00382 }
00383
00384 void K3dQuaternion::FromRotationMatrix ( K3dVector3 akRotColumn[3] )
00385 {
00386 K3dMatrix kRot;
00387 for ( int iCol = 0; iCol < 3; iCol++ )
00388 {
00389 kRot ( 0,iCol ) = akRotColumn[iCol][0];
00390 kRot ( 1,iCol ) = akRotColumn[iCol][1];
00391 kRot ( 2,iCol ) = akRotColumn[iCol][2];
00392 }
00393 FromRotationMatrix ( kRot );
00394 }
00395
00396
00397 void K3dQuaternion::ToRotationMatrix ( K3dVector3 akRotColumn[3] )
00398 {
00399 K3dMatrix kRot;
00400 ToRotationMatrix ( kRot );
00401 for ( int iCol = 0; iCol < 3; iCol++ )
00402 {
00403 akRotColumn[iCol][0] = kRot ( 0,iCol );
00404 akRotColumn[iCol][1] = kRot ( 1,iCol );
00405 akRotColumn[iCol][2] = kRot ( 2,iCol );
00406 }
00407 }
00408
00409
00410
00412 void K3dQuaternion::FromAxisAngle ( K3dVector3 _kAngle )
00413 {
00414 float fAngle;
00415 K3dVector3 kSin, kCos;
00416
00417 fAngle = _kAngle[0] * 0.5f;
00418 kSin[0] = sin ( fAngle );
00419 kCos[0] = cos ( fAngle );
00420 fAngle = _kAngle[1] * 0.5f;
00421 kSin[1] = sin ( fAngle );
00422 kCos[1] = cos ( fAngle );
00423 fAngle = _kAngle[2] * 0.5f;
00424 kSin[2] = sin ( fAngle );
00425 kCos[2] = cos ( fAngle );
00426
00427 float fSqrCos = kCos[0] * kCos[1];
00428 float fSqrSin = kSin[0] * kSin[1];
00429
00430 m_afTuple[0] = ( float ) ( kSin[0] * kCos[1] * kCos[2] - kCos[0] * kSin[1] * kSin[2] );
00431 m_afTuple[1] = ( float ) ( kCos[0] * kSin[1] * kCos[2] + kSin[0] * kCos[1] * kSin[2] );
00432 m_afTuple[2] = ( float ) ( fSqrCos * kSin[2] - fSqrSin * kCos[2] );
00433 m_afTuple[3] = ( float ) ( fSqrCos * kCos[2] + fSqrSin * kSin[2] );
00434 }
00435
00437 void K3dQuaternion::FromAxisAngle ( K3dVector3& rkAxis, float fAngle )
00438 {
00439 float fHalfAngle = ( ( float ) 0.5 ) *fAngle;
00440 float fSin = K3dMath::Sin ( fHalfAngle );
00441 m_afTuple[0] = K3dMath::Cos ( fHalfAngle );
00442 m_afTuple[1] = fSin*rkAxis[0];
00443 m_afTuple[2] = fSin*rkAxis[1];
00444 m_afTuple[3] = fSin*rkAxis[2];
00445 }
00446
00448 void K3dQuaternion::ToAxisAngle ( K3dVector3& rkAxis, float& rfAngle )
00449 {
00450 float fSqrLength = m_afTuple[1]*m_afTuple[1] + m_afTuple[2]*m_afTuple[2]
00451 + m_afTuple[3]*m_afTuple[3];
00452 if ( fSqrLength > K3dMath::EPSILON )
00453 {
00454 rfAngle = ( ( float ) 2.0 ) *K3dMath::ACos ( m_afTuple[0] );
00455 float fInvLength = K3dMath::InvSqrt ( fSqrLength );
00456 rkAxis[0] = m_afTuple[1]*fInvLength;
00457 rkAxis[1] = m_afTuple[2]*fInvLength;
00458 rkAxis[2] = m_afTuple[3]*fInvLength;
00459 }
00460 else
00461 {
00462
00463 rfAngle = ( float ) 0.0;
00464 rkAxis[0] = ( float ) 1.0;
00465 rkAxis[1] = ( float ) 0.0;
00466 rkAxis[2] = ( float ) 0.0;
00467 }
00468 }
00469
00470 float K3dQuaternion::Dot ( K3dQuaternion& rkQ )
00471 {
00472 float fDot = ( float ) 0.0;
00473 for ( int i = 0; i < 4; i++ )
00474 fDot += m_afTuple[i]*rkQ.m_afTuple[i];
00475 return fDot;
00476 }
00477
00478 K3dQuaternion& K3dQuaternion::Inverse ()
00479 {
00480 K3dQuaternion kInverse;
00481
00482 float fNorm = ( float ) 0.0;
00483 int i;
00484 for ( i = 0; i < 4; i++ )
00485 fNorm += m_afTuple[i]*m_afTuple[i];
00486
00487 if ( fNorm > ( float ) 0.0 )
00488 {
00489 float fInvNorm = ( ( float ) 1.0 ) /fNorm;
00490 kInverse.m_afTuple[0] = m_afTuple[0]*fInvNorm;
00491 kInverse.m_afTuple[1] = -m_afTuple[1]*fInvNorm;
00492 kInverse.m_afTuple[2] = -m_afTuple[2]*fInvNorm;
00493 kInverse.m_afTuple[3] = -m_afTuple[3]*fInvNorm;
00494 }
00495 else
00496 {
00497
00498 for ( i = 0; i < 4; i++ )
00499 kInverse.m_afTuple[i] = ( float ) 0.0;
00500 }
00501 *this = kInverse;
00502 return *this;
00503
00504 }
00505
00506 K3dQuaternion& K3dQuaternion::Conjugate ()
00507 {
00508 m_afTuple[0] = - m_afTuple[0];
00509 m_afTuple[1] = - m_afTuple[1];
00510 m_afTuple[2] = - m_afTuple[2];
00511
00512 return *this;
00513 }
00514
00518 K3dQuaternion& K3dQuaternion::Exp ()
00519 {
00520 K3dQuaternion kResult;
00521
00522 float fAngle = K3dMath::Sqrt ( m_afTuple[1]*m_afTuple[1] +
00523 m_afTuple[2]*m_afTuple[2] + m_afTuple[3]*m_afTuple[3] );
00524
00525 float fSin = K3dMath::Sin ( fAngle );
00526 kResult.m_afTuple[0] = K3dMath::Cos ( fAngle );
00527
00528 int i;
00529
00530 if ( K3dMath::FAbs ( fSin ) >= K3dMath::EPSILON )
00531 {
00532 float fCoeff = fSin/fAngle;
00533 for ( i = 1; i <= 3; i++ )
00534 kResult.m_afTuple[i] = fCoeff*m_afTuple[i];
00535 }
00536 else
00537 {
00538 for ( i = 1; i <= 3; i++ )
00539 kResult.m_afTuple[i] = m_afTuple[i];
00540 }
00541 *this = kResult;
00542 return *this;
00543 }
00544
00548 K3dQuaternion& K3dQuaternion::Log ()
00549 {
00550 K3dQuaternion kResult;
00551 kResult.m_afTuple[0] = ( float ) 0.0;
00552
00553 int i;
00554
00555 if ( K3dMath::FAbs ( m_afTuple[0] ) < ( float ) 1.0 )
00556 {
00557 float fAngle = K3dMath::ACos ( m_afTuple[0] );
00558 float fSin = K3dMath::Sin ( fAngle );
00559 if ( K3dMath::FAbs ( fSin ) >= K3dMath::EPSILON )
00560 {
00561 float fCoeff = fAngle/fSin;
00562 for ( i = 1; i <= 3; i++ )
00563 kResult.m_afTuple[i] = fCoeff*m_afTuple[i];
00564 *this = kResult;
00565 return *this;
00566 }
00567 }
00568
00569 for ( i = 1; i <= 3; i++ )
00570 kResult.m_afTuple[i] = m_afTuple[i];
00571 *this = kResult;
00572 return *this;
00573 }
00574
00592 K3dVector3& K3dQuaternion::operator* ( K3dVector3& rkVector )
00593 {
00594 K3dMatrix kRot;
00595 ToRotationMatrix ( kRot );
00596 rkVector = kRot*rkVector;
00597 return rkVector;
00598 }
00599
00600
00601 K3dQuaternion& K3dQuaternion::Slerp ( float fT, K3dQuaternion& rkP, K3dQuaternion& rkQ )
00602 {
00603 float fCos = rkP.Dot ( rkQ );
00604 float fAngle = K3dMath::ACos ( fCos );
00605
00606 if ( K3dMath::FAbs ( fAngle ) < K3dMath::EPSILON )
00607 return rkP;
00608
00609 float fSin = K3dMath::Sin ( fAngle );
00610 float fInvSin = ( ( float ) 1.0 ) /fSin;
00611 float fCoeff0 = K3dMath::Sin ( ( ( ( float ) 1.0 )-fT ) *fAngle ) *fInvSin;
00612 float fCoeff1 = K3dMath::Sin ( fT*fAngle ) *fInvSin;
00613 rkP = rkP*fCoeff0;
00614 rkQ = rkQ*fCoeff1;
00615
00616 return rkP + rkQ;
00617 }
00618
00619
00620 K3dQuaternion& K3dQuaternion::SlerpExtraSpins ( float fT,
00621 K3dQuaternion& rkP, K3dQuaternion& rkQ, int iExtraSpins )
00622 {
00623 float fCos = rkP.Dot ( rkQ );
00624 float fAngle = K3dMath::ACos ( fCos );
00625
00626 if ( K3dMath::FAbs ( fAngle ) < K3dMath::EPSILON )
00627 return rkP;
00628
00629 float fSin = K3dMath::Sin ( fAngle );
00630 float fPhase = K3dMath::K_PI*iExtraSpins*fT;
00631 float fInvSin = ( ( float ) 1.0 ) /fSin;
00632 float fCoeff0 = K3dMath::Sin ( ( ( ( float ) 1.0 )-fT ) *fAngle-fPhase ) *fInvSin;
00633 float fCoeff1 = K3dMath::Sin ( fT*fAngle + fPhase ) *fInvSin;
00634 return rkP*fCoeff0 + rkQ*fCoeff1;
00635 }
00636
00637
00638 K3dQuaternion& K3dQuaternion::GetIntermediate ( K3dQuaternion& rkQ0,
00639 K3dQuaternion& rkQ1, K3dQuaternion& rkQ2 )
00640 {
00641 K3dQuaternion kQ1Inv = rkQ1.Conjugate();
00642 K3dQuaternion kP0 = kQ1Inv*rkQ0;
00643 K3dQuaternion kP2 = kQ1Inv*rkQ2;
00644 K3dQuaternion kArg = - ( ( kP0.Log() * ( float ) 0.25 ) +kP2.Log() );
00645 K3dQuaternion kA = rkQ1*kArg.Exp();
00646 *this = kA;
00647 return *this;
00648 }
00649
00650
00651 K3dQuaternion& K3dQuaternion::Squad ( float fT, K3dQuaternion& rkQ0,
00652 K3dQuaternion& rkA0, K3dQuaternion& rkA1, K3dQuaternion& rkQ1 )
00653 {
00654 float fSlerpT = ( ( float ) 2.0 ) *fT* ( ( ( float ) 1.0 )-fT );
00655 K3dQuaternion kSlerpP = Slerp ( fT,rkQ0,rkQ1 );
00656 K3dQuaternion kSlerpQ = Slerp ( fT,rkA0,rkA1 );
00657 return Slerp ( fSlerpT,kSlerpP,kSlerpQ );
00658 }
00659
00660
00662 void K3dQuaternion::GetValue ( K3dMatrix & rkMatrix )
00663 {
00664 float s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
00665
00666 float fNorm = m_afTuple[0] * m_afTuple[0] + m_afTuple[1] * m_afTuple[1] + m_afTuple[2] * m_afTuple[2] + m_afTuple[3] * m_afTuple[3];
00667
00668 s = ( EQUIVALENT ( fNorm, ( float ) 0 ) ) ? ( float ) 0 : ( ( float ) 2 / fNorm );
00669
00670 xs = m_afTuple[0] * s;
00671 ys = m_afTuple[1] * s;
00672 zs = m_afTuple[2] * s;
00673
00674 wx = m_afTuple[3] * xs;
00675 wy = m_afTuple[3] * ys;
00676 wz = m_afTuple[3] * zs;
00677
00678 xx = m_afTuple[0] * xs;
00679 xy = m_afTuple[0] * ys;
00680 xz = m_afTuple[0] * zs;
00681
00682 yy = m_afTuple[1] * ys;
00683 yz = m_afTuple[1] * zs;
00684 zz = m_afTuple[2] * zs;
00685
00686 rkMatrix ( 0,0 ) = float ( ( float ) 1 - ( yy + zz ) );
00687 rkMatrix ( 1,0 ) = float ( xy + wz );
00688 rkMatrix ( 2,0 ) = float ( xz - wy );
00689
00690 rkMatrix ( 0,1 ) = float ( xy - wz );
00691 rkMatrix ( 1,1 ) = float ( ( float ) 1 - ( xx + zz ) );
00692 rkMatrix ( 2,1 ) = float ( yz + wx );
00693
00694 rkMatrix ( 0,2 ) = float ( xz + wy );
00695 rkMatrix ( 1,2 ) = float ( yz - wx );
00696 rkMatrix ( 2,2 ) = float ( ( float ) 1 - ( xx + yy ) );
00697
00698 rkMatrix ( 3,0 ) = rkMatrix ( 3,1 ) = rkMatrix ( 3,2 ) = rkMatrix ( 0,3 ) = rkMatrix ( 1,3 ) = rkMatrix ( 2,3 ) = ( float ) 0;
00699 rkMatrix ( 3,3 ) = ( float ) 1;
00700 }
00701
00703
00704 const float K3dQuaternion::IDENTITY[4] = {1.0f,0.0f,0.0f,0.0f};
00705 const float K3dQuaternion::ZERO[4] = {0.0f,0.0f,0.0f,0.0f};
00706 const int K3dQuaternion::NEXT[3] = { 1, 2, 0 };
00707
00708