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__