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 | */ |
31 | class FBXSDK_DLL FbxAMatrix : public FbxDouble4x4 |
32 | { |
33 | public: |
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 | |