xsi_quaternionf.h Source File
 
 
 
xsi_quaternionf.h
Go to the documentation of this file.
00001 //*****************************************************************************
00011 //*****************************************************************************
00012 #ifndef __XSIQUATERNIONF_H__
00013 #define __XSIQUATERNIONF_H__
00014 
00015 #include "sicppsdk.h"
00016 #include "xsi_vector4f.h"
00017 #include "xsi_vector3f.h"
00018 
00019 namespace XSI {
00020 
00021 namespace MATH {
00022 
00023 class CRotation3f;
00024 
00025 //*****************************************************************************
00036 //*****************************************************************************
00037 class SICPPSDKDECL CQuaternionf
00038 {
00039 public:
00044         SICPPSDK_INLINE CQuaternionf();
00045 
00049         SICPPSDK_INLINE CQuaternionf( const CQuaternionf& in_quaternion );
00050 
00052         ~CQuaternionf() {};
00053 
00058         SICPPSDK_INLINE CQuaternionf & operator=( const CQuaternionf & in_quaternion);
00059 
00066         SICPPSDK_INLINE CQuaternionf( const float in_W, const float in_X, const float in_Y, const float in_Z );
00067 
00072         SICPPSDK_INLINE CQuaternionf( const CVector3f& in_vct );
00073 
00077         SICPPSDK_INLINE CQuaternionf( const CVector4f& in_vct );
00078 
00084         SICPPSDK_INLINE bool Equals( const CQuaternionf &in_Quat ) const;
00085 
00091         SICPPSDK_INLINE bool EpsilonEquals( const CQuaternionf& in_quat, const float in_fEpsilon ) const;
00092 
00098         SICPPSDK_INLINE bool operator == ( const CQuaternionf &in_Quat ) const;
00099 
00107         SICPPSDK_INLINE bool operator < ( const CQuaternionf& in_Quat ) const;
00108 
00114         SICPPSDK_INLINE CQuaternionf& operator *= ( const CQuaternionf &in_Quat );
00115 
00121         SICPPSDK_INLINE CQuaternionf& Mul( const CQuaternionf &in_Quat );
00122 
00128         SICPPSDK_INLINE CQuaternionf& Mul( const CQuaternionf &in_Quat1, const CQuaternionf &in_Quat2);
00129 
00134         SICPPSDK_INLINE float Dot( const CQuaternionf& in_quat1 ) const;
00135 
00142         SICPPSDK_INLINE CQuaternionf& Slerp( const CQuaternionf& in_quatStart, const CQuaternionf& in_quatEnd, const float in_fU );
00143 
00149         SICPPSDK_INLINE CQuaternionf& operator -= ( const CQuaternionf &in_Quat );
00150 
00156         SICPPSDK_INLINE CQuaternionf& SubInPlace( const CQuaternionf &in_Quat );
00157 
00164         SICPPSDK_INLINE CQuaternionf& Sub( const CQuaternionf &in_Quat1,  const CQuaternionf &in_Quat2);
00165 
00170         SICPPSDK_INLINE CQuaternionf& NegateInPlace();
00171 
00177         SICPPSDK_INLINE CQuaternionf& Negate( const CQuaternionf &in_Quat);
00178 
00183         SICPPSDK_INLINE float GetSquaredLength() const;
00184 
00189         SICPPSDK_INLINE float GetLength() const;
00190 
00195         SICPPSDK_INLINE CQuaternionf& operator += ( const CQuaternionf &in_Quat);
00196 
00201         SICPPSDK_INLINE CQuaternionf& AddInPlace( const CQuaternionf &in_Quat );
00202 
00209         SICPPSDK_INLINE CQuaternionf& Add( const CQuaternionf &in_Quat1,  const CQuaternionf &in_Quat2);
00210 
00215         SICPPSDK_INLINE CQuaternionf& ConjugateInPlace();
00216 
00222         SICPPSDK_INLINE CQuaternionf& Conjugate( const CQuaternionf &in_Quat);
00223 
00228         SICPPSDK_INLINE CQuaternionf& InvertInPlace();
00229 
00235         SICPPSDK_INLINE CQuaternionf& Invert( const CQuaternionf &in_Quat);
00236 
00240         SICPPSDK_INLINE CQuaternionf& SetIdentity();
00241 
00246         SICPPSDK_INLINE CQuaternionf& Copy( const CQuaternionf &in_Quat );
00247 
00251         SICPPSDK_INLINE CQuaternionf& NormalizeInPlace();
00252 
00259         SICPPSDK_INLINE void Get( float &out_W, float &out_X, float &out_Y, float &out_Z ) const;
00260 
00264         SICPPSDK_INLINE CVector3f GetVector3() const;
00265 
00269         SICPPSDK_INLINE CVector4f GetVector4() const;
00270 
00274         SICPPSDK_INLINE void Get( CVector4f &io_XYZWVector ) const;
00275 
00283         SICPPSDK_INLINE CQuaternionf& Set( float in_W,  float in_X,  float in_Y,  float in_Z);
00284 
00290         SICPPSDK_INLINE CQuaternionf& Set( const CVector3f &in_XYZVector );
00291 
00297         SICPPSDK_INLINE CQuaternionf& Set( const CVector4f &in_XYZWVector );
00298 
00305         SICPPSDK_INLINE float GetValue( short in_nIndex ) const;
00306 
00314         SICPPSDK_INLINE CQuaternionf& SetValue( short in_nIndex, float newVal);
00315 
00319         SICPPSDK_INLINE float GetW() const;
00320 
00325         SICPPSDK_INLINE CQuaternionf& PutW( float newVal);
00326 
00330         SICPPSDK_INLINE float GetZ() const;
00331 
00336         SICPPSDK_INLINE CQuaternionf& PutZ( float newVal);
00337 
00341         SICPPSDK_INLINE float GetY() const;
00342 
00347         SICPPSDK_INLINE CQuaternionf& PutY( float newVal);
00348 
00352         SICPPSDK_INLINE float GetX() const;
00353 
00358         SICPPSDK_INLINE CQuaternionf& PutX( float newVal);
00359 
00366         SICPPSDK_INLINE bool operator !=(const CQuaternionf & in_quat ) const;
00367 
00368 private:
00369         float m_W, m_X, m_Y, m_Z;
00370 };
00371 
00372 //inline functions
00373 SICPPSDK_INLINE CQuaternionf::CQuaternionf()
00374 {
00375         SetIdentity();
00376 }
00377 
00378 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const CQuaternionf& in_quaternion)
00379 {
00380         *this = in_quaternion;
00381 }
00382 
00383 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator=( const CQuaternionf & in_Quat )
00384 {
00385         m_W = in_Quat.m_W;
00386         m_X = in_Quat.m_X;
00387         m_Y = in_Quat.m_Y;
00388         m_Z = in_Quat.m_Z;
00389 
00390         return *this;
00391 }
00392 
00393 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const float in_W, const float in_X, const float in_Y, const float in_Z )
00394 {
00395         Set( in_W, in_X, in_Y, in_Z );
00396 }
00397 
00398 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const XSI::MATH::CVector3f& in_vct )
00399 {
00400         Set( in_vct );
00401 }
00402 
00403 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const XSI::MATH::CVector4f& in_vct )
00404 {
00405         Set( in_vct );
00406 }
00407 
00408 SICPPSDK_INLINE bool CQuaternionf::Equals( const CQuaternionf &in_Quat ) const
00409 {
00410         return (this == &in_Quat) ? true :
00411                 (m_W == in_Quat.m_W &&
00412                 m_X == in_Quat.m_X &&
00413                 m_Y == in_Quat.m_Y &&
00414                 m_Z == in_Quat.m_Z );
00415 }
00416 
00417 SICPPSDK_INLINE bool CQuaternionf::operator == ( const CQuaternionf &in_Quat ) const
00418 {
00419         return Equals(in_Quat);
00420 }
00421 
00422 SICPPSDK_INLINE bool CQuaternionf::operator < ( const CQuaternionf& in_Quat) const
00423 {
00424         if ( m_W != in_Quat.m_W ) return m_W < in_Quat.m_W;
00425         if ( m_Z != in_Quat.m_Z ) return m_Z < in_Quat.m_Z;
00426         if ( m_Y != in_Quat.m_Y ) return m_Y < in_Quat.m_Y;
00427         if ( m_X != in_Quat.m_X ) return m_X < in_Quat.m_X;
00428         return false;
00429 }
00430 
00431 SICPPSDK_INLINE bool CQuaternionf::operator != ( const CQuaternionf &in_Quat ) const
00432 {
00433         return ! Equals( in_Quat );
00434 }
00435 
00436 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator *= ( const CQuaternionf &in_Quat )
00437 {
00438 
00439         return Mul(*this, in_Quat);
00440 }
00441 
00442 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Mul( const CQuaternionf &in_Quat )
00443 {
00444         return Mul(*this, in_Quat);
00445 }
00446 
00447 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Mul
00448 (
00449         const CQuaternionf &in_Quat1,
00450         const CQuaternionf &in_Quat2
00451 )
00452 {
00453         float dW, dX, dY, dZ;
00454 
00455         dW = in_Quat1.m_W * in_Quat2.m_W - in_Quat1.m_X * in_Quat2.m_X -
00456                 in_Quat1.m_Y * in_Quat2.m_Y - in_Quat1.m_Z * in_Quat2.m_Z ;
00457 
00458         dX = in_Quat1.m_W * in_Quat2.m_X + in_Quat2.m_W * in_Quat1.m_X +
00459                 in_Quat1.m_Y * in_Quat2.m_Z - in_Quat2.m_Y * in_Quat1.m_Z ;
00460 
00461         dY = in_Quat1.m_W * in_Quat2.m_Y + in_Quat2.m_W * in_Quat1.m_Y -
00462                 in_Quat1.m_X * in_Quat2.m_Z + in_Quat2.m_X * in_Quat1.m_Z ;
00463 
00464         dZ = in_Quat1.m_W * in_Quat2.m_Z + in_Quat2.m_W * in_Quat1.m_Z +
00465                 in_Quat1.m_X * in_Quat2.m_Y - in_Quat2.m_X * in_Quat1.m_Y ;
00466 
00467         m_W = dW; m_X = dX; m_Y = dY; m_Z = dZ;
00468 
00469         return *this;
00470 }
00471 
00472 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator -= ( const CQuaternionf &in_Quat )
00473 {
00474         return Sub(*this, in_Quat );
00475 }
00476 
00477 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SubInPlace( const CQuaternionf &in_Quat )
00478 {
00479         return Sub(*this, in_Quat );
00480 }
00481 
00482 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Sub
00483 (
00484         const CQuaternionf &in_Quat1,
00485         const CQuaternionf &in_Quat2
00486 )
00487 {
00488         m_W = in_Quat1.m_W - in_Quat2.m_W;
00489         m_X = in_Quat1.m_X - in_Quat2.m_X;
00490         m_Y = in_Quat1.m_Y - in_Quat2.m_Y;
00491         m_Z = in_Quat1.m_Z - in_Quat2.m_Z;
00492 
00493         return *this;
00494 }
00495 
00496 SICPPSDK_INLINE CQuaternionf& CQuaternionf::NegateInPlace()
00497 {
00498    return Negate(*this);
00499 }
00500 
00501 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Negate( const CQuaternionf &in_Quat)
00502 {
00503    m_W = -(in_Quat.m_W);
00504    m_X = -(in_Quat.m_X);
00505    m_Y = -(in_Quat.m_Y);
00506    m_Z = -(in_Quat.m_Z);
00507 
00508    return( *this );
00509 }
00510 
00511 SICPPSDK_INLINE float CQuaternionf::GetSquaredLength() const
00512 {
00513         return( m_W * m_W + m_X * m_X + m_Y * m_Y + m_Z * m_Z );
00514 }
00515 
00516 SICPPSDK_INLINE float CQuaternionf::GetLength() const
00517 {
00518         return( sqrt( GetSquaredLength() ) );
00519 }
00520 
00521 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator += ( const CQuaternionf &in_Quat)
00522 {
00523         return Add( *this,  in_Quat );
00524 }
00525 
00526 SICPPSDK_INLINE CQuaternionf& CQuaternionf::AddInPlace( const CQuaternionf &in_Quat )
00527 {
00528         return Add( *this,  in_Quat );
00529 }
00530 
00531 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Add
00532 (
00533         const CQuaternionf &in_Quat1,
00534         const CQuaternionf &in_Quat2
00535 )
00536 {
00537         m_W = in_Quat1.m_W + in_Quat2.m_W;
00538         m_X = in_Quat1.m_X + in_Quat2.m_X;
00539         m_Y = in_Quat1.m_Y + in_Quat2.m_Y;
00540         m_Z = in_Quat1.m_Z + in_Quat2.m_Z;
00541         return *this;
00542 }
00543 
00544 SICPPSDK_INLINE CQuaternionf& CQuaternionf::ConjugateInPlace()
00545 {
00546         return Conjugate(*this);
00547 }
00548 
00549 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Conjugate( const CQuaternionf &in_Quat)
00550 {
00551         m_W = in_Quat.m_W;
00552         m_X = -in_Quat.m_X;
00553         m_Y = -in_Quat.m_Y;
00554         m_Z = -in_Quat.m_Z;
00555 
00556         return( *this );
00557 }
00558 
00559 SICPPSDK_INLINE CQuaternionf& CQuaternionf::InvertInPlace()
00560 {
00561         return Invert(*this);
00562 }
00563 
00564 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Invert( const CQuaternionf &in_Quat)
00565 {
00566         return Conjugate(in_Quat);
00567 }
00568 
00569 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SetIdentity()
00570 {
00571         m_W = 1.0;
00572         m_X = m_Y = m_Z = 0.0;
00573 
00574         return( *this );
00575 }
00576 
00577 SICPPSDK_INLINE CQuaternionf&  CQuaternionf::Copy( const CQuaternionf &in_Quat )
00578 {
00579         return *this = in_Quat;
00580 }
00581 
00582 SICPPSDK_INLINE CVector3f CQuaternionf::GetVector3( ) const
00583 {
00584         return CVector3f( m_X, m_Y, m_Z);
00585 }
00586 
00587 SICPPSDK_INLINE CVector4f CQuaternionf::GetVector4( ) const
00588 {
00589         return CVector4f( m_X, m_Y, m_Z, m_W);
00590 }
00591 
00592 SICPPSDK_INLINE void CQuaternionf::Get
00593 (
00594         float &io_W,
00595         float &io_X,
00596         float &io_Y,
00597         float &io_Z
00598 ) const
00599 {
00600         io_W = m_W;
00601         io_X = m_X;
00602         io_Y = m_Y;
00603         io_Z = m_Z;
00604 }
00605 
00606 SICPPSDK_INLINE void CQuaternionf::Get( CVector4f &io_XYZWVector ) const
00607 {
00608         io_XYZWVector.Set( m_X, m_Y, m_Z, m_W);
00609 }
00610 
00611 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set
00612 (
00613         float in_W,
00614         float in_X,
00615         float in_Y,
00616         float in_Z
00617 )
00618 {
00619         m_W = in_W;
00620         m_X = in_X;
00621         m_Y = in_Y;
00622         m_Z = in_Z;
00623 
00624         return *this;
00625 }
00626 
00627 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set( const CVector3f &in_XYZVector )
00628 {
00629         m_W = 1.0;
00630         m_X = in_XYZVector.GetX();
00631         m_Y = in_XYZVector.GetY();
00632         m_Z = in_XYZVector.GetZ();
00633 
00634         return *this;
00635 }
00636 
00637 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set( const CVector4f &in_XYZWVector )
00638 {
00639         m_W = in_XYZWVector.GetW();
00640         m_X = in_XYZWVector.GetX();
00641         m_Y = in_XYZWVector.GetY();
00642         m_Z = in_XYZWVector.GetZ();
00643 
00644         return *this;
00645 }
00646 
00647 SICPPSDK_INLINE float CQuaternionf::GetValue( short in_nIndex ) const
00648 {
00649         assert(in_nIndex >= 0 && in_nIndex < 4);
00650 
00651         switch (in_nIndex)
00652         {
00653                 case 0: return m_W;
00654                 case 1: return m_X;
00655                 case 2: return m_Y;
00656                 case 3: return m_Z;
00657         }
00658 
00659         return 0.0; // invalid index, return 0.0
00660 }
00661 
00662 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SetValue( short in_nIndex,  float newVal)
00663 {
00664         assert(in_nIndex >= 0 && in_nIndex < 4);
00665 
00666         switch (in_nIndex)
00667         {
00668                 case 0:  m_W = newVal; break;
00669                 case 1:  m_X = newVal; break;
00670                 case 2:  m_Y = newVal; break;
00671                 case 3:  m_Z = newVal; break;
00672                 // note: do nothing when invalid index is provided
00673         }
00674 
00675         return *this;
00676 }
00677 
00678 SICPPSDK_INLINE float CQuaternionf::GetW() const
00679 {
00680         return m_W;
00681 }
00682 
00683 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutW( float newVal)
00684 {
00685         m_W = newVal;
00686 
00687         return *this;
00688 }
00689 
00690 SICPPSDK_INLINE float CQuaternionf::GetZ() const
00691 {
00692         return m_Z;
00693 }
00694 
00695 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutZ( float newVal)
00696 {
00697         m_Z = newVal;
00698         return *this;
00699 }
00700 
00701 SICPPSDK_INLINE float CQuaternionf::GetY() const
00702 {
00703         return m_Y;
00704 }
00705 
00706 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutY( float newVal)
00707 {
00708         m_Y = newVal;
00709         return *this;
00710 }
00711 
00712 
00713 SICPPSDK_INLINE float CQuaternionf::GetX() const
00714 {
00715         return m_X;
00716 }
00717 
00718 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutX( float newVal)
00719 {
00720         m_X = newVal;
00721         return *this;
00722 }
00723 
00724 SICPPSDK_INLINE CQuaternionf& CQuaternionf::NormalizeInPlace()
00725 {
00726    float rLen = GetSquaredLength();
00727 
00728    if( fabs( rLen - 1.0f ) >= PicoEPS )
00729    {
00730       if( rLen < PicoEPS )
00731       {
00732          m_X = m_Y = m_Z = 0.0;
00733          m_W = 1.0;
00734       }
00735       else
00736       {
00737          rLen = 1.0f / sqrt( rLen );
00738          m_W *= rLen;
00739          m_X *= rLen;
00740          m_Y *= rLen;
00741          m_Z *= rLen;
00742 
00743                  LimitValue( m_W, -1.0, 1.0 );
00744       }
00745    }
00746    else
00747    {
00748                 LimitValue( m_W, -1.0, 1.0 );
00749    }
00750 
00751    return( *this );
00752 }
00753 
00754 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Slerp
00755 (
00756         const CQuaternionf& in_quatStart,
00757         const CQuaternionf& in_quatEnd,
00758         const float                     in_fU
00759 )
00760 {
00761    float fDot, fScale1, fScale2;
00762    bool bNegate = false;
00763 
00764    fDot = in_quatStart.Dot( in_quatEnd );
00765    if ( fDot < 0.0 )
00766    {
00767       fDot = -fDot;
00768       bNegate = true;
00769    }
00770 
00771    if( fDot >= ( 1.0f - MicroEPS ) )
00772    {
00773       fScale1 = 1.0f - in_fU;
00774       fScale2 = in_fU;
00775    }
00776    else
00777    {
00778       float fAngle, fFactor;
00779 
00780       LimitValue( fDot, -1.0, 1.0 );
00781       fAngle = acos( fDot );
00782       fFactor = 1.0f / sin( fAngle );
00783 
00784       fScale1 = sin( (1.0f - in_fU) * fAngle ) * fFactor;
00785       fScale2 = sin( in_fU * fAngle ) * fFactor;
00786    }
00787 
00788    if( bNegate == true )
00789       fScale2 = -fScale2;
00790 
00791    m_W = fScale1 * in_quatStart.m_W + fScale2 * in_quatEnd.m_W;
00792    m_X = fScale1 * in_quatStart.m_X + fScale2 * in_quatEnd.m_X;
00793    m_Y = fScale1 * in_quatStart.m_Y + fScale2 * in_quatEnd.m_Y;
00794    m_Z = fScale1 * in_quatStart.m_Z + fScale2 * in_quatEnd.m_Z;
00795 
00796    return( *this );
00797 }
00798 
00799 SICPPSDK_INLINE float CQuaternionf::Dot( const CQuaternionf& in_quat ) const
00800 {
00801    return( GetW() * in_quat.GetW() +
00802            GetX() * in_quat.GetX() +
00803            GetY() * in_quat.GetY() +
00804            GetZ() * in_quat.GetZ() );
00805 }
00806 
00807 SICPPSDK_INLINE bool CQuaternionf::EpsilonEquals( const CQuaternionf& in_quat, const float in_fEpsilon ) const
00808 {
00809    return( fabs( GetW() - in_quat.GetW() ) < in_fEpsilon &&
00810            fabs( GetX() - in_quat.GetX() ) < in_fEpsilon &&
00811            fabs( GetY() - in_quat.GetY() ) < in_fEpsilon &&
00812            fabs( GetZ() - in_quat.GetZ() ) < in_fEpsilon );
00813 }
00814 
00815 };
00816 };
00817 
00818 #endif // __XSIQUATERNIONF_H__