| 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 | |