SIBCRotationd.h

00001 //***************************************************************************************
00002 //
00003 // File supervisor: Crosswalk team
00004 //
00005 // Copyright 2008 Autodesk, Inc.  All rights reserved.  
00006 // Use of this software is subject to the terms of the Autodesk license agreement 
00007 // provided at the time of installation or download, or which otherwise accompanies 
00008 // this software in either electronic or hard copy form.
00009 //
00010 //***************************************************************************************
00011 
00012 #if (_MSC_VER > 1000) || defined(SGI_COMPILER)
00013 #pragma once
00014 #endif
00015 
00016 //******************************************************************************
00017 // Defines
00018 //******************************************************************************
00019 
00020 #ifndef _ROTATION_H_
00021 #define _ROTATION_H_
00022 
00023 //******************************************************************************
00024 // Includes
00025 //******************************************************************************
00026 
00027 #include "SIBCMathLib.h"
00028 
00029 //******************************************************************************
00030 // Typedefs
00031 //******************************************************************************
00032 
00033 // Utility functions
00043 double F3DArcSinCos( double dSinus, double dCosinus );
00044 
00050 void F3DLimit( double& io_dVal, double in_dMin, double in_dMax );
00051 
00056 void F3DQuatToMat( const CSIBCQuaterniond& in_quat, CSIBCRotMatd& out_mat );
00057 
00062 void F3DMatToQuat( const CSIBCRotMatd& in_mat, CSIBCQuaterniond& out_quat );
00063 
00068 void F3DEulerToQuat( const CSIBCVector3Dd& in_vct, CSIBCQuaterniond& out_quat );
00069 
00074 void F3DEulerToMat( const CSIBCVector3Dd& in_vct, CSIBCRotMatd& out_mat ); 
00075 
00080 void F3DMatToEuler( const CSIBCRotMatd& in_mat, CSIBCVector3Dd& out_vct );
00081 
00091 void F3DMatToEulerUsingTarget( const CSIBCRotMatd& in_mat, CSIBCVector3Dd& inout_vct );
00092 
00098 void F3DQuatToAxisAngle( const CSIBCQuaterniond& in_quat, CSIBCVector3Dd& out_vctAxis, double& out_dAngle );
00099 
00105 void F3DAxisAngleToQuat( const CSIBCVector3Dd& in_vctAxis, const double& in_dAngle, CSIBCQuaterniond& out_quat );
00106 
00107 // Angle utility functions
00108 
00114 double F3DBoundAngleInMinus2PITo2PI( double in_dDesiredAngle);
00115 
00121 void F3DBoundAngleInZeroToTwoPI( double& in_dAngle );
00122 
00128 void F3DBoundAngleInMinusPIToPI( double& in_dAngle );
00129 
00137 double F3DGetUnboundedAngle( double in_dDesiredAngle, double in_dRefAngle );
00138 
00147 void F3DBoundAnglesInMatrixInMinus2PITo2PI( CSIBCMatrixMNd &io_matMN,   int in_nFirstRow, int in_nLastRow );
00148 
00157 double F3DGetClosestAngle( double in_dAngle, double in_dFirstAngle, double in_dSecondAngle );
00158 
00161 //******************************************************************************
00162 //  Mask Values for m_oRotationInfo. These are used internally by CSIBCRotationd,
00163 //  and do not require documentation.
00164 //******************************************************************************
00165 
00166 #define MASK_ORIGREP                    0x03
00167 #define BITVAL_ORIGREP_QUATERNION       0x00
00168 #define BITVAL_ORIGREP_ROTATION_MATRIX  0x01
00169 #define BITVAL_ORIGREP_EULER_ANGLES     0x02
00170 
00171 #define MASK_ISQUAT_DIRTY               (1 << 2 )   //   00000100
00172 #define MASK_ISMAT_DIRTY                (1 << 3 )   //   00001000
00173 #define MASK_ISANGLES_DIRTY             (1 << 4 )   //   00010000
00174 
00175 // Used to identify which of the three possible representations of a rotation is used.
00176 typedef enum tagE3DROTREPTYPE
00177 {
00178    QUATERNION_REP           = BITVAL_ORIGREP_QUATERNION,
00179    ROTATION_MATRIX_REP      = BITVAL_ORIGREP_ROTATION_MATRIX,
00180    EULER_ANGLES_REP         = BITVAL_ORIGREP_EULER_ANGLES
00181 } E3DRotRepType;
00182 
00183 
00184 //******************************************************************************
00185 // CSIBCRotationd | Implementation of a rotation object.
00186 //******************************************************************************
00187 
00189 
00201 class XSICOREEXPORT CSIBCRotationd
00202 {
00203     // Public members
00204     public:
00205         //****************************************
00206         // IMPLEMENTATION
00207         //****************************************
00208 
00213         CSIBCRotationd();
00214 
00219         CSIBCRotationd( const CSIBCQuaterniond& in_quat );
00220         
00225         CSIBCRotationd( const CSIBCRotMatd& in_matRot );
00226 
00232         CSIBCRotationd( const CSIBCVector3Dd& in_vctXYZAngles );
00233         
00240         CSIBCRotationd( double in_dX, double in_dY, double in_dZ );
00241 
00247         CSIBCRotationd( const E3DAxisType in_axis, const double in_dAngle );
00248 
00254         CSIBCRotationd( const CSIBCVector3Dd& in_vctAxis,
00255                           const double in_dAngle );
00256 
00263         CSIBCRotationd( const CSIBCVector3Dd& in_vctFrom,
00264                           const CSIBCVector3Dd& in_vctTo );
00265 
00266         ~CSIBCRotationd();
00267 
00273         CSIBCRotationd& SetIdentity();
00274 
00282         bool IsIdentity();
00283 
00293         bool IsAlmostIdentity(const double& in_rdTolerance = PICO_EPS) const;
00294 
00302         CSIBCQuaterniond& GetQuat( CSIBCQuaterniond& out_quat );
00303 
00313         const CSIBCRotMatd* GetMatrix();
00314 
00324         CSIBCRotMatd& GetMatrix( CSIBCRotMatd& out_matRot );
00325 
00336         CSIBCVector3Dd& GetXYZAngles( CSIBCVector3Dd& out_vctXYZAngles );
00337 
00348         void GetXYZAngles( double& out_dX, double& out_dY, double& out_dZ );
00349 
00358         void GetAxisAngle( CSIBCVector3Dd& out_vctAxis, double& out_dAngle );
00359 
00365         CSIBCRotationd& Set( const CSIBCRotationd& in_rot );
00366 
00372         CSIBCRotationd& Set( const CSIBCQuaterniond& in_quat );
00373 
00379         CSIBCRotationd& Set( const CSIBCRotMatd& in_matRot );
00380 
00388         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctXYZAngles );
00389 
00398         CSIBCRotationd& Set( double in_dX, double in_dY, double in_dZ );
00399 
00408         CSIBCRotationd& Set( const E3DAxisType in_axis, const double in_dAngle );
00409 
00418         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctAxis, const double in_dAngle );
00419 
00420 
00433         bool Set( const CSIBCVector3Dd& in_vctFrom, const CSIBCVector3Dd& in_vctTo, int& out_bFlip );
00434 
00442         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctX, const CSIBCVector3Dd& in_vctY,
00443                         const CSIBCVector3Dd& in_vctZ );
00444 
00458         bool MinAlignToX( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00459 
00473         bool MinAlignToY( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00474 
00488         bool MinAlignToZ( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00489 
00502         bool AlignToX( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00503 
00516         bool AlignToY( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00517 
00530         bool AlignToZ( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00531 
00550         bool AlignAxesToVct( const E3DAxisType in_eFirstAxis,
00551                            const CSIBCVector3Dd& in_vct1,
00552                            const E3DAxisType in_eSecondAxis,
00553                            const CSIBCVector3Dd& in_vct2,
00554                            int& out_bFlip );
00555 
00566         CSIBCRotationd& Mul( CSIBCRotationd& in_rot1, CSIBCRotationd& in_rot2 ); 
00567 
00577         CSIBCRotationd& Mul( CSIBCRotationd& in_rot );
00578 
00588         CSIBCRotationd& LeftMul( CSIBCRotationd& in_rot );
00589 
00603         CSIBCRotationd& MulUsingEulerAnglesTarget( CSIBCRotationd& in_rot1, 
00604                                               CSIBCRotationd& in_rot2,
00605                                               CSIBCVector3Dd& in_oEulerAngles );
00606 
00607 
00622         CSIBCRotationd& MulAndUpdateEulerAngles( CSIBCRotationd& in_rot1, 
00623                                             CSIBCRotationd& in_rot2, 
00624                                             ULONG in_ulUseRot1OrUseRot2AsTarget); 
00625 
00626 
00632         CSIBCRotationd& Invert( CSIBCRotationd& in_rot );
00633 
00638         CSIBCRotationd& Invert();
00639 
00647         CSIBCRotationd& Interpolate( CSIBCRotationd& in_rot1,
00648                                 CSIBCRotationd& in_rot2,
00649                                 const double in_dU );
00650 
00658         CSIBCVector3Dd& RotateVct( const CSIBCVector3Dd& in_vct, CSIBCVector3Dd& out_vct );
00659 
00667         void RotateVct( const CSIBCVector3Dd *in_vcts,
00668                       const LONG in_lNbVcts,
00669                       CSIBCVector3Dd *out_vcts );
00670 
00678         CSIBCVector3Dd& InvRotateVct( const CSIBCVector3Dd& in_vct, CSIBCVector3Dd& out_vct );
00679 
00687         void InvRotateVct( const CSIBCVector3Dd *in_vcts,
00688                          const LONG in_lNbVcts,
00689                          CSIBCVector3Dd *out_vcts );
00690 
00702         friend CSIBCVector3Dd& MapDirSpaceToWorld(
00703                                              CSIBCRotationd& in_rotFrom,
00704                                              const CSIBCVector3Dd& in_vctDir,
00705                                              CSIBCVector3Dd& out_vctDir );
00706 
00717         friend CSIBCVector3Dd& MapDirWorldToSpace(
00718                                              CSIBCRotationd& in_rotTo,
00719                                              const CSIBCVector3Dd& in_vctDir,
00720                                              CSIBCVector3Dd& out_vctDir );
00721 
00734         friend CSIBCVector3Dd& MapDirSpaceToSpace(
00735                                              CSIBCRotationd& in_rotFrom,
00736                                              CSIBCRotationd& in_rotTo,
00737                                              const CSIBCVector3Dd& in_vctDir,
00738                                              CSIBCVector3Dd& out_vctDir );
00739 
00741         // TO BE IMPLEMENTED LATER IF NEEDED... //
00743 
00744         // IMPORTANT: In the following tests, don't forget to compare q1 to q2
00745         //            and q1 to -q2 if quaternion representation is used.
00746 
00747         // AreAlmostEqual       | Verify if two rotations are equal within epsilon.
00749         friend bool AreAlmostEqual( const CSIBCRotationd& in_rot1,
00750                                   const CSIBCRotationd& in_rot2,
00751                                   const double in_dEpsilon = PICO_EPS );
00752 
00753         // operator==           | Verify equality between rotations.
00755         bool operator ==( const CSIBCRotationd& in_rot ) const;
00756 
00757         // operator!=           | Verify non-equality between rotations.
00759         bool operator !=( const CSIBCRotationd& in_rot ) const;
00760 
00761 
00762     // Protected members
00763     protected:
00764 
00765         //****************************************
00766         // IMPLEMENTATION
00767         //****************************************
00768 
00769         // SetMatrixRep       | Set rotation matrix representation as the
00770         //                      original one and raise dirty flags of
00771         //                      other representations.
00772 
00773         void SetQuatRep();
00774 
00775         // SetQuatRep         | Set quaternion representation as the
00776         //                      original one and raise dirty flags of
00777         //                      other representations.
00778         void SetMatrixRep();
00779 
00780         // SetXYZAnglesRep    | Set Euler angles representation as the
00781         //                      original one and raise dirty flags of
00782         //                      other representations.
00783         void SetXYZAnglesRep();
00784 
00785         // UpdateQuat         | Update the quaternion representation
00786         //                      from the original representation.
00787         void UpdateQuat();
00788 
00789         // UpdateMatrix       | Update the rotation matrix representation
00790         //                      from the original representation.
00791         void UpdateMatrix();
00792         
00793         // UpdateXYZAngles    | Update the Euler angles representation
00794         //                      from the original representation.
00795         void UpdateXYZAngles();
00796 
00797         // NextAxis           | Return the next axis of the given one
00798         //                      (in the order X, Y, Z).
00799         int NextAxis( int in_nAxis );
00800 
00801     // Private members
00802     private:
00803 
00804         //****************************************
00805         // ATTRIBUTES
00806         //****************************************
00807         // CSIBCQuaterniond | CSIBCRotationd | m_quat | Quaternion representation
00808         //          of the rotation (unitary quaternion).
00809         // CSIBCRotMatd | CSIBCRotationd | m_matRot | Rotation matrix
00810         //          representation.
00811         // CSIBCVector3Dd | CSIBCRotationd | m_vctXYZAngles | XYZ Euler angles
00812         //          representation.
00813         // double | CSIBCRotationd | m_dAngle | Original rotation angle
00814         //          used in the quaternion representation.
00815         CSIBCQuaterniond m_quat;
00816         CSIBCRotMatd m_matRot;
00817         CSIBCVector3Dd m_vctXYZAngles;
00818         double m_dAngle;
00819 
00820         //***********************************************************************
00821         // m_oRotationInfo comprises formely known m_bQuatDirty, m_bMatDirty
00822         // and m_bAnglesDirty and the enum m_eOrigRep.
00823         // Bit 0 and 1 = used for enum m_eOrigRep of type E3DRotRepType
00824         // E3DRotRepType : QUATERNION_REP       == value 0 ( bit 0 and  1 set to 0 )            //00
00825         //                 ROTATION_MATRIX_REP  == value 1 ( bit 0 set to 1, bit 1 set to 0 )   //01
00826         //                 EULER_ANGLES_REP     == value 2 ( bit 0 set to 0, bit 1 set to 1 )   //10
00827         // Bit 2 = m_bQuatDirty
00828         // Bit 3 = m_bMatDirty
00829         // Bit 4 = m_bAnglesDirty
00830         // Bit 5 to 7 = unused
00831 
00832         unsigned char m_oRotationInfo;
00833 
00834          void _SetQuatDirty(bool in_bIsDirty );
00835          void _SetMatDirty(bool in_bIsDirty );
00836          void _SetAnglesDirty(bool in_bIsDirty );
00837          void _SetOrigRep(E3DRotRepType in_eOrigRep );
00838 
00839          bool _IsQuatDirty () const;
00840          bool _IsMatDirty () const;
00841          bool _AreAnglesDirty () const;
00842          E3DRotRepType _GetOrigRep() const;
00843 
00844         // Disable copy constructor and assignment operator:
00845         CSIBCRotationd( const CSIBCRotationd& in_rot );
00846         CSIBCRotationd& operator =( const CSIBCRotationd& in_rot );
00847 };
00848 
00849 #endif