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 fbxaffinematrix.h
13#ifndef _FBXSDK_CORE_MATH_AFFINE_MATRIX_H_
14#define _FBXSDK_CORE_MATH_AFFINE_MATRIX_H_
15
16#include <fbxsdk/fbxsdk_def.h>
17
18#include <fbxsdk/core/math/fbxvector4.h>
19
20#include <fbxsdk/fbxsdk_nsbegin.h>
21
22/** FBX SDK affine matrix class.
23 * \nosubgrouping
24 * Matrices are defined using the Column Major scheme. When a FbxAMatrix represents a transformation (translation, rotation and scale),
25 * the last row of the matrix represents the translation part of the transformation.
26 *
27 * \remarks It is important to realize that an affine matrix must respect a certain structure. To be sure the structure is respected,
28 * use SetT, SetR, SetS, SetQ, SetTRS or SetTQS. If by mistake bad data is entered in this affine matrix, some functions such as
29 * Inverse() will yield wrong results. If a matrix is needed to hold values that aren't associate with an affine matrix, please use FbxMatrix instead.
30 */
31class FBXSDK_DLL FbxAMatrix : public FbxDouble4x4
32{
33public:
34 /**
35 * \name Constructors and Destructor
36 */
37 //@{
38 //! Constructor.
39 FbxAMatrix();
40
41 /** Copy constructor.
42 * \param pOther FbxAMatrix copied to this one.
43 */
44 FbxAMatrix(const FbxAMatrix& pOther);
45
46 /** Constructor.
47 * \param pT Translation vector.
48 * \param pR Euler rotation vector.
49 * \param pS Scale vector.
50 */
51 FbxAMatrix(const FbxVector4& pT, const FbxVector4& pR, const FbxVector4& pS);
52
53 //! Destructor.
54 ~FbxAMatrix();
55 //@}
56
57 /**
58 * \name Access
59 */
60 //@{
61 /** Retrieve matrix element.
62 * \param pY Row index.
63 * \param pX Column index.
64 * \return Cell [ pX, pY ] value.
65 */
66 double Get(int pY, int pX) const;
67
68 /** Extract translation vector.
69 * \return Translation vector.
70 */
71 FbxVector4 GetT() const;
72
73 /** Extract rotation vector.
74 * \return Rotation vector.
75 * \remarks The returned rotation vector is in Euler angle and the rotation order is XYZ.
76 */
77 FbxVector4 GetR() const;
78
79 /** Extract quaternion vector.
80 * \return Quaternion vector.
81 */
82 FbxQuaternion GetQ() const;
83
84 /** Extract scale vector.
85 * \return Scale vector.
86 */
87 FbxVector4 GetS() const;
88
89 /** Extract a row vector.
90 * \param pY Row index.
91 * \return The row vector.
92 */
93 FbxVector4 GetRow(int pY) const;
94
95 /** Extract a column vector.
96 * \param pX Column index.
97 * \return The column vector.
98 */
99 FbxVector4 GetColumn(int pX) const;
100
101 //! Set matrix to identity.
102 void SetIdentity();
103
104 /** Set matrix's translation.
105 * \param pT Translation vector.
106 */
107 void SetT(const FbxVector4& pT);
108
109 /** Set matrix's Euler rotation.
110 * \param pR X, Y and Z rotation values expressed as a vector.
111 * \remarks The rotation transform is constructed in rotation order XYZ.
112 */
113 void SetR(const FbxVector4& pR);
114
115 /** Set matrix's quaternion.
116 * \param pQ The new quaternion.
117 */
118 void SetQ(const FbxQuaternion& pQ);
119
120 /** Set matrix's scale.
121 * \param pS X, Y and Z scaling factors expressed as a vector.
122 */
123 void SetS(const FbxVector4& pS);
124
125 /** Set matrix.
126 * \param pT Translation vector.
127 * \param pR Rotation vector.
128 * \param pS Scale vector.
129 */
130 void SetTRS(const FbxVector4& pT, const FbxVector4& pR, const FbxVector4& pS);
131
132 /** Set matrix.
133 * \param pT Translation vector.
134 * \param pQ Quaternion vector.
135 * \param pS Scale vector.
136 */
137 void SetTQS(const FbxVector4& pT, const FbxQuaternion& pQ, const FbxVector4& pS);
138
139 /** Assignment operator.
140 * \param pM FbxAMatrix assigned to this one.
141 */
142 FbxAMatrix& operator=(const FbxAMatrix& pM);
143 //@}
144
145 /**
146 * \name Scalar Operations
147 */
148 //@{
149 /** Multiply matrix by a scalar value.
150 * \param pValue Scalar value.
151 * \return The scaled matrix.
152 * \remarks The passed value is not checked.
153 * This operator operates on the first three rows and columns of the matrix.
154 * So only the rotation and scaling are scaled, not the translation part.
155 * After operation, the translation vector will be set as (0,0,0,1);
156 */
157 FbxAMatrix operator*(double pValue) const;
158
159 /** Divide matrix by a scalar value.
160 * \param pValue Scalar value.
161 * \return The divided matrix.
162 * \remarks The passed value is not checked.
163 * This operator operates on the first three rows and columns of the matrix.
164 * So only the rotation and scaling are scaled, not the translation part.
165 * After operation, the translation vector will be set as (0,0,0,1);
166 */
167 FbxAMatrix operator/(double pValue) const;
168
169 /** Multiply matrix by a scalar value.
170 * \param pValue Scalar value.
171 * \return \e this updated with the result of the multiplication.
172 * \remarks The passed value is not checked.
173 * This operator operates on the first three rows and columns of the matrix.
174 * So only the rotation and scaling are scaled, not the translation part.
175 * After operation, the translation vector will keep original value.
176 */
177 FbxAMatrix& operator*=(double pValue);
178
179 /** Divide matrix by a scalar value.
180 * \param pValue Scalar value.
181 * \return \e this updated with the result of the division.
182 * \remarks The passed value is not checked.
183 * This operator operates on the first three rows and columns of the matrix.
184 * So only the rotation and scaling are scaled, not the translation part.
185 * After operation, the translation vector will keep original value.
186 */
187 FbxAMatrix& operator/=(double pValue);
188 //@}
189
190 /**
191 * \name Vector Operations
192 */
193 //@{
194 /** Multiply matrix by a translation vector.
195 * \param pVector4 Translation vector.
196 * \return t' = M * t
197 */
198 FbxVector4 MultT(const FbxVector4& pVector4) const;
199
200 /** Multiply matrix by an Euler rotation vector.
201 * \param pVector4 Euler Rotation vector.
202 * \return r' = M * r
203 */
204 FbxVector4 MultR(const FbxVector4& pVector4) const;
205
206 /** Multiply matrix by a quaternion.
207 * \param pQuaternion Rotation value.
208 * \return q' = M * q
209 */
210 FbxQuaternion MultQ(const FbxQuaternion& pQuaternion) const;
211
212 /** Multiply matrix by a scale vector.
213 * \param pVector4 Scaling vector.
214 * \return s' = M * s
215 */
216 FbxVector4 MultS(const FbxVector4& pVector4) const;
217 //@}
218
219 /**
220 * \name Matrix Operations
221 */
222 //@{
223 /** Unary minus operator.
224 * \return A matrix where each element is multiplied by -1.
225 */
226 FbxAMatrix operator-() const;
227
228 /** Multiply two matrices together.
229 * \param pOther A Matrix.
230 * \return this * pMatrix.
231 * \remarks Transformations are pre-multiplied.
232 * That means to scale, then rotate, and then translate a vector V, the transform should be T * R * S * V. \n
233 * Below is an example of code that shows how to construct rotation transform in XYZ rotation order.
234 * \code
235 * FbxAMatrix lRotateXM, lRotateYM, lRotateZM, lRotateXYZM, lRotateM;
236 * // Construct rotation matrix around X, Y and Z axises separately and then combine them.
237 * FbxVector4 lRotateX(10, 0, 0);
238 * FbxVector4 lRotateY(0, 10, 0);
239 * FbxVector4 lRotateZ(0, 0, 10);
240 * lRotateXM.SetR(lRotateX);
241 * lRotateYM.SetR(lRotateY);
242 * lRotateZM.SetR(lRotateZ);
243 * lRotateXYZM = lRotateZM * lRotateYM * lRotateXM;
244 *
245 * // Alternatively, we can use SetR() directly.
246 * // lRotateXYZM and lRotateM will be the same.
247 * FbxVector4 lRotateXYZ (10, 10, 10);
248 * lRotateM.SetR(lRotateXYZ);
249 * \endcode
250 * \note Please refer to the FBX SDK programmers guide for more details.
251 */
252 FbxAMatrix operator*(const FbxAMatrix& pOther) const;
253
254 /** Multiply two matrices together.
255 * \param pOther A Matrix.
256 * \return \e this updated with the result of the multiplication.
257 */
258 FbxAMatrix& operator*=(const FbxAMatrix& pOther);
259
260 /** Calculate the matrix inverse.
261 * \return The inverse matrix of \e this.
262 */
263 FbxAMatrix Inverse() const;
264
265 /** Calculate the matrix transpose.
266 * \return The transposed matrix of \e this.
267 */
268 FbxAMatrix Transpose() const;
269
270 /** Calculate a spherical linear interpolation matrix.
271 * \param pOther The other rotation matrix to interpolate with.
272 * \param pWeight A value between 0.0 and 1.0 to specify the interpolation amount.
273 * \remark This matrix and other matrix should contain only rotations, otherwise result may be undefined. */
274 FbxAMatrix Slerp(const FbxAMatrix& pOther, double pWeight) const;
275 //@}
276
277 /**
278 * \name Boolean Operations
279 */
280 //@{
281 /** Equivalence operator.
282 * \param pOther The matrix to be compared to \e this.
283 * \return \c true if the two matrices are equal (each element is within a FBXSDK_TOLERANCE tolerance) and \c false otherwise.
284 */
285 bool operator==(const FbxAMatrix& pOther) const;
286
287 /** Non-equivalence operator.
288 * \param pOther The matrix to be compared to \e this.
289 * \return \c false if the two matrices are equal (each element is within a FBXSDK_TOLERANCE tolerance) and \c true otherwise.
290 */
291 bool operator!=(const FbxAMatrix& pOther) const;
292 //@}
293
294 /**
295 * \name Casting
296 */
297 //@{
298 //! Cast the matrix in a double pointer.
299 operator double* ();
300 //! Cast the matrix in a const double pointer.
301 operator const double* () const;
302 //! Define 4*4 array as a new type
303 typedef const double(kDouble44)[4][4] ;
304 //! Cast the matrix in a reference to a 4*4 array.
305 inline kDouble44 & Double44() const { return *((kDouble44 *)&mData[0][0]); }
306 //@}
307
308 /** Find out if the matrix is equal to identity matrix.
309 * \return \c true if the matrix is equal to identity matrix, \c false otherwise. */
310 bool IsIdentity(const double pThreshold=FBXSDK_TOLERANCE);
311
312/*****************************************************************************************************************************
313** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
314*****************************************************************************************************************************/
315#ifndef DOXYGEN_SHOULD_SKIP_THIS
316 FbxAMatrix(const FbxVector4& pT, const FbxQuaternion& pQ, const FbxVector4& pS);
317
318 void SetTRS(const FbxVector4& pT, const FbxAMatrix& pRM, const FbxVector4& pS);
319 void SetRow(int pY, const FbxVector4& pRow);
320 void SetTOnly(const FbxVector4& pT);
321 void SetROnly(const FbxVector4& pR);
322 void SetQOnly(const FbxQuaternion& pQ);
323 FbxVector4 GetROnly() const;
324 FbxQuaternion GetUnnormalizedQ() const;
325
326 // pOrd is assumed to be an FbxEuler::EOrder (or its synonym EFbxRotationOrder)
327 void SetR(const FbxVector4& pV, const int pOrd);
328 FbxVector4 GetR(const int pOrd) const;
329
330 void MultRM(const FbxVector4& pR);
331 void MultSM(const FbxVector4& pS);
332 bool IsRightHand() const;
333 double Determinant() const;
334 int Compare(const FbxAMatrix pM, const double pThreshold=FBXSDK_TOLERANCE) const;
335#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
336};
337
338#include <fbxsdk/fbxsdk_nsend.h>
339
340#endif /* _FBXSDK_CORE_MATH_AFFINE_MATRIX_H_ */
341