# 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