xsi_quaternion.h Source File
 
 
 
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__