00001
00011
00012 #ifndef __XSIROTATIONF_H__
00013 #define __XSIROTATIONF_H__
00014
00015 #include "sicppsdk.h"
00016 #include "xsi_math.h"
00017 #include "xsi_vector3f.h"
00018 #include "xsi_vector4f.h"
00019 #include "xsi_matrix3f.h"
00020 #include "xsi_quaternionf.h"
00021
00022 namespace XSI {
00023
00024 namespace MATH {
00025
00026
00036
00037 class SICPPSDKDECL CRotationf
00038 {
00039 public:
00042 enum RotationOrder
00043 {
00044 siXYZ = 0,
00045 siXZY = 1,
00046 siYXZ = 2,
00047 siYZX = 3,
00048 siZXY = 4,
00049 siZYX = 5
00050 };
00051
00054 enum RotationRep
00055 {
00056 siQuaternionRot = 0,
00057 siEulerRot,
00058 siAxisAngleRot
00059 };
00060
00062 SICPPSDK_INLINE CRotationf();
00063
00067 SICPPSDK_INLINE CRotationf( const CRotationf& in_rotation);
00068
00074 SICPPSDK_INLINE CRotationf( const CVector3f &in_EulerAngles, const RotationOrder in_RotOrder = siXYZ);
00075
00083 SICPPSDK_INLINE CRotationf( const float in_X, const float in_Y, const float in_Z, const RotationOrder in_RotOrder = siXYZ);
00084
00089 SICPPSDK_INLINE CRotationf( const CQuaternionf &in_Quat );
00090
00096 SICPPSDK_INLINE CRotationf( const CVector3f &in_Axis, const float in_Angle );
00097
00099 SICPPSDK_INLINE ~CRotationf();
00100
00105 SICPPSDK_INLINE CRotationf & operator=( const CRotationf & in_rotation);
00106
00112 SICPPSDK_INLINE CVector3f GetXYZAngles(const RotationOrder in_Order) const;
00113
00120 SICPPSDK_INLINE void GetXYZAngles( float &io_X, float &io_Y, float &io_Z ) const;
00121
00126 SICPPSDK_INLINE CVector3f GetXYZAngles( ) const;
00127
00131 SICPPSDK_INLINE RotationOrder GetOrder() const;
00132
00137 SICPPSDK_INLINE void SetOrder( const RotationOrder in_rotOrder );
00138
00142 SICPPSDK_INLINE RotationRep GetRepresentation() const;
00143
00149 SICPPSDK_INLINE void SetRepresentation( const RotationRep in_rotRep, const RotationOrder in_order = siXYZ );
00150
00161 SICPPSDK_INLINE CRotationf& Set( const RotationOrder in_order, const bool in_bCompensate = false );
00162
00169 SICPPSDK_INLINE CRotationf& Set( const CVector3f &in_EulerAngles, const RotationOrder in_Order = siXYZ);
00170
00179 SICPPSDK_INLINE CRotationf& Set( const float in_X, const float in_Y, const float in_Z, const RotationOrder in_Order = siXYZ);
00180
00186 SICPPSDK_INLINE CRotationf& Set( const CQuaternionf &in_Quat);
00187
00192 SICPPSDK_INLINE CRotationf& Mul( const CRotationf &in_rot );
00193
00199 SICPPSDK_INLINE CRotationf& Mul( const CRotationf &in_rot1, const CRotationf &in_rot2 );
00200
00205 SICPPSDK_INLINE CRotationf& Mul( const float in_scalar );
00206
00211 SICPPSDK_INLINE CRotationf& LeftMul( const CRotationf &in_rot );
00212
00219 SICPPSDK_INLINE CRotationf& Interpolate( const CRotationf& in_rot1, const CRotationf& in_rot2, const float in_u );
00220
00226 SICPPSDK_INLINE CRotationf& Div ( const CRotationf& in_rot1, const float in_scalar );
00227
00232 SICPPSDK_INLINE CRotationf& Div ( const float in_scalar );
00233
00238 SICPPSDK_INLINE CRotationf& Div( const CRotationf& in_rot );
00239
00245 SICPPSDK_INLINE CRotationf& Div( const CRotationf& in_rot1, const CRotationf& in_rot2 );
00246
00250 SICPPSDK_INLINE CRotationf& Invert();
00251
00256 SICPPSDK_INLINE CRotationf& Invert( const CRotationf &in_rot );
00257
00262 SICPPSDK_INLINE CQuaternionf GetQuaternion() const;
00263
00269 SICPPSDK_INLINE CRotationf& operator = ( const CQuaternionf &in_Quat );
00270
00276 SICPPSDK_INLINE CVector3f GetAxisAngle( float &io_Angle) const;
00277
00284 SICPPSDK_INLINE CRotationf& Set( const CVector3f &in_Axis, const float in_Angle );
00285
00288 SICPPSDK_INLINE void SetIdentity();
00289
00295 SICPPSDK_INLINE bool Equals( const CRotationf &in_rot ) const;
00296
00302 SICPPSDK_INLINE bool EpsilonEquals( const CRotationf& in_rot, const float in_fEpsilon ) const;
00303
00309 SICPPSDK_INLINE bool operator == ( const CRotationf &in_rot ) const;
00310
00316 SICPPSDK_INLINE bool operator !=(const CRotationf & in_rot ) const;
00317
00325 SICPPSDK_INLINE bool operator < ( const CRotationf& in_rot ) const;
00326
00327 private:
00328 SICPPSDK_INLINE void QuatToEuler( const CQuaternionf& in_quat, CVector3f& out_vct, const RotationOrder in_eOrder );
00329 SICPPSDK_INLINE void QuatToMat( const CQuaternionf& in_quat, CMatrix3f& out_mat );
00330 SICPPSDK_INLINE void AxisAngleToQuat( const CVector3f& in_vctAxis, const float in_fAngle, CQuaternionf& out_quat);
00331 SICPPSDK_INLINE void QuatToAxisAngle(const CQuaternionf& in_quat, CVector3f& out_vctAxis, float& out_fAngle );
00332
00333 SICPPSDK_INLINE RotationOrder GetRotOrder() const;
00334
00335 float m_X, m_Y, m_Z;
00336 union
00337 {
00338 float m_W;
00339 float m_Angle;
00340 RotationOrder m_rotOrder;
00341 };
00342 unsigned char m_rotRep;
00343 };
00344
00345 SICPPSDK_INLINE CRotationf::CRotationf()
00346 {
00347 m_X = m_Y = m_Z = 0.0;
00348 m_W = 1.0;
00349 m_rotRep = siQuaternionRot;
00350 }
00351
00352 SICPPSDK_INLINE CRotationf::CRotationf( const CRotationf& in_rotation)
00353 {
00354 *this = in_rotation;
00355 }
00356
00357 SICPPSDK_INLINE CRotationf::CRotationf( const CQuaternionf& in_quat )
00358 {
00359 Set( in_quat );
00360 }
00361
00362 SICPPSDK_INLINE CRotationf::CRotationf( const CVector3f &in_Angles, const RotationOrder in_Order)
00363 {
00364 Set( in_Angles, in_Order );
00365 }
00366
00367 SICPPSDK_INLINE CRotationf::CRotationf( const CVector3f &in_Axis, const float in_fAngle )
00368 {
00369 Set( in_Axis, in_fAngle );
00370 }
00371
00372 SICPPSDK_INLINE CRotationf::CRotationf( float in_fX, float in_fY, float in_fZ, const RotationOrder in_Order )
00373 {
00374 Set( in_fX, in_fY, in_fZ, in_Order );
00375 }
00376
00377 SICPPSDK_INLINE CRotationf::~CRotationf()
00378 {
00379 }
00380
00381 SICPPSDK_INLINE CRotationf& CRotationf::operator=( const CRotationf & in_rotation)
00382 {
00383 m_X = in_rotation.m_X;
00384 m_Y = in_rotation.m_Y;
00385 m_Z = in_rotation.m_Z;
00386 m_W = in_rotation.m_W;
00387 m_rotRep = in_rotation.m_rotRep;
00388 return *this;
00389 }
00390
00391 SICPPSDK_INLINE CRotationf& CRotationf::Set( const CVector3f &in_AngleValues, const RotationOrder in_Order )
00392 {
00393 return Set( in_AngleValues.GetX(), in_AngleValues.GetY(), in_AngleValues.GetZ(), in_Order );
00394 }
00395
00396 SICPPSDK_INLINE CRotationf& CRotationf::Set
00397 (
00398 const float in_fX,
00399 const float in_fY,
00400 const float in_fZ,
00401 const RotationOrder in_Order
00402 )
00403 {
00404 m_rotRep = siEulerRot;
00405 m_rotOrder = in_Order;
00406 m_X = in_fX; m_Y = in_fY; m_Z = in_fZ;
00407
00408 return *this;
00409 }
00410
00411 SICPPSDK_INLINE CRotationf& CRotationf::Set( const RotationOrder in_order, const bool in_bCompensate )
00412 {
00413 if ( m_rotRep != siEulerRot )
00414 {
00415 SetRepresentation( siEulerRot, in_bCompensate ? in_order : siXYZ );
00416 }
00417
00418 if ( in_order != m_rotRep )
00419 {
00420 if ( in_bCompensate )
00421 {
00422 CMatrix3f vRotTmp;
00423 CVector3f vEuler( m_X, m_Y, m_Z );
00424 XSI::MATH::EulerToMat( vEuler, vRotTmp, (int)m_rotOrder );
00425
00426 vEuler.SetNull( );
00427 XSI::MATH::MatToEuler( vRotTmp, vEuler, in_order );
00428 vEuler.Get( m_X, m_Y, m_Z );
00429 }
00430 m_rotOrder = in_order;
00431 }
00432 return *this;
00433 }
00434
00435 SICPPSDK_INLINE CRotationf& CRotationf::Set( const CQuaternionf &in_Quat )
00436 {
00437 m_rotRep = siQuaternionRot;
00438
00439 m_W = in_Quat.GetW();
00440 m_X = in_Quat.GetX();
00441 m_Y = in_Quat.GetY();
00442 m_Z = in_Quat.GetZ();
00443
00444 return *this;
00445 }
00446
00447 SICPPSDK_INLINE CRotationf::RotationOrder CRotationf::GetRotOrder() const
00448 {
00449 return ( m_rotRep == siEulerRot ? m_rotOrder : siXYZ );
00450 }
00451
00452 SICPPSDK_INLINE CVector3f CRotationf::GetXYZAngles(const RotationOrder in_Order) const
00453 {
00454 CVector3f outV;
00455 if ( m_rotRep == siEulerRot && m_rotOrder == in_Order )
00456 {
00457 outV.Set( m_X, m_Y, m_Z );
00458 }
00459 else
00460 {
00461 CRotationf rot( *this );
00462 rot.Set( in_Order, true );
00463 outV.Set( rot.m_X, rot.m_Y, rot.m_Z );
00464 }
00465 return outV;
00466 }
00467
00468 SICPPSDK_INLINE void CRotationf::GetXYZAngles( float &io_fX, float &io_fY, float &io_fZ ) const
00469 {
00470 CVector3f vEuler = GetXYZAngles( GetRotOrder() );
00471 vEuler.Get( io_fX, io_fY, io_fZ );
00472 }
00473
00474 SICPPSDK_INLINE CVector3f CRotationf::GetXYZAngles() const
00475 {
00476 return GetXYZAngles( GetRotOrder() );
00477 }
00478
00479 SICPPSDK_INLINE CRotationf& CRotationf::Mul( const CRotationf &in_rot )
00480 {
00481 return Mul( *this, in_rot );
00482 }
00483
00484 SICPPSDK_INLINE CRotationf& CRotationf::Mul( const CRotationf &in_rot1, const CRotationf &in_rot2 )
00485 {
00486 CQuaternionf q1 = in_rot1.GetQuaternion();
00487 CQuaternionf q2 = in_rot2.GetQuaternion();
00488 q2.Mul( q1 ).NormalizeInPlace();
00489 return Set( q2 );
00490 }
00491
00492 SICPPSDK_INLINE CRotationf& CRotationf::Mul( const float in_scalar )
00493 {
00494 switch (m_rotRep)
00495 {
00496 case siQuaternionRot:
00497 case siEulerRot:
00498 {
00499 CRotationf identity;
00500 Interpolate( identity, *this, in_scalar );
00501 }
00502 break;
00503
00504 case siAxisAngleRot:
00505 {
00506 m_Angle *= in_scalar;
00507 }
00508 break;
00509 }
00510 return *this;
00511 }
00512
00513 SICPPSDK_INLINE CRotationf& CRotationf::Div( const CRotationf &in_rot )
00514 {
00515 return Div( *this, in_rot );
00516 }
00517
00518 SICPPSDK_INLINE CRotationf& CRotationf::Div( const float in_scalar )
00519 {
00520 return Mul( 1.0f/in_scalar );
00521 }
00522
00523 SICPPSDK_INLINE CRotationf& CRotationf::Div( const CRotationf &in_rot1, const CRotationf &in_rot2 )
00524 {
00525 CRotationf rotInv;
00526 return Mul( in_rot1, rotInv.Invert(in_rot2) );
00527 }
00528
00529 SICPPSDK_INLINE CRotationf& CRotationf::LeftMul( const CRotationf &in_rot )
00530 {
00531 return Mul( in_rot, *this );
00532 }
00533
00534 SICPPSDK_INLINE CRotationf& CRotationf::Interpolate ( const CRotationf& in_rot1, const CRotationf& in_rot2, const float in_u )
00535 {
00536 CQuaternionf q1 = in_rot1.GetQuaternion();
00537 CQuaternionf q2 = in_rot2.GetQuaternion();
00538 CQuaternionf q;
00539 q.Slerp( q1, q2, in_u );
00540 return Set( q );
00541 }
00542
00543 SICPPSDK_INLINE CRotationf& CRotationf::Invert( )
00544 {
00545 static RotationOrder InvRotOrder[] = { siZYX, siYZX, siZXY, siXZY, siYXZ, siXYZ };
00546
00547 switch (m_rotRep)
00548 {
00549 case siQuaternionRot:
00550 m_X = -m_X; m_Y = -m_Y; m_Z = -m_Z;
00551 break;
00552 case siEulerRot:
00553 m_rotOrder = InvRotOrder[m_rotOrder];
00554 m_X = -m_X; m_Y = -m_Y; m_Z = -m_Z;
00555 break;
00556 case siAxisAngleRot:
00557 m_Angle = -m_Angle;
00558 break;
00559 }
00560 return *this;
00561 }
00562
00563 SICPPSDK_INLINE CRotationf& CRotationf::Invert( const CRotationf &in_rot )
00564 {
00565 *this = in_rot;
00566 return Invert( );
00567 }
00568
00569 SICPPSDK_INLINE CVector3f CRotationf::GetAxisAngle( float &io_fAngle ) const
00570 {
00571 CVector3f out_axis;
00572 if ( m_rotRep == siAxisAngleRot )
00573 {
00574 out_axis.Set( m_X, m_Y, m_Z );
00575 io_fAngle = m_Angle;
00576 }
00577 else
00578 {
00579 CRotationf rot( *this );
00580 rot.SetRepresentation( siAxisAngleRot );
00581 out_axis.Set( rot.m_X, rot.m_Y, rot.m_Z );
00582 io_fAngle = rot.m_Angle;
00583 }
00584 return out_axis;
00585 }
00586
00587 SICPPSDK_INLINE CRotationf& CRotationf::Set( const CVector3f &in_axis, const float in_fAngle )
00588 {
00589 m_rotRep = siAxisAngleRot;
00590 m_Angle = in_fAngle;
00591 in_axis.Get( m_X, m_Y, m_Z );
00592
00593 return *this;
00594 }
00595
00596 SICPPSDK_INLINE void CRotationf::SetIdentity()
00597 {
00598 switch (m_rotRep)
00599 {
00600 case siQuaternionRot:
00601 m_W = 1.0; m_X = m_Y = m_Z = 0.0;
00602 break;
00603 case siEulerRot:
00604 m_X = m_Y = m_Z = 0.0; m_rotOrder = siXYZ;
00605 break;
00606 case siAxisAngleRot:
00607 m_Angle = 0.0; m_X = 1.0; m_Y = m_Z = 0.0;
00608 break;
00609 }
00610 }
00611
00612 SICPPSDK_INLINE CRotationf::RotationOrder CRotationf::GetOrder() const
00613 {
00614 return m_rotOrder;
00615 }
00616
00617 SICPPSDK_INLINE CRotationf::RotationRep CRotationf::GetRepresentation() const
00618 {
00619 return (CRotationf::RotationRep)m_rotRep;
00620 }
00621
00622 void CRotationf::SetRepresentation( const RotationRep in_rep, const RotationOrder in_order )
00623 {
00624 if ( m_rotRep != in_rep )
00625 {
00626 switch( in_rep )
00627 {
00628 case siQuaternionRot:
00629 {
00630 CQuaternionf l_quat;
00631 switch ( m_rotRep )
00632 {
00633 case siEulerRot:
00634 {
00635 CVector3f l_euler( m_X, m_Y, m_Z );
00636 XSI::MATH::EulerToQuat( l_euler, l_quat, m_rotOrder );
00637 }
00638 break;
00639 case siAxisAngleRot:
00640 {
00641 CVector3f l_axis( m_X, m_Y, m_Z );
00642 if ( l_axis.GetLength() > MicroEPS )
00643 {
00644 l_axis.NormalizeInPlace();
00645 AxisAngleToQuat( l_axis, m_Angle, l_quat );
00646 }
00647 }
00648 break;
00649 }
00650 *this = l_quat;
00651 }
00652 break;
00653
00654 case siEulerRot:
00655 {
00656 CVector3f l_euler;
00657 switch ( m_rotRep )
00658 {
00659 case siQuaternionRot:
00660 {
00661 CQuaternionf l_quat( m_W, m_X, m_Y, m_Z );
00662 l_quat.NormalizeInPlace();
00663 QuatToEuler( l_quat, l_euler, in_order );
00664 }
00665 break;
00666 case siAxisAngleRot:
00667 {
00668 CQuaternionf l_quat;
00669 CVector3f l_axis( m_X, m_Y, m_Z );
00670 if ( l_axis.GetLength() > MicroEPS )
00671 {
00672 l_axis.NormalizeInPlace();
00673 AxisAngleToQuat( l_axis, m_Angle, l_quat );
00674 }
00675 QuatToEuler( l_quat, l_euler, in_order );
00676 }
00677 break;
00678 }
00679 Set( l_euler, in_order );
00680 }
00681 break;
00682 case siAxisAngleRot:
00683 {
00684 float l_angle = 0;
00685 CVector3f l_axis;
00686 switch ( m_rotRep )
00687 {
00688 case siQuaternionRot:
00689 {
00690 CQuaternionf l_quat( m_W, m_X, m_Y, m_Z );
00691 l_quat.NormalizeInPlace();
00692 QuatToAxisAngle( l_quat, l_axis, l_angle );
00693 }
00694 break;
00695
00696 case siEulerRot:
00697 {
00698 CQuaternionf l_quat;
00699 CVector3f l_euler( m_X, m_Y, m_Z );
00700 XSI::MATH::EulerToQuat( l_euler, l_quat, m_rotOrder );
00701 QuatToAxisAngle( l_quat, l_axis, l_angle );
00702 }
00703 break;
00704 }
00705
00706 if ( l_axis.IsNull() )
00707 {
00708 l_axis.Set(1.0, 0.0, 0.0);
00709 }
00710 Set( l_axis, l_angle );
00711 }
00712 break;
00713 }
00714 }
00715 }
00716
00717 SICPPSDK_INLINE CQuaternionf CRotationf::GetQuaternion() const
00718 {
00719 CQuaternionf out_quat;
00720 if ( m_rotRep == siQuaternionRot )
00721 {
00722 out_quat.Set( m_W, m_X, m_Y, m_Z );
00723 }
00724 else
00725 {
00726 CRotationf rot( *this );
00727 rot.SetRepresentation( siQuaternionRot );
00728 out_quat.Set( rot.m_W, rot.m_X, rot.m_Y, rot.m_Z );
00729 }
00730 return out_quat;
00731 }
00732
00733 SICPPSDK_INLINE CRotationf& CRotationf::operator = ( const CQuaternionf &in_Quat )
00734 {
00735 return Set( in_Quat );
00736 }
00737
00738 SICPPSDK_INLINE bool CRotationf::Equals( const CRotationf &in_rot ) const
00739 {
00740 if (this == &in_rot) return true;
00741
00742 CQuaternionf q1 = GetQuaternion();
00743 CQuaternionf q2 = in_rot.GetQuaternion();
00744
00745 return (true == ( q1 == q2) );
00746 }
00747
00748 SICPPSDK_INLINE bool CRotationf::EpsilonEquals( const CRotationf& in_rot, const float in_fEpsilon ) const
00749 {
00750 CRotationf r1( *this );
00751 CRotationf r2( in_rot );
00752 if ( r1.GetRepresentation() != r2.GetRepresentation() )
00753 {
00754 r2.SetRepresentation( r1.GetRepresentation() );
00755 }
00756 switch (r1.GetRepresentation())
00757 {
00758 case siQuaternionRot:
00759 {
00760 return r1.GetQuaternion().EpsilonEquals( r2.GetQuaternion(), in_fEpsilon );
00761 }
00762 case siEulerRot:
00763 {
00764 return ( r1.GetOrder() == r2.GetOrder() && r1.GetXYZAngles().EpsilonEquals( r2.GetXYZAngles(), in_fEpsilon ) );
00765 }
00766 case siAxisAngleRot:
00767 {
00768 float a1, a2;
00769 CVector3f v1 = r1.GetAxisAngle( a1 );
00770 CVector3f v2 = r2.GetAxisAngle( a2 );
00771 return ( fabs( a1 - a2 ) < in_fEpsilon && v1.EpsilonEquals( v2, in_fEpsilon ) );
00772 }
00773 default:
00774 break;
00775 }
00776 return false;
00777 }
00778
00779 SICPPSDK_INLINE bool CRotationf::operator == ( const CRotationf &in_rot ) const
00780 {
00781 return Equals( in_rot );
00782 }
00783
00784 SICPPSDK_INLINE bool CRotationf::operator != ( const CRotationf &in_rot ) const
00785 {
00786 return ! Equals( in_rot );
00787 }
00788
00789 SICPPSDK_INLINE bool CRotationf::operator < ( const CRotationf& in_rot) const
00790 {
00791 if ( m_W != in_rot.m_W ) return m_W < in_rot.m_W;
00792 if ( m_Z != in_rot.m_Z ) return m_Z < in_rot.m_Z;
00793 if ( m_Y != in_rot.m_Y ) return m_Y < in_rot.m_Y;
00794 if ( m_X != in_rot.m_X ) return m_X < in_rot.m_X;
00795 if ( m_rotRep != in_rot.m_rotRep ) return m_rotRep < in_rot.m_rotRep;
00796
00797 return false;
00798 }
00799
00800 SICPPSDK_INLINE void CRotationf::QuatToMat( const CQuaternionf& in_quat, CMatrix3f& out_mat )
00801 {
00802 float d2X, d2Y, d2Z, d2X2, d2Y2, d2Z2, d2WX, d2WY, d2WZ, d2XY, d2XZ, d2YZ;
00803
00804 d2X = (float)2.0 * in_quat.GetX();
00805 d2Y = (float)2.0 * in_quat.GetY();
00806 d2Z = (float)2.0 * in_quat.GetZ();
00807
00808 d2X2 = d2X * in_quat.GetX();
00809 d2Y2 = d2Y * in_quat.GetY();
00810 d2Z2 = d2Z * in_quat.GetZ();
00811
00812 d2WX = d2X * in_quat.GetW();
00813 d2WY = d2Y * in_quat.GetW();
00814 d2WZ = d2Z * in_quat.GetW();
00815 d2XY = d2X * in_quat.GetY();
00816 d2YZ = d2Y * in_quat.GetZ();
00817 d2XZ = d2Z * in_quat.GetX();
00818
00819 out_mat.SetValue( 0, 0, (float)1.0 - d2Y2 - d2Z2 );
00820 out_mat.SetValue( 1, 1, (float)1.0 - d2X2 - d2Z2 );
00821 out_mat.SetValue( 2, 2, (float)1.0 - d2X2 - d2Y2 );
00822 out_mat.SetValue( 0, 1, d2XY + d2WZ );
00823 out_mat.SetValue( 1, 0, d2XY - d2WZ );
00824 out_mat.SetValue( 0, 2, d2XZ - d2WY );
00825 out_mat.SetValue( 2, 0, d2XZ + d2WY );
00826 out_mat.SetValue( 1, 2, d2YZ + d2WX );
00827 out_mat.SetValue( 2, 1, d2YZ - d2WX );
00828 }
00829
00830 SICPPSDK_INLINE void CRotationf::QuatToEuler( const CQuaternionf& in_quat, CVector3f& out_vct, const RotationOrder in_eOrder )
00831 {
00832 CMatrix3f mat;
00833 QuatToMat( in_quat, mat );
00834 XSI::MATH::MatToEuler( mat, out_vct, in_eOrder);
00835 }
00836
00837 SICPPSDK_INLINE void CRotationf::AxisAngleToQuat( const CVector3f& in_vctAxis, const float in_fAngle, CQuaternionf& out_quat)
00838 {
00839 float fCos, fSin;
00840 CVector3f vct(in_vctAxis);
00841
00842 fCos = cos( in_fAngle * 0.5f );
00843 fSin = sin( in_fAngle * 0.5f );
00844
00845 vct.SetLength( fSin );
00846 out_quat.Set( fCos, vct.GetX(), vct.GetY(), vct.GetZ() );
00847 }
00848
00849 SICPPSDK_INLINE void CRotationf::QuatToAxisAngle(const CQuaternionf& in_quat, CVector3f& out_vctAxis, float& out_fAngle )
00850 {
00851 out_fAngle = (float)(2.0 * ::acos( in_quat.GetW() ));
00852
00853
00854 float fSin = (float)sin( 0.5f * out_fAngle );
00855
00856 if( ::fabs( fSin ) < MicroEPS )
00857 {
00858
00859 out_vctAxis.SetNull();
00860 }
00861 else
00862 {
00863
00864 fSin = 1.0f / fSin;
00865 out_vctAxis.PutX( in_quat.GetX() * fSin );
00866 out_vctAxis.PutY( in_quat.GetY() * fSin );
00867 out_vctAxis.PutZ( in_quat.GetZ() * fSin );
00868 }
00869 }
00870
00871 };
00872 };
00873
00874 #endif // __XSIROTATIONF_H__