xsi_quaternion.h
Go to the documentation of this file.

    00001 //*****************************************************************************
    00011 //*****************************************************************************
    00012 #ifndef __XSIQUATERNION_H__
    00013 #define __XSIQUATERNION_H__
    00014
    00015 #include "sicppsdk.h"
    00016 #include "xsi_rotation.h"
    00017 #include "xsi_vector3.h"
    00018 #include "xsi_vector4.h"
    00019
    00020 namespace XSI {
    00021
    00022 namespace MATH {
    00023
    00024 class CVector3;
    00025 class CVector4;
    00026
    00027 //*****************************************************************************
    00098 //*****************************************************************************
    00099 class SICPPSDKDECL CQuaternion
    00100 {
    00101 public:
    00106     SICPPSDK_INLINE CQuaternion();
    00107
    00111     SICPPSDK_INLINE CQuaternion( const CQuaternion& in_quaternion);
    00112
    00114     ~CQuaternion() {};
    00115
    00120     SICPPSDK_INLINE CQuaternion & operator=( const CQuaternion & in_quaternion);
    00121
    00128     SICPPSDK_INLINE CQuaternion( const double in_dW, const double in_dX,
    00129                const double in_dY, const double in_dZ );
    00130
    00135     SICPPSDK_INLINE CQuaternion( const CVector3& in_vct );
    00136
    00140     SICPPSDK_INLINE CQuaternion( const CVector4& in_vct );
    00141
    00145     SICPPSDK_INLINE CQuaternion( const CRotation& in_Rot );
    00146
    00151     CQuaternion& operator = ( const CRotation &in_Rot );
    00152
    00157     CQuaternion& SetFromRotation( const CRotation &in_Rot );
    00158
    00162     CRotation GetRotation() const;
    00163
    00166     CQuaternion& Normalize();
    00167
    00177     bool EpsilonEquals( const CQuaternion &in_Quat, double in_dEpsilon ) const;
    00178
    00184     SICPPSDK_INLINE bool Equals( const CQuaternion &in_Quat ) const;
    00185
    00191     SICPPSDK_INLINE bool operator == ( const CQuaternion &in_Quat ) const;
    00192
    00200     CQuaternion& Slerp( const CQuaternion &in_Quat1, const CQuaternion &in_Quat2, double in_dU);
    00201
    00207     SICPPSDK_INLINE CQuaternion& operator *= ( const CQuaternion &in_Quat );
    00208
    00214     SICPPSDK_INLINE CQuaternion& MulInPlace( const CQuaternion &in_Quat );
    00215
    00221     SICPPSDK_INLINE CQuaternion& Mul( const CQuaternion &in_Quat1, const CQuaternion &in_Quat2);
    00222
    00228     SICPPSDK_INLINE CQuaternion& operator -= ( const CQuaternion &in_Quat );
    00229
    00235     SICPPSDK_INLINE CQuaternion& SubInPlace( const CQuaternion &in_Quat );
    00236
    00243     SICPPSDK_INLINE CQuaternion& Sub( const CQuaternion &in_Quat1,  const CQuaternion &in_Quat2);
    00244
    00249     SICPPSDK_INLINE CQuaternion& NegateInPlace();
    00250
    00256     SICPPSDK_INLINE CQuaternion& Negate( const CQuaternion &in_Quat);
    00257
    00262     double GetLengthSquared() const;
    00263
    00268     double GetLength() const;
    00269
    00274     SICPPSDK_INLINE CQuaternion& operator += ( const CQuaternion &in_Quat);
    00275
    00280     SICPPSDK_INLINE CQuaternion& AddInPlace( const CQuaternion &in_Quat );
    00281
    00288     SICPPSDK_INLINE CQuaternion& Add( const CQuaternion &in_Quat1,  const CQuaternion &in_Quat2);
    00289
    00294     SICPPSDK_INLINE CQuaternion& ConjugateInPlace();
    00295
    00301     SICPPSDK_INLINE CQuaternion& Conjugate( const CQuaternion &in_Quat);
    00302
    00307     SICPPSDK_INLINE CQuaternion& InvertInPlace();
    00308
    00314     SICPPSDK_INLINE CQuaternion& Invert( const CQuaternion &in_Quat);
    00315
    00319     SICPPSDK_INLINE CQuaternion& SetIdentity();
    00320
    00325     SICPPSDK_INLINE CQuaternion&  Copy( const CQuaternion &in_Quat );
    00326
    00333     SICPPSDK_INLINE void Get( double &out_dW, double &out_dX, double &out_dY, double &out_dZ ) const;
    00334
    00338     CVector3 Get() const;
    00339
    00343     SICPPSDK_INLINE void Get( CVector4 &io_XYZWVector ) const;
    00344
    00352     SICPPSDK_INLINE CQuaternion& Set( double in_dW,  double in_dX,  double in_dY,  double in_dZ);
    00353
    00359     SICPPSDK_INLINE CQuaternion& Set( const CVector3 &in_XYZVector );
    00360
    00366     SICPPSDK_INLINE CQuaternion& Set( const CVector4 &in_XYZWVector );
    00367
    00375     SICPPSDK_INLINE double GetValue( short in_nIndex ) const;
    00376
    00385     SICPPSDK_INLINE CQuaternion& PutValue( short in_nIndex,  double newVal);
    00386
    00390     SICPPSDK_INLINE double GetW() const;
    00391
    00396     SICPPSDK_INLINE CQuaternion& PutW( double newVal);
    00397
    00401     SICPPSDK_INLINE double GetZ() const;
    00402
    00407     SICPPSDK_INLINE CQuaternion& PutZ( double newVal);
    00408
    00412     SICPPSDK_INLINE double GetY() const;
    00413
    00418     SICPPSDK_INLINE CQuaternion& PutY( double newVal);
    00419
    00423     SICPPSDK_INLINE double GetX() const;
    00424
    00429     SICPPSDK_INLINE CQuaternion& PutX( double newVal);
    00430
    00437     CQuaternion& SetFromXYZAnglesValues( double x, double y, double z );
    00438
    00444     void GetXYZAnglesValues( double& x, double& y, double& z )const;
    00445
    00452     SICPPSDK_INLINE bool operator !=(const CQuaternion & in_quat ) const;
    00453
    00454 private:
    00455     double m_dX, m_dY, m_dZ, m_dW;
    00456 };
    00457
    00458 //inline functions
    00459 SICPPSDK_INLINE CQuaternion::CQuaternion()
    00460 {
    00461     SetIdentity();
    00462 }
    00463
    00464 SICPPSDK_INLINE CQuaternion::CQuaternion( const CQuaternion& in_quaternion)
    00465 {
    00466     *this = in_quaternion;
    00467 }
    00468
    00469
    00470 SICPPSDK_INLINE CQuaternion& CQuaternion::operator=( const CQuaternion & in_Quat )
    00471 {
    00472     m_dW = in_Quat.m_dW;
    00473     m_dX = in_Quat.m_dX;
    00474     m_dY = in_Quat.m_dY;
    00475     m_dZ = in_Quat.m_dZ;
    00476
    00477     return *this;
    00478 }
    00479
    00480 SICPPSDK_INLINE CQuaternion::CQuaternion( const double in_dW, const double in_dX,
    00481            const double in_dY, const double in_dZ )
    00482 {
    00483     Set( in_dW, in_dX, in_dY, in_dZ );
    00484 }
    00485
    00486 SICPPSDK_INLINE CQuaternion::CQuaternion( const XSI::MATH::CVector3& in_vct )
    00487 {
    00488     Set( in_vct );
    00489 }
    00490
    00491 SICPPSDK_INLINE CQuaternion::CQuaternion( const XSI::MATH::CVector4& in_vct )
    00492 {
    00493     Set( in_vct );
    00494 }
    00495
    00496 SICPPSDK_INLINE bool CQuaternion::Equals( const CQuaternion &in_Quat ) const
    00497 {
    00498     return (this == &in_Quat) ? true :
    00499         (m_dW == in_Quat.m_dW &&
    00500         m_dX == in_Quat.m_dX &&
    00501         m_dY == in_Quat.m_dY &&
    00502         m_dZ == in_Quat.m_dZ );
    00503 }
    00504
    00505 SICPPSDK_INLINE bool CQuaternion::operator == ( const CQuaternion &in_Quat ) const
    00506 {
    00507     return Equals(in_Quat);
    00508 }
    00509
    00510 SICPPSDK_INLINE bool CQuaternion::operator != ( const CQuaternion &in_Quat ) const
    00511 {
    00512     return ! Equals( in_Quat );
    00513 }
    00514
    00515 SICPPSDK_INLINE CQuaternion& CQuaternion::operator *= ( const CQuaternion &in_Quat )
    00516 {
    00517
    00518     return Mul(*this, in_Quat);
    00519 }
    00520
    00521 SICPPSDK_INLINE CQuaternion& CQuaternion::MulInPlace( const CQuaternion &in_Quat )
    00522 {
    00523     return Mul(*this, in_Quat);
    00524 }
    00525
    00526 SICPPSDK_INLINE CQuaternion& CQuaternion::Mul
    00527 (
    00528     const CQuaternion &in_Quat1,
    00529     const CQuaternion &in_Quat2
    00530 )
    00531 {
    00532     double dW, dX, dY, dZ;
    00533
    00534     dW = in_Quat1.m_dW * in_Quat2.m_dW - in_Quat1.m_dX * in_Quat2.m_dX -
    00535         in_Quat1.m_dY * in_Quat2.m_dY - in_Quat1.m_dZ * in_Quat2.m_dZ ;
    00536
    00537     dX = in_Quat1.m_dW * in_Quat2.m_dX + in_Quat2.m_dW * in_Quat1.m_dX +
    00538         in_Quat1.m_dY * in_Quat2.m_dZ - in_Quat2.m_dY * in_Quat1.m_dZ ;
    00539
    00540     dY = in_Quat1.m_dW * in_Quat2.m_dY + in_Quat2.m_dW * in_Quat1.m_dY -
    00541         in_Quat1.m_dX * in_Quat2.m_dZ + in_Quat2.m_dX * in_Quat1.m_dZ ;
    00542
    00543     dZ = in_Quat1.m_dW * in_Quat2.m_dZ + in_Quat2.m_dW * in_Quat1.m_dZ +
    00544         in_Quat1.m_dX * in_Quat2.m_dY - in_Quat2.m_dX * in_Quat1.m_dY ;
    00545
    00546     m_dW = dW; m_dX = dX; m_dY = dY; m_dZ = dZ;
    00547
    00548     return *this;
    00549 }
    00550
    00551 SICPPSDK_INLINE CQuaternion& CQuaternion::operator -= ( const CQuaternion &in_Quat )
    00552 {
    00553     return Sub(*this, in_Quat );
    00554 }
    00555
    00556 SICPPSDK_INLINE CQuaternion& CQuaternion::SubInPlace( const CQuaternion &in_Quat )
    00557 {
    00558     return Sub(*this, in_Quat );
    00559 }
    00560
    00561 SICPPSDK_INLINE CQuaternion& CQuaternion::Sub
    00562 (
    00563     const CQuaternion &in_Quat1,
    00564     const CQuaternion &in_Quat2
    00565 )
    00566 {
    00567     m_dW = in_Quat1.m_dW - in_Quat2.m_dW;
    00568     m_dX = in_Quat1.m_dX - in_Quat2.m_dX;
    00569     m_dY = in_Quat1.m_dY - in_Quat2.m_dY;
    00570     m_dZ = in_Quat1.m_dZ - in_Quat2.m_dZ;
    00571
    00572     return *this;
    00573 }
    00574
    00575 SICPPSDK_INLINE CQuaternion& CQuaternion::NegateInPlace()
    00576 {
    00577    return Negate(*this);
    00578 }
    00579
    00580 SICPPSDK_INLINE CQuaternion& CQuaternion::Negate( const CQuaternion &in_Quat)
    00581 {
    00582    m_dW = -(in_Quat.m_dW);
    00583    m_dX = -(in_Quat.m_dX);
    00584    m_dY = -(in_Quat.m_dY);
    00585    m_dZ = -(in_Quat.m_dZ);
    00586
    00587    return( *this );
    00588 }
    00589
    00590 SICPPSDK_INLINE double CQuaternion::GetLengthSquared() const
    00591 {
    00592     return( m_dW * m_dW + m_dX * m_dX + m_dY * m_dY + m_dZ * m_dZ );
    00593 }
    00594
    00595 SICPPSDK_INLINE CQuaternion& CQuaternion::operator += ( const CQuaternion &in_Quat)
    00596 {
    00597     return Add( *this,  in_Quat );
    00598 }
    00599
    00600 SICPPSDK_INLINE CQuaternion& CQuaternion::AddInPlace( const CQuaternion &in_Quat )
    00601 {
    00602     return Add( *this,  in_Quat );
    00603 }
    00604
    00605 SICPPSDK_INLINE CQuaternion& CQuaternion::Add
    00606 (
    00607     const CQuaternion &in_Quat1,
    00608     const CQuaternion &in_Quat2
    00609 )
    00610 {
    00611     m_dW = in_Quat1.m_dW + in_Quat2.m_dW;
    00612     m_dX = in_Quat1.m_dX + in_Quat2.m_dX;
    00613     m_dY = in_Quat1.m_dY + in_Quat2.m_dY;
    00614     m_dZ = in_Quat1.m_dZ + in_Quat2.m_dZ;
    00615     return *this;
    00616 }
    00617
    00618 SICPPSDK_INLINE CQuaternion& CQuaternion::ConjugateInPlace()
    00619 {
    00620     return Conjugate(*this);
    00621 }
    00622
    00623 SICPPSDK_INLINE CQuaternion& CQuaternion::Conjugate( const CQuaternion &in_Quat)
    00624 {
    00625     m_dW = in_Quat.m_dW;
    00626     m_dX = -in_Quat.m_dX;
    00627     m_dY = -in_Quat.m_dY;
    00628     m_dZ = -in_Quat.m_dZ;
    00629
    00630     return( *this );
    00631 }
    00632
    00633 SICPPSDK_INLINE CQuaternion& CQuaternion::InvertInPlace()
    00634 {
    00635     return Invert(*this);
    00636 }
    00637
    00638 SICPPSDK_INLINE CQuaternion& CQuaternion::Invert( const CQuaternion &in_Quat)
    00639 {
    00640     return Conjugate(in_Quat);
    00641 }
    00642
    00643 SICPPSDK_INLINE CQuaternion& CQuaternion::SetIdentity()
    00644 {
    00645     m_dW = 1.0;
    00646     m_dX = m_dY = m_dZ = 0.0;
    00647
    00648     return( *this );
    00649 }
    00650
    00651 SICPPSDK_INLINE CQuaternion&  CQuaternion::Copy( const CQuaternion &in_Quat )
    00652 {
    00653     return *this = in_Quat;
    00654 }
    00655
    00656 SICPPSDK_INLINE void CQuaternion::Get
    00657 (
    00658     double &io_dW,
    00659     double &io_dX,
    00660     double &io_dY,
    00661     double &io_dZ
    00662 ) const
    00663 {
    00664     io_dW = m_dW;
    00665     io_dX = m_dX;
    00666     io_dY = m_dY;
    00667     io_dZ = m_dZ;
    00668 }
    00669
    00670 SICPPSDK_INLINE void CQuaternion::Get( CVector4 &io_XYZWVector ) const
    00671 {
    00672     io_XYZWVector.Set( m_dX, m_dY, m_dZ, m_dW);
    00673 }
    00674
    00675
    00676 SICPPSDK_INLINE CQuaternion& CQuaternion::Set
    00677 (
    00678     double in_dW,
    00679     double in_dX,
    00680     double in_dY,
    00681     double in_dZ
    00682 )
    00683 {
    00684     m_dW = in_dW;
    00685     m_dX = in_dX;
    00686     m_dY = in_dY;
    00687     m_dZ = in_dZ;
    00688
    00689     return *this;
    00690 }
    00691
    00692 SICPPSDK_INLINE CQuaternion& CQuaternion::Set( const CVector3 &in_XYZVector )
    00693 {
    00694     m_dW = 1.0;
    00695     m_dX = in_XYZVector.GetX();
    00696     m_dY = in_XYZVector.GetY();
    00697     m_dZ = in_XYZVector.GetZ();
    00698
    00699     return *this;
    00700 }
    00701
    00702 SICPPSDK_INLINE CQuaternion& CQuaternion::Set( const CVector4 &in_XYZWVector )
    00703 {
    00704     m_dW = in_XYZWVector.GetW();
    00705     m_dX = in_XYZWVector.GetX();
    00706     m_dY = in_XYZWVector.GetY();
    00707     m_dZ = in_XYZWVector.GetZ();
    00708
    00709     return *this;
    00710 }
    00711
    00712 SICPPSDK_INLINE double CQuaternion::GetValue( short in_nIndex ) const
    00713 {
    00714     assert(in_nIndex >= 0 && in_nIndex < 4);
    00715
    00716     switch (in_nIndex)
    00717     {
    00718         case 0: return m_dW;
    00719         case 1: return m_dX;
    00720         case 2: return m_dY;
    00721         case 3: return m_dZ;
    00722     }
    00723
    00724     return 0.0; // invalid index, return 0.0
    00725 }
    00726
    00727 SICPPSDK_INLINE CQuaternion& CQuaternion::PutValue( short in_nIndex,  double newVal)
    00728 {
    00729     assert(in_nIndex >= 0 && in_nIndex < 4);
    00730
    00731     switch (in_nIndex)
    00732     {
    00733         case 0:  m_dW = newVal; break;
    00734         case 1:  m_dX = newVal; break;
    00735         case 2:  m_dY = newVal; break;
    00736         case 3:  m_dZ = newVal; break;
    00737         // note: do nothing when invalid index is provided
    00738     }
    00739
    00740     return *this;
    00741 }
    00742
    00743 SICPPSDK_INLINE double CQuaternion::GetW() const
    00744 {
    00745     return m_dW;
    00746 }
    00747
    00748 SICPPSDK_INLINE CQuaternion& CQuaternion::PutW( double newVal)
    00749 {
    00750     m_dW = newVal;
    00751
    00752     return *this;
    00753 }
    00754
    00755 SICPPSDK_INLINE double CQuaternion::GetZ() const
    00756 {
    00757     return m_dZ;
    00758 }
    00759
    00760 SICPPSDK_INLINE CQuaternion& CQuaternion::PutZ( double newVal)
    00761 {
    00762     m_dZ = newVal;
    00763     return *this;
    00764 }
    00765
    00766 SICPPSDK_INLINE double CQuaternion::GetY() const
    00767 {
    00768     return m_dY;
    00769 }
    00770
    00771 SICPPSDK_INLINE CQuaternion& CQuaternion::PutY( double newVal)
    00772 {
    00773     m_dY = newVal;
    00774     return *this;
    00775 }
    00776
    00777
    00778 SICPPSDK_INLINE double CQuaternion::GetX() const
    00779 {
    00780     return m_dX;
    00781 }
    00782
    00783 SICPPSDK_INLINE CQuaternion& CQuaternion::PutX( double newVal)
    00784 {
    00785     m_dX = newVal;
    00786     return *this;
    00787 }
    00788
    00789 SICPPSDK_INLINE CQuaternion::CQuaternion( const CRotation& in_Rot )
    00790 {
    00791     *this = in_Rot;
    00792 }
    00793
    00794
    00795 };
    00796 };
    00797
    00798 #endif // __XSIQUATERNION_H__