PixelLightAPI  .
Matrix3x4.h
Go to the documentation of this file.
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__


PixelLight PixelLight 0.9.10-R1
Copyright (C) 2002-2011 by The PixelLight Team
Last modified Fri Dec 23 2011 15:50:57
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported