SIBCRotationd.h

00001 //***************************************************************************************
00002 //
00003 // File supervisor: Softimage 3D Games & 3D Bridge team
00004 //
00005 // (c) Copyright 1999-2002 Avid Technology, Inc. . All rights reserved.
00006 //
00007 // SIBCRotationd.h  | Main header file for CSIBCRotationd implementation
00008 //***************************************************************************************
00009 
00010 /****************************************************************************************
00011 THIS CODE IS PUBLISHED AS A SAMPLE ONLY AND IS PROVIDED "AS IS".
00012 IN NO EVENT SHALL SOFTIMAGE, AVID TECHNOLOGY, INC. AND/OR THEIR RESPECTIVE
00013 SUPPLIERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
00014 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00015 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
00016 CONNECTION WITH THE USE OR PERFORMANCE OF THIS CODE .
00017 
00018 COPYRIGHT NOTICE. Copyright © 1999-2002 Avid Technology Inc. . All rights reserved. 
00019 
00020 SOFTIMAGE is a registered trademark of Avid Technology Inc. or its subsidiaries 
00021 or divisions. Windows NT is a registered trademark of Microsoft Corp. All other
00022 trademarks contained herein are the property of their respective owners. 
00023 ****************************************************************************************/
00024 
00025 #if (_MSC_VER > 1000) || defined(SGI_COMPILER)
00026 #pragma once
00027 #endif
00028 
00029 //******************************************************************************
00030 // Defines
00031 //******************************************************************************
00032 
00033 #ifndef _ROTATION_H_
00034 #define _ROTATION_H_
00035 
00036 //******************************************************************************
00037 // Includes
00038 //******************************************************************************
00039 
00040 #include "SIBCMathLib.h"
00041 
00042 //******************************************************************************
00043 // Typedefs
00044 //******************************************************************************
00045 
00046 // Utility functions
00056 double F3DArcSinCos( double dSinus, double dCosinus );
00057 
00063 void F3DLimit( double& io_dVal, double in_dMin, double in_dMax );
00064 
00069 void F3DQuatToMat( const CSIBCQuaterniond& in_quat, CSIBCRotMatd& out_mat );
00070 
00075 void F3DMatToQuat( const CSIBCRotMatd& in_mat, CSIBCQuaterniond& out_quat );
00076 
00081 void F3DEulerToQuat( const CSIBCVector3Dd& in_vct, CSIBCQuaterniond& out_quat );
00082 
00087 void F3DEulerToMat( const CSIBCVector3Dd& in_vct, CSIBCRotMatd& out_mat ); 
00088 
00093 void F3DMatToEuler( const CSIBCRotMatd& in_mat, CSIBCVector3Dd& out_vct );
00094 
00104 void F3DMatToEulerUsingTarget( const CSIBCRotMatd& in_mat, CSIBCVector3Dd& inout_vct );
00105 
00111 void F3DQuatToAxisAngle( const CSIBCQuaterniond& in_quat, CSIBCVector3Dd& out_vctAxis, double& out_dAngle );
00112 
00118 void F3DAxisAngleToQuat( const CSIBCVector3Dd& in_vctAxis, const double& in_dAngle, CSIBCQuaterniond& out_quat );
00119 
00120 // Angle utility functions
00121 
00127 double F3DBoundAngleInMinus2PITo2PI( double in_dDesiredAngle);
00128 
00134 void F3DBoundAngleInZeroToTwoPI( double& in_dAngle );
00135 
00141 void F3DBoundAngleInMinusPIToPI( double& in_dAngle );
00142 
00150 double F3DGetUnboundedAngle( double in_dDesiredAngle, double in_dRefAngle );
00151 
00160 void F3DBoundAnglesInMatrixInMinus2PITo2PI( CSIBCMatrixMNd &io_matMN,   int in_nFirstRow, int in_nLastRow );
00161 
00170 double F3DGetClosestAngle( double in_dAngle, double in_dFirstAngle, double in_dSecondAngle );
00171 
00174 //******************************************************************************
00175 //  Mask Values for m_oRotationInfo. These are used internally by CSIBCRotationd,
00176 //  and do not require documentation.
00177 //******************************************************************************
00178 
00179 #define MASK_ORIGREP                    0x03
00180 #define BITVAL_ORIGREP_QUATERNION       0x00
00181 #define BITVAL_ORIGREP_ROTATION_MATRIX  0x01
00182 #define BITVAL_ORIGREP_EULER_ANGLES     0x02
00183 
00184 #define MASK_ISQUAT_DIRTY               (1 << 2 )   //   00000100
00185 #define MASK_ISMAT_DIRTY                (1 << 3 )   //   00001000
00186 #define MASK_ISANGLES_DIRTY             (1 << 4 )   //   00010000
00187 
00188 // Used to identify which of the three possible representations of a rotation is used.
00189 typedef enum tagE3DROTREPTYPE
00190 {
00191    QUATERNION_REP           = BITVAL_ORIGREP_QUATERNION,
00192    ROTATION_MATRIX_REP      = BITVAL_ORIGREP_ROTATION_MATRIX,
00193    EULER_ANGLES_REP         = BITVAL_ORIGREP_EULER_ANGLES
00194 } E3DRotRepType;
00195 
00196 
00197 //******************************************************************************
00198 // CSIBCRotationd | Implementation of a rotation object.
00199 //******************************************************************************
00200 
00202 
00214 class XSICOREEXPORT CSIBCRotationd
00215 {
00216     // Public members
00217     public:
00218         //****************************************
00219         // IMPLEMENTATION
00220         //****************************************
00221 
00226         CSIBCRotationd();
00227 
00232         CSIBCRotationd( const CSIBCQuaterniond& in_quat );
00233         
00238         CSIBCRotationd( const CSIBCRotMatd& in_matRot );
00239 
00245         CSIBCRotationd( const CSIBCVector3Dd& in_vctXYZAngles );
00246         
00253         CSIBCRotationd( double in_dX, double in_dY, double in_dZ );
00254 
00260         CSIBCRotationd( const E3DAxisType in_axis, const double in_dAngle );
00261 
00267         CSIBCRotationd( const CSIBCVector3Dd& in_vctAxis,
00268                           const double in_dAngle );
00269 
00276         CSIBCRotationd( const CSIBCVector3Dd& in_vctFrom,
00277                           const CSIBCVector3Dd& in_vctTo );
00278 
00279         ~CSIBCRotationd();
00280 
00286         CSIBCRotationd& SetIdentity();
00287 
00295         bool IsIdentity();
00296 
00306         bool IsAlmostIdentity(const double& in_rdTolerance = PICO_EPS) const;
00307 
00315         CSIBCQuaterniond& GetQuat( CSIBCQuaterniond& out_quat );
00316 
00326         const CSIBCRotMatd* GetMatrix();
00327 
00337         CSIBCRotMatd& GetMatrix( CSIBCRotMatd& out_matRot );
00338 
00349         CSIBCVector3Dd& GetXYZAngles( CSIBCVector3Dd& out_vctXYZAngles );
00350 
00361         void GetXYZAngles( double& out_dX, double& out_dY, double& out_dZ );
00362 
00371         void GetAxisAngle( CSIBCVector3Dd& out_vctAxis, double& out_dAngle );
00372 
00378         CSIBCRotationd& Set( const CSIBCRotationd& in_rot );
00379 
00385         CSIBCRotationd& Set( const CSIBCQuaterniond& in_quat );
00386 
00392         CSIBCRotationd& Set( const CSIBCRotMatd& in_matRot );
00393 
00401         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctXYZAngles );
00402 
00411         CSIBCRotationd& Set( double in_dX, double in_dY, double in_dZ );
00412 
00421         CSIBCRotationd& Set( const E3DAxisType in_axis, const double in_dAngle );
00422 
00431         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctAxis, const double in_dAngle );
00432 
00433 
00446         bool Set( const CSIBCVector3Dd& in_vctFrom, const CSIBCVector3Dd& in_vctTo, int& out_bFlip );
00447 
00455         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctX, const CSIBCVector3Dd& in_vctY,
00456                         const CSIBCVector3Dd& in_vctZ );
00457 
00471         bool MinAlignToX( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00472 
00486         bool MinAlignToY( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00487 
00501         bool MinAlignToZ( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00502 
00515         bool AlignToX( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00516 
00529         bool AlignToY( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00530 
00543         bool AlignToZ( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00544 
00563         bool AlignAxesToVct( const E3DAxisType in_eFirstAxis,
00564                            const CSIBCVector3Dd& in_vct1,
00565                            const E3DAxisType in_eSecondAxis,
00566                            const CSIBCVector3Dd& in_vct2,
00567                            int& out_bFlip );
00568 
00579         CSIBCRotationd& Mul( CSIBCRotationd& in_rot1, CSIBCRotationd& in_rot2 ); 
00580 
00590         CSIBCRotationd& Mul( CSIBCRotationd& in_rot );
00591 
00601         CSIBCRotationd& LeftMul( CSIBCRotationd& in_rot );
00602 
00616         CSIBCRotationd& MulUsingEulerAnglesTarget( CSIBCRotationd& in_rot1, 
00617                                               CSIBCRotationd& in_rot2,
00618                                               CSIBCVector3Dd& in_oEulerAngles );
00619 
00620 
00635         CSIBCRotationd& MulAndUpdateEulerAngles( CSIBCRotationd& in_rot1, 
00636                                             CSIBCRotationd& in_rot2, 
00637                                             ULONG in_ulUseRot1OrUseRot2AsTarget); 
00638 
00639 
00645         CSIBCRotationd& Invert( CSIBCRotationd& in_rot );
00646 
00651         CSIBCRotationd& Invert();
00652 
00660         CSIBCRotationd& Interpolate( CSIBCRotationd& in_rot1,
00661                                 CSIBCRotationd& in_rot2,
00662                                 const double in_dU );
00663 
00671         CSIBCVector3Dd& RotateVct( const CSIBCVector3Dd& in_vct, CSIBCVector3Dd& out_vct );
00672 
00680         void RotateVct( const CSIBCVector3Dd *in_vcts,
00681                       const LONG in_lNbVcts,
00682                       CSIBCVector3Dd *out_vcts );
00683 
00691         CSIBCVector3Dd& InvRotateVct( const CSIBCVector3Dd& in_vct, CSIBCVector3Dd& out_vct );
00692 
00700         void InvRotateVct( const CSIBCVector3Dd *in_vcts,
00701                          const LONG in_lNbVcts,
00702                          CSIBCVector3Dd *out_vcts );
00703 
00715         friend CSIBCVector3Dd& MapDirSpaceToWorld(
00716                                              CSIBCRotationd& in_rotFrom,
00717                                              const CSIBCVector3Dd& in_vctDir,
00718                                              CSIBCVector3Dd& out_vctDir );
00719 
00730         friend CSIBCVector3Dd& MapDirWorldToSpace(
00731                                              CSIBCRotationd& in_rotTo,
00732                                              const CSIBCVector3Dd& in_vctDir,
00733                                              CSIBCVector3Dd& out_vctDir );
00734 
00747         friend CSIBCVector3Dd& MapDirSpaceToSpace(
00748                                              CSIBCRotationd& in_rotFrom,
00749                                              CSIBCRotationd& in_rotTo,
00750                                              const CSIBCVector3Dd& in_vctDir,
00751                                              CSIBCVector3Dd& out_vctDir );
00752 
00754         // TO BE IMPLEMENTED LATER IF NEEDED... //
00756 
00757         // IMPORTANT: In the following tests, don't forget to compare q1 to q2
00758         //            and q1 to -q2 if quaternion representation is used.
00759 
00760         // AreAlmostEqual       | Verify if two rotations are equal within epsilon.
00762         friend bool AreAlmostEqual( const CSIBCRotationd& in_rot1,
00763                                   const CSIBCRotationd& in_rot2,
00764                                   const double in_dEpsilon = PICO_EPS );
00765 
00766         // operator==           | Verify equality between rotations.
00768         bool operator ==( const CSIBCRotationd& in_rot ) const;
00769 
00770         // operator!=           | Verify non-equality between rotations.
00772         bool operator !=( const CSIBCRotationd& in_rot ) const;
00773 
00774 
00775     // Protected members
00776     protected:
00777 
00778         //****************************************
00779         // IMPLEMENTATION
00780         //****************************************
00781 
00782         // SetMatrixRep       | Set rotation matrix representation as the
00783         //                      original one and raise dirty flags of
00784         //                      other representations.
00785 
00786         void SetQuatRep();
00787 
00788         // SetQuatRep         | Set quaternion representation as the
00789         //                      original one and raise dirty flags of
00790         //                      other representations.
00791         void SetMatrixRep();
00792 
00793         // SetXYZAnglesRep    | Set Euler angles representation as the
00794         //                      original one and raise dirty flags of
00795         //                      other representations.
00796         void SetXYZAnglesRep();
00797 
00798         // UpdateQuat         | Update the quaternion representation
00799         //                      from the original representation.
00800         void UpdateQuat();
00801 
00802         // UpdateMatrix       | Update the rotation matrix representation
00803         //                      from the original representation.
00804         void UpdateMatrix();
00805         
00806         // UpdateXYZAngles    | Update the Euler angles representation
00807         //                      from the original representation.
00808         void UpdateXYZAngles();
00809 
00810         // NextAxis           | Return the next axis of the given one
00811         //                      (in the order X, Y, Z).
00812         int NextAxis( int in_nAxis );
00813 
00814     // Private members
00815     private:
00816 
00817         //****************************************
00818         // ATTRIBUTES
00819         //****************************************
00820         // CSIBCQuaterniond | CSIBCRotationd | m_quat | Quaternion representation
00821         //          of the rotation (unitary quaternion).
00822         // CSIBCRotMatd | CSIBCRotationd | m_matRot | Rotation matrix
00823         //          representation.
00824         // CSIBCVector3Dd | CSIBCRotationd | m_vctXYZAngles | XYZ Euler angles
00825         //          representation.
00826         // double | CSIBCRotationd | m_dAngle | Original rotation angle
00827         //          used in the quaternion representation.
00828         CSIBCQuaterniond m_quat;
00829         CSIBCRotMatd m_matRot;
00830         CSIBCVector3Dd m_vctXYZAngles;
00831         double m_dAngle;
00832 
00833         //***********************************************************************
00834         // m_oRotationInfo comprises formely known m_bQuatDirty, m_bMatDirty
00835         // and m_bAnglesDirty and the enum m_eOrigRep.
00836         // Bit 0 and 1 = used for enum m_eOrigRep of type E3DRotRepType
00837         // E3DRotRepType : QUATERNION_REP       == value 0 ( bit 0 and  1 set to 0 )            //00
00838         //                 ROTATION_MATRIX_REP  == value 1 ( bit 0 set to 1, bit 1 set to 0 )   //01
00839         //                 EULER_ANGLES_REP     == value 2 ( bit 0 set to 0, bit 1 set to 1 )   //10
00840         // Bit 2 = m_bQuatDirty
00841         // Bit 3 = m_bMatDirty
00842         // Bit 4 = m_bAnglesDirty
00843         // Bit 5 to 7 = unused
00844 
00845         unsigned char m_oRotationInfo;
00846 
00847          void _SetQuatDirty(bool in_bIsDirty );
00848          void _SetMatDirty(bool in_bIsDirty );
00849          void _SetAnglesDirty(bool in_bIsDirty );
00850          void _SetOrigRep(E3DRotRepType in_eOrigRep );
00851 
00852          bool _IsQuatDirty () const;
00853          bool _IsMatDirty () const;
00854          bool _AreAnglesDirty () const;
00855          E3DRotRepType _GetOrigRep() const;
00856 
00857         // Disable copy constructor and assignment operator:
00858         CSIBCRotationd( const CSIBCRotationd& in_rot );
00859         CSIBCRotationd& operator =( const CSIBCRotationd& in_rot );
00860 };
00861 
00862 #endif