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 
00017 namespace XSI {
00018 
00019 namespace MATH {
00020 
00021 class CRotation3f;
00022 
00023 //*****************************************************************************
00034 //*****************************************************************************
00035 class SICPPSDKDECL CQuaternionf
00036 {
00037 public:
00042     SICPPSDK_INLINE CQuaternionf();
00043 
00047     SICPPSDK_INLINE CQuaternionf( const CQuaternionf& in_quaternion );
00048 
00050     ~CQuaternionf() {};
00051 
00056     SICPPSDK_INLINE CQuaternionf & operator=( const CQuaternionf & in_quaternion);
00057 
00064     SICPPSDK_INLINE CQuaternionf( const float in_W, const float in_X, const float in_Y, const float in_Z );
00065 
00070     SICPPSDK_INLINE CQuaternionf( const CVector3f& in_vct );
00071 
00075     SICPPSDK_INLINE CQuaternionf( const CVector4f& in_vct );
00076 
00082     SICPPSDK_INLINE bool Equals( const CQuaternionf &in_Quat ) const;
00083 
00089     SICPPSDK_INLINE bool EpsilonEquals( const CQuaternionf& in_quat, const float in_fEpsilon ) const;
00090 
00096     SICPPSDK_INLINE bool operator == ( const CQuaternionf &in_Quat ) const;
00097 
00105     SICPPSDK_INLINE bool operator < ( const CQuaternionf& in_Quat ) const;
00106 
00112     SICPPSDK_INLINE CQuaternionf& operator *= ( const CQuaternionf &in_Quat );
00113 
00119     SICPPSDK_INLINE CQuaternionf& Mul( const CQuaternionf &in_Quat );
00120 
00126     SICPPSDK_INLINE CQuaternionf& Mul( const CQuaternionf &in_Quat1, const CQuaternionf &in_Quat2);
00127 
00132     SICPPSDK_INLINE float Dot( const CQuaternionf& in_quat1 ) const;
00133 
00140     SICPPSDK_INLINE CQuaternionf& Slerp( const CQuaternionf& in_quatStart, const CQuaternionf& in_quatEnd, const float in_fU );
00141 
00147     SICPPSDK_INLINE CQuaternionf& operator -= ( const CQuaternionf &in_Quat );
00148 
00154     SICPPSDK_INLINE CQuaternionf& SubInPlace( const CQuaternionf &in_Quat );
00155 
00162     SICPPSDK_INLINE CQuaternionf& Sub( const CQuaternionf &in_Quat1,  const CQuaternionf &in_Quat2);
00163 
00168     SICPPSDK_INLINE CQuaternionf& NegateInPlace();
00169 
00175     SICPPSDK_INLINE CQuaternionf& Negate( const CQuaternionf &in_Quat);
00176 
00181     SICPPSDK_INLINE float GetSquaredLength() const;
00182 
00187     SICPPSDK_INLINE float GetLength() const;
00188 
00193     SICPPSDK_INLINE CQuaternionf& operator += ( const CQuaternionf &in_Quat);
00194 
00199     SICPPSDK_INLINE CQuaternionf& AddInPlace( const CQuaternionf &in_Quat );
00200 
00207     SICPPSDK_INLINE CQuaternionf& Add( const CQuaternionf &in_Quat1,  const CQuaternionf &in_Quat2);
00208 
00213     SICPPSDK_INLINE CQuaternionf& ConjugateInPlace();
00214 
00220     SICPPSDK_INLINE CQuaternionf& Conjugate( const CQuaternionf &in_Quat);
00221 
00226     SICPPSDK_INLINE CQuaternionf& InvertInPlace();
00227 
00233     SICPPSDK_INLINE CQuaternionf& Invert( const CQuaternionf &in_Quat);
00234 
00238     SICPPSDK_INLINE CQuaternionf& SetIdentity();
00239 
00244     SICPPSDK_INLINE CQuaternionf& Copy( const CQuaternionf &in_Quat );
00245 
00249     SICPPSDK_INLINE CQuaternionf& NormalizeInPlace();
00250 
00257     SICPPSDK_INLINE void Get( float &out_W, float &out_X, float &out_Y, float &out_Z ) const;
00258 
00262     SICPPSDK_INLINE CVector3f Get() const;
00263 
00267     SICPPSDK_INLINE void Get( CVector4f &io_XYZWVector ) const;
00268 
00276     SICPPSDK_INLINE CQuaternionf& Set( float in_W,  float in_X,  float in_Y,  float in_Z);
00277 
00283     SICPPSDK_INLINE CQuaternionf& Set( const CVector3f &in_XYZVector );
00284 
00290     SICPPSDK_INLINE CQuaternionf& Set( const CVector4f &in_XYZWVector );
00291 
00298     SICPPSDK_INLINE float GetValue( short in_nIndex ) const;
00299 
00307     SICPPSDK_INLINE CQuaternionf& SetValue( short in_nIndex, float newVal);
00308 
00312     SICPPSDK_INLINE float GetW() const;
00313 
00318     SICPPSDK_INLINE CQuaternionf& PutW( float newVal);
00319 
00323     SICPPSDK_INLINE float GetZ() const;
00324 
00329     SICPPSDK_INLINE CQuaternionf& PutZ( float newVal);
00330 
00334     SICPPSDK_INLINE float GetY() const;
00335 
00340     SICPPSDK_INLINE CQuaternionf& PutY( float newVal);
00341 
00345     SICPPSDK_INLINE float GetX() const;
00346 
00351     SICPPSDK_INLINE CQuaternionf& PutX( float newVal);
00352 
00359     SICPPSDK_INLINE bool operator !=(const CQuaternionf & in_quat ) const;
00360 
00361 private:
00362     float m_X, m_Y, m_Z, m_W;
00363 };
00364 
00365 //inline functions
00366 SICPPSDK_INLINE CQuaternionf::CQuaternionf()
00367 {
00368     SetIdentity();
00369 }
00370 
00371 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const CQuaternionf& in_quaternion)
00372 {
00373     *this = in_quaternion;
00374 }
00375 
00376 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator=( const CQuaternionf & in_Quat )
00377 {
00378     m_W = in_Quat.m_W;
00379     m_X = in_Quat.m_X;
00380     m_Y = in_Quat.m_Y;
00381     m_Z = in_Quat.m_Z;
00382 
00383     return *this;
00384 }
00385 
00386 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const float in_W, const float in_X, const float in_Y, const float in_Z )
00387 {
00388     Set( in_W, in_X, in_Y, in_Z );
00389 }
00390 
00391 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const XSI::MATH::CVector3f& in_vct )
00392 {
00393     Set( in_vct );
00394 }
00395 
00396 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const XSI::MATH::CVector4f& in_vct )
00397 {
00398     Set( in_vct );
00399 }
00400 
00401 SICPPSDK_INLINE bool CQuaternionf::Equals( const CQuaternionf &in_Quat ) const
00402 {
00403     return (this == &in_Quat) ? true :
00404         (m_W == in_Quat.m_W &&
00405         m_X == in_Quat.m_X &&
00406         m_Y == in_Quat.m_Y &&
00407         m_Z == in_Quat.m_Z );
00408 }
00409 
00410 SICPPSDK_INLINE bool CQuaternionf::operator == ( const CQuaternionf &in_Quat ) const
00411 {
00412     return Equals(in_Quat);
00413 }
00414 
00415 SICPPSDK_INLINE bool CQuaternionf::operator < ( const CQuaternionf& in_Quat) const
00416 {
00417     if ( m_W != in_Quat.m_W ) return m_W < in_Quat.m_W;
00418     if ( m_Z != in_Quat.m_Z ) return m_Z < in_Quat.m_Z;
00419     if ( m_Y != in_Quat.m_Y ) return m_Y < in_Quat.m_Y;
00420     if ( m_X != in_Quat.m_X ) return m_X < in_Quat.m_X;
00421     return false;
00422 }
00423 
00424 SICPPSDK_INLINE bool CQuaternionf::operator != ( const CQuaternionf &in_Quat ) const
00425 {
00426     return ! Equals( in_Quat );
00427 }
00428 
00429 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator *= ( const CQuaternionf &in_Quat )
00430 {
00431 
00432     return Mul(*this, in_Quat);
00433 }
00434 
00435 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Mul( const CQuaternionf &in_Quat )
00436 {
00437     return Mul(*this, in_Quat);
00438 }
00439 
00440 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Mul
00441 (
00442     const CQuaternionf &in_Quat1,
00443     const CQuaternionf &in_Quat2
00444 )
00445 {
00446     float dW, dX, dY, dZ;
00447 
00448     dW = in_Quat1.m_W * in_Quat2.m_W - in_Quat1.m_X * in_Quat2.m_X -
00449         in_Quat1.m_Y * in_Quat2.m_Y - in_Quat1.m_Z * in_Quat2.m_Z ;
00450 
00451     dX = in_Quat1.m_W * in_Quat2.m_X + in_Quat2.m_W * in_Quat1.m_X +
00452         in_Quat1.m_Y * in_Quat2.m_Z - in_Quat2.m_Y * in_Quat1.m_Z ;
00453 
00454     dY = in_Quat1.m_W * in_Quat2.m_Y + in_Quat2.m_W * in_Quat1.m_Y -
00455         in_Quat1.m_X * in_Quat2.m_Z + in_Quat2.m_X * in_Quat1.m_Z ;
00456 
00457     dZ = in_Quat1.m_W * in_Quat2.m_Z + in_Quat2.m_W * in_Quat1.m_Z +
00458         in_Quat1.m_X * in_Quat2.m_Y - in_Quat2.m_X * in_Quat1.m_Y ;
00459 
00460     m_W = dW; m_X = dX; m_Y = dY; m_Z = dZ;
00461 
00462     return *this;
00463 }
00464 
00465 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator -= ( const CQuaternionf &in_Quat )
00466 {
00467     return Sub(*this, in_Quat );
00468 }
00469 
00470 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SubInPlace( const CQuaternionf &in_Quat )
00471 {
00472     return Sub(*this, in_Quat );
00473 }
00474 
00475 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Sub
00476 (
00477     const CQuaternionf &in_Quat1,
00478     const CQuaternionf &in_Quat2
00479 )
00480 {
00481     m_W = in_Quat1.m_W - in_Quat2.m_W;
00482     m_X = in_Quat1.m_X - in_Quat2.m_X;
00483     m_Y = in_Quat1.m_Y - in_Quat2.m_Y;
00484     m_Z = in_Quat1.m_Z - in_Quat2.m_Z;
00485 
00486     return *this;
00487 }
00488 
00489 SICPPSDK_INLINE CQuaternionf& CQuaternionf::NegateInPlace()
00490 {
00491    return Negate(*this);
00492 }
00493 
00494 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Negate( const CQuaternionf &in_Quat)
00495 {
00496    m_W = -(in_Quat.m_W);
00497    m_X = -(in_Quat.m_X);
00498    m_Y = -(in_Quat.m_Y);
00499    m_Z = -(in_Quat.m_Z);
00500 
00501    return( *this );
00502 }
00503 
00504 SICPPSDK_INLINE float CQuaternionf::GetSquaredLength() const
00505 {
00506     return( m_W * m_W + m_X * m_X + m_Y * m_Y + m_Z * m_Z );
00507 }
00508 
00509 SICPPSDK_INLINE float CQuaternionf::GetLength() const
00510 {
00511     return( sqrt( GetSquaredLength() ) );
00512 }
00513 
00514 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator += ( const CQuaternionf &in_Quat)
00515 {
00516     return Add( *this,  in_Quat );
00517 }
00518 
00519 SICPPSDK_INLINE CQuaternionf& CQuaternionf::AddInPlace( const CQuaternionf &in_Quat )
00520 {
00521     return Add( *this,  in_Quat );
00522 }
00523 
00524 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Add
00525 (
00526     const CQuaternionf &in_Quat1,
00527     const CQuaternionf &in_Quat2
00528 )
00529 {
00530     m_W = in_Quat1.m_W + in_Quat2.m_W;
00531     m_X = in_Quat1.m_X + in_Quat2.m_X;
00532     m_Y = in_Quat1.m_Y + in_Quat2.m_Y;
00533     m_Z = in_Quat1.m_Z + in_Quat2.m_Z;
00534     return *this;
00535 }
00536 
00537 SICPPSDK_INLINE CQuaternionf& CQuaternionf::ConjugateInPlace()
00538 {
00539     return Conjugate(*this);
00540 }
00541 
00542 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Conjugate( const CQuaternionf &in_Quat)
00543 {
00544     m_W = in_Quat.m_W;
00545     m_X = -in_Quat.m_X;
00546     m_Y = -in_Quat.m_Y;
00547     m_Z = -in_Quat.m_Z;
00548 
00549     return( *this );
00550 }
00551 
00552 SICPPSDK_INLINE CQuaternionf& CQuaternionf::InvertInPlace()
00553 {
00554     return Invert(*this);
00555 }
00556 
00557 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Invert( const CQuaternionf &in_Quat)
00558 {
00559     return Conjugate(in_Quat);
00560 }
00561 
00562 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SetIdentity()
00563 {
00564     m_W = 1.0;
00565     m_X = m_Y = m_Z = 0.0;
00566 
00567     return( *this );
00568 }
00569 
00570 SICPPSDK_INLINE CQuaternionf&  CQuaternionf::Copy( const CQuaternionf &in_Quat )
00571 {
00572     return *this = in_Quat;
00573 }
00574 
00575 SICPPSDK_INLINE void CQuaternionf::Get
00576 (
00577     float &io_W,
00578     float &io_X,
00579     float &io_Y,
00580     float &io_Z
00581 ) const
00582 {
00583     io_W = m_W;
00584     io_X = m_X;
00585     io_Y = m_Y;
00586     io_Z = m_Z;
00587 }
00588 
00589 SICPPSDK_INLINE void CQuaternionf::Get( CVector4f &io_XYZWVector ) const
00590 {
00591     io_XYZWVector.Set( m_X, m_Y, m_Z, m_W);
00592 }
00593 
00594 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set
00595 (
00596     float in_W,
00597     float in_X,
00598     float in_Y,
00599     float in_Z
00600 )
00601 {
00602     m_W = in_W;
00603     m_X = in_X;
00604     m_Y = in_Y;
00605     m_Z = in_Z;
00606 
00607     return *this;
00608 }
00609 
00610 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set( const CVector3f &in_XYZVector )
00611 {
00612     m_W = 1.0;
00613     m_X = in_XYZVector.GetX();
00614     m_Y = in_XYZVector.GetY();
00615     m_Z = in_XYZVector.GetZ();
00616 
00617     return *this;
00618 }
00619 
00620 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set( const CVector4f &in_XYZWVector )
00621 {
00622     m_W = in_XYZWVector.GetW();
00623     m_X = in_XYZWVector.GetX();
00624     m_Y = in_XYZWVector.GetY();
00625     m_Z = in_XYZWVector.GetZ();
00626 
00627     return *this;
00628 }
00629 
00630 SICPPSDK_INLINE float CQuaternionf::GetValue( short in_nIndex ) const
00631 {
00632     assert(in_nIndex >= 0 && in_nIndex < 4);
00633 
00634     switch (in_nIndex)
00635     {
00636         case 0: return m_W;
00637         case 1: return m_X;
00638         case 2: return m_Y;
00639         case 3: return m_Z;
00640     }
00641 
00642     return 0.0; // invalid index, return 0.0
00643 }
00644 
00645 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SetValue( short in_nIndex,  float newVal)
00646 {
00647     assert(in_nIndex >= 0 && in_nIndex < 4);
00648 
00649     switch (in_nIndex)
00650     {
00651         case 0:  m_W = newVal; break;
00652         case 1:  m_X = newVal; break;
00653         case 2:  m_Y = newVal; break;
00654         case 3:  m_Z = newVal; break;
00655         // note: do nothing when invalid index is provided
00656     }
00657 
00658     return *this;
00659 }
00660 
00661 SICPPSDK_INLINE float CQuaternionf::GetW() const
00662 {
00663     return m_W;
00664 }
00665 
00666 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutW( float newVal)
00667 {
00668     m_W = newVal;
00669 
00670     return *this;
00671 }
00672 
00673 SICPPSDK_INLINE float CQuaternionf::GetZ() const
00674 {
00675     return m_Z;
00676 }
00677 
00678 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutZ( float newVal)
00679 {
00680     m_Z = newVal;
00681     return *this;
00682 }
00683 
00684 SICPPSDK_INLINE float CQuaternionf::GetY() const
00685 {
00686     return m_Y;
00687 }
00688 
00689 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutY( float newVal)
00690 {
00691     m_Y = newVal;
00692     return *this;
00693 }
00694 
00695 
00696 SICPPSDK_INLINE float CQuaternionf::GetX() const
00697 {
00698     return m_X;
00699 }
00700 
00701 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutX( float newVal)
00702 {
00703     m_X = newVal;
00704     return *this;
00705 }
00706 
00707 SICPPSDK_INLINE CQuaternionf& CQuaternionf::NormalizeInPlace()
00708 {
00709    float rLen = GetSquaredLength();
00710 
00711    if( fabs( rLen - 1.0f ) >= PicoEPS )
00712    {
00713       if( rLen < PicoEPS )
00714       {
00715          m_X = m_Y = m_Z = 0.0;
00716          m_W = 1.0;
00717       }
00718       else
00719       {
00720          rLen = 1.0f / sqrt( rLen );
00721          m_W *= rLen;
00722          m_X *= rLen;
00723          m_Y *= rLen;
00724          m_Z *= rLen;
00725 
00726          LimitValue( m_W, -1.0, 1.0 );
00727       }
00728    }
00729    else
00730    {
00731         LimitValue( m_W, -1.0, 1.0 );
00732    }
00733 
00734    return( *this );
00735 }
00736 
00737 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Slerp
00738 (
00739     const CQuaternionf& in_quatStart,
00740     const CQuaternionf& in_quatEnd,
00741     const float         in_fU
00742 )
00743 {
00744    float fDot, fScale1, fScale2;
00745    bool bNegate = false;
00746 
00747    fDot = in_quatStart.Dot( in_quatEnd );
00748    if ( fDot < 0.0 )
00749    {
00750       fDot = -fDot;
00751       bNegate = true;
00752    }
00753 
00754    if( fDot >= ( 1.0f - MicroEPS ) )
00755    {
00756       fScale1 = 1.0f - in_fU;
00757       fScale2 = in_fU;
00758    }
00759    else
00760    {
00761       float fAngle, fFactor;
00762 
00763       LimitValue( fDot, -1.0, 1.0 );
00764       fAngle = acos( fDot );
00765       fFactor = 1.0f / sin( fAngle );
00766 
00767       fScale1 = sin( (1.0f - in_fU) * fAngle ) * fFactor;
00768       fScale2 = sin( in_fU * fAngle ) * fFactor;
00769    }
00770 
00771    if( bNegate == true )
00772       fScale2 = -fScale2;
00773 
00774    m_W = fScale1 * in_quatStart.m_W + fScale2 * in_quatEnd.m_W;
00775    m_X = fScale1 * in_quatStart.m_X + fScale2 * in_quatEnd.m_X;
00776    m_Y = fScale1 * in_quatStart.m_Y + fScale2 * in_quatEnd.m_Y;
00777    m_Z = fScale1 * in_quatStart.m_Z + fScale2 * in_quatEnd.m_Z;
00778 
00779    return( *this );
00780 }
00781 
00782 SICPPSDK_INLINE float CQuaternionf::Dot( const CQuaternionf& in_quat ) const
00783 {
00784    return( GetW() * in_quat.GetW() +
00785            GetX() * in_quat.GetX() +
00786            GetY() * in_quat.GetY() +
00787            GetZ() * in_quat.GetZ() );
00788 }
00789 
00790 SICPPSDK_INLINE bool CQuaternionf::EpsilonEquals( const CQuaternionf& in_quat, const float in_fEpsilon ) const
00791 {
00792    return( fabs( GetW() - in_quat.GetW() ) < in_fEpsilon &&
00793            fabs( GetX() - in_quat.GetX() ) < in_fEpsilon &&
00794            fabs( GetY() - in_quat.GetY() ) < in_fEpsilon &&
00795            fabs( GetZ() - in_quat.GetZ() ) < in_fEpsilon );
00796 }
00797 
00798 };
00799 };
00800 
00801 #endif // __XSIQUATERNIONF_H__