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 */
97class FBXSDK_DLL FbxAxisSystem
98{
99public:
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
269protected:
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