home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / idlib / math / Quat.h < prev    next >
C/C++ Source or Header  |  2005-11-14  |  9KB  |  379 lines

  1.  
  2. #ifndef __MATH_QUAT_H__
  3. #define __MATH_QUAT_H__
  4.  
  5. /*
  6. ===============================================================================
  7.  
  8.     Quaternion
  9.  
  10. ===============================================================================
  11. */
  12.  
  13.  
  14. class idVec3;
  15. class idAngles;
  16. class idRotation;
  17. class idMat3;
  18. class idMat4;
  19. class idCQuat;
  20.  
  21. class idQuat {
  22. public:
  23.     float            x;
  24.     float            y;
  25.     float            z;
  26.     float            w;
  27.  
  28.                     idQuat( void );
  29.                     idQuat( float x, float y, float z, float w );
  30.  
  31.     void             Set( float x, float y, float z, float w );
  32.  
  33.     float            operator[]( int index ) const;
  34.     float &            operator[]( int index );
  35.     idQuat            operator-() const;
  36.     idQuat &        operator=( const idQuat &a );
  37.     idQuat            operator+( const idQuat &a ) const;
  38.     idQuat &        operator+=( const idQuat &a );
  39.     idQuat            operator-( const idQuat &a ) const;
  40.     idQuat &        operator-=( const idQuat &a );
  41.     idQuat            operator*( const idQuat &a ) const;
  42.     idVec3            operator*( const idVec3 &a ) const;
  43.     idQuat            operator*( float a ) const;
  44.     idQuat &        operator*=( const idQuat &a );
  45.     idQuat &        operator*=( float a );
  46.  
  47.     friend idQuat    operator*( const float a, const idQuat &b );
  48.     friend idVec3    operator*( const idVec3 &a, const idQuat &b );
  49.  
  50.     bool            Compare( const idQuat &a ) const;                        // exact compare, no epsilon
  51.     bool            Compare( const idQuat &a, const float epsilon ) const;    // compare with epsilon
  52.     bool            operator==(    const idQuat &a ) const;                    // exact compare, no epsilon
  53.     bool            operator!=(    const idQuat &a ) const;                    // exact compare, no epsilon
  54.  
  55.     idQuat            Inverse( void ) const;
  56.     float            Length( void ) const;
  57.     idQuat &        Normalize( void );
  58.  
  59.     float            CalcW( void ) const;
  60.     int                GetDimension( void ) const;
  61.  
  62.     idAngles        ToAngles( void ) const;
  63.     idRotation        ToRotation( void ) const;
  64.     idMat3            ToMat3( void ) const;
  65.     idMat4            ToMat4( void ) const;
  66.     idCQuat            ToCQuat( void ) const;
  67.     idVec3            ToAngularVelocity( void ) const;
  68.     const float *    ToFloatPtr( void ) const;
  69.     float *            ToFloatPtr( void );
  70.     const char *    ToString( int precision = 2 ) const;
  71.  
  72.     idQuat &        Slerp( const idQuat &from, const idQuat &to, float t );
  73. };
  74.  
  75. ID_INLINE idQuat::idQuat( void ) {
  76. }
  77.  
  78. ID_INLINE idQuat::idQuat( float x, float y, float z, float w ) {
  79.     this->x = x;
  80.     this->y = y;
  81.     this->z = z;
  82.     this->w = w;
  83. }
  84.  
  85. ID_INLINE float idQuat::operator[]( int index ) const {
  86.     assert( ( index >= 0 ) && ( index < 4 ) );
  87.     return ( &x )[ index ];
  88. }
  89.  
  90. ID_INLINE float& idQuat::operator[]( int index ) {
  91.     assert( ( index >= 0 ) && ( index < 4 ) );
  92.     return ( &x )[ index ];
  93. }
  94.  
  95. ID_INLINE idQuat idQuat::operator-() const {
  96.     return idQuat( -x, -y, -z, -w );
  97. }
  98.  
  99. ID_INLINE idQuat &idQuat::operator=( const idQuat &a ) {
  100.     x = a.x;
  101.     y = a.y;
  102.     z = a.z;
  103.     w = a.w;
  104.  
  105.     return *this;
  106. }
  107.  
  108. ID_INLINE idQuat idQuat::operator+( const idQuat &a ) const {
  109.     return idQuat( x + a.x, y + a.y, z + a.z, w + a.w );
  110. }
  111.  
  112. ID_INLINE idQuat& idQuat::operator+=( const idQuat &a ) {
  113.     x += a.x;
  114.     y += a.y;
  115.     z += a.z;
  116.     w += a.w;
  117.  
  118.     return *this;
  119. }
  120.  
  121. ID_INLINE idQuat idQuat::operator-( const idQuat &a ) const {
  122.     return idQuat( x - a.x, y - a.y, z - a.z, w - a.w );
  123. }
  124.  
  125. ID_INLINE idQuat& idQuat::operator-=( const idQuat &a ) {
  126.     x -= a.x;
  127.     y -= a.y;
  128.     z -= a.z;
  129.     w -= a.w;
  130.  
  131.     return *this;
  132. }
  133.  
  134. ID_INLINE idQuat idQuat::operator*( const idQuat &a ) const {
  135.     return idQuat(    w*a.x + x*a.w + y*a.z - z*a.y,
  136.                     w*a.y + y*a.w + z*a.x - x*a.z,
  137.                     w*a.z + z*a.w + x*a.y - y*a.x,
  138.                     w*a.w - x*a.x - y*a.y - z*a.z );
  139. }
  140.  
  141. ID_INLINE idVec3 idQuat::operator*( const idVec3 &a ) const {
  142. #if 0
  143.     // it's faster to do the conversion to a 3x3 matrix and multiply the vector by this 3x3 matrix
  144.     return ( ToMat3() * a );
  145. #else
  146.     // result = this->Inverse() * idQuat( a.x, a.y, a.z, 0.0f ) * (*this)
  147.     float xx = x * x;
  148.     float zz = z * z;
  149.     float ww = w * w;
  150.     float yy = y * y;
  151.  
  152.     float xw2 = x*w*2.0f;
  153.     float xy2 = x*y*2.0f;
  154.     float xz2 = x*z*2.0f;
  155.     float yw2 = y*w*2.0f;
  156.     float yz2 = y*z*2.0f;
  157.     float zw2 = z*w*2.0f;
  158.  
  159.     return idVec3(
  160.         ( xx - yy - zz + ww )    * a.x    + ( xy2 + zw2 )            * a.y    + ( xz2 - yw2 )            * a.z,
  161.         ( xy2 - zw2 )            * a.x    + ( -xx + yy - zz + ww )* a.y    + ( yz2 + xw2 )            * a.z,
  162.         ( xz2 + yw2 )            * a.x    + ( yz2 - xw2 )            * a.y    + ( -xx - yy + zz + ww )* a.z );
  163. #endif
  164. }
  165.  
  166. ID_INLINE idQuat idQuat::operator*( float a ) const {
  167.     return idQuat( x * a, y * a, z * a, w * a );
  168. }
  169.  
  170. ID_INLINE idQuat operator*( const float a, const idQuat &b ) {
  171.     return b * a;
  172. }
  173.  
  174. ID_INLINE idVec3 operator*( const idVec3 &a, const idQuat &b ) {
  175.     return b * a;
  176. }
  177.  
  178. ID_INLINE idQuat& idQuat::operator*=( const idQuat &a ) {
  179.     *this = *this * a;
  180.  
  181.     return *this;
  182. }
  183.  
  184. ID_INLINE idQuat& idQuat::operator*=( float a ) {
  185.     x *= a;
  186.     y *= a;
  187.     z *= a;
  188.     w *= a;
  189.  
  190.     return *this;
  191. }
  192.  
  193. ID_INLINE bool idQuat::Compare( const idQuat &a ) const {
  194.     return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && ( w == a.w ) );
  195. }
  196.  
  197. ID_INLINE bool idQuat::Compare( const idQuat &a, const float epsilon ) const {
  198.     if ( idMath::Fabs( x - a.x ) > epsilon ) {
  199.         return false;
  200.     }
  201.     if ( idMath::Fabs( y - a.y ) > epsilon ) {
  202.         return false;
  203.     }
  204.     if ( idMath::Fabs( z - a.z ) > epsilon ) {
  205.         return false;
  206.     }
  207.     if ( idMath::Fabs( w - a.w ) > epsilon ) {
  208.         return false;
  209.     }
  210.     return true;
  211. }
  212.  
  213. ID_INLINE bool idQuat::operator==( const idQuat &a ) const {
  214.     return Compare( a );
  215. }
  216.  
  217. ID_INLINE bool idQuat::operator!=( const idQuat &a ) const {
  218.     return !Compare( a );
  219. }
  220.  
  221. ID_INLINE void idQuat::Set( float x, float y, float z, float w ) {
  222.     this->x = x;
  223.     this->y = y;
  224.     this->z = z;
  225.     this->w = w;
  226. }
  227.  
  228. ID_INLINE idQuat idQuat::Inverse( void ) const {
  229.     return idQuat( -x, -y, -z, w );
  230. }
  231.  
  232. ID_INLINE float idQuat::Length( void ) const {
  233.     float len;
  234.  
  235.     len = x * x + y * y + z * z + w * w;
  236.     return idMath::Sqrt( len );
  237. }
  238.  
  239. ID_INLINE idQuat& idQuat::Normalize( void ) {
  240.     float len;
  241.     float ilength;
  242.  
  243.     len = this->Length();
  244.     if ( len ) {
  245.         ilength = 1 / len;
  246.         x *= ilength;
  247.         y *= ilength;
  248.         z *= ilength;
  249.         w *= ilength;
  250.     }
  251.     return *this;
  252. }
  253.  
  254. ID_INLINE float idQuat::CalcW( void ) const {
  255.     // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1
  256.     return idMath::Sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) );
  257. }
  258.  
  259. ID_INLINE int idQuat::GetDimension( void ) const {
  260.     return 4;
  261. }
  262.  
  263. ID_INLINE const float *idQuat::ToFloatPtr( void ) const {
  264.     return &x;
  265. }
  266.  
  267. ID_INLINE float *idQuat::ToFloatPtr( void ) {
  268.     return &x;
  269. }
  270.  
  271.  
  272. /*
  273. ===============================================================================
  274.  
  275.     Compressed quaternion
  276.  
  277. ===============================================================================
  278. */
  279.  
  280. class idCQuat {
  281. public:
  282.     float            x;
  283.     float            y;
  284.     float            z;
  285.  
  286.                     idCQuat( void );
  287.                     idCQuat( float x, float y, float z );
  288.  
  289.     void             Set( float x, float y, float z );
  290.  
  291.     float            operator[]( int index ) const;
  292.     float &            operator[]( int index );
  293.  
  294.     bool            Compare( const idCQuat &a ) const;                        // exact compare, no epsilon
  295.     bool            Compare( const idCQuat &a, const float epsilon ) const;    // compare with epsilon
  296.     bool            operator==(    const idCQuat &a ) const;                    // exact compare, no epsilon
  297.     bool            operator!=(    const idCQuat &a ) const;                    // exact compare, no epsilon
  298.  
  299.     int                GetDimension( void ) const;
  300.  
  301.     idAngles        ToAngles( void ) const;
  302.     idRotation        ToRotation( void ) const;
  303.     idMat3            ToMat3( void ) const;
  304.     idMat4            ToMat4( void ) const;
  305.     idQuat            ToQuat( void ) const;
  306.     const float *    ToFloatPtr( void ) const;
  307.     float *            ToFloatPtr( void );
  308.     const char *    ToString( int precision = 2 ) const;
  309. };
  310.  
  311. ID_INLINE idCQuat::idCQuat( void ) {
  312. }
  313.  
  314. ID_INLINE idCQuat::idCQuat( float x, float y, float z ) {
  315.     this->x = x;
  316.     this->y = y;
  317.     this->z = z;
  318. }
  319.  
  320. ID_INLINE void idCQuat::Set( float x, float y, float z ) {
  321.     this->x = x;
  322.     this->y = y;
  323.     this->z = z;
  324. }
  325.  
  326. ID_INLINE float idCQuat::operator[]( int index ) const {
  327.     assert( ( index >= 0 ) && ( index < 3 ) );
  328.     return ( &x )[ index ];
  329. }
  330.  
  331. ID_INLINE float& idCQuat::operator[]( int index ) {
  332.     assert( ( index >= 0 ) && ( index < 3 ) );
  333.     return ( &x )[ index ];
  334. }
  335.  
  336. ID_INLINE bool idCQuat::Compare( const idCQuat &a ) const {
  337.     return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) );
  338. }
  339.  
  340. ID_INLINE bool idCQuat::Compare( const idCQuat &a, const float epsilon ) const {
  341.     if ( idMath::Fabs( x - a.x ) > epsilon ) {
  342.         return false;
  343.     }
  344.     if ( idMath::Fabs( y - a.y ) > epsilon ) {
  345.         return false;
  346.     }
  347.     if ( idMath::Fabs( z - a.z ) > epsilon ) {
  348.         return false;
  349.     }
  350.     return true;
  351. }
  352.  
  353. ID_INLINE bool idCQuat::operator==( const idCQuat &a ) const {
  354.     return Compare( a );
  355. }
  356.  
  357. ID_INLINE bool idCQuat::operator!=( const idCQuat &a ) const {
  358.     return !Compare( a );
  359. }
  360.  
  361. ID_INLINE int idCQuat::GetDimension( void ) const {
  362.     return 3;
  363. }
  364.  
  365. ID_INLINE idQuat idCQuat::ToQuat( void ) const {
  366.     // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1
  367.     return idQuat( x, y, z, idMath::Sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) ) );
  368. }
  369.  
  370. ID_INLINE const float *idCQuat::ToFloatPtr( void ) const {
  371.     return &x;
  372. }
  373.  
  374. ID_INLINE float *idCQuat::ToFloatPtr( void ) {
  375.     return &x;
  376. }
  377.  
  378. #endif /* !__MATH_QUAT_H__ */
  379.