"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSMathLib/Src/Quaternion/LSMQuaternion.h

00001 
00016 #ifndef __LSM_QUATERNION_H__
00017 #define __LSM_QUATERNION_H__
00018 
00019 #include "../LSMMathLib.h"
00020 #include "../Matrix/LSMMatrix4x4.h"
00021 #include "../Vector/LSMVector3.h"
00022 
00023 #pragma warning( push )
00024 
00025 // warning C4201: nonstandard extension used : nameless struct/union
00026 #pragma warning( disable : 4201 )
00027 
00028 
00029 namespace lsm {
00030 
00037         class CQuaternion {
00038         public :
00039                 // == Various constructors.
00040                 LSE_INLINE LSE_CALLCTOR                                 CQuaternion();
00041                 LSE_INLINE LSE_CALLCTOR                                 CQuaternion( LSREAL _fX, LSREAL _fY, LSREAL _fZ, LSREAL _fW );
00042                 LSE_INLINE LSE_CALLCTOR                                 CQuaternion( const CQuaternion &_qQuat );
00043 
00044 
00045                 // == Operators.
00052                 LSE_INLINE CQuaternion & LSE_FCALL              operator += ( const CQuaternion &_qQuat );
00053 
00060                 LSE_INLINE CQuaternion & LSE_FCALL              operator -= ( const CQuaternion &_qQuat );
00061 
00068                 LSE_INLINE CQuaternion & LSE_FCALL              operator *= ( const CQuaternion &_qQuat );
00069 
00076                 LSE_INLINE CQuaternion & LSE_FCALL              operator *= ( LSREAL _fVal );
00077 
00084                 LSE_INLINE CQuaternion & LSE_FCALL              operator /= ( LSREAL _fVal );
00085 
00091                 LSE_INLINE CQuaternion  LSE_FCALL               operator + () const;
00092 
00098                 LSE_INLINE CQuaternion  LSE_FCALL               operator - () const;
00099 
00106                 LSE_INLINE CQuaternion  LSE_FCALL               operator + ( const CQuaternion &_qQuat ) const;
00107                 
00114                 LSE_INLINE CQuaternion  LSE_FCALL               operator - ( const CQuaternion &_qQuat ) const;
00115 
00122                 LSE_INLINE CQuaternion  LSE_FCALL               operator * ( const CQuaternion &_qQuat ) const;
00123 
00130                 LSE_INLINE CQuaternion  LSE_FCALL               operator * ( LSREAL _fVal ) const;
00131 
00138                 LSE_INLINE CQuaternion  LSE_FCALL               operator / ( LSREAL _fVal ) const;
00139 
00146                 LSE_INLINE bool LSE_FCALL                               operator == ( const CQuaternion &_qQuat ) const;
00147 
00154                 LSE_INLINE bool LSE_FCALL                               operator != ( const CQuaternion &_qQuat ) const;
00155 
00162                 LSE_INLINE LSREAL & LSE_FCALL                   operator [] ( LSUINT32 _ui32Index );
00163 
00170                 LSE_INLINE LSREAL LSE_FCALL                             operator [] ( LSUINT32 _ui32Index ) const;
00171 
00172 
00173                 // == Functions.
00180                 LSE_INLINE CQuaternion & LSE_FCALL              Identity();
00181                 
00187                 LSE_INLINE CQuaternion LSE_FCALL                Conjugate() const;
00188                 
00195                 LSE_INLINE LSREAL LSE_FCALL                             Dot( const CQuaternion &_qQuat ) const;
00196                 
00202                 CQuaternion LSE_FCALL                                   Exp() const;
00203                 
00209                 CQuaternion LSE_FCALL                                   Log() const;
00210                 
00216                 LSE_INLINE LSREAL LSE_FCALL                             LenSq() const;
00217                 
00223                 LSE_INLINE LSREAL LSE_FCALL                             Len() const;
00224                 
00228                 LSE_INLINE LSVOID LSE_FCALL                             Normalize();
00229                 
00235                 LSE_INLINE CQuaternion LSE_FCALL                Inverse();
00236                 
00245                 LSE_INLINE CQuaternion & LSE_FCALL              Lerp( const CQuaternion &_qLeft, const CQuaternion &_qRight, LSREAL _fT );
00246                 
00255                 CQuaternion & LSE_FCALL                                 Slerp( const CQuaternion &_qLeft, const CQuaternion &_qRight, LSREAL _fT );
00256                 
00267                 CQuaternion & LSE_FCALL                                 Squad( const CQuaternion &_qQ, const CQuaternion &_qA, const CQuaternion &_qB, const CQuaternion &_qC, LSREAL _fT );
00268 
00275                 CQuaternion & LSE_FCALL                                 FromRotationMatrix( const CMatrix4x4 &_mMat );
00276                 
00283                 LSVOID LSE_FCALL                                                ToRotationMatrix( CMatrix4x4 &_mMat ) const;
00284 
00291                 CQuaternion & LSE_FCALL                                 FromRotationVectors( const CVector3 _vVectors[3] );
00292 
00300                 CQuaternion & LSE_FCALL                                 AddScaledVector( const CVector3 &_vVec, LSREAL _fTime );
00301                 
00307                 LSE_INLINE LSREAL & LSE_FCALL                   X();
00308                 
00314                 LSE_INLINE LSREAL & LSE_FCALL                   Y();
00315                 
00321                 LSE_INLINE LSREAL & LSE_FCALL                   Z();
00322                 
00328                 LSE_INLINE LSREAL & LSE_FCALL                   W();
00329 
00330                 // == Members.
00331 #pragma pack( push, 1 )
00332                 struct {
00336                         LSREAL                                                          x,
00337                                                                                                 y,
00338                                                                                                 z,
00339                                                                                                 w;
00340                 } u;
00341 #pragma pack( pop )
00342 
00343         protected :
00344                 static LSUINT32                                                 m_ui32Next[3];
00345         };
00346 
00347 
00348         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00349         // DEFINITIONS
00350         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00351         // == Various constructors.
00352         LSE_INLINE LSE_CALLCTOR CQuaternion::CQuaternion() {}
00353         LSE_INLINE LSE_CALLCTOR CQuaternion::CQuaternion( LSREAL _fX, LSREAL _fY, LSREAL _fZ, LSREAL _fW ) {
00354                 u.x = _fX;
00355                 u.y = _fY;
00356                 u.z = _fZ;
00357                 u.w = _fW;
00358         }
00359         LSE_INLINE LSE_CALLCTOR CQuaternion::CQuaternion( const CQuaternion &_qQuat ) {
00360                 u.x = _qQuat[0];
00361                 u.y = _qQuat[1];
00362                 u.z = _qQuat[2];
00363                 u.w = _qQuat[3];
00364         }
00365 
00366 
00367         // == Operators.
00374         LSE_INLINE CQuaternion & LSE_FCALL CQuaternion::operator += ( const CQuaternion &_qQuat ) {
00375                 u.x += _qQuat[0];
00376                 u.y += _qQuat[1];
00377                 u.z += _qQuat[2];
00378                 u.w += _qQuat[3];
00379                 return (*this);
00380         }
00381 
00388         LSE_INLINE CQuaternion & LSE_FCALL CQuaternion::operator -= ( const CQuaternion &_qQuat ) {
00389                 u.x -= _qQuat[0];
00390                 u.y -= _qQuat[1];
00391                 u.z -= _qQuat[2];
00392                 u.w -= _qQuat[3];
00393                 return (*this);
00394         }
00395 
00402         LSE_INLINE CQuaternion & LSE_FCALL CQuaternion::operator *= ( const CQuaternion &_qQuat ) {
00403                 CQuaternion qProd;
00404 
00405                 qProd[3] =
00406                         u.w * _qQuat[3] -
00407                         u.x * _qQuat[0] -
00408                         u.y * _qQuat[1] -
00409                         u.z * _qQuat[2];
00410 
00411                 qProd[0] =
00412                         u.w * _qQuat[0] +
00413                         u.x * _qQuat[3] +
00414                         u.y * _qQuat[2] -
00415                         u.z * _qQuat[1];
00416 
00417                 qProd[1] =
00418                         u.w * _qQuat[1] +
00419                         u.y * _qQuat[3] +
00420                         u.z * _qQuat[0] -
00421                         u.x * _qQuat[2];
00422 
00423                 qProd[2] =
00424                         u.w * _qQuat[2] +
00425                         u.z * _qQuat[3] +
00426                         u.x * _qQuat[1] -
00427                         u.y * _qQuat[0];
00428 
00429                 (*this) = qProd;
00430                 return (*this);
00431         }
00432 
00439         LSE_INLINE CQuaternion & LSE_FCALL CQuaternion::operator *= ( LSREAL _fVal ) {
00440                 u.x *= _fVal;
00441                 u.y *= _fVal;
00442                 u.z *= _fVal;
00443                 u.w *= _fVal;
00444                 return (*this);
00445         }
00446 
00453         LSE_INLINE CQuaternion & LSE_FCALL CQuaternion::operator /= ( LSREAL _fVal ) {
00454                 _fVal = LSM_ONE / _fVal;
00455                 u.x *= _fVal;
00456                 u.y *= _fVal;
00457                 u.z *= _fVal;
00458                 u.w *= _fVal;
00459                 return (*this);
00460         }
00461 
00462 
00468         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::operator + () const {
00469                 return CQuaternion( +u.x, +u.y, +u.z, +u.w );
00470         }
00471 
00477         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::operator - () const {
00478                 return CQuaternion( -u.x, -u.y, -u.z, -u.w );
00479         }
00480 
00481 
00488         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::operator + ( const CQuaternion &_qQuat ) const {
00489                 return CQuaternion( u.x + _qQuat.u.x, u.y + _qQuat.u.y, u.z + _qQuat.u.z, u.w + _qQuat.u.w );
00490         }
00491 
00498         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::operator - ( const CQuaternion &_qQuat ) const {
00499                 return CQuaternion( u.x - _qQuat.u.x, u.y - _qQuat.u.y, u.z - _qQuat.u.z, u.w - _qQuat.u.w );
00500         }
00501 
00508         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::operator * ( const CQuaternion &_qQuat ) const {
00509                 /*return CQuaternion( u.w * _qQuat.u.x +
00510                         u.x * _qQuat.u.w +
00511                         u.y * _qQuat.u.z -
00512                         u.z * _qQuat.u.y,
00513                         u.w * _qQuat.u.y +
00514                         u.y * _qQuat.u.w +
00515                         u.z * _qQuat.u.x -
00516                         u.x * _qQuat.u.z,
00517                         u.w * _qQuat.u.z +
00518                         u.z * _qQuat.u.w +
00519                         u.x * _qQuat.u.y -
00520                         u.y * _qQuat.u.x,
00521                         u.w * _qQuat.u.w -
00522                         u.x * _qQuat.u.x -
00523                         u.y * _qQuat.u.y -
00524                         u.z * _qQuat.u.z );*/
00525                 return CQuaternion( u.w * _qQuat.u.x +
00526                         u.x * _qQuat.u.w -
00527                         u.y * _qQuat.u.z -
00528                         u.z * _qQuat.u.y,
00529                         u.w * _qQuat.u.y -
00530                         u.x * _qQuat.u.z +
00531                         u.y * _qQuat.u.w -
00532                         u.z * _qQuat.u.x,
00533                         u.w * _qQuat.u.z +
00534                         u.x * _qQuat.u.y -
00535                         u.y * _qQuat.u.x +
00536                         u.z * _qQuat.u.w,
00537                         u.w * _qQuat.u.w -
00538                         u.x * _qQuat.u.x -
00539                         u.y * _qQuat.u.y -
00540                         u.z * _qQuat.u.z );
00541         }
00542 
00549         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::operator * ( LSREAL _fVal ) const {
00550                 return CQuaternion( u.x * _fVal, u.y * _fVal, u.z * _fVal, u.w * _fVal );
00551         }
00552 
00559         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::operator / ( LSREAL _fVal ) const {
00560                 register LSREAL fVal = LSM_ONE / _fVal;
00561                 return CQuaternion( u.x * fVal, u.y * fVal, u.z * fVal, u.w * fVal );
00562         }
00563 
00570         LSE_INLINE bool LSE_FCALL CQuaternion::operator == ( const CQuaternion &_qQuat ) const {
00571                 return u.x == _qQuat[0] && u.y == _qQuat[1] && u.z == _qQuat[2] && u.w == _qQuat[3];
00572         }
00573 
00580         LSE_INLINE bool LSE_FCALL CQuaternion::operator != ( const CQuaternion &_qQuat ) const {
00581                 return u.x != _qQuat[0] || u.y != _qQuat[1] || u.z != _qQuat[2] || u.w != _qQuat[3];
00582         }
00583 
00590         LSE_INLINE LSREAL & LSE_FCALL CQuaternion::operator [] ( LSUINT32 _ui32Index ) {
00591                 return reinterpret_cast<LSREAL *>(this)[_ui32Index];
00592         }
00593 
00600         LSE_INLINE LSREAL LSE_FCALL CQuaternion::operator [] ( LSUINT32 _ui32Index ) const {
00601                 return reinterpret_cast<const LSREAL *>(this)[_ui32Index];
00602         }
00603 
00604 
00611         LSE_INLINE CQuaternion & LSE_FCALL CQuaternion::Identity() {
00612                 u.x = u.y = u.z = LSM_ZERO;
00613                 u.w = LSM_ONE;
00614                 return (*this);
00615         }
00616 
00622         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::Conjugate() const {
00623                 return CQuaternion( -u.x, -u.y, -u.z, u.w );
00624         }
00625 
00632         LSE_INLINE LSREAL LSE_FCALL CQuaternion::Dot( const CQuaternion &_qQuat ) const {
00633                 return (u.x * _qQuat[0]) +
00634                         (u.y * _qQuat[1]) +
00635                         (u.z * _qQuat[2]) +
00636                         (u.w * _qQuat[3]);
00637         }
00638 
00644         LSE_INLINE LSREAL LSE_FCALL CQuaternion::LenSq() const {
00645                 return u.x * u.x +
00646                         u.y * u.y +
00647                         u.z * u.z +
00648                         u.w * u.w;
00649         }
00650 
00656         LSE_INLINE LSREAL LSE_FCALL CQuaternion::Len() const {
00657                 return CMathLib::Sqrt( u.x * u.x +
00658                         u.y * u.y +
00659                         u.z * u.z +
00660                         u.w * u.w );
00661         }
00662 
00666         LSE_INLINE LSVOID LSE_FCALL CQuaternion::Normalize() {
00667                 LSREAL fInvLen = CMathLib::InvSqrt( u.x * u.x +
00668                         u.y * u.y +
00669                         u.z * u.z +
00670                         u.w * u.w );
00671                 u.x *= fInvLen;
00672                 u.y *= fInvLen;
00673                 u.z *= fInvLen;
00674                 u.w *= fInvLen;
00675         }
00676 
00682         LSE_INLINE CQuaternion LSE_FCALL CQuaternion::Inverse() {
00683                 CQuaternion qRet;
00684 
00685                 LSREAL fInvLen = -CMathLib::InvSqrt( u.x * u.x +
00686                         u.y * u.y +
00687                         u.z * u.z +
00688                         u.w * u.w );
00689 
00690                 qRet[3] = u.w * -fInvLen;
00691                 qRet[0] = u.x * fInvLen;
00692                 qRet[1] = u.y * fInvLen;
00693                 qRet[2] = u.z * fInvLen;
00694 
00695                 return qRet;
00696         }
00697 
00706         LSE_INLINE CQuaternion & LSE_FCALL CQuaternion::Lerp( const CQuaternion &_qLeft, const CQuaternion &_qRight, LSREAL _fT ) {
00707                 (*this) = _qLeft + (_qRight - _qLeft) * _fT;
00708                 Normalize();
00709                 return (*this);
00710         }
00711 
00718         LSE_INLINE LSVOID LSE_FCALL CQuaternion::ToRotationMatrix( CMatrix4x4 &_mMat ) const {
00719                 LSREAL fTx  = LSM_TWO * u.x;
00720                 LSREAL fTy  = LSM_TWO * u.y;
00721                 LSREAL fTz  = LSM_TWO * u.z;
00722                 LSREAL fTwx = fTx * u.w;
00723                 LSREAL fTwy = fTy * u.w;
00724                 LSREAL fTwz = fTz * u.w;
00725                 LSREAL fTxx = fTx * u.x;
00726                 LSREAL fTxy = fTy * u.x;
00727                 LSREAL fTxz = fTz * u.x;
00728                 LSREAL fTyy = fTy * u.y;
00729                 LSREAL fTyz = fTz * u.y;
00730                 LSREAL fTzz = fTz * u.z;
00731 
00732                 _mMat( 0, 0 ) = LSM_ONE - (fTyy + fTzz);
00733                 _mMat( 1, 0 ) = fTxy - fTwz;
00734                 _mMat( 2, 0 ) = fTxz + fTwy;
00735                 _mMat( 0, 1 ) = fTxy + fTwz;
00736                 _mMat( 1, 1 ) = LSM_ONE - (fTxx + fTzz);
00737                 _mMat( 2, 1 ) = fTyz - fTwx;
00738                 _mMat( 0, 2 ) = fTxz - fTwy;
00739                 _mMat( 1, 2 ) = fTyz + fTwx;
00740                 _mMat( 2, 2 ) = LSM_ONE - (fTxx + fTyy);
00741         }
00742         
00748         LSE_INLINE LSREAL & LSE_FCALL CQuaternion::X() {
00749                 return u.x;
00750         }
00751         
00757         LSE_INLINE LSREAL & LSE_FCALL CQuaternion::Y() {
00758                 return u.y;
00759         }
00760         
00766         LSE_INLINE LSREAL & LSE_FCALL CQuaternion::Z() {
00767                 return u.z;
00768         }
00769         
00775         LSE_INLINE LSREAL & LSE_FCALL CQuaternion::W() {
00776                 return u.w;
00777         }
00778 
00779 }       // namespace lsm
00780 
00781 #pragma warning( pop )
00782 
00783 #endif  // __LSM_QUATERNION_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator