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
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;
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
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__