| 1 | /**************************************************************************************** |
| 2 | |
| 3 | Copyright (C) 2015 Autodesk, Inc. |
| 4 | All rights reserved. |
| 5 | |
| 6 | Use of this software is subject to the terms of the Autodesk license agreement |
| 7 | provided at the time of installation or download, or which otherwise accompanies |
| 8 | this software in either electronic or hard copy form. |
| 9 | |
| 10 | ****************************************************************************************/ |
| 11 | |
| 12 | //! \file fbxaxissystem.h |
| 13 | #ifndef _FBXSDK_SCENE_AXIS_SYSTEM_H_ |
| 14 | #define _FBXSDK_SCENE_AXIS_SYSTEM_H_ |
| 15 | |
| 16 | #include <fbxsdk/fbxsdk_def.h> |
| 17 | |
| 18 | #include <fbxsdk/core/base/fbxarray.h> |
| 19 | #include <fbxsdk/core/base/fbxstring.h> |
| 20 | |
| 21 | #include <fbxsdk/fbxsdk_nsbegin.h> |
| 22 | |
| 23 | /** This class represents the coordinate system of the scene and can convert scenes |
| 24 | to other coordinate systems. By default the FbxScene uses a Y-Up axis |
| 25 | system. If the calling application wishes to change the default axis it will need to define the new |
| 26 | axis system and call the convert method with the scene as argument. The appropriate transforms will be |
| 27 | applied to the first level objects of the scene only (objects whose parent is the scene itself). Child |
| 28 | objects do not need to be transformed since they inherit from their parents. |
| 29 | The adjustment will affect the translation animation curves and the objects pivots values (the rotation |
| 30 | transformation is applied as a pre-rotation transform therefore the rotation animation curves do not need to |
| 31 | be transformed). Once converted, the scene will have its axis definition changed to the new system. |
| 32 | |
| 33 | For example: |
| 34 | \code |
| 35 | FbxScene* lScene = FbxScene::Create(sdkmanager, "MyScene"); |
| 36 | ... |
| 37 | // the scene is filled with objects |
| 38 | |
| 39 | int dir; |
| 40 | lScene->GetGlobalSettings().GetAxisSystem().GetUpVector(dir); // this returns the equivalent of FbxAxisSystem::eYAxis |
| 41 | |
| 42 | FbxAxisSystem max; // we desire to convert the scene from Y-Up to Z-Up |
| 43 | max.ConvertScene(lScene); |
| 44 | |
| 45 | lScene->GetGlobalSettings().GetAxisSystem().GetUpVector(dir); // this will now return the equivalent of FbxAxisSystem::eZAxis |
| 46 | \endcode |
| 47 | |
| 48 | No conversion will take place if the scene current axis system is equal to the new one. |
| 49 | |
| 50 | The EUpVector specifies which axis has the up and down direction in the system (typically this is the Y or Z axis). |
| 51 | The sign of the EUpVector is applied to represent the direction (1 is up and -1 is down relative to the observer). |
| 52 | |
| 53 | The EFrontVector specifies which axis has the front and back direction in the system. It is not an independent variable, |
| 54 | which means it depends on EUpVector. The enum values ParityEven and ParityOdd denote the first one and |
| 55 | the second one of the remain two axes in addition to the up axis. |
| 56 | |
| 57 | For example if the up axis is X, the remain two axes will be Y And Z, so the ParityEven is Y, and the ParityOdd is Z |
| 58 | ; If the up axis is Y, the remain two axes will X And Z, so the ParityEven is X, and the ParityOdd is Z; |
| 59 | If the up axis is Z, the remain two axes will X And Y, so the ParityEven is X, and the ParityOdd is Y. |
| 60 | |
| 61 | There still needs a parameter to denote the direction of the EFrontVector just as the EUpVector. And the sign of the |
| 62 | EFrontVector represents the direction (1 is front and -1 is back relative to observer). |
| 63 | |
| 64 | If the front axis and the up axis are determined, the third axis will be automatically determined as the left one. |
| 65 | The ECoordSystem enum is a parameter to determine the direction of the third axis just as the EUpVector sign. |
| 66 | It determines if the axis system is right-handed or left-handed just as the enum values. |
| 67 | |
| 68 | Some code for reconstructing a FbxAxisSystem object from reference scene. |
| 69 | \code |
| 70 | //the reference scene |
| 71 | FbxScene* lSceneReference = FbxScene::Create(sdkmanager, "ReferenceScene"); |
| 72 | ... |
| 73 | // the scene is filled with objects |
| 74 | |
| 75 | FbxAxisSystem lAxisSytemReference = lSceneReference->GetGlobalSettings().GetAxisSystem(); |
| 76 | |
| 77 | int lUpVectorSign = 1; |
| 78 | int lFrontVectorSign = 1; |
| 79 | |
| 80 | //get upVector and its sign. |
| 81 | EUpVector lUpVector = lAxisSsytemReference.getUpVector( lUpVectorSign ); |
| 82 | |
| 83 | //get FrontVector and its sign. |
| 84 | EFrontVector lFrontVector = lAxisSsytemReference.getFrontVector( lFrontVectorSign ); |
| 85 | |
| 86 | //get uCoorSystem. |
| 87 | ECoordSystem lCoorSystem = lAxisSsytemReference.GetCoorSystem(); |
| 88 | |
| 89 | //The FbxAxisSystem object to reconstruct back by saved parameter |
| 90 | FbxAxisSystem lAxisSytemReconstruct( lUpVectorSign * lUpVector, |
| 91 | lFrontVectorSign * lFrontVector, |
| 92 | lCoorSystem); |
| 93 | \endcode |
| 94 | |
| 95 | * \nosubgrouping |
| 96 | */ |
| 97 | class FBXSDK_DLL FbxAxisSystem |
| 98 | { |
| 99 | public: |
| 100 | |
| 101 | /** \enum EUpVector Specifies which canonical axis represents up in the system (typically Y or Z). |
| 102 | */ |
| 103 | enum EUpVector |
| 104 | { |
| 105 | eXAxis = 1, |
| 106 | eYAxis = 2, |
| 107 | eZAxis = 3 |
| 108 | }; |
| 109 | |
| 110 | /** \enum EFrontVector Vector with origin at the screen pointing toward the camera. |
| 111 | * This is a subset of enum EUpVector because axis cannot be repeated. |
| 112 | * We use the system of "parity" to define this vector because its value (X,Y or Z axis) |
| 113 | * really depends on the up-vector. The EPreDefinedAxisSystem list the up-vector, parity and |
| 114 | * coordinate system values for the predefined systems. |
| 115 | * \see Detailed description of FbxAxisSystem. |
| 116 | */ |
| 117 | enum EFrontVector |
| 118 | { |
| 119 | eParityEven = 1, |
| 120 | eParityOdd = 2 |
| 121 | }; |
| 122 | |
| 123 | /** \enum ECoordSystem Specifies the third vector of the system. |
| 124 | * The FbxAxisSystem deduces the correct vector and direction based on this flag |
| 125 | * and the relationship with the up and front vectors. The EPreDefinedAxisSystem list the up-vector, parity and |
| 126 | * coordinate system values for the predefined systems. |
| 127 | */ |
| 128 | enum ECoordSystem |
| 129 | { |
| 130 | eRightHanded, |
| 131 | eLeftHanded |
| 132 | }; |
| 133 | |
| 134 | /** \enum EPreDefinedAxisSystem Enumeration that can be used to initialize a new instance of this class with |
| 135 | * predefined configurations (see the "Predefined axis systems" section). |
| 136 | */ |
| 137 | enum EPreDefinedAxisSystem |
| 138 | { |
| 139 | eMayaZUp, /*!< UpVector = ZAxis, FrontVector = -ParityOdd, CoordSystem = RightHanded */ |
| 140 | eMayaYUp, /*!< UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = RightHanded */ |
| 141 | eMax, /*!< UpVector = ZAxis, FrontVector = -ParityOdd, CoordSystem = RightHanded */ |
| 142 | eMotionBuilder, /*!< UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = RightHanded */ |
| 143 | eOpenGL, /*!< UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = RightHanded */ |
| 144 | eDirectX, /*!< UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = LeftHanded */ |
| 145 | eLightwave /*!< UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = LeftHanded */ |
| 146 | }; |
| 147 | |
| 148 | /** |
| 149 | * \name Constructor and Destructor |
| 150 | */ |
| 151 | //@{ |
| 152 | FbxAxisSystem(); |
| 153 | |
| 154 | /** Constructor! |
| 155 | * \param pUpVector Specify the up vector. |
| 156 | * \param pFrontVector Specify the front vector. |
| 157 | * \param pCoorSystem Specify RightHanded coordinate system or LeftHanded coordinate system. |
| 158 | */ |
| 159 | FbxAxisSystem(EUpVector pUpVector, EFrontVector pFrontVector, ECoordSystem pCoorSystem); |
| 160 | |
| 161 | /** Copy constructor! |
| 162 | * \param pAxisSystem Another FbxAxisSystem object copied to this one. |
| 163 | */ |
| 164 | FbxAxisSystem(const FbxAxisSystem& pAxisSystem); |
| 165 | |
| 166 | /** Constructor! |
| 167 | * \param pAxisSystem Specify which predefined axis system to copy. |
| 168 | */ |
| 169 | FbxAxisSystem(const EPreDefinedAxisSystem pAxisSystem); |
| 170 | |
| 171 | //! Destructor. |
| 172 | virtual ~FbxAxisSystem(); |
| 173 | //@} |
| 174 | |
| 175 | /** |
| 176 | * \name Boolean operation. |
| 177 | */ |
| 178 | //@{ |
| 179 | |
| 180 | /** Equivalence operator. |
| 181 | * \param pAxisSystem The axis system to compare against this one. |
| 182 | * \return \c true if these two axis systems are equal, \c false otherwise. |
| 183 | */ |
| 184 | bool operator==(const FbxAxisSystem& pAxisSystem)const; |
| 185 | |
| 186 | /** Non-equivalence operator. |
| 187 | * \param pAxisSystem The axis system to compare against this one. |
| 188 | * \return \c true if these two axis systems are unequal, \c false otherwise. |
| 189 | */ |
| 190 | bool operator!=(const FbxAxisSystem& pAxisSystem)const; |
| 191 | //@} |
| 192 | |
| 193 | /** Assignment operation. |
| 194 | * \param pAxisSystem Axis system assigned to this one. |
| 195 | */ |
| 196 | FbxAxisSystem& operator=(const FbxAxisSystem& pAxisSystem); |
| 197 | |
| 198 | /** |
| 199 | * \name Predefined axis systems. |
| 200 | * These static members define the axis system of the most popular applications. |
| 201 | */ |
| 202 | //@{ |
| 203 | |
| 204 | //! Predefined axis system: MayaZUp (UpVector = +Z, FrontVector = -Y, CoordSystem = +X (RightHanded)) |
| 205 | static const FbxAxisSystem MayaZUp; |
| 206 | |
| 207 | //! Predefined axis system: MayaYUp (UpVector = +Y, FrontVector = +Z, CoordSystem = +X (RightHanded)) |
| 208 | static const FbxAxisSystem MayaYUp; |
| 209 | |
| 210 | //! Predefined axis system: Max (UpVector = +Z, FrontVector = -Y, CoordSystem = +X (RightHanded)) |
| 211 | static const FbxAxisSystem Max; |
| 212 | |
| 213 | //! Predefined axis system: Motionbuilder (UpVector = +Y, FrontVector = +Z, CoordSystem = +X (RightHanded)) |
| 214 | static const FbxAxisSystem Motionbuilder; |
| 215 | |
| 216 | //! Predefined axis system: OpenGL (UpVector = +Y, FrontVector = +Z, CoordSystem = +X (RightHanded)) |
| 217 | static const FbxAxisSystem OpenGL; |
| 218 | |
| 219 | //! Predefined axis system: DirectX (UpVector = +Y, FrontVector = +Z, CoordSystem = -X (LeftHanded)) |
| 220 | static const FbxAxisSystem DirectX; |
| 221 | |
| 222 | //! Predefined axis system: Lightwave (UpVector = +Y, FrontVector = +Z, CoordSystem = -X (LeftHanded)) |
| 223 | static const FbxAxisSystem Lightwave; |
| 224 | //@} |
| 225 | |
| 226 | /** Convert a scene to this axis system. Sets the axis system of the scene to this system unit. |
| 227 | * \param pScene The scene to convert |
| 228 | */ |
| 229 | void ConvertScene(FbxScene* pScene) const; |
| 230 | |
| 231 | /** Convert a scene to this axis system by using the specified |
| 232 | * node as an Fbx_Root. This is provided for backwards compatibility |
| 233 | * only and ConvertScene(FbxScene* pScene) should be used instead when possible. |
| 234 | * \param pScene The scene to convert |
| 235 | * \param pFbxRoot The Fbx_Root node that will be transformed. |
| 236 | */ |
| 237 | void ConvertScene(FbxScene* pScene, FbxNode* pFbxRoot) const; |
| 238 | |
| 239 | /** Get the EFrontVector and its sign of this axis system. |
| 240 | * \param pSign The sign of the axis, 1 for front, -1 for back (relative to observer). |
| 241 | * \return The EFrontVector of this axis system. |
| 242 | */ |
| 243 | EFrontVector GetFrontVector( int & pSign ) const; |
| 244 | |
| 245 | /** Get the EUpVector and its sign of this axis system. |
| 246 | * \param pSign The sign of the axis, 1 for up, -1 for down (relative to observer). |
| 247 | * \return The EUpVector of this axis system. |
| 248 | */ |
| 249 | EUpVector GetUpVector( int & pSign ) const; |
| 250 | |
| 251 | /** Accessor to the ECoordSystem of this object. |
| 252 | * \return The current coordinate axis system of this object. |
| 253 | */ |
| 254 | ECoordSystem GetCoorSystem() const; |
| 255 | |
| 256 | /** Converts the children of the given node to this axis system. |
| 257 | * Unlike the ConvertScene() method, this method does not set the axis system |
| 258 | * of the scene that the pRoot node belongs, nor does it adjust FbxPose |
| 259 | * as they are not stored under the scene, and not under a particular node. |
| 260 | * \param pRoot The node whose children are converted. |
| 261 | * \param pSrcSystem The source axis system. |
| 262 | */ |
| 263 | void ConvertChildren(FbxNode* pRoot, const FbxAxisSystem& pSrcSystem) const; |
| 264 | |
| 265 | /***************************************************************************************************************************** |
| 266 | ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! ** |
| 267 | *****************************************************************************************************************************/ |
| 268 | #ifndef DOXYGEN_SHOULD_SKIP_THIS |
| 269 | protected: |
| 270 | class AxisDef |
| 271 | { |
| 272 | public: |
| 273 | enum EAxis {eXAxis, eYAxis, eZAxis}; |
| 274 | bool operator==(const AxisDef& pAxis) const { return (mAxis == pAxis.mAxis) && (mSign == pAxis.mSign); } |
| 275 | EAxis mAxis; |
| 276 | int mSign; |
| 277 | }; |
| 278 | |
| 279 | AxisDef mUpVector; |
| 280 | AxisDef mFrontVector; |
| 281 | AxisDef mCoorSystem; |
| 282 | |
| 283 | void ConvertTProperty(FbxArray<FbxNode*>& pNodes, const FbxAxisSystem& pFrom) const; |
| 284 | void ConvertCurveNodes(FbxArray<FbxAnimCurveNode*>& pCurveNodes, const FbxAxisSystem& pFrom) const; |
| 285 | void AdjustPreRotation(FbxNode* pNode, const FbxMatrix& pConversionRM) const; |
| 286 | void AdjustPivots(FbxNode* pNode, const FbxMatrix& pConversionRM) const; |
| 287 | void GetConversionMatrix(const FbxAxisSystem& pFrom, FbxMatrix& pConversionRM) const; |
| 288 | void AdjustLimits(FbxNode* pNode, const FbxMatrix& pConversionRM) const; |
| 289 | void AdjustPoses(FbxScene* pScene, const FbxMatrix& pConversionRM) const; |
| 290 | void AdjustCamera(FbxNode* pNode, const FbxMatrix& pConversionRM ) const; |
| 291 | void AdjustCluster(FbxNode* pNode, const FbxMatrix& pConversionRM) const; |
| 292 | void ConvertChildren(FbxNode* pRoot, const FbxAxisSystem& pSrcSystem, bool pSubChildrenOnly) const; |
| 293 | |
| 294 | friend class FbxGlobalSettings; |
| 295 | #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/ |
| 296 | }; |
| 297 | |
| 298 | #include <fbxsdk/fbxsdk_nsend.h> |
| 299 | |
| 300 | #endif /* _FBXSDK_SCENE_AXIS_SYSTEM_H_ */ |
| 301 | |