PixelLightAPI  .
Matrix4x4.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: Matrix4x4.h                                    *
00003  *
00004  *  Copyright (C) 2002-2012 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_MATRIX4X4_H__
00024 #define __PLMATH_MATRIX4X4_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 *    4x4 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 Matrix4x4 {
00062 
00063 
00064     //[-------------------------------------------------------]
00065     //[ Public static data                                    ]
00066     //[-------------------------------------------------------]
00067     public:
00068         static PLMATH_API const Matrix4x4 Zero;     /**< Zero matrix */
00069         static PLMATH_API const Matrix4x4 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 <= 3) and column c (0 <= c <= 3) is
00087             *    stored at index i = r+4*c (0 <= i <= 15).\n
00088             *    Indices:
00089             *    @code
00090             *      | 0  4  8  12 |
00091             *      | 1  5  9  13 |
00092             *      | 2  6  10 14 |
00093             *      | 3  7  11 15 |
00094             *    @endcode
00095             */
00096             float fM[16];
00097 
00098             /**
00099             *  @brief
00100             *    Direct element representation
00101             *
00102             *  @remarks
00103             *    Indices: (row/column)
00104             *    @code
00105             *      | xx xy xz xw |
00106             *      | yx yy yz yw |
00107             *      | zx zy zz zw |
00108             *      | wx wy wz ww |
00109             *    @endcode
00110             *    It's recommended to use this way to access the elements.
00111             */
00112             struct {
00113                 float xx, yx, zx, wx;
00114                 float xy, yy, zy, wy;
00115                 float xz, yz, zz, wz;
00116                 float xw, yw, zw, ww;
00117             };
00118 
00119             /**
00120             *  @brief
00121             *    Two dimensional array representation
00122             *
00123             *  @remarks
00124             *    fM44[i][j] -> i=column, j=row\n
00125             *    Try to avoid this access mode. This can be a problem on a platform/console that
00126             *    chooses to store the data in column-major rather than row-major format.
00127             */
00128             struct {
00129                 float fM44[4][4];
00130             };
00131         };
00132 
00133 
00134     //[-------------------------------------------------------]
00135     //[ Public functions                                      ]
00136     //[-------------------------------------------------------]
00137     public:
00138         //[-------------------------------------------------------]
00139         //[ Constructor                                           ]
00140         //[-------------------------------------------------------]
00141         /**
00142         *  @brief
00143         *    Default constructor setting an identity matrix
00144         */
00145         inline Matrix4x4();
00146 
00147         inline Matrix4x4(const float fS[]);
00148         PLMATH_API Matrix4x4(const Matrix3x3 &mM);
00149         PLMATH_API Matrix4x4(const Matrix3x4 &mM);
00150         inline Matrix4x4(const Matrix4x4 &mM);
00151         inline Matrix4x4(float fXX, float fXY, float fXZ, float fXW,
00152                          float fYX, float fYY, float fYZ, float fYW,
00153                          float fZX, float fZY, float fZZ, float fZW,
00154                          float fWX, float fWY, float fWZ, float fWW);
00155 
00156         //[-------------------------------------------------------]
00157         //[ Destructor                                            ]
00158         //[-------------------------------------------------------]
00159         inline ~Matrix4x4();
00160 
00161         //[-------------------------------------------------------]
00162         //[ Comparison                                            ]
00163         //[-------------------------------------------------------]
00164         /** 3x4: The last row is compared with (0, 0, 0, 1) */
00165         PLMATH_API bool operator ==(const Matrix3x4 &mM) const;
00166         PLMATH_API bool operator ==(const Matrix4x4 &mM) const;
00167         /** 3x4: The last row is compared with (0, 0, 0, 1) */
00168         PLMATH_API bool operator !=(const Matrix3x4 &mM) const;
00169         PLMATH_API bool operator !=(const Matrix4x4 &mM) const;
00170         // fEpsilon = epsilon environment (to take computation errors into account...)
00171         PLMATH_API bool CompareScale(const Matrix4x4 &mM, float fEpsilon = Math::Epsilon) const;
00172         PLMATH_API bool CompareTranslation(const Matrix4x4 &mM, float fEpsilon = Math::Epsilon) const;
00173         PLMATH_API bool CompareRotation(const Matrix4x4 &mM, float fEpsilon = Math::Epsilon) const;
00174 
00175         //[-------------------------------------------------------]
00176         //[ Operators                                             ]
00177         //[-------------------------------------------------------]
00178         inline Matrix4x4     &operator =(const float fS[]);
00179         PLMATH_API Matrix4x4 &operator =(const Matrix3x3 &mM);
00180         PLMATH_API Matrix4x4 &operator =(const Matrix3x4 &mM);
00181         inline Matrix4x4     &operator =(const Matrix4x4 &mM);
00182         inline Matrix4x4      operator +(const Matrix4x4 &mM) const;
00183         inline void           operator +=(const Matrix4x4 &mM);
00184         inline Matrix4x4      operator -() const;
00185         inline Matrix4x4      operator -(const Matrix4x4 &mM) const;
00186         inline void           operator -=(const Matrix4x4 &mM);
00187         inline Matrix4x4      operator *(float fS) const;
00188         inline void           operator *=(float fS);
00189         inline Vector2        operator *(const Vector2 &vV) const;
00190         inline Vector3        operator *(const Vector3 &vV) const;
00191         inline Vector4        operator *(const Vector4 &vV) const;
00192         /** A 4x4*3x4 matrix multiplication is NOT defined, so we use the given 3x4 matrix with
00193             a fourth row (0, 0, 0, 1) which result in a 4x4*4x4 matrix multiplication which is
00194             allowed */
00195         PLMATH_API Matrix4x4  operator *(const Matrix3x4 &mM) const;
00196         PLMATH_API Matrix4x4  operator *(const Matrix4x4 &mM) const;
00197         /** @see - *(const Matrix3x4 &mM) */
00198         inline void           operator *=(const Matrix3x4 &mM);
00199         inline void           operator *=(const Matrix4x4 &mM);
00200         inline Matrix4x4      operator /(float fS) const;
00201         inline void           operator /=(float fS);
00202         inline float          operator [](int nIndex) const;
00203         inline float         &operator [](int nIndex);
00204         inline float          operator ()(PLCore::uint32 nRow = 0, PLCore::uint32 nColumn = 0) const;
00205         inline float         &operator ()(PLCore::uint32 nRow = 0, PLCore::uint32 nColumn = 0);
00206         inline                operator float *();
00207         inline                operator const float *() const;
00208 
00209         //[-------------------------------------------------------]
00210         //[ Matrix operations                                     ]
00211         //[-------------------------------------------------------]
00212         /**
00213         *  @brief
00214         *    Returns whether or not this matrix is the zero matrix using an epsilon environment
00215         *
00216         *  @return
00217         *    'true' if this matrix is the zero matrix, else 'false'
00218         */
00219         inline bool IsZero() const;
00220 
00221         /**
00222         *  @brief
00223         *    Returns whether or not this matrix is truly the zero matrix
00224         *
00225         *  @remarks
00226         *    All components MUST be exactly 0. Floating point inaccuracy
00227         *    is not taken into account.
00228         *
00229         *  @return
00230         *    'true' if this matrix is truly the zero matrix, else 'false'
00231         */
00232         inline bool IsTrueZero() const;
00233 
00234         /**
00235         *  @brief
00236         *    Sets a zero matrix
00237         *
00238         *  @remarks
00239         *    @code
00240         *    | 0 0 0 0 |
00241         *    | 0 0 0 0 |
00242         *    | 0 0 0 0 |
00243         *    | 0 0 0 0 |
00244         *    @endcode
00245         */
00246         inline void SetZero();
00247 
00248         /**
00249         *  @brief
00250         *    Returns whether or not this matrix is the identity matrix using an epsilon environment
00251         *
00252         *  @return
00253         *    'true' if this matrix is the identity matrix, else 'false'
00254         */
00255         inline bool IsIdentity() const;
00256 
00257         /**
00258         *  @brief
00259         *    Returns whether or not this matrix is truly the identity matrix
00260         *
00261         *  @remarks
00262         *    All components MUST be exactly either 0 or 1. Floating point inaccuracy
00263         *    is not taken into account.
00264         *
00265         *  @return
00266         *    'true' if this matrix is truly the identity matrix, else 'false'
00267         */
00268         inline bool IsTrueIdentity() const;
00269 
00270         /**
00271         *  @brief
00272         *    Sets an identity matrix
00273         *
00274         *  @remarks
00275         *    @code
00276         *    | 1 0 0 0 |
00277         *    | 0 1 0 0 |
00278         *    | 0 0 1 0 |
00279         *    | 0 0 0 1 |
00280         *    @endcode
00281         */
00282         inline void SetIdentity();
00283 
00284         /**
00285         *  @brief
00286         *    Sets the elements of the matrix
00287         */
00288         PLMATH_API void Set(float fXX, float fXY, float fXZ, float fXW,
00289                             float fYX, float fYY, float fYZ, float fYW,
00290                             float fZX, float fZY, float fZZ, float fZW,
00291                             float fWX, float fWY, float fWZ, float fWW);
00292 
00293         /**
00294         *  @brief
00295         *    Returns a requested row
00296         *
00297         *  @param[in] nRow
00298         *    Index of the row to return (0-3)
00299         *
00300         *  @return
00301         *    The requested row (null vector on error)
00302         *
00303         *  @remarks
00304         *    @code
00305         *    | x y z w | <- Row 0
00306         *    | 0 0 0 0 |
00307         *    | 0 0 0 0 |
00308         *    | 0 0 0 0 |
00309         *    @endcode
00310         */
00311         inline Vector4 GetRow(PLCore::uint8 nRow) const;
00312 
00313         /**
00314         *  @brief
00315         *    Sets a row
00316         *
00317         *  @param[in] nRow
00318         *    Index of the row to set (0-3)
00319         *  @param[in] vRow
00320         *    Row vector
00321         *
00322         *  @see
00323         *    - GetRow()
00324         */
00325         inline void SetRow(PLCore::uint8 nRow, const Vector4 &vRow);
00326 
00327         /**
00328         *  @brief
00329         *    Returns a requested column
00330         *
00331         *  @param[in] nColumn
00332         *    Index of the column to return (0-3)
00333         *
00334         *  @return
00335         *    The requested column (null vector on error)
00336         *
00337         *  @remarks
00338         *    @code
00339         *    | x 0 0 0 |
00340         *    | y 0 0 0 |
00341         *    | z 0 0 0 |
00342         *    | w 0 0 0 |
00343         *      ^
00344         *      |
00345         *      Column 0
00346         *    @endcode
00347         */
00348         inline Vector4 GetColumn(PLCore::uint8 nColumn) const;
00349 
00350         /**
00351         *  @brief
00352         *    Sets a column
00353         *
00354         *  @param[in] nColumn
00355         *    Index of the column to set (0-3)
00356         *  @param[in] vColumn
00357         *    Column vector
00358         *
00359         *  @see
00360         *    - GetColumn()
00361         */
00362         inline void SetColumn(PLCore::uint8 nColumn, const Vector4 &vColumn);
00363 
00364         /**
00365         *  @brief
00366         *    Returns true if the matrix is symmetric
00367         *
00368         *  @return
00369         *    'true' if the matrix is symmetric, else 'false'
00370         *
00371         *  @remarks
00372         *    A matrix is symmetric if it is equal to it's transposed matrix.\n
00373         *    A = A^T  ->  a(i, j) = a(j, i)
00374         */
00375         inline bool IsSymmetric() const;
00376 
00377         /**
00378         *  @brief
00379         *    Returns true if this matrix is orthogonal
00380         *
00381         *  @return
00382         *    'true' if the matrix is orthogonal, else 'false'
00383         *
00384         *  @remarks
00385         *    A matrix is orthogonal if it's transposed matrix is equal to it's inversed matrix.\n
00386         *    A^T = A^-1  or  A*A^T = A^T*A = I
00387         *
00388         *  @note
00389         *    - An orthogonal matrix is always nonsingular (invertible) and it's inverse is equal to it's transposed
00390         *    - The transpose and inverse of the matrix is orthogonal, too
00391         *    - Products of orthogonal matrices are orthogonal, too
00392         *    - The determinant of a orthogonal matrix is +/- 1
00393         *    - The row and column vectors of an orthogonal matrix form an orthonormal basis,
00394         *      that is, these vectors are unit-length and they are mutually perpendicular
00395         */
00396         inline bool IsOrthogonal() const;
00397 
00398         /**
00399         *  @brief
00400         *    Returns true if this matrix is a rotation matrix
00401         *
00402         *  @return
00403         *    'true' if this matrix is a rotation matrix, else 'false'
00404         *
00405         *  @remarks
00406         *    A rotation matrix is orthogonal and it's determinant is 1 to rule out reflections.
00407         *
00408         *  @see
00409         *    - IsOrthogonal()
00410         */
00411         inline bool IsRotationMatrix() const;
00412 
00413         /**
00414         *  @brief
00415         *    Returns true if this matrix is a rotation and translation matrix
00416         *
00417         *  @return
00418         *    'true' if this matrix is a rotation and translation matrix, else 'false'
00419         *
00420         *  @remarks
00421         *    A rotation and translation matrix looks like this:
00422         *    @code
00423         *      | x x x x |
00424         *      | x x x x |
00425         *      | x x x x |
00426         *      | 0 0 0 1 |
00427         *    @endcode
00428         *    Were 'x' means this field is used and as you see the last row must be empty.
00429         *
00430         *  @see
00431         *    - IsRotationMatrix()
00432         */
00433         inline bool IsRotationTranslationMatrix() const;
00434 
00435         /**
00436         *  @brief
00437         *    Returns the trace of the matrix
00438         *
00439         *  @return
00440         *    The trace of the matrix
00441         *
00442         *  @remarks
00443         *    The trace of the matrix is the sum of the main diagonal elements:\n
00444         *      xx+yy+zz+ww
00445         */
00446         inline float GetTrace() const;
00447 
00448         /**
00449         *  @brief
00450         *    Returns the determinant of the matrix
00451         *
00452         *  @return
00453         *    Determinant of the matrix
00454         *
00455         *  @note
00456         *    - If the determinant is non-zero, then an inverse matrix exists
00457         *    - If the determinant is 0, the matrix is called singular, else nonsingular (invertible) matrix
00458         *    - If the determinant is 1, the inverse matrix is equal to the transpose of the matrix
00459         */
00460         PLMATH_API float GetDeterminant() const;
00461 
00462         /**
00463         *  @brief
00464         *    Transpose this matrix
00465         *
00466         *  @remarks
00467         *    The transpose of matrix is the matrix generated when every element in
00468         *    the matrix is swapped with the opposite relative to the major diagonal
00469         *    This can be expressed as the mathematical operation:
00470         *    @code
00471         *      M'   = M
00472         *        ij    ji
00473         *
00474         *      | xx xy xz xw |                    | xx yx zx wx |
00475         *      | yx yy yz yw |  the transpose is  | xy yy zy wy |
00476         *      | zx zy zz zw |                    | xz yz zz wz |
00477         *      | wx wy wz ww |                    | xw yw zw ww |
00478         *    @endcode
00479         *
00480         *  @note
00481         *    - If the matrix is a rotation matrix (= isotropic matrix = determinant is 1),
00482         *      then the transpose is guaranteed to be the inverse of the matrix
00483         */
00484         PLMATH_API void Transpose();
00485 
00486         /**
00487         *  @brief
00488         *    Returns the transposed matrix
00489         *
00490         *  @return
00491         *    Transposed matrix
00492         *
00493         *  @see
00494         *    - Transpose()
00495         */
00496         PLMATH_API Matrix4x4 GetTransposed() const;
00497 
00498         /**
00499         *  @brief
00500         *    Inverts the matrix
00501         *
00502         *  @return
00503         *    'true' if all went fine, else 'false' (maybe the determinant is null?)
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         PLMATH_API Matrix4x4 GetInverted() const;
00518 
00519         /**
00520         *  @brief
00521         *    Rotates a vector
00522         *
00523         *  @param[in] fX
00524         *    X component of the vector to rotate
00525         *  @param[in] fY
00526         *    Y component of the vector to rotate
00527         *  @param[in] fZ
00528         *    Z component of the vector to rotate
00529         *  @param[in] bUniformScale
00530         *    Is this a uniform scale matrix? (all axis are scaled equally)
00531         *    If you know EXACTLY it's one, set this to 'true' to gain some more speed, else DON'T set to 'true'!
00532         *
00533         *  @return
00534         *    The rotated vector
00535         *
00536         *  @remarks
00537         *    This function is similar to a matrix * vector operation - except that the
00538         *    translation of the matrix is ignored and this function can deal with none
00539         *    uniform scale. So, this function can for instance be used to rotate a
00540         *    direction vector. (matrix * direction vector)
00541         *
00542         *  @note
00543         *    - You can't assume that the resulting vector is normalized
00544         *    - Use this function to rotate for example a normal vector
00545         */
00546         PLMATH_API Vector3 RotateVector(float fX, float fY, float fZ, bool bUniformScale = false) const;
00547 
00548         /**
00549         *  @brief
00550         *    Rotates a vector
00551         *
00552         *  @param[in] vV
00553         *    Vector to rotate
00554         *  @param[in] bUniformScale
00555         *    Is this a uniform scale matrix? (all axis are scaled equally)
00556         *    If you know EXACTLY it's one, set this to 'true' to gain some more speed, else DON'T set to 'true'!
00557         *
00558         *  @return
00559         *    The rotated vector
00560         *
00561         *  @see
00562         *    - RotateVector(float, float, float) above
00563         */
00564         PLMATH_API Vector3 RotateVector(const Vector3 &vV, bool bUniformScale = false) const;
00565 
00566         //[-------------------------------------------------------]
00567         //[ Scale                                                 ]
00568         //[-------------------------------------------------------]
00569         /**
00570         *  @brief
00571         *    Sets a scale matrix
00572         *
00573         *  @param[in] fX
00574         *    X scale
00575         *  @param[in] fY
00576         *    Y scale
00577         *  @param[in] fZ
00578         *    Z scale
00579         *
00580         *  @remarks
00581         *    @code
00582         *    | x 0 0 0 |
00583         *    | 0 y 0 0 |
00584         *    | 0 0 z 0 |
00585         *    | 0 0 0 1 |
00586         *    @endcode
00587         */
00588         inline void SetScaleMatrix(float fX, float fY, float fZ);
00589         inline void SetScaleMatrix(const Vector3 &vV);
00590 
00591         /**
00592         *  @brief
00593         *    Extracts the scale vector from the matrix as good as possible
00594         *
00595         *  @param[out] fX
00596         *    Receives the x scale
00597         *  @param[out] fY
00598         *    Receives the y scale
00599         *  @param[out] fZ
00600         *    Receives the z scale
00601         *
00602         *  @note
00603         *    - This function will not work correctly if one or two components are negative while
00604         *      another is/are not (we can't figure out WHICH axis are negative!)
00605         */
00606         PLMATH_API void GetScale(float &fX, float &fY, float &fZ) const;
00607         inline Vector3 GetScale() const;
00608         inline void GetScale(float fV[]) const;
00609 
00610         //[-------------------------------------------------------]
00611         //[ Translation                                           ]
00612         //[-------------------------------------------------------]
00613         /**
00614         *  @brief
00615         *    Sets a translation matrix
00616         *
00617         *  @param[in] fX
00618         *    X translation
00619         *  @param[in] fY
00620         *    Y translation
00621         *  @param[in] fZ
00622         *    Z translation
00623         *
00624         *  @remarks
00625         *    @code
00626         *    | 1 0 0 x |
00627         *    | 0 1 0 y |
00628         *    | 0 0 1 z |
00629         *    | 0 0 0 1 |
00630         *    @endcode
00631         */
00632         inline void SetTranslationMatrix(float fX, float fY, float fZ);
00633         inline void SetTranslationMatrix(const Vector3 &vV);
00634 
00635         // Get and set
00636         inline void GetTranslation(float &fX, float &fY, float &fZ) const;
00637         inline Vector3 GetTranslation() const;
00638         inline void GetTranslation(float fV[]) const;
00639         inline void SetTranslation(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f);
00640         inline void SetTranslation(const Vector3 &vV);
00641         inline void SetTranslation(const float fV[]);
00642 
00643         //[-------------------------------------------------------]
00644         //[ Rotation                                              ]
00645         //[-------------------------------------------------------]
00646         /**
00647         *  @brief
00648         *    Sets an x axis rotation matrix by using one given Euler angle
00649         *
00650         *  @param[in] fAngleX
00651         *    Rotation angle around the x axis (in radian, between [0, Math::Pi2])
00652         *
00653         *  @remarks
00654         *    @code
00655         *         |    1       0       0    0 |
00656         *    RX = |    0     cos(a) -sin(a) 0 |
00657         *         |    0     sin(a)  cos(a) 0 |
00658         *         |    0       0       0    1 |
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         *         |    0       0       0    1 |
00677         *    @endcode
00678         *    where a > 0 indicates a counterclockwise rotation in the zx-plane (if you look along -y)
00679         */
00680         PLMATH_API void FromEulerAngleY(float fAngleY);
00681 
00682         /**
00683         *  @brief
00684         *    Sets an z axis rotation matrix by using one given Euler angle
00685         *
00686         *  @param[in] fAngleZ
00687         *    Rotation angle around the z axis (in radian, between [0, Math::Pi2])
00688         *
00689         *  @remarks
00690         *    @code
00691         *         |  cos(a) -sin(a)    0    0 |
00692         *    RZ = |  sin(a)  cos(a)    0    0 |
00693         *         |    0       0       1    0 |
00694         *         |    0       0       0    1 |
00695         *    @endcode
00696         *    where a > 0 indicates a counterclockwise rotation in the xy-plane (if you look along -z)
00697         */
00698         PLMATH_API void FromEulerAngleZ(float fAngleZ);
00699 
00700         /**
00701         *  @brief
00702         *    Returns a rotation matrix as a selected axis and angle
00703         *
00704         *  @param[out] fX
00705         *    Will receive the x component of the selected axis
00706         *  @param[out] fY
00707         *    Will receive the y component of the selected axis
00708         *  @param[out] fZ
00709         *    Will receive the z component of the selected axis
00710         *  @param[out] fAngle
00711         *    Will receive the rotation angle around the selected axis (in radian, between [0, Math::Pi])
00712         */
00713         PLMATH_API void ToAxisAngle(float &fX, float &fY, float &fZ, float &fAngle) const;
00714 
00715         /**
00716         *  @brief
00717         *    Sets a rotation matrix by using a selected axis and angle
00718         *
00719         *  @param[in] fX
00720         *    X component of the selected axis
00721         *  @param[in] fY
00722         *    Y component of the selected axis
00723         *  @param[in] fZ
00724         *    Z component of the selected axis
00725         *  @param[in] fAngle
00726         *    Rotation angle around the selected axis (in radian, between [0, Math::Pi])
00727         *
00728         *  @note
00729         *    - The given selected axis must be normalized!
00730         */
00731         PLMATH_API void FromAxisAngle(float fX, float fY, float fZ, float fAngle);
00732 
00733         /**
00734         *  @brief
00735         *    Returns the x (left) axis
00736         *
00737         *  @return
00738         *    The x (left) axis
00739         *
00740         *  @remarks
00741         *    @code
00742         *    | x 0 0 0 |
00743         *    | y 0 0 0 |
00744         *    | z 0 0 0 |
00745         *    | 0 0 0 1 |
00746         *    @endcode
00747         *
00748         *  @note
00749         *    - It's possible that the axis vector is not normalized because for instance
00750         *      the matrix was scaled
00751         */
00752         inline Vector3 GetXAxis() const;
00753 
00754         /**
00755         *  @brief
00756         *    Returns the y (up) axis
00757         *
00758         *  @return
00759         *    The y (up) axis
00760         *
00761         *  @remarks
00762         *    @code
00763         *    | 0 x 0 0 |
00764         *    | 0 y 0 0 |
00765         *    | 0 z 0 0 |
00766         *    | 0 0 0 1 |
00767         *    @endcode
00768         *
00769         *  @see
00770         *    - GetXAxis()
00771         */
00772         inline Vector3 GetYAxis() const;
00773 
00774         /**
00775         *  @brief
00776         *    Returns the z (forward) axis
00777         *
00778         *  @return
00779         *    The z (forward) axis
00780         *
00781         *  @remarks
00782         *    @code
00783         *    | 0 0 x 0 |
00784         *    | 0 0 y 0 |
00785         *    | 0 0 z 0 |
00786         *    | 0 0 0 1 |
00787         *    @endcode
00788         *
00789         *  @see
00790         *    - GetXAxis()
00791         */
00792         inline Vector3 GetZAxis() const;
00793 
00794         /**
00795         *  @brief
00796         *    Returns the three axis of a rotation matrix (not normalized)
00797         *
00798         *  @param[out] vX
00799         *    Will receive the x axis
00800         *  @param[out] vY
00801         *    Will receive the y axis
00802         *  @param[out] vZ
00803         *    Will receive the z axis
00804         *
00805         *  @remarks
00806         *    @code
00807         *    | vX.x vY.x vZ.x 0 |
00808         *    | vX.y vY.y vZ.y 0 |
00809         *    | vX.z vY.z vZ.z 0 |
00810         *    | 0    0    0    1 |
00811         *    @endcode
00812         */
00813         PLMATH_API void ToAxis(Vector3 &vX, Vector3 &vY, Vector3 &vZ) const;
00814 
00815         /**
00816         *  @brief
00817         *    Sets a rotation matrix by using three given axis
00818         *
00819         *  @param[in] vX
00820         *    X axis
00821         *  @param[in] vY
00822         *    Y axis
00823         *  @param[in] vZ
00824         *    Z axis
00825         *
00826         *  @see
00827         *    - ToAxis()
00828         */
00829         PLMATH_API void FromAxis(const Vector3 &vX, const Vector3 &vY, const Vector3 &vZ);
00830 
00831         /**
00832         *  @brief
00833         *    Builds a look-at matrix
00834         *
00835         *  @param[in] vEye
00836         *    Eye position
00837         *  @param[in] vAt
00838         *    Camera look-at target
00839         *  @param[in] vUp
00840         *    Current world's up, usually [0, 1, 0]
00841         *
00842         *  @return
00843         *    This instance
00844         */
00845         PLMATH_API Matrix4x4 &LookAt(const Vector3 &vEye, const Vector3 &vAt, const Vector3 &vUp);
00846 
00847         /**
00848         *  @brief
00849         *    Builds a view matrix
00850         *
00851         *  @param[in] qRotation
00852         *    Rotation quaternion
00853         *  @param[in] vPosition
00854         *    Position vector
00855         *
00856         *  @return
00857         *    This instance
00858         *
00859         *  @remarks
00860         *    @code
00861         *    | RotT.xx RotT.xy RotT.xz T.x |
00862         *    | RotT.yx RotT.yy RotT.yz T.y |
00863         *    | RotT.zx RotT.zy RotT.zz T.z |
00864         *    | 0       0       0       1   |
00865         *    @endcode
00866         *
00867         *    RotT = Transposed(Rot)
00868         *    T    = -(Transposed(Rot) * Pos)
00869         */
00870         PLMATH_API Matrix4x4 &View(const Quaternion &qRotation, const Vector3 &vPosition);
00871 
00872         //[-------------------------------------------------------]
00873         //[ Misc                                                  ]
00874         //[-------------------------------------------------------]
00875         /**
00876         *  @brief
00877         *    Sets a matrix using a given quaternion and translation
00878         *
00879         *  @param[in] qRotation
00880         *    Rotation quaternion
00881         *  @param[in] vTranslation
00882         *    Translation vector
00883         *
00884         *  @return
00885         *    This instance
00886         *
00887         *  @remarks
00888         *    First this function is using Quaternion::ToRotationMatrix() to create a rotation matrix.
00889         *    Then the translation components are set. (Matrix4x4::SetTranslation())
00890         */
00891         PLMATH_API Matrix4x4 &FromQuatTrans(const Quaternion &qRotation, const Vector3 &vTranslation);
00892 
00893         /**
00894         *  @brief
00895         *    Sets a shearing matrix
00896         *
00897         *  @param[in] fShearXY
00898         *    Shear X by Y
00899         *  @param[in] fShearXZ
00900         *    Shear X by Z
00901         *  @param[in] fShearYX
00902         *    Shear Y by X
00903         *  @param[in] fShearYZ
00904         *    Shear Y by Z
00905         *  @param[in] fShearZX
00906         *    Shear Z by X
00907         *  @param[in] fShearZY
00908         *    Shear Z by Y
00909         *
00910         *  @return
00911         *    This instance
00912         *
00913         *  @remarks
00914         *    A shearing matrix can be used to for instance make a 3D model appear to slant
00915         *    sideways. Here's a table showing how a combined shearing matrix looks like:
00916         *    @code
00917         *    | 1        fShearYX  fShearZX  0 |
00918         *    | fShearXY 1         fShearZY  0 |
00919         *    | fShearXZ fShearYZ  1         0 |
00920         *    | 0        0         0         1 |
00921         *    @endcode
00922         *    If you only want to shear one axis it's recommended to construct the matrix by yourself.
00923         */
00924         inline Matrix4x4 &SetShearing(float fShearXY, float fShearXZ, float fShearYX, float fShearYZ,
00925                                       float fShearZX, float fShearZY);
00926 
00927         /**
00928         *  @brief
00929         *    Sets a matrix that reflects the coordinate system about a plane
00930         *
00931         *  @param[in] cPlane
00932         *    Reflection plane (must be normalized!)
00933         *
00934         *  @return
00935         *    This instance
00936         *
00937         *  @remarks
00938         *    @code
00939         *    | -2*cPlane.a*cPlane.a+1 -2*cPlane.a*cPlane.b   -2*cPlane.a*cPlane.c   -2*cPlane.a*cPlane.d |
00940         *    | -2*cPlane.b*cPlane.a   -2*cPlane.b*cPlane.b+1 -2*cPlane.b*cPlane.c   -2*cPlane.b*cPlane.d |
00941         *    | -2*cPlane.c*cPlane.a   -2*cPlane.c*cPlane.b   -2*cPlane.c*cPlane.c+1 -2*cPlane.c*cPlane.d |
00942         *    |                      0                      0                      0                    1 |
00943         *    @endcode
00944         */
00945         PLMATH_API Matrix4x4 &SetReflection(const Plane &cPlane);
00946 
00947         /**
00948         *  @brief
00949         *    Sets a shadow projection matrix
00950         *
00951         *  @param[in] vLight
00952         *    Light source position (if the light is directional, the w value should be 0)
00953         *  @param[in] cPlane
00954         *    Plane where to project the shadow onto
00955         *
00956         *  @return
00957         *    This instance
00958         *
00959         *  @remarks
00960         *    @code
00961         *    | fDot-vLight.x*cPlane.a     -vLight.x*cPlane.b     -vLight.x*cPlane.c     -vLight.x*cPlane.d |
00962         *    |     -vLight.y*cPlane.a fDot-vLight.y*cPlane.b     -vLight.y*cPlane.c     -vLight.y*cPlane.d |
00963         *    |     -vLight.z*cPlane.a     -vLight.z*cPlane.b fDot-vLight.z*cPlane.c     -vLight.z*cPlane.d |
00964         *    |     -vLight.w*cPlane.a     -vLight.w*cPlane.b     -vLight.w*cPlane.c fDot-vLight.w*cPlane.d |
00965         *
00966         *    where:
00967         *      float fDot = cPlane.a*vLight.x + cPlane.b*vLight.y + cPlane.c*vLight.z + cPlane.d*vLight.w;
00968         *    @endcode
00969         */
00970         PLMATH_API Matrix4x4 &SetShadowProjection(const Vector4 &vLight, const Plane &cPlane);
00971 
00972         /**
00973         *  @brief
00974         *    Creates a projection matrix that restricts drawing to a small region of the given viewport
00975         *
00976         *  @param[in] vStartPos
00977         *    Region start position
00978         *  @param[in] vEndPos
00979         *    Region end position
00980         *  @param[in] nX
00981         *    X component of the pixel coordinate of the upper-left corner of the viewport
00982         *  @param[in] nY
00983         *    Y component of the pixel coordinate of the upper-left corner of the viewport
00984         *  @param[in] nWidth
00985         *    Width of the clip volume, in pixels
00986         *  @param[in] nHeight
00987         *    Height of the clip volume, in pixels
00988         *
00989         *  @note
00990         *    - The start and end positions are within the given viewport
00991         *    - Multiply this projection matrix with our standard projection matrix to get a restricted version
00992         */
00993         PLMATH_API void RestrictedProjection(const Vector2 &vStartPos, const Vector2 &vEndPos,
00994                                              int nX, int nY, int nWidth, int nHeight);
00995 
00996         /**
00997         *  @brief
00998         *    Builds a perspective projection matrix
00999         *
01000         *  @param[in] fWidth
01001         *    Width of the view volume at the near view-plane
01002         *  @param[in] fHeight
01003         *    Height of the view volume at the near view-plane
01004         *  @param[in] fZNear
01005         *    Z-value of the near view-plane (always positive)
01006         *  @param[in] fZFar
01007         *    Z-value of the far view-plane (always positive)
01008         *
01009         *  @return
01010         *    This instance
01011         *
01012         *  @remarks
01013         *    @code
01014         *    | 2*fZNear/fWidth 0                0                    0                           |
01015         *    | 0               2*fZNear/fHeight 0                    0                           |
01016         *    | 0               0                fZFar/(fZNear-fZFar) fZNear*fZFar/(fZNear-fZFar) |
01017         *    | 0               0                -1                   0                           |
01018         *    @endcode
01019         */
01020         PLMATH_API Matrix4x4 &Perspective(float fWidth, float fHeight, float fZNear, float fZFar);
01021 
01022         /**
01023         *  @brief
01024         *    Builds a perspective projection matrix based on a field of view
01025         *
01026         *  @param[in] fFov
01027         *    The field of view angle in the y direction (in radian)
01028         *  @param[in] fAspect
01029         *    The aspect ratio that determines the field of view in the x-direction
01030         *    The aspect ratio is the ratio of x (width) to y (height) (width/height)
01031         *  @param[in] fZNear
01032         *    The distance from the viewer to the near clipping plane (always positive)
01033         *  @param[in] fZFar
01034         *    The distance from the viewer to the far clipping plane (always positive)
01035         *
01036         *  @return
01037         *    This instance
01038         *
01039         *  @remarks
01040         *    @code
01041         *    | e/fAspect 0    0                             0                               |
01042         *    | 0         e    0                             0                               |
01043         *    | 0         0    (fZFar+fZNear)/(fZNear-fZFar) (2*fZNear*fZFar)/(fZNear-fZFar) |
01044         *    | 0         0    -1                            0                               |
01045         *
01046         *    where:
01047         *      float e = 1/tanf(fFov/2); // Focal length
01048         *    @endcode
01049         */
01050         PLMATH_API Matrix4x4 &PerspectiveFov(float fFov, float fAspect, float fZNear, float fZFar);
01051 
01052         /**
01053         *  @brief
01054         *    Builds an infinite perspective projection matrix
01055         *
01056         *  @param[in] fWidth
01057         *    Width of the view volume at the near view-plane
01058         *  @param[in] fHeight
01059         *    Height of the view volume at the near view-plane
01060         *  @param[in] fZNear
01061         *    Z-value of the near view-plane (always positive)
01062         *
01063         *  @return
01064         *    This instance
01065         *
01066         *  @remarks
01067         *    @code
01068         *    | 2*fZNear/fWidth 0                0     0         |
01069         *    | 0               2*fZNear/fHeight 0     0         |
01070         *    | 0               0                -1    -2*fZNear |
01071         *    | 0               0                -1    0         |
01072         *    @endcode
01073         */
01074         PLMATH_API Matrix4x4 &PerspectiveInfinite(float fWidth, float fHeight, float fZNear);
01075 
01076         /**
01077         *  @brief
01078         *    Builds an infinite perspective projection matrix based on a field of view
01079         *
01080         *  @param[in] fFov
01081         *    The field of view angle in the y direction (in radian)
01082         *  @param[in] fAspect
01083         *    The aspect ratio that determines the field of view in the x-direction
01084         *    The aspect ratio is the ratio of x (width) to y (height) (width/height)
01085         *  @param[in] fZNear
01086         *    The distance from the viewer to the near clipping plane (always positive)
01087         *
01088         *  @return
01089         *    This instance
01090         *
01091         *  @remarks
01092         *    @code
01093         *    | e/fAspect 0    0     0         |
01094         *    | 0         e    0     0         |
01095         *    | 0         0    -1    -2*fZNear |
01096         *    | 0         0    -1    0         |
01097         *
01098         *    where:
01099         *      float e = 1/tanf(fFov/2); // Focal length
01100         *    @endcode
01101         */
01102         PLMATH_API Matrix4x4 &PerspectiveFovInfinite(float fFov, float fAspect, float fZNear);
01103 
01104         /**
01105         *  @brief
01106         *    Builds a customized, perspective projection matrix
01107         *
01108         *  @param[in] fL
01109         *    Minimum x-value of view volume
01110         *  @param[in] fR
01111         *    Maximum x-value of view volume
01112         *  @param[in] fT
01113         *    Maximum y-value of view volume
01114         *  @param[in] fB
01115         *    Minimum y-value of view volume
01116         *  @param[in] fZNear
01117         *    Minimum z-value of the view volume
01118         *  @param[in] fZFar
01119         *    Maximum z-value of the view volume
01120         *
01121         *  @remarks
01122         *    @code
01123         *    | 2*fZNear/(fR-fL) 0                (fL+fR)/(fR-fL)      0                           |
01124         *    | 0                2*fZNear/(fT-fB) (fT+fB)/(fT-fB)      0                           |
01125         *    | 0                0                fZFar/(fZNear-fZFar) fZNear*fZFar/(fZNear-fZFar) |
01126         *    | 0                0                -1                   0                           |
01127         *    @endcode
01128         *
01129         *  @return
01130         *    This instance
01131         */
01132         PLMATH_API Matrix4x4 &PerspectiveOffCenter(float fL, float fR, float fB, float fT, float fZNear, float fZFar);
01133 
01134         /**
01135         *  @brief
01136         *    Builds a orthogonal projection matrix
01137         *
01138         *  @param[in] fWidth
01139         *    Width of the view volume
01140         *  @param[in] fHeight
01141         *    Height of the view volume
01142         *  @param[in] fZNear
01143         *    Minimum z-value of the view volume
01144         *  @param[in] fZFar
01145         *    Maximum z-value of the view volume
01146         *
01147         *  @return
01148         *    This instance
01149         *
01150         *  @remarks
01151         *    @code
01152         *    | 2/fWidth 0         0                0                     |
01153         *    | 0        2/fHeight 0                0                     |
01154         *    | 0        0         1/(fZNear-fZFar) fZNear/(fZNear-fZFar) |
01155         *    | 0        0         0                1                     |
01156         *    @endcode
01157         *
01158         *  @note
01159         *    - An orthogonal matrix is an invertible matrix for which the inverse of the matrix
01160         *      is equal to the transpose of the matrix
01161         */
01162         PLMATH_API Matrix4x4 &Ortho(float fWidth, float fHeight, float fZNear, float fZFar);
01163 
01164         /**
01165         *  @brief
01166         *    Builds a customized, orthogonal projection matrix
01167         *
01168         *  @param[in] fL
01169         *    Minimum x-value of view volume
01170         *  @param[in] fR
01171         *    Maximum x-value of view volume
01172         *  @param[in] fT
01173         *    Maximum y-value of view volume
01174         *  @param[in] fB
01175         *    Minimum y-value of view volume
01176         *  @param[in] fZNear
01177         *    Minimum z-value of the view volume
01178         *  @param[in] fZFar
01179         *    Maximum z-value of the view volume
01180         *
01181         *  @return
01182         *    This instance
01183         *
01184         *  @remarks
01185         *    @code
01186         *    | 2/(fR-fL) 0         0                (fL+fR)/(fL-fR)       |
01187         *    | 0         2/(fT-fB) 0                (fT+fB)/(fB-fT)       |
01188         *    | 0         0         1/(fZNear-fZFar) fZNear/(fZNear-fZFar) |
01189         *    | 0         0         0                1                     |
01190         *    @endcode
01191         *
01192         *  @note
01193         *    - An orthogonal matrix is an invertible matrix for which the inverse of the matrix
01194         *      is equal to the transpose of the matrix
01195         */
01196         PLMATH_API Matrix4x4 &OrthoOffCenter(float fL, float fR, float fT, float fB, float fZNear, float fZFar);
01197 
01198 
01199 };
01200 
01201 
01202 //[-------------------------------------------------------]
01203 //[ Namespace                                             ]
01204 //[-------------------------------------------------------]
01205 } // PLMath
01206 
01207 
01208 //[-------------------------------------------------------]
01209 //[ Implementation                                        ]
01210 //[-------------------------------------------------------]
01211 #include "PLMath/Matrix4x4.inl"
01212 
01213 
01214 #endif // __PLMATH_MATRIX4X4_H__


PixelLight PixelLight 0.9.11-R1
Copyright (C) 2002-2012 by The PixelLight Team
Last modified Thu Feb 23 2012 14:08:57
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported