00001
00011
00012 #ifndef __XSIQUATERNIONF_H__
00013 #define __XSIQUATERNIONF_H__
00014
00015 #include "sicppsdk.h"
00016 #include "xsi_vector4f.h"
00017 #include "xsi_vector3f.h"
00018
00019 namespace XSI {
00020
00021 namespace MATH {
00022
00023 class CRotation3f;
00024
00025
00036
00037 class SICPPSDKDECL CQuaternionf
00038 {
00039 public:
00044 SICPPSDK_INLINE CQuaternionf();
00045
00049 SICPPSDK_INLINE CQuaternionf( const CQuaternionf& in_quaternion );
00050
00052 ~CQuaternionf() {};
00053
00058 SICPPSDK_INLINE CQuaternionf & operator=( const CQuaternionf & in_quaternion);
00059
00066 SICPPSDK_INLINE CQuaternionf( const float in_W, const float in_X, const float in_Y, const float in_Z );
00067
00072 SICPPSDK_INLINE CQuaternionf( const CVector3f& in_vct );
00073
00077 SICPPSDK_INLINE CQuaternionf( const CVector4f& in_vct );
00078
00084 SICPPSDK_INLINE bool Equals( const CQuaternionf &in_Quat ) const;
00085
00091 SICPPSDK_INLINE bool EpsilonEquals( const CQuaternionf& in_quat, const float in_fEpsilon ) const;
00092
00098 SICPPSDK_INLINE bool operator == ( const CQuaternionf &in_Quat ) const;
00099
00107 SICPPSDK_INLINE bool operator < ( const CQuaternionf& in_Quat ) const;
00108
00114 SICPPSDK_INLINE CQuaternionf& operator *= ( const CQuaternionf &in_Quat );
00115
00121 SICPPSDK_INLINE CQuaternionf& Mul( const CQuaternionf &in_Quat );
00122
00128 SICPPSDK_INLINE CQuaternionf& Mul( const CQuaternionf &in_Quat1, const CQuaternionf &in_Quat2);
00129
00134 SICPPSDK_INLINE float Dot( const CQuaternionf& in_quat1 ) const;
00135
00142 SICPPSDK_INLINE CQuaternionf& Slerp( const CQuaternionf& in_quatStart, const CQuaternionf& in_quatEnd, const float in_fU );
00143
00149 SICPPSDK_INLINE CQuaternionf& operator -= ( const CQuaternionf &in_Quat );
00150
00156 SICPPSDK_INLINE CQuaternionf& SubInPlace( const CQuaternionf &in_Quat );
00157
00164 SICPPSDK_INLINE CQuaternionf& Sub( const CQuaternionf &in_Quat1, const CQuaternionf &in_Quat2);
00165
00170 SICPPSDK_INLINE CQuaternionf& NegateInPlace();
00171
00177 SICPPSDK_INLINE CQuaternionf& Negate( const CQuaternionf &in_Quat);
00178
00183 SICPPSDK_INLINE float GetSquaredLength() const;
00184
00189 SICPPSDK_INLINE float GetLength() const;
00190
00195 SICPPSDK_INLINE CQuaternionf& operator += ( const CQuaternionf &in_Quat);
00196
00201 SICPPSDK_INLINE CQuaternionf& AddInPlace( const CQuaternionf &in_Quat );
00202
00209 SICPPSDK_INLINE CQuaternionf& Add( const CQuaternionf &in_Quat1, const CQuaternionf &in_Quat2);
00210
00215 SICPPSDK_INLINE CQuaternionf& ConjugateInPlace();
00216
00222 SICPPSDK_INLINE CQuaternionf& Conjugate( const CQuaternionf &in_Quat);
00223
00228 SICPPSDK_INLINE CQuaternionf& InvertInPlace();
00229
00235 SICPPSDK_INLINE CQuaternionf& Invert( const CQuaternionf &in_Quat);
00236
00240 SICPPSDK_INLINE CQuaternionf& SetIdentity();
00241
00246 SICPPSDK_INLINE CQuaternionf& Copy( const CQuaternionf &in_Quat );
00247
00251 SICPPSDK_INLINE CQuaternionf& NormalizeInPlace();
00252
00259 SICPPSDK_INLINE void Get( float &out_W, float &out_X, float &out_Y, float &out_Z ) const;
00260
00264 SICPPSDK_INLINE CVector3f GetVector3() const;
00265
00269 SICPPSDK_INLINE CVector4f GetVector4() const;
00270
00274 SICPPSDK_INLINE void Get( CVector4f &io_XYZWVector ) const;
00275
00283 SICPPSDK_INLINE CQuaternionf& Set( float in_W, float in_X, float in_Y, float in_Z);
00284
00290 SICPPSDK_INLINE CQuaternionf& Set( const CVector3f &in_XYZVector );
00291
00297 SICPPSDK_INLINE CQuaternionf& Set( const CVector4f &in_XYZWVector );
00298
00305 SICPPSDK_INLINE float GetValue( short in_nIndex ) const;
00306
00314 SICPPSDK_INLINE CQuaternionf& SetValue( short in_nIndex, float newVal);
00315
00319 SICPPSDK_INLINE float GetW() const;
00320
00325 SICPPSDK_INLINE CQuaternionf& PutW( float newVal);
00326
00330 SICPPSDK_INLINE float GetZ() const;
00331
00336 SICPPSDK_INLINE CQuaternionf& PutZ( float newVal);
00337
00341 SICPPSDK_INLINE float GetY() const;
00342
00347 SICPPSDK_INLINE CQuaternionf& PutY( float newVal);
00348
00352 SICPPSDK_INLINE float GetX() const;
00353
00358 SICPPSDK_INLINE CQuaternionf& PutX( float newVal);
00359
00366 SICPPSDK_INLINE bool operator !=(const CQuaternionf & in_quat ) const;
00367
00368 private:
00369 float m_W, m_X, m_Y, m_Z;
00370 };
00371
00372
00373 SICPPSDK_INLINE CQuaternionf::CQuaternionf()
00374 {
00375 SetIdentity();
00376 }
00377
00378 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const CQuaternionf& in_quaternion)
00379 {
00380 *this = in_quaternion;
00381 }
00382
00383 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator=( const CQuaternionf & in_Quat )
00384 {
00385 m_W = in_Quat.m_W;
00386 m_X = in_Quat.m_X;
00387 m_Y = in_Quat.m_Y;
00388 m_Z = in_Quat.m_Z;
00389
00390 return *this;
00391 }
00392
00393 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const float in_W, const float in_X, const float in_Y, const float in_Z )
00394 {
00395 Set( in_W, in_X, in_Y, in_Z );
00396 }
00397
00398 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const XSI::MATH::CVector3f& in_vct )
00399 {
00400 Set( in_vct );
00401 }
00402
00403 SICPPSDK_INLINE CQuaternionf::CQuaternionf( const XSI::MATH::CVector4f& in_vct )
00404 {
00405 Set( in_vct );
00406 }
00407
00408 SICPPSDK_INLINE bool CQuaternionf::Equals( const CQuaternionf &in_Quat ) const
00409 {
00410 return (this == &in_Quat) ? true :
00411 (m_W == in_Quat.m_W &&
00412 m_X == in_Quat.m_X &&
00413 m_Y == in_Quat.m_Y &&
00414 m_Z == in_Quat.m_Z );
00415 }
00416
00417 SICPPSDK_INLINE bool CQuaternionf::operator == ( const CQuaternionf &in_Quat ) const
00418 {
00419 return Equals(in_Quat);
00420 }
00421
00422 SICPPSDK_INLINE bool CQuaternionf::operator < ( const CQuaternionf& in_Quat) const
00423 {
00424 if ( m_W != in_Quat.m_W ) return m_W < in_Quat.m_W;
00425 if ( m_Z != in_Quat.m_Z ) return m_Z < in_Quat.m_Z;
00426 if ( m_Y != in_Quat.m_Y ) return m_Y < in_Quat.m_Y;
00427 if ( m_X != in_Quat.m_X ) return m_X < in_Quat.m_X;
00428 return false;
00429 }
00430
00431 SICPPSDK_INLINE bool CQuaternionf::operator != ( const CQuaternionf &in_Quat ) const
00432 {
00433 return ! Equals( in_Quat );
00434 }
00435
00436 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator *= ( const CQuaternionf &in_Quat )
00437 {
00438
00439 return Mul(*this, in_Quat);
00440 }
00441
00442 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Mul( const CQuaternionf &in_Quat )
00443 {
00444 return Mul(*this, in_Quat);
00445 }
00446
00447 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Mul
00448 (
00449 const CQuaternionf &in_Quat1,
00450 const CQuaternionf &in_Quat2
00451 )
00452 {
00453 float dW, dX, dY, dZ;
00454
00455 dW = in_Quat1.m_W * in_Quat2.m_W - in_Quat1.m_X * in_Quat2.m_X -
00456 in_Quat1.m_Y * in_Quat2.m_Y - in_Quat1.m_Z * in_Quat2.m_Z ;
00457
00458 dX = in_Quat1.m_W * in_Quat2.m_X + in_Quat2.m_W * in_Quat1.m_X +
00459 in_Quat1.m_Y * in_Quat2.m_Z - in_Quat2.m_Y * in_Quat1.m_Z ;
00460
00461 dY = in_Quat1.m_W * in_Quat2.m_Y + in_Quat2.m_W * in_Quat1.m_Y -
00462 in_Quat1.m_X * in_Quat2.m_Z + in_Quat2.m_X * in_Quat1.m_Z ;
00463
00464 dZ = in_Quat1.m_W * in_Quat2.m_Z + in_Quat2.m_W * in_Quat1.m_Z +
00465 in_Quat1.m_X * in_Quat2.m_Y - in_Quat2.m_X * in_Quat1.m_Y ;
00466
00467 m_W = dW; m_X = dX; m_Y = dY; m_Z = dZ;
00468
00469 return *this;
00470 }
00471
00472 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator -= ( const CQuaternionf &in_Quat )
00473 {
00474 return Sub(*this, in_Quat );
00475 }
00476
00477 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SubInPlace( const CQuaternionf &in_Quat )
00478 {
00479 return Sub(*this, in_Quat );
00480 }
00481
00482 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Sub
00483 (
00484 const CQuaternionf &in_Quat1,
00485 const CQuaternionf &in_Quat2
00486 )
00487 {
00488 m_W = in_Quat1.m_W - in_Quat2.m_W;
00489 m_X = in_Quat1.m_X - in_Quat2.m_X;
00490 m_Y = in_Quat1.m_Y - in_Quat2.m_Y;
00491 m_Z = in_Quat1.m_Z - in_Quat2.m_Z;
00492
00493 return *this;
00494 }
00495
00496 SICPPSDK_INLINE CQuaternionf& CQuaternionf::NegateInPlace()
00497 {
00498 return Negate(*this);
00499 }
00500
00501 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Negate( const CQuaternionf &in_Quat)
00502 {
00503 m_W = -(in_Quat.m_W);
00504 m_X = -(in_Quat.m_X);
00505 m_Y = -(in_Quat.m_Y);
00506 m_Z = -(in_Quat.m_Z);
00507
00508 return( *this );
00509 }
00510
00511 SICPPSDK_INLINE float CQuaternionf::GetSquaredLength() const
00512 {
00513 return( m_W * m_W + m_X * m_X + m_Y * m_Y + m_Z * m_Z );
00514 }
00515
00516 SICPPSDK_INLINE float CQuaternionf::GetLength() const
00517 {
00518 return( sqrt( GetSquaredLength() ) );
00519 }
00520
00521 SICPPSDK_INLINE CQuaternionf& CQuaternionf::operator += ( const CQuaternionf &in_Quat)
00522 {
00523 return Add( *this, in_Quat );
00524 }
00525
00526 SICPPSDK_INLINE CQuaternionf& CQuaternionf::AddInPlace( const CQuaternionf &in_Quat )
00527 {
00528 return Add( *this, in_Quat );
00529 }
00530
00531 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Add
00532 (
00533 const CQuaternionf &in_Quat1,
00534 const CQuaternionf &in_Quat2
00535 )
00536 {
00537 m_W = in_Quat1.m_W + in_Quat2.m_W;
00538 m_X = in_Quat1.m_X + in_Quat2.m_X;
00539 m_Y = in_Quat1.m_Y + in_Quat2.m_Y;
00540 m_Z = in_Quat1.m_Z + in_Quat2.m_Z;
00541 return *this;
00542 }
00543
00544 SICPPSDK_INLINE CQuaternionf& CQuaternionf::ConjugateInPlace()
00545 {
00546 return Conjugate(*this);
00547 }
00548
00549 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Conjugate( const CQuaternionf &in_Quat)
00550 {
00551 m_W = in_Quat.m_W;
00552 m_X = -in_Quat.m_X;
00553 m_Y = -in_Quat.m_Y;
00554 m_Z = -in_Quat.m_Z;
00555
00556 return( *this );
00557 }
00558
00559 SICPPSDK_INLINE CQuaternionf& CQuaternionf::InvertInPlace()
00560 {
00561 return Invert(*this);
00562 }
00563
00564 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Invert( const CQuaternionf &in_Quat)
00565 {
00566 return Conjugate(in_Quat);
00567 }
00568
00569 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SetIdentity()
00570 {
00571 m_W = 1.0;
00572 m_X = m_Y = m_Z = 0.0;
00573
00574 return( *this );
00575 }
00576
00577 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Copy( const CQuaternionf &in_Quat )
00578 {
00579 return *this = in_Quat;
00580 }
00581
00582 SICPPSDK_INLINE CVector3f CQuaternionf::GetVector3( ) const
00583 {
00584 return CVector3f( m_X, m_Y, m_Z);
00585 }
00586
00587 SICPPSDK_INLINE CVector4f CQuaternionf::GetVector4( ) const
00588 {
00589 return CVector4f( m_X, m_Y, m_Z, m_W);
00590 }
00591
00592 SICPPSDK_INLINE void CQuaternionf::Get
00593 (
00594 float &io_W,
00595 float &io_X,
00596 float &io_Y,
00597 float &io_Z
00598 ) const
00599 {
00600 io_W = m_W;
00601 io_X = m_X;
00602 io_Y = m_Y;
00603 io_Z = m_Z;
00604 }
00605
00606 SICPPSDK_INLINE void CQuaternionf::Get( CVector4f &io_XYZWVector ) const
00607 {
00608 io_XYZWVector.Set( m_X, m_Y, m_Z, m_W);
00609 }
00610
00611 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set
00612 (
00613 float in_W,
00614 float in_X,
00615 float in_Y,
00616 float in_Z
00617 )
00618 {
00619 m_W = in_W;
00620 m_X = in_X;
00621 m_Y = in_Y;
00622 m_Z = in_Z;
00623
00624 return *this;
00625 }
00626
00627 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set( const CVector3f &in_XYZVector )
00628 {
00629 m_W = 1.0;
00630 m_X = in_XYZVector.GetX();
00631 m_Y = in_XYZVector.GetY();
00632 m_Z = in_XYZVector.GetZ();
00633
00634 return *this;
00635 }
00636
00637 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Set( const CVector4f &in_XYZWVector )
00638 {
00639 m_W = in_XYZWVector.GetW();
00640 m_X = in_XYZWVector.GetX();
00641 m_Y = in_XYZWVector.GetY();
00642 m_Z = in_XYZWVector.GetZ();
00643
00644 return *this;
00645 }
00646
00647 SICPPSDK_INLINE float CQuaternionf::GetValue( short in_nIndex ) const
00648 {
00649 assert(in_nIndex >= 0 && in_nIndex < 4);
00650
00651 switch (in_nIndex)
00652 {
00653 case 0: return m_W;
00654 case 1: return m_X;
00655 case 2: return m_Y;
00656 case 3: return m_Z;
00657 }
00658
00659 return 0.0;
00660 }
00661
00662 SICPPSDK_INLINE CQuaternionf& CQuaternionf::SetValue( short in_nIndex, float newVal)
00663 {
00664 assert(in_nIndex >= 0 && in_nIndex < 4);
00665
00666 switch (in_nIndex)
00667 {
00668 case 0: m_W = newVal; break;
00669 case 1: m_X = newVal; break;
00670 case 2: m_Y = newVal; break;
00671 case 3: m_Z = newVal; break;
00672
00673 }
00674
00675 return *this;
00676 }
00677
00678 SICPPSDK_INLINE float CQuaternionf::GetW() const
00679 {
00680 return m_W;
00681 }
00682
00683 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutW( float newVal)
00684 {
00685 m_W = newVal;
00686
00687 return *this;
00688 }
00689
00690 SICPPSDK_INLINE float CQuaternionf::GetZ() const
00691 {
00692 return m_Z;
00693 }
00694
00695 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutZ( float newVal)
00696 {
00697 m_Z = newVal;
00698 return *this;
00699 }
00700
00701 SICPPSDK_INLINE float CQuaternionf::GetY() const
00702 {
00703 return m_Y;
00704 }
00705
00706 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutY( float newVal)
00707 {
00708 m_Y = newVal;
00709 return *this;
00710 }
00711
00712
00713 SICPPSDK_INLINE float CQuaternionf::GetX() const
00714 {
00715 return m_X;
00716 }
00717
00718 SICPPSDK_INLINE CQuaternionf& CQuaternionf::PutX( float newVal)
00719 {
00720 m_X = newVal;
00721 return *this;
00722 }
00723
00724 SICPPSDK_INLINE CQuaternionf& CQuaternionf::NormalizeInPlace()
00725 {
00726 float rLen = GetSquaredLength();
00727
00728 if( fabs( rLen - 1.0f ) >= PicoEPS )
00729 {
00730 if( rLen < PicoEPS )
00731 {
00732 m_X = m_Y = m_Z = 0.0;
00733 m_W = 1.0;
00734 }
00735 else
00736 {
00737 rLen = 1.0f / sqrt( rLen );
00738 m_W *= rLen;
00739 m_X *= rLen;
00740 m_Y *= rLen;
00741 m_Z *= rLen;
00742
00743 LimitValue( m_W, -1.0, 1.0 );
00744 }
00745 }
00746 else
00747 {
00748 LimitValue( m_W, -1.0, 1.0 );
00749 }
00750
00751 return( *this );
00752 }
00753
00754 SICPPSDK_INLINE CQuaternionf& CQuaternionf::Slerp
00755 (
00756 const CQuaternionf& in_quatStart,
00757 const CQuaternionf& in_quatEnd,
00758 const float in_fU
00759 )
00760 {
00761 float fDot, fScale1, fScale2;
00762 bool bNegate = false;
00763
00764 fDot = in_quatStart.Dot( in_quatEnd );
00765 if ( fDot < 0.0 )
00766 {
00767 fDot = -fDot;
00768 bNegate = true;
00769 }
00770
00771 if( fDot >= ( 1.0f - MicroEPS ) )
00772 {
00773 fScale1 = 1.0f - in_fU;
00774 fScale2 = in_fU;
00775 }
00776 else
00777 {
00778 float fAngle, fFactor;
00779
00780 LimitValue( fDot, -1.0, 1.0 );
00781 fAngle = acos( fDot );
00782 fFactor = 1.0f / sin( fAngle );
00783
00784 fScale1 = sin( (1.0f - in_fU) * fAngle ) * fFactor;
00785 fScale2 = sin( in_fU * fAngle ) * fFactor;
00786 }
00787
00788 if( bNegate == true )
00789 fScale2 = -fScale2;
00790
00791 m_W = fScale1 * in_quatStart.m_W + fScale2 * in_quatEnd.m_W;
00792 m_X = fScale1 * in_quatStart.m_X + fScale2 * in_quatEnd.m_X;
00793 m_Y = fScale1 * in_quatStart.m_Y + fScale2 * in_quatEnd.m_Y;
00794 m_Z = fScale1 * in_quatStart.m_Z + fScale2 * in_quatEnd.m_Z;
00795
00796 return( *this );
00797 }
00798
00799 SICPPSDK_INLINE float CQuaternionf::Dot( const CQuaternionf& in_quat ) const
00800 {
00801 return( GetW() * in_quat.GetW() +
00802 GetX() * in_quat.GetX() +
00803 GetY() * in_quat.GetY() +
00804 GetZ() * in_quat.GetZ() );
00805 }
00806
00807 SICPPSDK_INLINE bool CQuaternionf::EpsilonEquals( const CQuaternionf& in_quat, const float in_fEpsilon ) const
00808 {
00809 return( fabs( GetW() - in_quat.GetW() ) < in_fEpsilon &&
00810 fabs( GetX() - in_quat.GetX() ) < in_fEpsilon &&
00811 fabs( GetY() - in_quat.GetY() ) < in_fEpsilon &&
00812 fabs( GetZ() - in_quat.GetZ() ) < in_fEpsilon );
00813 }
00814
00815 };
00816 };
00817
00818 #endif // __XSIQUATERNIONF_H__