PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: Matrix3x4.h * 00003 * 00004 * Copyright (C) 2002-2011 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLMATH_MATRIX3X4_H__ 00024 #define __PLMATH_MATRIX3X4_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include "PLMath/Vector2.h" 00032 #include "PLMath/Vector4.h" 00033 00034 00035 //[-------------------------------------------------------] 00036 //[ Namespace ] 00037 //[-------------------------------------------------------] 00038 namespace PLMath { 00039 00040 00041 //[-------------------------------------------------------] 00042 //[ Forward declarations ] 00043 //[-------------------------------------------------------] 00044 class Plane; 00045 00046 00047 //[-------------------------------------------------------] 00048 //[ Classes ] 00049 //[-------------------------------------------------------] 00050 /** 00051 * @brief 00052 * 3x4 matrix 00053 * 00054 * @remarks 00055 * Matrices are stored in column major order like OpenGL does. (right-handed matrix) 00056 * So, it's possible to give OpenGL the matrix data without transposing it first. 00057 * 00058 * @note 00059 * - Some symbols within the comments: T = transposed, I = identity 00060 */ 00061 class Matrix3x4 { 00062 00063 00064 //[-------------------------------------------------------] 00065 //[ Public static data ] 00066 //[-------------------------------------------------------] 00067 public: 00068 static PLMATH_API const Matrix3x4 Zero; /**< Zero matrix */ 00069 static PLMATH_API const Matrix3x4 Identity; /**< Identity matrix */ 00070 00071 00072 //[-------------------------------------------------------] 00073 //[ Public data ] 00074 //[-------------------------------------------------------] 00075 public: 00076 /** 00077 * @brief 00078 * Some direct matrix accesses 00079 */ 00080 union { 00081 /** 00082 * @brief 00083 * One dimensional array representation 00084 * 00085 * @remarks 00086 * The entry of the matrix in row r (0 <= r <= 2) and column c (0 <= c <= 3) is 00087 * stored at index i = r+3*c (0 <= i <= 11).\n 00088 * Indices: 00089 * @code 00090 * | 0 3 6 9 | 00091 * | 1 4 7 10 | 00092 * | 2 5 8 11 | 00093 * @endcode 00094 */ 00095 float fM[12]; 00096 00097 /** 00098 * @brief 00099 * Direct element representation 00100 * 00101 * @remarks 00102 * Indices: (row/column) 00103 * @code 00104 * | xx xy xz xw | 00105 * | yx yy yz yw | 00106 * | zx zy zz zw | 00107 * @endcode 00108 * It's recommended to use this way to access the elements. 00109 */ 00110 struct { 00111 float xx, yx, zx; 00112 float xy, yy, zy; 00113 float xz, yz, zz; 00114 float xw, yw, zw; 00115 }; 00116 00117 /** 00118 * @brief 00119 * Two dimensional array representation 00120 * 00121 * @remarks 00122 * fM43[i][j] -> i=column, j=row\n 00123 * Try to avoid this access mode. This can be a problem on a platform/console that 00124 * chooses to store the data in column-major rather than row-major format. 00125 */ 00126 struct { 00127 float fM43[4][3]; 00128 }; 00129 }; 00130 00131 00132 //[-------------------------------------------------------] 00133 //[ Public functions ] 00134 //[-------------------------------------------------------] 00135 public: 00136 //[-------------------------------------------------------] 00137 //[ Constructor ] 00138 //[-------------------------------------------------------] 00139 /** 00140 * @brief 00141 * Default constructor setting an identity matrix 00142 */ 00143 inline Matrix3x4(); 00144 00145 inline Matrix3x4(const float fS[]); 00146 PLMATH_API Matrix3x4(const Matrix3x3 &mM); 00147 inline Matrix3x4(const Matrix3x4 &mM); 00148 PLMATH_API Matrix3x4(const Matrix4x4 &mM); 00149 inline Matrix3x4(float fXX, float fXY, float fXZ, float fXW, 00150 float fYX, float fYY, float fYZ, float fYW, 00151 float fZX, float fZY, float fZZ, float fZW); 00152 00153 //[-------------------------------------------------------] 00154 //[ Destructor ] 00155 //[-------------------------------------------------------] 00156 inline ~Matrix3x4(); 00157 00158 //[-------------------------------------------------------] 00159 //[ Comparison ] 00160 //[-------------------------------------------------------] 00161 PLMATH_API bool operator ==(const Matrix3x4 &mM) const; 00162 PLMATH_API bool operator !=(const Matrix3x4 &mM) const; 00163 // fEpsilon = epsilon environment (to take computation errors into account...) 00164 PLMATH_API bool CompareScale(const Matrix3x4 &mM, float fEpsilon = Math::Epsilon) const; 00165 PLMATH_API bool CompareTranslation(const Matrix3x4 &mM, float fEpsilon = Math::Epsilon) const; 00166 PLMATH_API bool CompareRotation(const Matrix3x4 &mM, float fEpsilon = Math::Epsilon) const; 00167 00168 //[-------------------------------------------------------] 00169 //[ Operators ] 00170 //[-------------------------------------------------------] 00171 inline Matrix3x4 &operator =(const float fS[]); 00172 PLMATH_API Matrix3x4 &operator =(const Matrix3x3 &mM); 00173 inline Matrix3x4 &operator =(const Matrix3x4 &mM); 00174 PLMATH_API Matrix3x4 &operator =(const Matrix4x4 &mM); 00175 inline Matrix3x4 operator +(const Matrix3x4 &mM) const; 00176 inline void operator +=(const Matrix3x4 &mM); 00177 inline Matrix3x4 operator -() const; 00178 inline Matrix3x4 operator -(const Matrix3x4 &mM) const; 00179 inline void operator -=(const Matrix3x4 &mM); 00180 inline Matrix3x4 operator *(float fS) const; 00181 inline void operator *=(float fS); 00182 inline Vector2 operator *(const Vector2 &vV) const; 00183 inline Vector3 operator *(const Vector3 &vV) const; 00184 inline Vector4 operator *(const Vector4 &vV) const; 00185 /** A 3x4*3x4 matrix multiplication is NOT defined, so we use the given 3x4 matrix with 00186 a fourth row (0, 0, 0, 1) which result in a 3x4*4x4 matrix multiplication which is 00187 allowed */ 00188 PLMATH_API Matrix3x4 operator *(const Matrix3x4 &mM) const; 00189 PLMATH_API Matrix3x4 operator *(const Matrix4x4 &mM) const; 00190 /** @see - *(const Matrix3x4 &mM) */ 00191 inline void operator *=(const Matrix3x4 &mM); 00192 PLMATH_API void operator *=(const Matrix4x4 &mM); 00193 inline Matrix3x4 operator /(float fS) const; 00194 inline void operator /=(float fS); 00195 inline float operator [](int nIndex) const; 00196 inline float &operator [](int nIndex); 00197 inline float operator ()(PLCore::uint32 nRow = 0, PLCore::uint32 nColumn = 0) const; 00198 inline float &operator ()(PLCore::uint32 nRow = 0, PLCore::uint32 nColumn = 0); 00199 inline operator float *(); 00200 inline operator const float *() const; 00201 00202 //[-------------------------------------------------------] 00203 //[ Matrix operations ] 00204 //[-------------------------------------------------------] 00205 /** 00206 * @brief 00207 * Returns whether or not this matrix is the zero matrix using an epsilon environment 00208 * 00209 * @return 00210 * 'true' if this matrix is the zero matrix, else 'false' 00211 */ 00212 inline bool IsZero() const; 00213 00214 /** 00215 * @brief 00216 * Returns whether or not this matrix is truly the zero matrix 00217 * 00218 * @remarks 00219 * All components MUST be exactly 0. Floating point inaccuracy 00220 * is not taken into account. 00221 * 00222 * @return 00223 * 'true' if this matrix is truly the zero matrix, else 'false' 00224 */ 00225 inline bool IsTrueZero() const; 00226 00227 /** 00228 * @brief 00229 * Sets a zero matrix 00230 * 00231 * @remarks 00232 * @code 00233 * | 0 0 0 0 | 00234 * | 0 0 0 0 | 00235 * | 0 0 0 0 | 00236 * @endcode 00237 */ 00238 inline void SetZero(); 00239 00240 /** 00241 * @brief 00242 * Returns whether or not this matrix is the identity matrix using an epsilon environment 00243 * 00244 * @return 00245 * 'true' if this matrix is the identity matrix, else 'false' 00246 */ 00247 inline bool IsIdentity() const; 00248 00249 /** 00250 * @brief 00251 * Returns whether or not this matrix is truly the identity matrix 00252 * 00253 * @remarks 00254 * All components MUST be exactly either 0 or 1. Floating point inaccuracy 00255 * is not taken into account. 00256 * 00257 * @return 00258 * 'true' if this matrix is truly the identity matrix, else 'false' 00259 */ 00260 inline bool IsTrueIdentity() const; 00261 00262 /** 00263 * @brief 00264 * Sets an identity matrix 00265 * 00266 * @remarks 00267 * @code 00268 * | 1 0 0 0 | 00269 * | 0 1 0 0 | 00270 * | 0 0 1 0 | 00271 * @endcode 00272 */ 00273 inline void SetIdentity(); 00274 00275 /** 00276 * @brief 00277 * Sets the elements of the matrix 00278 */ 00279 PLMATH_API void Set(float fXX, float fXY, float fXZ, float fXW, 00280 float fYX, float fYY, float fYZ, float fYW, 00281 float fZX, float fZY, float fZZ, float fZW); 00282 00283 /** 00284 * @brief 00285 * Returns a requested row 00286 * 00287 * @param[in] nRow 00288 * Index of the row to return (0-2) 00289 * 00290 * @return 00291 * The requested row (null vector on error) 00292 * 00293 * @remarks 00294 * @code 00295 * | x y z w | <- Row 0 00296 * | 0 0 0 0 | 00297 * | 0 0 0 0 | 00298 * @endcode 00299 */ 00300 inline Vector4 GetRow(PLCore::uint8 nRow) const; 00301 00302 /** 00303 * @brief 00304 * Sets a row 00305 * 00306 * @param[in] nRow 00307 * Index of the row to set (0-2) 00308 * @param[in] vRow 00309 * Row vector 00310 * 00311 * @see 00312 * - GetRow() 00313 */ 00314 inline void SetRow(PLCore::uint8 nRow, const Vector4 &vRow); 00315 00316 /** 00317 * @brief 00318 * Returns a requested column 00319 * 00320 * @param[in] nColumn 00321 * Index of the column to return (0-3) 00322 * 00323 * @return 00324 * The requested column (null vector on error) 00325 * 00326 * @remarks 00327 * @code 00328 * | x 0 0 0 | 00329 * | y 0 0 0 | 00330 * | z 0 0 0 | 00331 * ^ 00332 * | 00333 * Column 0 00334 * @endcode 00335 */ 00336 inline Vector3 GetColumn(PLCore::uint8 nColumn) const; 00337 00338 /** 00339 * @brief 00340 * Sets a column 00341 * 00342 * @param[in] nColumn 00343 * Index of the column to set (0-3) 00344 * @param[in] vColumn 00345 * Column vector 00346 * 00347 * @see 00348 * - GetColumn() 00349 */ 00350 inline void SetColumn(PLCore::uint8 nColumn, const Vector3 &vColumn); 00351 00352 /** 00353 * @brief 00354 * Returns true if the matrix is symmetric 00355 * 00356 * @return 00357 * 'true' if the matrix is symmetric, else 'false' 00358 * 00359 * @remarks 00360 * A matrix is symmetric if it is equal to it's transposed matrix.\n 00361 * A = A^T -> a(i, j) = a(j, i) 00362 */ 00363 inline bool IsSymmetric() const; 00364 00365 /** 00366 * @brief 00367 * Returns true if this matrix is orthogonal 00368 * 00369 * @return 00370 * 'true' if the matrix is orthogonal, else 'false' 00371 * 00372 * @remarks 00373 * A matrix is orthogonal if it's transposed matrix is equal to it's inversed matrix.\n 00374 * A^T = A^-1 or A*A^T = A^T*A = I 00375 * 00376 * @note 00377 * - An orthogonal matrix is always nonsingular (invertible) and it's inverse is equal to it's transposed 00378 * - The transpose and inverse of the matrix is orthogonal, too 00379 * - Products of orthogonal matrices are orthogonal, too 00380 * - The determinant of a orthogonal matrix is +/- 1 00381 * - The row and column vectors of an orthogonal matrix form an orthonormal basis, 00382 * that is, these vectors are unit-length and they are mutually perpendicular 00383 */ 00384 inline bool IsOrthogonal() const; 00385 00386 /** 00387 * @brief 00388 * Returns true if this matrix is a rotation matrix 00389 * 00390 * @return 00391 * 'true' if this matrix is a rotation matrix, else 'false' 00392 * 00393 * @remarks 00394 * A rotation matrix is orthogonal and it's determinant is 1 to rule out reflections. 00395 * 00396 * @see 00397 * - IsOrthogonal() 00398 */ 00399 inline bool IsRotationMatrix() const; 00400 00401 /** 00402 * @brief 00403 * Returns true if this matrix is a rotation and translation matrix 00404 * 00405 * @return 00406 * 'true' if this matrix is a rotation and translation matrix, else 'false' 00407 * 00408 * @remarks 00409 * A rotation and translation matrix looks like this: 00410 * @code 00411 * | x x x x | 00412 * | x x x x | 00413 * | x x x x | 00414 * @endcode 00415 * Were 'x' means this field is used and as you see the last row must be empty. 00416 * 00417 * @see 00418 * - IsRotationMatrix() 00419 */ 00420 inline bool IsRotationTranslationMatrix() const; 00421 00422 /** 00423 * @brief 00424 * Returns the trace of the matrix 00425 * 00426 * @return 00427 * The trace of the matrix 00428 * 00429 * @remarks 00430 * The trace of the matrix is the sum of the main diagonal elements:\n 00431 * xx+yy+zz 00432 */ 00433 inline float GetTrace() const; 00434 00435 /** 00436 * @brief 00437 * Returns the determinant of the matrix 00438 * 00439 * @return 00440 * Determinant of the matrix 00441 * 00442 * @remarks 00443 * The determinant is calculated using the Sarrus diagram: 00444 * @code 00445 * | xx xy xz | xx xy | 00446 * | \ /\ /\ / | 00447 * | yx yy yz | yx yy | = xx*yy*zz + xy*yz*zx + xz*yx*zy - 00448 * | / /\ /\ \ | (zx*yy*xz + zy*yz*xx + zz*yx*xy) 00449 * | zx zy zz | zx zy | 00450 * @endcode 00451 * 00452 * @note 00453 * - If the determinant is non-zero, then an inverse matrix exists 00454 * - If the determinant is 0, the matrix is called singular, else nonsingular (invertible) matrix 00455 * - If the determinant is 1, the inverse matrix is equal to the transpose of the matrix 00456 */ 00457 inline float GetDeterminant() const; 00458 00459 /** 00460 * @brief 00461 * Transpose this matrix 00462 * 00463 * @remarks 00464 * The transpose of matrix is the matrix generated when every element in 00465 * the matrix is swapped with the opposite relative to the major diagonal 00466 * This can be expressed as the mathematical operation: 00467 * @code 00468 * M' = M 00469 * ij ji 00470 * 00471 * | xx xy xz xw | | xx yx zx xw | 00472 * | yx yy yz yw | the transpose is | xy yy zy yw | 00473 * | zx zy zz zw | | xz yz zz zw | 00474 * @endcode 00475 * 00476 * @note 00477 * - If the matrix is a rotation matrix (= isotropic matrix = determinant is 1), 00478 * then the transpose is guaranteed to be the inverse of the matrix 00479 * - Only the upper left 3x3 part is manipulated 00480 */ 00481 inline void Transpose(); 00482 00483 /** 00484 * @brief 00485 * Returns the transposed matrix 00486 * 00487 * @return 00488 * Transposed matrix 00489 * 00490 * @see 00491 * - Transpose() 00492 */ 00493 inline Matrix3x4 GetTransposed() const; 00494 00495 /** 00496 * @brief 00497 * Inverts the matrix 00498 * 00499 * @return 00500 * 'true' if all went fine, else 'false' (maybe the determinant is null?) 00501 * 00502 * @remarks 00503 * P = [R T] -> inv(P) = [R' -R'*T] (R = rotation, R' = transposed rotation, T = translation vector) 00504 * 00505 * @note 00506 * - If the determinant is 1, the inversed matrix is equal to the transposed one 00507 */ 00508 PLMATH_API bool Invert(); 00509 00510 /** 00511 * @brief 00512 * Returns the inverse of the matrix 00513 * 00514 * @return 00515 * Inverse of the matrix, if the determinant is null, an identity matrix is returned 00516 * 00517 * @see 00518 * - Invert() 00519 */ 00520 PLMATH_API Matrix3x4 GetInverted() const; 00521 00522 /** 00523 * @brief 00524 * Rotates a vector 00525 * 00526 * @param[in] fX 00527 * X component of the vector to rotate 00528 * @param[in] fY 00529 * Y component of the vector to rotate 00530 * @param[in] fZ 00531 * Z component of the vector to rotate 00532 * @param[in] bUniformScale 00533 * Is this a uniform scale matrix? (all axis are scaled equally) 00534 * If you know EXACTLY it's one, set this to 'true' to gain some more speed, else DON'T set to 'true'! 00535 * 00536 * @return 00537 * The rotated vector 00538 * 00539 * @remarks 00540 * This function is similar to a matrix * vector operation - except that the 00541 * translation of the matrix is ignored and this function can deal with none 00542 * uniform scale. So, this function can for instance be used to rotate a 00543 * direction vector. (matrix * direction vector) 00544 * 00545 * @note 00546 * - You can't assume that the resulting vector is normalized 00547 * - Use this function to rotate for example a normal vector 00548 */ 00549 PLMATH_API Vector3 RotateVector(float fX, float fY, float fZ, bool bUniformScale = false) const; 00550 00551 /** 00552 * @brief 00553 * Rotates a vector 00554 * 00555 * @param[in] vV 00556 * Vector to rotate 00557 * @param[in] bUniformScale 00558 * Is this a uniform scale matrix? (all axis are scaled equally) 00559 * If you know EXACTLY it's one, set this to 'true' to gain some more speed, else DON'T set to 'true'! 00560 * 00561 * @return 00562 * The rotated vector 00563 * 00564 * @see 00565 * - RotateVector(float, float, float) above 00566 */ 00567 PLMATH_API Vector3 RotateVector(const Vector3 &vV, bool bUniformScale = false) const; 00568 00569 //[-------------------------------------------------------] 00570 //[ Scale ] 00571 //[-------------------------------------------------------] 00572 /** 00573 * @brief 00574 * Sets a scale matrix 00575 * 00576 * @param[in] fX 00577 * X scale 00578 * @param[in] fY 00579 * Y scale 00580 * @param[in] fZ 00581 * Z scale 00582 * 00583 * @remarks 00584 * @code 00585 * | x 0 0 0 | 00586 * | 0 y 0 0 | 00587 * | 0 0 z 0 | 00588 * @endcode 00589 */ 00590 inline void SetScaleMatrix(float fX, float fY, float fZ); 00591 inline void SetScaleMatrix(const Vector3 &vV); 00592 00593 /** 00594 * @brief 00595 * Extracts the scale vector from the matrix as good as possible 00596 * 00597 * @param[out] fX 00598 * Receives the x scale 00599 * @param[out] fY 00600 * Receives the y scale 00601 * @param[out] fZ 00602 * Receives the z scale 00603 * 00604 * @note 00605 * - This function will not work correctly if one or two components are negative while 00606 * another is/are not (we can't figure out WHICH axis are negative!) 00607 */ 00608 PLMATH_API void GetScale(float &fX, float &fY, float &fZ) const; 00609 inline Vector3 GetScale() const; 00610 inline void GetScale(float fV[]) const; 00611 00612 //[-------------------------------------------------------] 00613 //[ Translation ] 00614 //[-------------------------------------------------------] 00615 /** 00616 * @brief 00617 * Sets a translation matrix 00618 * 00619 * @param[in] fX 00620 * X translation 00621 * @param[in] fY 00622 * Y translation 00623 * @param[in] fZ 00624 * Z translation 00625 * 00626 * @remarks 00627 * @code 00628 * | 1 0 0 x | 00629 * | 0 1 0 y | 00630 * | 0 0 1 z | 00631 * @endcode 00632 */ 00633 inline void SetTranslationMatrix(float fX, float fY, float fZ); 00634 inline void SetTranslationMatrix(const Vector3 &vV); 00635 00636 // Get and set 00637 inline void GetTranslation(float &fX, float &fY, float &fZ) const; 00638 inline Vector3 GetTranslation() const; 00639 inline void GetTranslation(float fV[]) const; 00640 inline void SetTranslation(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f); 00641 inline void SetTranslation(const Vector3 &vV); 00642 inline void SetTranslation(const float fV[]); 00643 00644 //[-------------------------------------------------------] 00645 //[ Rotation ] 00646 //[-------------------------------------------------------] 00647 /** 00648 * @brief 00649 * Sets an x axis rotation matrix by using one given Euler angle 00650 * 00651 * @param[in] fAngleX 00652 * Rotation angle around the x axis (in radian, between [0, Math::Pi2]) 00653 * 00654 * @remarks 00655 * @code 00656 * | 1 0 0 0 | 00657 * RX = | 0 cos(a) -sin(a) 0 | 00658 * | 0 sin(a) cos(a) 0 | 00659 * @endcode 00660 * where a > 0 indicates a counterclockwise rotation in the yz-plane (if you look along -x) 00661 */ 00662 PLMATH_API void FromEulerAngleX(float fAngleX); 00663 00664 /** 00665 * @brief 00666 * Sets an y axis rotation matrix by using one given Euler angle 00667 * 00668 * @param[in] fAngleY 00669 * Rotation angle around the y axis (in radian, between [0, Math::Pi2]) 00670 * 00671 * @remarks 00672 * @code 00673 * | cos(a) 0 sin(a) 0 | 00674 * RY = | 0 1 0 0 | 00675 * | -sin(a) 0 cos(a) 0 | 00676 * @endcode 00677 * where a > 0 indicates a counterclockwise rotation in the zx-plane (if you look along -y) 00678 */ 00679 PLMATH_API void FromEulerAngleY(float fAngleY); 00680 00681 /** 00682 * @brief 00683 * Sets an z axis rotation matrix by using one given Euler angle 00684 * 00685 * @param[in] fAngleZ 00686 * Rotation angle around the z axis (in radian, between [0, Math::Pi2]) 00687 * 00688 * @remarks 00689 * @code 00690 * | cos(a) -sin(a) 0 0 | 00691 * RZ = | sin(a) cos(a) 0 0 | 00692 * | 0 0 1 0 | 00693 * @endcode 00694 * where a > 0 indicates a counterclockwise rotation in the xy-plane (if you look along -z) 00695 */ 00696 PLMATH_API void FromEulerAngleZ(float fAngleZ); 00697 00698 /** 00699 * @brief 00700 * Returns a rotation matrix as a selected axis and angle 00701 * 00702 * @param[out] fX 00703 * Will receive the x component of the selected axis 00704 * @param[out] fY 00705 * Will receive the y component of the selected axis 00706 * @param[out] fZ 00707 * Will receive the z component of the selected axis 00708 * @param[out] fAngle 00709 * Will receive the rotation angle around the selected axis (in radian, between [0, Math::Pi]) 00710 */ 00711 PLMATH_API void ToAxisAngle(float &fX, float &fY, float &fZ, float &fAngle) const; 00712 00713 /** 00714 * @brief 00715 * Sets a rotation matrix by using a selected axis and angle 00716 * 00717 * @param[in] fX 00718 * X component of the selected axis 00719 * @param[in] fY 00720 * Y component of the selected axis 00721 * @param[in] fZ 00722 * Z component of the selected axis 00723 * @param[in] fAngle 00724 * Rotation angle around the selected axis (in radian, between [0, Math::Pi]) 00725 * 00726 * @note 00727 * - The given selected axis must be normalized! 00728 */ 00729 PLMATH_API void FromAxisAngle(float fX, float fY, float fZ, float fAngle); 00730 00731 /** 00732 * @brief 00733 * Returns the x (left) axis 00734 * 00735 * @return 00736 * The x (left) axis 00737 * 00738 * @remarks 00739 * @code 00740 * | x 0 0 0 | 00741 * | y 0 0 0 | 00742 * | z 0 0 0 | 00743 * @endcode 00744 * 00745 * @note 00746 * - It's possible that the axis vector is not normalized because for instance 00747 * the matrix was scaled 00748 */ 00749 inline Vector3 GetXAxis() const; 00750 00751 /** 00752 * @brief 00753 * Returns the y (up) axis 00754 * 00755 * @return 00756 * The y (up) axis 00757 * 00758 * @remarks 00759 * @code 00760 * | 0 x 0 0 | 00761 * | 0 y 0 0 | 00762 * | 0 z 0 0 | 00763 * @endcode 00764 * 00765 * @see 00766 * - GetXAxis() 00767 */ 00768 inline Vector3 GetYAxis() const; 00769 00770 /** 00771 * @brief 00772 * Returns the z (forward) axis 00773 * 00774 * @return 00775 * The z (forward) axis 00776 * 00777 * @remarks 00778 * @code 00779 * | 0 0 x 0 | 00780 * | 0 0 y 0 | 00781 * | 0 0 z 0 | 00782 * @endcode 00783 * 00784 * @see 00785 * - GetXAxis() 00786 */ 00787 inline Vector3 GetZAxis() const; 00788 00789 /** 00790 * @brief 00791 * Returns the three axis of a rotation matrix (not normalized) 00792 * 00793 * @param[out] vX 00794 * Will receive the x axis 00795 * @param[out] vY 00796 * Will receive the y axis 00797 * @param[out] vZ 00798 * Will receive the z axis 00799 * 00800 * @remarks 00801 * @code 00802 * | vX.x vY.x vZ.x 0 | 00803 * | vX.y vY.y vZ.y 0 | 00804 * | vX.z vY.z vZ.z 0 | 00805 * @endcode 00806 */ 00807 PLMATH_API void ToAxis(Vector3 &vX, Vector3 &vY, Vector3 &vZ) const; 00808 00809 /** 00810 * @brief 00811 * Sets a rotation matrix by using three given axis 00812 * 00813 * @param[in] vX 00814 * X axis 00815 * @param[in] vY 00816 * Y axis 00817 * @param[in] vZ 00818 * Z axis 00819 * 00820 * @see 00821 * - ToAxis() 00822 */ 00823 PLMATH_API void FromAxis(const Vector3 &vX, const Vector3 &vY, const Vector3 &vZ); 00824 00825 /** 00826 * @brief 00827 * Builds a look-at matrix 00828 * 00829 * @param[in] vEye 00830 * Eye position 00831 * @param[in] vAt 00832 * Camera look-at target 00833 * @param[in] vUp 00834 * Current world's up, usually [0, 1, 0] 00835 * 00836 * @return 00837 * This instance 00838 */ 00839 PLMATH_API Matrix3x4 &LookAt(const Vector3 &vEye, const Vector3 &vAt, const Vector3 &vUp); 00840 00841 /** 00842 * @brief 00843 * Builds a view matrix 00844 * 00845 * @param[in] qRotation 00846 * Rotation quaternion 00847 * @param[in] vPosition 00848 * Position vector 00849 * 00850 * @return 00851 * This instance 00852 * 00853 * @remarks 00854 * @code 00855 * | RotT.xx RotT.xy RotT.xz T.x | 00856 * | RotT.yx RotT.yy RotT.yz T.y | 00857 * | RotT.zx RotT.zy RotT.zz T.z | 00858 * @endcode 00859 * 00860 * RotT = Transposed(Rot) 00861 * T = -(Transposed(Rot) * Pos) 00862 */ 00863 PLMATH_API Matrix3x4 &View(const Quaternion &qRotation, const Vector3 &vPosition); 00864 00865 //[-------------------------------------------------------] 00866 //[ Misc ] 00867 //[-------------------------------------------------------] 00868 /** 00869 * @brief 00870 * Sets a matrix using a given quaternion and translation 00871 * 00872 * @param[in] qRotation 00873 * Rotation quaternion 00874 * @param[in] vTranslation 00875 * Translation vector 00876 * 00877 * @return 00878 * This instance 00879 * 00880 * @remarks 00881 * First this function is using Quaternion::ToRotationMatrix() to create a rotation matrix. 00882 * Then the translation components are set. (Matrix3x4::SetTranslation()) 00883 */ 00884 PLMATH_API Matrix3x4 &FromQuatTrans(const Quaternion &qRotation, const Vector3 &vTranslation); 00885 00886 /** 00887 * @brief 00888 * Sets a shearing matrix 00889 * 00890 * @param[in] fShearXY 00891 * Shear X by Y 00892 * @param[in] fShearXZ 00893 * Shear X by Z 00894 * @param[in] fShearYX 00895 * Shear Y by X 00896 * @param[in] fShearYZ 00897 * Shear Y by Z 00898 * @param[in] fShearZX 00899 * Shear Z by X 00900 * @param[in] fShearZY 00901 * Shear Z by Y 00902 * 00903 * @return 00904 * This instance 00905 * 00906 * @remarks 00907 * A shearing matrix can be used to for instance make a 3D model appear to slant 00908 * sideways. Here's a table showing how a combined shearing matrix looks like: 00909 * @code 00910 * | 1 fShearYX fShearZX 0 | 00911 * | fShearXY 1 fShearZY 0 | 00912 * | fShearXZ fShearYZ 1 0 | 00913 * @endcode 00914 * If you only want to shear one axis it's recommended to construct the matrix by yourself. 00915 */ 00916 inline Matrix3x4 &SetShearing(float fShearXY, float fShearXZ, float fShearYX, float fShearYZ, 00917 float fShearZX, float fShearZY); 00918 00919 /** 00920 * @brief 00921 * Sets a matrix that reflects the coordinate system about a plane 00922 * 00923 * @param[in] cPlane 00924 * Reflection plane (must be normalized!) 00925 * 00926 * @return 00927 * This instance 00928 * 00929 * @remarks 00930 * @code 00931 * | -2*cPlane.a*cPlane.a+1 -2*cPlane.a*cPlane.b -2*cPlane.a*cPlane.c -2*cPlane.a*cPlane.d | 00932 * | -2*cPlane.b*cPlane.a -2*cPlane.b*cPlane.b+1 -2*cPlane.b*cPlane.c -2*cPlane.b*cPlane.d | 00933 * | -2*cPlane.c*cPlane.a -2*cPlane.c*cPlane.b -2*cPlane.c*cPlane.c+1 -2*cPlane.c*cPlane.d | 00934 * @endcode 00935 */ 00936 PLMATH_API Matrix3x4 &SetReflection(const Plane &cPlane); 00937 00938 00939 }; 00940 00941 00942 //[-------------------------------------------------------] 00943 //[ Namespace ] 00944 //[-------------------------------------------------------] 00945 } // PLMath 00946 00947 00948 //[-------------------------------------------------------] 00949 //[ Implementation ] 00950 //[-------------------------------------------------------] 00951 #include "PLMath/Matrix3x4.inl" 00952 00953 00954 #endif // __PLMATH_MATRIX3X4_H__
|