Back to index

nux  3.0.0
Matrix4.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #ifndef MATRIX4_H
00024 #define MATRIX4_H
00025 
00026 
00027 #include "Vector3.h"
00028 #include "Vector4.h"
00029 
00030 namespace nux
00031 {
00032 
00033 //  Our matrices are Row major just like C/C++:
00034 //      m[2][3] represent the element at row 2 and column 3.
00035 //  When multiplying a vector by a matrix, the vector is a column at the right of the matrix
00036 //
00037 //    |a00,  a01,  a02,  a03|       |v0|
00038 //    |a10,  a11,  a12,  a13|   *   |v1|
00039 //    |a20,  a21,  a22,  a23|       |v2|
00040 //    |a30,  a31,  a32,  a33|       |v3|
00041 //
00042 // Note: OpenGL is column major. Before passing it a Matrix4x4 through glLoadMatrix, transpose it.
00043 
00044   template<typename T>
00045   class Matrix4x4
00046   {
00047   public:
00048     Matrix4x4<T>();
00049     ~Matrix4x4<T>();
00050     Matrix4x4<T> (const Matrix4x4 &);
00051     Matrix4x4<T> (
00052       T a00, T a01, T a02, T a03,
00053       T a10, T a11, T a12, T a13,
00054       T a20, T a21, T a22, T a23,
00055       T a30, T a31, T a32, T a33);
00056 
00057     Matrix4x4<T>& operator = (const Matrix4x4<T>&);
00058     bool operator == (const Matrix4x4<T>&);
00059     Matrix4x4<T> operator * (const Matrix4x4<T>&) const;
00060     Matrix4x4<T> operator + (const Matrix4x4<T>&) const;
00061     Matrix4x4<T> operator - (const Matrix4x4<T>&) const;
00062     Matrix4x4<T>& operator *= (const Matrix4x4<T>&) const;
00063     Matrix4x4<T>& operator += (const Matrix4x4<T>&) const;
00064     Matrix4x4<T>& operator -= (const Matrix4x4<T>&) const;
00065 
00066     Matrix4x4<T> operator * (const T &) const;
00067     Matrix4x4<T> operator / (const T &) const;
00068     Matrix4x4<T> operator *= (const T &) const;
00069     Matrix4x4<T> operator /= (const T &) const;
00070 
00071     Vector4      operator * (const Vector4 &) const;
00072     Matrix4x4<T> operator - ();
00073 
00074     // Get the (i, j) element of the current matrix.
00075     T &operator() (unsigned int i, unsigned int j);
00076     T operator () (unsigned int i, unsigned int j) const;
00077 
00078     // Get a pointer to the current matrix.
00079     operator T *();
00080     operator const T *() const;
00081 
00082     // Utility for 3D
00083     void Translate (T x, T y, T z);
00084     void Translate (const Vector3 &);
00085 
00086     void Rotate_x (T angle);
00087     void Rotate_y (T angle);
00088     void Rotate_z (T angle);
00089     void Scale (T sx, T sy, T sz);
00090 
00091     // Matrix Math
00092     T Trace() const;
00093     T Determinant() const ;
00094     void Inverse();
00095     Matrix4x4<T> GetInverse() const;
00096     void Transpose();
00097 
00098     //Matrix3x3<T> GetUpper3x3() const;
00099     //Matrix2x2<T> GetUpper2x2() const;
00100 
00102     void Scale (T s);
00103     void Diagonal (T x, T y, T z, T w = T (1) );
00104     void Rotate (T angle, Vector3 axis);
00105 
00106     // OpenGL
00107     void LookAt (const Vector3 &eye, const Vector3 &at, const Vector3 &up);
00108     void Orthographic (T l, T r, T b, T t, T n, T f);
00109     void Perspective (T l, T r, T t, T b, T n, T f);
00110     void PerspectiveInverse (T l, T r, T t, T b, T n, T f);
00111     void Perspective (T FoV, T AspectRatio, T NearPlane, T FarPlane);
00112 
00113     void Zero();
00114     void Identity();
00115 
00116     static Matrix4x4<T> IDENTITY();
00117     static Matrix4x4<T> ZERO();
00118     static Matrix4x4<T> ROTATEX(T angle);
00119     static Matrix4x4<T> ROTATEY(T angle);
00120     static Matrix4x4<T> ROTATEZ(T angle);
00121     static Matrix4x4<T> TRANSLATE(T x, T y, T z);
00122     static Matrix4x4<T> SCALE(T x, T y, T z);
00123     T m[4][4];
00124   };
00125 
00126 
00127   /***************************************************************************************\
00128   Function:       Matrix4x4<T>::Matrix4x4<T>
00129 
00130   Description:    Constructor. Initialize the matrix to identity.
00131 
00132   Parameters:     None.
00133 
00134   Return Value:   None.
00135 
00136   Comments:       None.
00137   \***************************************************************************************/
00138   template<typename T>
00139   Matrix4x4<T>::Matrix4x4()
00140   {
00141     Identity();
00142   }
00143 
00144   /***************************************************************************************\
00145   Function:       Matrix4x4<T>::~Matrix4x4
00146 
00147   Description:    Destructor.
00148 
00149   Parameters:     None.
00150 
00151   Return Value:   None.
00152 
00153   Comments:       None.
00154   \***************************************************************************************/
00155   template<typename T>
00156   Matrix4x4<T>::~Matrix4x4()
00157   {
00158 
00159   }
00160 
00161   /***************************************************************************************\
00162   Function:       Matrix4x4<T>::Matrix4x4
00163 
00164   Description:    None.
00165 
00166   Parameters:     - M
00167 
00168   Return Value:   None.
00169 
00170   Comments:       None.
00171   \***************************************************************************************/
00172   template<typename T>
00173   Matrix4x4<T>::Matrix4x4 (const Matrix4x4 &M)
00174   {
00175     m[0][0] = M.m[0][0];
00176     m[0][1] = M.m[0][1];
00177     m[0][2] = M.m[0][2];
00178     m[0][3] = M.m[0][3];
00179     m[1][0] = M.m[1][0];
00180     m[1][1] = M.m[1][1];
00181     m[1][2] = M.m[1][2];
00182     m[1][3] = M.m[1][3];
00183     m[2][0] = M.m[2][0];
00184     m[2][1] = M.m[2][1];
00185     m[2][2] = M.m[2][2];
00186     m[2][3] = M.m[2][3];
00187     m[3][0] = M.m[3][0];
00188     m[3][1] = M.m[3][1];
00189     m[3][2] = M.m[3][2];
00190     m[3][3] = M.m[3][3];
00191   }
00192 
00193   /***************************************************************************************\
00194   Function:       Matrix4x4<T>::Matrix4x4
00195 
00196   Description:    None.
00197 
00198   Parameters:     T a00, T a01, T a02, T a03,
00199                   T a10, T a11, T a12, T a13,
00200                   T a20, T a21, T a22, T a23,
00201                   T a30, T a31, T a32, T a33
00202 
00203   Return Value:   None.
00204 
00205   Comments:       None.
00206   \***************************************************************************************/
00207   template<typename T>
00208   Matrix4x4<T>::Matrix4x4 (
00209     T a00, T a01, T a02, T a03,
00210     T a10, T a11, T a12, T a13,
00211     T a20, T a21, T a22, T a23,
00212     T a30, T a31, T a32, T a33)
00213   {
00214     m[0][0] = a00;
00215     m[0][1] = a01;
00216     m[0][2] = a02;
00217     m[0][3] = a03;
00218     m[1][0] = a10;
00219     m[1][1] = a11;
00220     m[1][2] = a12;
00221     m[1][3] = a13;
00222     m[2][0] = a20;
00223     m[2][1] = a21;
00224     m[2][2] = a22;
00225     m[2][3] = a23;
00226     m[3][0] = a30;
00227     m[3][1] = a31;
00228     m[3][2] = a32;
00229     m[3][3] = a33;
00230   }
00231 
00232   /***************************************************************************************\
00233   Function:       Matrix4x4<T>::Matrix4x4
00234 
00235   Description:    Assignment operator.
00236 
00237   Parameters:     - M
00238 
00239   Return Value:   Matrix4x4<T>.
00240 
00241   Comments:       None.
00242   \***************************************************************************************/
00243   template<typename T>
00244   Matrix4x4<T>& Matrix4x4<T>::operator = (const Matrix4x4<T>& M)
00245   {
00246     m[0][0] = M.m[0][0];
00247     m[0][1] = M.m[0][1];
00248     m[0][2] = M.m[0][2];
00249     m[0][3] = M.m[0][3];
00250     m[1][0] = M.m[1][0];
00251     m[1][1] = M.m[1][1];
00252     m[1][2] = M.m[1][2];
00253     m[1][3] = M.m[1][3];
00254     m[2][0] = M.m[2][0];
00255     m[2][1] = M.m[2][1];
00256     m[2][2] = M.m[2][2];
00257     m[2][3] = M.m[2][3];
00258     m[3][0] = M.m[3][0];
00259     m[3][1] = M.m[3][1];
00260     m[3][2] = M.m[3][2];
00261     m[3][3] = M.m[3][3];
00262 
00263     return (*this);
00264   }
00265 
00266   template <typename T>
00267   bool Matrix4x4<T>::operator == (const Matrix4x4<T>& M)
00268   {
00269     for (int i = 0; i < 4; i++)
00270       for (int j = 0; j < 4; j++)
00271       {
00272         if (m[i][j] != M.m[i][j])
00273           return false;
00274       }
00275 
00276     return true;
00277   }
00278 
00279 
00280   /***************************************************************************************\
00281   Function:       Matrix4x4<T>::operator *
00282 
00283   Description:    Multiply by matrix iM.
00284 
00285   Parameters:     - iM
00286 
00287   Return Value:   Matrix4x4<T>.
00288 
00289   Comments:       None.
00290   \***************************************************************************************/
00291   template<typename T>
00292   Matrix4x4<T> Matrix4x4<T>::operator * (const Matrix4x4<T>& iM) const
00293   {
00294     Matrix4x4<T> oM;
00295 
00296     // Output matrix first row
00297     oM.m[0][0] = m[0][0] * iM.m[0][0] + m[0][1] * iM.m[1][0] + m[0][2] * iM.m[2][0] + m[0][3] * iM.m[3][0];
00298     oM.m[0][1] = m[0][0] * iM.m[0][1] + m[0][1] * iM.m[1][1] + m[0][2] * iM.m[2][1] + m[0][3] * iM.m[3][1];
00299     oM.m[0][2] = m[0][0] * iM.m[0][2] + m[0][1] * iM.m[1][2] + m[0][2] * iM.m[2][2] + m[0][3] * iM.m[3][2];
00300     oM.m[0][3] = m[0][0] * iM.m[0][3] + m[0][1] * iM.m[1][3] + m[0][2] * iM.m[2][3] + m[0][3] * iM.m[3][3];
00301 
00302     // Output matrix second row
00303     oM.m[1][0] = m[1][0] * iM.m[0][0] + m[1][1] * iM.m[1][0] + m[1][2] * iM.m[2][0] + m[1][3] * iM.m[3][0];
00304     oM.m[1][1] = m[1][0] * iM.m[0][1] + m[1][1] * iM.m[1][1] + m[1][2] * iM.m[2][1] + m[1][3] * iM.m[3][1];
00305     oM.m[1][2] = m[1][0] * iM.m[0][2] + m[1][1] * iM.m[1][2] + m[1][2] * iM.m[2][2] + m[1][3] * iM.m[3][2];
00306     oM.m[1][3] = m[1][0] * iM.m[0][3] + m[1][1] * iM.m[1][3] + m[1][2] * iM.m[2][3] + m[1][3] * iM.m[3][3];
00307 
00308     // Output matrix third row
00309     oM.m[2][0] = m[2][0] * iM.m[0][0] + m[2][1] * iM.m[1][0] + m[2][2] * iM.m[2][0] + m[2][3] * iM.m[3][0];
00310     oM.m[2][1] = m[2][0] * iM.m[0][1] + m[2][1] * iM.m[1][1] + m[2][2] * iM.m[2][1] + m[2][3] * iM.m[3][1];
00311     oM.m[2][2] = m[2][0] * iM.m[0][2] + m[2][1] * iM.m[1][2] + m[2][2] * iM.m[2][2] + m[2][3] * iM.m[3][2];
00312     oM.m[2][3] = m[2][0] * iM.m[0][3] + m[2][1] * iM.m[1][3] + m[2][2] * iM.m[2][3] + m[2][3] * iM.m[3][3];
00313 
00314     // Output matrix fourth row
00315     oM.m[3][0] = m[3][0] * iM.m[0][0] + m[3][1] * iM.m[1][0] + m[3][2] * iM.m[2][0] + m[3][3] * iM.m[3][0];
00316     oM.m[3][1] = m[3][0] * iM.m[0][1] + m[3][1] * iM.m[1][1] + m[3][2] * iM.m[2][1] + m[3][3] * iM.m[3][1];
00317     oM.m[3][2] = m[3][0] * iM.m[0][2] + m[3][1] * iM.m[1][2] + m[3][2] * iM.m[2][2] + m[3][3] * iM.m[3][2];
00318     oM.m[3][3] = m[3][0] * iM.m[0][3] + m[3][1] * iM.m[1][3] + m[3][2] * iM.m[2][3] + m[3][3] * iM.m[3][3];
00319 
00320     return oM;
00321   }
00322 
00323   /***************************************************************************************\
00324   Function:       Matrix4x4<T>::operator +
00325 
00326   Description:    Add matrix iM.
00327 
00328   Parameters:     - iM
00329 
00330   Return Value:   Matrix4x4<T>.
00331 
00332   Comments:       None.
00333   \***************************************************************************************/
00334   template<typename T>
00335   Matrix4x4<T> Matrix4x4<T>::operator + (const Matrix4x4<T>& iM) const
00336   {
00337     Matrix4x4<T> oM;
00338 
00339     oM.m[0][0] = m[0][0] + iM.m[0][0];
00340     oM.m[0][1] = m[0][1] + iM.m[0][1];
00341     oM.m[0][2] = m[0][2] + iM.m[0][2];
00342     oM.m[0][3] = m[0][3] + iM.m[0][3];
00343     oM.m[1][0] = m[1][0] + iM.m[1][0];
00344     oM.m[1][1] = m[1][1] + iM.m[1][1];
00345     oM.m[1][2] = m[1][2] + iM.m[1][2];
00346     oM.m[1][3] = m[1][3] + iM.m[1][3];
00347     oM.m[2][0] = m[2][0] + iM.m[2][0];
00348     oM.m[2][1] = m[2][1] + iM.m[2][1];
00349     oM.m[2][2] = m[2][2] + iM.m[2][2];
00350     oM.m[2][3] = m[2][3] + iM.m[2][3];
00351     oM.m[3][0] = m[3][0] + iM.m[3][0];
00352     oM.m[3][1] = m[3][1] + iM.m[3][1];
00353     oM.m[3][2] = m[3][2] + iM.m[3][2];
00354     oM.m[3][3] = m[3][3] + iM.m[3][3];
00355 
00356     return oM;
00357   }
00358 
00359   /***************************************************************************************\
00360   Function:       Matrix4x4<T>::operator -
00361 
00362   Description:    Substract matrix iM.
00363 
00364   Parameters:     - iM
00365 
00366   Return Value:   Matrix4x4<T>.
00367 
00368   Comments:       None.
00369   \***************************************************************************************/
00370   template<typename T>
00371   Matrix4x4<T> Matrix4x4<T>::operator - (const Matrix4x4<T>& iM) const
00372   {
00373     Matrix4x4<T> oM;
00374 
00375     oM.m[0][0] = m[0][0] - iM.m[0][0];
00376     oM.m[0][1] = m[0][1] - iM.m[0][1];
00377     oM.m[0][2] = m[0][2] - iM.m[0][2];
00378     oM.m[0][3] = m[0][3] - iM.m[0][3];
00379     oM.m[1][0] = m[1][0] - iM.m[1][0];
00380     oM.m[1][1] = m[1][1] - iM.m[1][1];
00381     oM.m[1][2] = m[1][2] - iM.m[1][2];
00382     oM.m[1][3] = m[1][3] - iM.m[1][3];
00383     oM.m[2][0] = m[2][0] - iM.m[2][0];
00384     oM.m[2][1] = m[2][1] - iM.m[2][1];
00385     oM.m[2][2] = m[2][2] - iM.m[2][2];
00386     oM.m[2][3] = m[2][3] - iM.m[2][3];
00387     oM.m[3][0] = m[3][0] - iM.m[3][0];
00388     oM.m[3][1] = m[3][1] - iM.m[3][1];
00389     oM.m[3][2] = m[3][2] - iM.m[3][2];
00390     oM.m[3][3] = m[3][3] - iM.m[3][3];
00391 
00392     return oM;
00393   }
00394 
00395 
00396 
00397 
00398 
00399   /***************************************************************************************\
00400   Function:       Matrix4x4<T>::operator *=
00401 
00402   Description:    Multiply by matrix iM.
00403 
00404   Parameters:     - iM
00405 
00406   Return Value:   Matrix4x4<T>.
00407 
00408   Comments:       None.
00409   \***************************************************************************************/
00410   template<typename T>
00411   Matrix4x4<T>& Matrix4x4<T>::operator *= (const Matrix4x4<T>& iM) const
00412   {
00413     Matrix4x4<T> oM;
00414 
00415     oM.m[0][0] = m[0][0] * iM.m[0][0] + m[0][1] * iM.m[1][0] + m[0][2] * iM.m[2][0] + m[0][3] * iM.m[3][0];
00416     oM.m[1][0] = m[1][0] * iM.m[0][0] + m[1][1] * iM.m[1][0] + m[1][2] * iM.m[2][0] + m[1][3] * iM.m[3][0];
00417     oM.m[2][0] = m[2][0] * iM.m[0][0] + m[2][1] * iM.m[1][0] + m[2][2] * iM.m[2][0] + m[2][3] * iM.m[3][0];
00418     oM.m[3][0] = m[3][0] * iM.m[0][0] + m[3][1] * iM.m[1][0] + m[3][2] * iM.m[2][0] + m[3][3] * iM.m[3][0];
00419 
00420     oM.m[0][1] = m[0][0] * iM.m[0][1] + m[0][1] * iM.m[1][1] + m[0][2] * iM.m[2][1] + m[0][3] * iM.m[3][1];
00421     oM.m[1][1] = m[1][0] * iM.m[0][1] + m[1][1] * iM.m[1][1] + m[1][2] * iM.m[2][1] + m[1][3] * iM.m[3][1];
00422     oM.m[2][1] = m[2][0] * iM.m[0][1] + m[2][1] * iM.m[1][1] + m[2][2] * iM.m[2][1] + m[2][3] * iM.m[3][1];
00423     oM.m[3][1] = m[3][0] * iM.m[0][1] + m[3][1] * iM.m[1][1] + m[3][2] * iM.m[2][1] + m[3][3] * iM.m[3][1];
00424 
00425     oM.m[0][2] = m[0][0] * iM.m[0][2] + m[0][1] * iM.m[1][2] + m[0][2] * iM.m[2][2] + m[0][3] * iM.m[3][2];
00426     oM.m[1][2] = m[1][0] * iM.m[0][2] + m[1][1] * iM.m[1][2] + m[1][2] * iM.m[2][2] + m[1][3] * iM.m[3][2];
00427     oM.m[2][2] = m[2][0] * iM.m[0][2] + m[2][1] * iM.m[1][2] + m[2][2] * iM.m[2][2] + m[2][3] * iM.m[3][2];
00428     oM.m[3][2] = m[3][0] * iM.m[0][2] + m[3][1] * iM.m[1][2] + m[3][2] * iM.m[2][2] + m[3][3] * iM.m[3][2];
00429 
00430     oM.m[0][3] = m[0][0] * iM.m[0][3] + m[0][1] * iM.m[1][3] + m[0][2] * iM.m[2][3] + m[0][3] * iM.m[3][3];
00431     oM.m[1][3] = m[1][0] * iM.m[0][3] + m[1][1] * iM.m[1][3] + m[1][2] * iM.m[2][3] + m[1][3] * iM.m[3][3];
00432     oM.m[2][3] = m[2][0] * iM.m[0][3] + m[2][1] * iM.m[1][3] + m[2][2] * iM.m[2][3] + m[2][3] * iM.m[3][3];
00433     oM.m[3][3] = m[3][0] * iM.m[0][3] + m[3][1] * iM.m[1][3] + m[3][2] * iM.m[2][3] + m[3][3] * iM.m[3][3];
00434 
00435     *this = oM;
00436     return *this;
00437   }
00438 
00439   /***************************************************************************************\
00440   Function:       Matrix4x4<T>::operator +=
00441 
00442   Description:    Add matrix iM.
00443 
00444   Parameters:     - iM
00445 
00446   Return Value:   Matrix4x4<T>.
00447 
00448   Comments:       None.
00449   \***************************************************************************************/
00450   template<typename T>
00451   Matrix4x4<T>& Matrix4x4<T>::operator += (const Matrix4x4<T>& iM) const
00452   {
00453     Matrix4x4<T> oM;
00454 
00455     oM.m[0][0] = m[0][0] + iM.m[0][0];
00456     oM.m[0][1] = m[0][1] + iM.m[0][1];
00457     oM.m[0][2] = m[0][2] + iM.m[0][2];
00458     oM.m[0][3] = m[0][3] + iM.m[0][3];
00459     oM.m[1][0] = m[1][0] + iM.m[1][0];
00460     oM.m[1][1] = m[1][1] + iM.m[1][1];
00461     oM.m[1][2] = m[1][2] + iM.m[1][2];
00462     oM.m[1][3] = m[1][3] + iM.m[1][3];
00463     oM.m[2][0] = m[2][0] + iM.m[2][0];
00464     oM.m[2][1] = m[2][1] + iM.m[2][1];
00465     oM.m[2][2] = m[2][2] + iM.m[2][2];
00466     oM.m[2][3] = m[2][3] + iM.m[2][3];
00467     oM.m[3][0] = m[3][0] + iM.m[3][0];
00468     oM.m[3][1] = m[3][1] + iM.m[3][1];
00469     oM.m[3][2] = m[3][2] + iM.m[3][2];
00470     oM.m[3][3] = m[3][3] + iM.m[3][3];
00471 
00472     *this = oM;
00473     return *this;
00474   }
00475 
00476   /***************************************************************************************\
00477   Function:       Matrix4x4<T>::operator -=
00478 
00479   Description:    Substract matrix iM.
00480 
00481   Parameters:     - iM
00482 
00483   Return Value:   Matrix4x4<T>.
00484 
00485   Comments:       None.
00486   \***************************************************************************************/
00487   template<typename T>
00488   Matrix4x4<T>& Matrix4x4<T>::operator -= (const Matrix4x4<T>& iM) const
00489   {
00490     Matrix4x4<T> oM;
00491 
00492     oM.m[0][0] = m[0][0] - iM.m[0][0];
00493     oM.m[0][1] = m[0][1] - iM.m[0][1];
00494     oM.m[0][2] = m[0][2] - iM.m[0][2];
00495     oM.m[0][3] = m[0][3] - iM.m[0][3];
00496     oM.m[1][0] = m[1][0] - iM.m[1][0];
00497     oM.m[1][1] = m[1][1] - iM.m[1][1];
00498     oM.m[1][2] = m[1][2] - iM.m[1][2];
00499     oM.m[1][3] = m[1][3] - iM.m[1][3];
00500     oM.m[2][0] = m[2][0] - iM.m[2][0];
00501     oM.m[2][1] = m[2][1] - iM.m[2][1];
00502     oM.m[2][2] = m[2][2] - iM.m[2][2];
00503     oM.m[2][3] = m[2][3] - iM.m[2][3];
00504     oM.m[3][0] = m[3][0] - iM.m[3][0];
00505     oM.m[3][1] = m[3][1] - iM.m[3][1];
00506     oM.m[3][2] = m[3][2] - iM.m[3][2];
00507     oM.m[3][3] = m[3][3] - iM.m[3][3];
00508 
00509     *this = oM;
00510     return *this;
00511   }
00512 
00513 
00514   /***************************************************************************************\
00515   Function:       Matrix4x4<T>::operator *
00516 
00517   Description:    Multiply all elements by f.
00518 
00519   Parameters:     - f
00520 
00521   Return Value:   Matrix4x4<T>.
00522 
00523   Comments:       None.
00524   \***************************************************************************************/
00525   template<typename T>
00526   Matrix4x4<T> Matrix4x4<T>::operator * (const T &f) const
00527   {
00528     Matrix4x4<T> oM;
00529 
00530     oM.m[0][0] = m[0][0] * f;
00531     oM.m[0][1] = m[0][1] * f;
00532     oM.m[0][2] = m[0][2] * f;
00533     oM.m[0][3] = m[0][3] * f;
00534     oM.m[1][0] = m[1][0] * f;
00535     oM.m[1][1] = m[1][1] * f;
00536     oM.m[1][2] = m[1][2] * f;
00537     oM.m[1][3] = m[1][3] * f;
00538     oM.m[2][0] = m[2][0] * f;
00539     oM.m[2][1] = m[2][1] * f;
00540     oM.m[2][2] = m[2][2] * f;
00541     oM.m[2][3] = m[2][3] * f;
00542     oM.m[3][0] = m[3][0] * f;
00543     oM.m[3][1] = m[3][1] * f;
00544     oM.m[3][2] = m[3][2] * f;
00545     oM.m[3][3] = m[3][3] * f;
00546 
00547     return oM;
00548   }
00549 
00550   /***************************************************************************************\
00551   Function:       Matrix4x4<T>::operator /
00552 
00553   Description:    Divide all elements by f.
00554 
00555   Parameters:     - f
00556 
00557   Return Value:   Matrix4x4<T>.
00558 
00559   Comments:       None.
00560   \***************************************************************************************/
00561   template<typename T>
00562   Matrix4x4<T> Matrix4x4<T>::operator / (const T &f) const
00563   {
00564     Matrix4x4<T> oM;
00565 
00566     oM.m[0][0] = m[0][0] / f;
00567     oM.m[0][1] = m[0][1] / f;
00568     oM.m[0][2] = m[0][2] / f;
00569     oM.m[0][3] = m[0][3] / f;
00570     oM.m[1][0] = m[1][0] / f;
00571     oM.m[1][1] = m[1][1] / f;
00572     oM.m[1][2] = m[1][2] / f;
00573     oM.m[1][3] = m[1][3] / f;
00574     oM.m[2][0] = m[2][0] / f;
00575     oM.m[2][1] = m[2][1] / f;
00576     oM.m[2][2] = m[2][2] / f;
00577     oM.m[2][3] = m[2][3] / f;
00578     oM.m[3][0] = m[3][0] / f;
00579     oM.m[3][1] = m[3][1] / f;
00580     oM.m[3][2] = m[3][2] / f;
00581     oM.m[3][3] = m[3][3] / f;
00582 
00583     return oM;
00584   }
00585 
00586 
00587 
00588 
00589   /***************************************************************************************\
00590   Function:       Matrix4x4<T>::operator *=
00591 
00592   Description:    Multiply all elements by f.
00593 
00594   Parameters:     - f
00595 
00596   Return Value:   Matrix4x4<T>.
00597 
00598   Comments:       None.
00599   \***************************************************************************************/
00600   template<typename T>
00601   Matrix4x4<T> Matrix4x4<T>::operator *= (const T &f) const
00602   {
00603     Matrix4x4<T> oM;
00604 
00605     oM.m[0][0] = m[0][0] * f;
00606     oM.m[0][1] = m[0][1] * f;
00607     oM.m[0][2] = m[0][2] * f;
00608     oM.m[0][3] = m[0][3] * f;
00609     oM.m[1][0] = m[1][0] * f;
00610     oM.m[1][1] = m[1][1] * f;
00611     oM.m[1][2] = m[1][2] * f;
00612     oM.m[1][3] = m[1][3] * f;
00613     oM.m[2][0] = m[2][0] * f;
00614     oM.m[2][1] = m[2][1] * f;
00615     oM.m[2][2] = m[2][2] * f;
00616     oM.m[2][3] = m[2][3] * f;
00617     oM.m[3][0] = m[3][0] * f;
00618     oM.m[3][1] = m[3][1] * f;
00619     oM.m[3][2] = m[3][2] * f;
00620     oM.m[3][3] = m[3][3] * f;
00621 
00622     *this = oM;
00623     return *this;
00624   }
00625 
00626   /***************************************************************************************\
00627   Function:       Matrix4x4<T>::operator /=
00628 
00629   Description:    Divide all elements by f.
00630 
00631   Parameters:     - f
00632 
00633   Return Value:   Matrix4x4<T>.
00634 
00635   Comments:       None.
00636   \***************************************************************************************/
00637   template<typename T>
00638   Matrix4x4<T> Matrix4x4<T>::operator /= (const T &f) const
00639   {
00640     Matrix4x4<T> oM;
00641 
00642     oM.m[0][0] = m[0][0] / f;
00643     oM.m[0][1] = m[0][1] / f;
00644     oM.m[0][2] = m[0][2] / f;
00645     oM.m[0][3] = m[0][3] / f;
00646     oM.m[1][0] = m[1][0] / f;
00647     oM.m[1][1] = m[1][1] / f;
00648     oM.m[1][2] = m[1][2] / f;
00649     oM.m[1][3] = m[1][3] / f;
00650     oM.m[2][0] = m[2][0] / f;
00651     oM.m[2][1] = m[2][1] / f;
00652     oM.m[2][2] = m[2][2] / f;
00653     oM.m[2][3] = m[2][3] / f;
00654     oM.m[3][0] = m[3][0] / f;
00655     oM.m[3][1] = m[3][1] / f;
00656     oM.m[3][2] = m[3][2] / f;
00657     oM.m[3][3] = m[3][3] / f;
00658 
00659     *this = oM;
00660     return *this;
00661   }
00662 
00663   /***************************************************************************************\
00664   Function:       Matrix4x4<T>::operator *
00665 
00666   Description:    Multiply a matrix by a vector.
00667 
00668   Parameters:     - V
00669 
00670   Return Value:   Vector4.
00671 
00672   Comments:       None.
00673   \***************************************************************************************/
00674   template<typename T>
00675   Vector4 Matrix4x4<T>::operator * (const Vector4 &V) const
00676   {
00677     Vector4 oV;
00678 
00679     oV.x = V.x * m[0][0] + V.y * m[0][1] + V.z * m[0][2] + V.w * m[0][3];
00680     oV.y = V.x * m[1][0] + V.y * m[1][1] + V.z * m[1][2] + V.w * m[1][3];
00681     oV.z = V.x * m[2][0] + V.y * m[2][1] + V.z * m[2][2] + V.w * m[2][3];
00682     oV.w = V.x * m[3][0] + V.y * m[3][1] + V.z * m[3][2] + V.w * m[3][3];
00683 
00684     return oV;
00685   }
00686 
00687   /***************************************************************************************\
00688   Function:       Matrix4x4<T>::operator - ()
00689 
00690   Description:    Negate all elements of the matrix.
00691 
00692   Parameters:     None.
00693 
00694   Return Value:   Matrix4x4<T>.
00695 
00696   Comments:       None.
00697   \***************************************************************************************/
00698   template<typename T>
00699   Matrix4x4<T> Matrix4x4<T>::operator - ()
00700   {
00701     Matrix4x4<T> oM;
00702 
00703     oM.m[0][0] = -m[0][0];
00704     oM.m[0][1] = -m[0][1];
00705     oM.m[0][2] = -m[0][2];
00706     oM.m[0][3] = -m[0][3];
00707 
00708     oM.m[1][0] = -m[1][0];
00709     oM.m[1][1] = -m[1][1];
00710     oM.m[1][2] = -m[1][2];
00711     oM.m[1][3] = -m[1][3];
00712 
00713     oM.m[2][0] = -m[2][0];
00714     oM.m[2][1] = -m[2][1];
00715     oM.m[2][2] = -m[2][2];
00716     oM.m[2][3] = -m[2][3];
00717 
00718     oM.m[3][0] = -m[3][0];
00719     oM.m[3][1] = -m[3][1];
00720     oM.m[3][2] = -m[3][2];
00721     oM.m[3][3] = -m[3][3];
00722 
00723     return oM;
00724   }
00725 
00726   template <typename T>
00727   T &Matrix4x4<T>::operator () (unsigned int i, unsigned int j)
00728   {
00729     return m[i][j];
00730   }
00731 
00732   template <typename T>
00733   T Matrix4x4<T>::operator () (unsigned int i, unsigned int j) const
00734   {
00735     return m[i][j];
00736   }
00737 
00738   template <typename T>
00739   Matrix4x4<T>::operator T *()
00740   {
00741     return reinterpret_cast<T *> (&m);
00742   }
00743 
00744   template <typename T>
00745   Matrix4x4<T>::operator const T *() const
00746   {
00747     return reinterpret_cast<const T *> (&m);
00748   }
00749 
00750 
00751   /***************************************************************************************\
00752   Function:       Matrix4x4<T>::zero
00753 
00754   Description:    Set the matrix to zero.
00755 
00756   Parameters:     None.
00757 
00758   Return Value:   None.
00759 
00760   Comments:       None.
00761   \***************************************************************************************/
00762   template <typename T>
00763   void Matrix4x4<T>::Zero()
00764   {
00765     m[0][0] = 0.0;
00766     m[0][1] = 0.0;
00767     m[0][2] = 0.0;
00768     m[0][3] = 0.0;
00769     m[1][0] = 0.0;
00770     m[1][1] = 0.0;
00771     m[1][2] = 0.0;
00772     m[1][3] = 0.0;
00773     m[2][0] = 0.0;
00774     m[2][1] = 0.0;
00775     m[2][2] = 0.0;
00776     m[2][3] = 0.0;
00777     m[3][0] = 0.0;
00778     m[3][1] = 0.0;
00779     m[3][2] = 0.0;
00780     m[3][3] = 0.0;
00781 
00782     //memset(m, 0, sizeof(m));
00783   }
00784 
00785   /***************************************************************************************\
00786   Function:       Matrix4x4<T>::identity
00787 
00788   Description:    Set the matrix to identity.
00789 
00790   Parameters:     None.
00791 
00792   Return Value:   None.
00793 
00794   Comments:       None.
00795   \***************************************************************************************/
00796   template <typename T>
00797   void Matrix4x4<T>::Identity()
00798   {
00799     m[0][0] = 1.0;
00800     m[0][1] = 0.0;
00801     m[0][2] = 0.0;
00802     m[0][3] = 0.0;
00803     m[1][0] = 0.0;
00804     m[1][1] = 1.0;
00805     m[1][2] = 0.0;
00806     m[1][3] = 0.0;
00807     m[2][0] = 0.0;
00808     m[2][1] = 0.0;
00809     m[2][2] = 1.0;
00810     m[2][3] = 0.0;
00811     m[3][0] = 0.0;
00812     m[3][1] = 0.0;
00813     m[3][2] = 0.0;
00814     m[3][3] = 1.0;
00815   }
00816 
00817   /***************************************************************************************\
00818   Function:       Matrix4x4<T>::translate
00819 
00820   Description:    Add a translation to the current matrix.
00821 
00822   Parameters:     - x
00823   - y
00824   - z
00825 
00826   Return Value:   None.
00827 
00828   Comments:       None.
00829   \***************************************************************************************/
00830   template <typename T>
00831   void Matrix4x4<T>::Translate (T x, T y, T z)
00832   {
00833     Identity();
00834     m[0][3] = x;
00835     m[1][3] = y;
00836     m[2][3] = z;
00837   }
00838 
00839   /***************************************************************************************\
00840   Function:       Matrix4x4<T>::Transpose
00841 
00842   Description:    Transpose the current matrix.
00843 
00844   Parameters:     None
00845 
00846   Return Value:   None.
00847 
00848   Comments:       None.
00849   \***************************************************************************************/
00850   template <typename T>
00851   void Matrix4x4<T>::Transpose()
00852   {
00853     for (int i = 0; i < 4; i++)
00854     {
00855       for (int j = 0; j < i; j++)
00856       {
00857         T t = m[i][j];
00858         m[i][j] = m[j][i];
00859         m[j][i] = t;
00860       }
00861     }
00862   }
00863 
00864 
00865   /***************************************************************************************\
00866   Function:       Matrix4x4<T>::Rotate_x
00867 
00868   Description:    Add rotation matrix around axe X.
00869 
00870   Parameters:     - angle
00871 
00872   Return Value:   None.
00873 
00874   Comments:       None.
00875   \***************************************************************************************/
00876   template <typename T>
00877   void Matrix4x4<T>::Rotate_x (T angle)
00878   {
00879     Identity();
00880 
00881     m[0][0] = 1.0f;
00882     m[1][0] = 0.0f;
00883     m[2][0] = 0.0f;
00884     m[3][0] = 0.0f;
00885 
00886     m[0][1] = 0.0f;
00887     m[1][1] = (T) cos (angle);
00888     m[2][1] = (T) sin (angle);
00889     m[3][1] = 0.0f;
00890 
00891     m[0][2] = 0.0f;
00892     m[1][2] = (T) - sin (angle);
00893     m[2][2] = (T) cos (angle);
00894     m[3][2] = 0.0f;
00895 
00896     m[0][3] = 0.0f;
00897     m[1][3] = 0.0f;
00898     m[2][3] = 0.0f;
00899     m[3][3] = 1.0f;
00900   }
00901 
00902   /***************************************************************************************\
00903   Function:       Matrix4x4<T>::Rotate_y
00904 
00905   Description:    Add rotation matrix around axe Y.
00906 
00907   Parameters:     - angle
00908 
00909   Return Value:   None.
00910 
00911   Comments:       None.
00912   \***************************************************************************************/
00913   template <typename T>
00914   void Matrix4x4<T>::Rotate_y (T angle)
00915   {
00916     Identity();
00917 
00918     m[0][0] = (T) cos (angle);
00919     m[1][0] = 0.0f;
00920     m[2][0] = (T) - sin (angle);
00921     m[3][0] = 0.0f;
00922 
00923     m[0][1] = 0.0f;
00924     m[1][1] = 1.0f;
00925     m[2][1] = 0.0f;
00926     m[3][1] = 0.0f;
00927 
00928     m[0][2] = (T) sin (angle);
00929     m[1][2] = 0.0f;
00930     m[2][2] = (T) cos (angle);
00931     m[3][2] = 0.0f;
00932 
00933     m[0][3] = 0.0f;
00934     m[1][3] = 0.0f;
00935     m[2][3] = 0.0f;
00936     m[3][3] = 1.0f;
00937   }
00938 
00939   /***************************************************************************************\
00940   Function:       Matrix4x4<T>::Rotate_z
00941 
00942   Description:    Add rotation matrix around axe Z.
00943 
00944   Parameters:     - angle
00945 
00946   Return Value:   None.
00947 
00948   Comments:       None.
00949   \***************************************************************************************/
00950   template <typename T>
00951   void Matrix4x4<T>::Rotate_z (T angle)
00952   {
00953     Identity();
00954 
00955     m[0][0] = (T) cos (angle);
00956     m[1][0] = (T) sin (angle);
00957     m[2][0] = 0.0f;
00958     m[3][0] = 0.0f;
00959 
00960     m[0][1] = (T) - sin (angle);
00961     m[1][1] = (T) cos (angle);
00962     m[2][1] = 0.0f;
00963     m[3][1] = 0.0f;
00964 
00965     m[0][2] = 0.0f;
00966     m[1][2] = 0.0f;
00967     m[2][2] = 1.0f;
00968     m[3][2] = 0.0f;
00969 
00970     m[0][3] = 0.0f;
00971     m[1][3] = 0.0f;
00972     m[2][3] = 0.0f;
00973     m[3][3] = 1.0f;
00974   }
00975 
00976   /***************************************************************************************\
00977   Function:       Matrix4x4<T>::Scale
00978 
00979   Description:    Add a scale matrix.
00980 
00981   Parameters:     - sx, sy, sz
00982 
00983   Return Value:   None.
00984 
00985   Comments:       None.
00986   \***************************************************************************************/
00987   template <typename T>
00988   void Matrix4x4<T>::Scale (T sx, T sy, T sz)
00989   {
00990     Identity();
00991 
00992     m[0][0] = sx;
00993     m[1][0] = 0.0f;
00994     m[2][0] = 0.0f;
00995     m[3][0] = 0.0f;
00996 
00997     m[0][1] = 0.0f;
00998     m[1][1] = sy;
00999     m[2][1] = 0.0f;
01000     m[3][1] = 0.0f;
01001 
01002     m[0][2] = 0.0f;
01003     m[1][2] = 0.0f;
01004     m[2][2] = sz;
01005     m[3][2] = 0.0f;
01006 
01007     m[0][3] = 0.0f;
01008     m[1][3] = 0.0f;
01009     m[2][3] = 0.0f;
01010     m[3][3] = 1.0f;
01011   }
01012 
01013   template <typename T>
01014   T Matrix4x4<T>::Trace() const
01015   {
01016     return m[0][0] + m[1][1] + m[2][2] + m[3][3];
01017   }
01018 
01019   template <typename T>
01020   T Matrix4x4<T>::Determinant() const
01021   {
01022     const T &m00 = m[0][0];
01023     const T &m01 = m[0][1];
01024     const T &m02 = m[0][2];
01025     const T &m03 = m[0][3];
01026     const T &m10 = m[1][0];
01027     const T &m11 = m[1][1];
01028     const T &m12 = m[1][2];
01029     const T &m13 = m[1][3];
01030     const T &m20 = m[2][0];
01031     const T &m21 = m[2][1];
01032     const T &m22 = m[2][2];
01033     const T &m23 = m[2][3];
01034     const T &m30 = m[3][0];
01035     const T &m31 = m[3][1];
01036     const T &m32 = m[3][2];
01037     const T &m33 = m[3][3];
01038 
01039     T det =
01040       m03 * m12 * m21 * m30 - m02 * m13 * m21 * m30 - m03 * m11 * m22 * m30 + m01 * m13 * m22 * m30 +
01041       m02 * m11 * m23 * m30 - m01 * m12 * m23 * m30 - m03 * m12 * m20 * m31 + m02 * m13 * m20 * m31 +
01042       m03 * m10 * m22 * m31 - m00 * m13 * m22 * m31 - m02 * m10 * m23 * m31 + m00 * m12 * m23 * m31 +
01043       m03 * m11 * m20 * m32 - m01 * m13 * m20 * m32 - m03 * m10 * m21 * m32 + m00 * m13 * m21 * m32 +
01044       m01 * m10 * m23 * m32 - m00 * m11 * m23 * m32 - m02 * m11 * m20 * m33 + m01 * m12 * m20 * m33 +
01045       m02 * m10 * m21 * m33 - m00 * m12 * m21 * m33 - m01 * m10 * m22 * m33 + m00 * m11 * m22 * m33;
01046 
01047     return det;
01048   }
01049 
01050   template <typename T>
01051   void Matrix4x4<T>::Inverse()
01052   {
01053     T det = Determinant();
01054 
01055     if (det == T (0) )
01056     {
01057       // Determinant is null. Matrix cannot be inverted.
01058 #ifdef NUX_DEBUG
01059       NUX_HARDWARE_BREAK;
01060 #endif
01061       return;
01062     }
01063 
01064     const T &m00 = m[0][0];
01065 
01066     const T &m01 = m[0][1];
01067 
01068     const T &m02 = m[0][2];
01069 
01070     const T &m03 = m[0][3];
01071 
01072     const T &m10 = m[1][0];
01073 
01074     const T &m11 = m[1][1];
01075 
01076     const T &m12 = m[1][2];
01077 
01078     const T &m13 = m[1][3];
01079 
01080     const T &m20 = m[2][0];
01081 
01082     const T &m21 = m[2][1];
01083 
01084     const T &m22 = m[2][2];
01085 
01086     const T &m23 = m[2][3];
01087 
01088     const T &m30 = m[3][0];
01089 
01090     const T &m31 = m[3][1];
01091 
01092     const T &m32 = m[3][2];
01093 
01094     const T &m33 = m[3][3];
01095 
01096     Matrix4x4<T> Temp;
01097 
01098     Temp.m[0][0] = m12 * m23 * m31 - m13 * m22 * m31 + m13 * m21 * m32 - m11 * m23 * m32 - m12 * m21 * m33 + m11 * m22 * m33;
01099 
01100     Temp.m[0][1] = m03 * m22 * m31 - m02 * m23 * m31 - m03 * m21 * m32 + m01 * m23 * m32 + m02 * m21 * m33 - m01 * m22 * m33;
01101 
01102     Temp.m[0][2] = m02 * m13 * m31 - m03 * m12 * m31 + m03 * m11 * m32 - m01 * m13 * m32 - m02 * m11 * m33 + m01 * m12 * m33;
01103 
01104     Temp.m[0][3] = m03 * m12 * m21 - m02 * m13 * m21 - m03 * m11 * m22 + m01 * m13 * m22 + m02 * m11 * m23 - m01 * m12 * m23;
01105 
01106     Temp.m[1][0] = m13 * m22 * m30 - m12 * m23 * m30 - m13 * m20 * m32 + m10 * m23 * m32 + m12 * m20 * m33 - m10 * m22 * m33;
01107 
01108     Temp.m[1][1] = m02 * m23 * m30 - m03 * m22 * m30 + m03 * m20 * m32 - m00 * m23 * m32 - m02 * m20 * m33 + m00 * m22 * m33;
01109 
01110     Temp.m[1][2] = m03 * m12 * m30 - m02 * m13 * m30 - m03 * m10 * m32 + m00 * m13 * m32 + m02 * m10 * m33 - m00 * m12 * m33;
01111 
01112     Temp.m[1][3] = m02 * m13 * m20 - m03 * m12 * m20 + m03 * m10 * m22 - m00 * m13 * m22 - m02 * m10 * m23 + m00 * m12 * m23;
01113 
01114     Temp.m[2][0] = m11 * m23 * m30 - m13 * m21 * m30 + m13 * m20 * m31 - m10 * m23 * m31 - m11 * m20 * m33 + m10 * m21 * m33;
01115 
01116     Temp.m[2][1] = m03 * m21 * m30 - m01 * m23 * m30 - m03 * m20 * m31 + m00 * m23 * m31 + m01 * m20 * m33 - m00 * m21 * m33;
01117 
01118     Temp.m[2][2] = m01 * m13 * m30 - m03 * m11 * m30 + m03 * m10 * m31 - m00 * m13 * m31 - m01 * m10 * m33 + m00 * m11 * m33;
01119 
01120     Temp.m[2][3] = m03 * m11 * m20 - m01 * m13 * m20 - m03 * m10 * m21 + m00 * m13 * m21 + m01 * m10 * m23 - m00 * m11 * m23;
01121 
01122     Temp.m[3][0] = m12 * m21 * m30 - m11 * m22 * m30 - m12 * m20 * m31 + m10 * m22 * m31 + m11 * m20 * m32 - m10 * m21 * m32;
01123 
01124     Temp.m[3][1] = m01 * m22 * m30 - m02 * m21 * m30 + m02 * m20 * m31 - m00 * m22 * m31 - m01 * m20 * m32 + m00 * m21 * m32;
01125 
01126     Temp.m[3][2] = m02 * m11 * m30 - m01 * m12 * m30 - m02 * m10 * m31 + m00 * m12 * m31 + m01 * m10 * m32 - m00 * m11 * m32;
01127 
01128     Temp.m[3][3] = m01 * m12 * m20 - m02 * m11 * m20 + m02 * m10 * m21 - m00 * m12 * m21 - m01 * m10 * m22 + m00 * m11 * m22;
01129 
01130     *this = (T (1) / det) * Temp;
01131   }
01132 
01133   template <typename T>
01134   Matrix4x4<T> Matrix4x4<T>::GetInverse() const
01135   {
01136     Matrix4x4<T> Temp = *this;
01137     Temp.Inverse();
01138     return Temp;
01139   }
01140 
01141 // template <typename T>
01142 // Matrix3x3<T> Matrix4x4<T>::GetUpper3x3() const
01143 // {
01144 //     Matrix3x3<T> Temp;
01145 //     Temp.m[0][0] = m[0][0];
01146 //     Temp.m[0][1] = m[0][1];
01147 //     Temp.m[0][2] = m[0][2];
01148 //
01149 //     Temp.m[1][0] = m[1][0];
01150 //     Temp.m[1][1] = m[1][1];
01151 //     Temp.m[1][2] = m[1][2];
01152 //
01153 //     Temp.m[2][0] = m[2][0];
01154 //     Temp.m[2][1] = m[2][1];
01155 //     Temp.m[2][2] = m[2][2];
01156 //
01157 //     return Temp;
01158 // }
01159 //
01160 // template <typename T>
01161 // Matrix2x2<T> Matrix4x4<T>::GetUpper2x2() const
01162 // {
01163 //     Matrix2x2<T> Temp;
01164 //     Temp.m[0][0] = m[0][0];
01165 //     Temp.m[0][1] = m[0][1];
01166 //
01167 //     Temp.m[1][0] = m[1][0];
01168 //     Temp.m[1][1] = m[1][1];
01169 //
01170 //     return Temp;
01171 // }
01172 
01173 // s 0 0 0
01174 // 0 s 0 0
01175 // 0 0 s 0
01176 // 0 0 0 1
01177 
01178   template <typename T>
01179   void Matrix4x4<T>::Scale (T s)
01180   {
01181     m[0][0] = s;
01182     m[0][1] = 0.0;
01183     m[0][2] = 0.0;
01184     m[0][3] = 0.0;
01185     m[1][0] = 0.0;
01186     m[1][1] = s;
01187     m[1][2] = 0.0;
01188     m[1][3] = 0.0;
01189     m[2][0] = 0.0;
01190     m[2][1] = 0.0;
01191     m[2][2] = s;
01192     m[2][3] = 0.0;
01193     m[3][0] = 0.0;
01194     m[3][1] = 0.0;
01195     m[3][2] = 0.0;
01196     m[3][3] = 1;
01197   }
01198 
01199 // x 0 0 0
01200 // 0 y 0 0
01201 // 0 0 z 0
01202 // 0 0 0 w
01203 
01204   template <typename T>
01205   void Matrix4x4<T>::Diagonal (T x, T y, T z, T w)
01206   {
01207     m[0][0] = x;
01208     m[0][1] = 0.0;
01209     m[0][2] = 0.0;
01210     m[0][3] = 0.0;
01211     m[1][0] = 0.0;
01212     m[1][1] = y;
01213     m[1][2] = 0.0;
01214     m[1][3] = 0.0;
01215     m[2][0] = 0.0;
01216     m[2][1] = 0.0;
01217     m[2][2] = z;
01218     m[2][3] = 0.0;
01219     m[3][0] = 0.0;
01220     m[3][1] = 0.0;
01221     m[3][2] = 0.0;
01222     m[3][3] = w;
01223   }
01224 
01225 
01226   template <typename T>
01227   void Matrix4x4<T>::Rotate (T angle, Vector3 axis)
01228   {
01229     //See Quaternion::from_angle_axis() and Quaternion::get_matrix()
01230     // note: adapted from david eberly's code without permission
01231     //TODO: make sure it is correct
01232     
01233     if (axis.LengthSquared() < constants::epsilon_micro)
01234     {
01235       Identity();
01236     }
01237     else
01238     {
01239       axis.Normalize();
01240 
01241       T fCos = (T) cos(angle);
01242       T fSin = (T) sin(angle);
01243       T fOneMinusCos = 1.0f-fCos;
01244       T fX2 = axis.x*axis.x;
01245       T fY2 = axis.y*axis.y;
01246       T fZ2 = axis.z*axis.z;
01247       T fXYM = axis.x*axis.y*fOneMinusCos;
01248       T fXZM = axis.x*axis.z*fOneMinusCos;
01249       T fYZM = axis.y*axis.z*fOneMinusCos;
01250       T fXSin = axis.x*fSin;
01251       T fYSin = axis.y*fSin;
01252       T fZSin = axis.z*fSin;
01253 
01254       m[0][0] = fX2*fOneMinusCos+fCos;
01255       m[0][1] = fXYM-fZSin;
01256       m[0][2] = fXZM+fYSin;
01257       m[0][3] = 0;
01258 
01259       m[1][0] = fXYM+fZSin;
01260       m[1][1] = fY2*fOneMinusCos+fCos;
01261       m[1][2] = fYZM-fXSin;
01262       m[1][3] = 0;
01263 
01264       m[2][0] = fXZM-fYSin;
01265       m[2][1] = fYZM+fXSin;
01266       m[2][2] = fZ2*fOneMinusCos+fCos;
01267       m[2][3] = 0;
01268 
01269       m[3][0] = 0;
01270       m[3][1] = 0;
01271       m[3][2] = 0;
01272       m[3][3] = 1;
01273     }
01274   }
01275 
01276   template <typename T>
01277   void Matrix4x4<T>::LookAt (const Vector3 &eye, const Vector3 &at, const Vector3 &up)
01278   {
01279     // left handed
01280 
01281     Vector3 z_axis = at - eye;
01282     Vector3 x_axis = z_axis.CrossProduct (up);
01283     Vector3 y_axis = x_axis.CrossProduct (z_axis);
01284 
01285     x_axis.Normalize();
01286     y_axis.Normalize();
01287     z_axis.Normalize();
01288 
01289     Matrix4x4<T> Rot;
01290     Rot.m[0][0]      = x_axis.x;
01291     Rot.m[0][1] = x_axis.y;
01292     Rot.m[0][2] = x_axis.z;
01293     Rot.m[0][3] = 0;
01294 
01295     Rot.m[1][0]      = y_axis.x;
01296     Rot.m[1][1] = y_axis.y;
01297     Rot.m[1][2] = y_axis.z;
01298     Rot.m[1][3] = 0;
01299 
01300     Rot.m[2][0]      = -z_axis.x;
01301     Rot.m[2][1] = -z_axis.y;
01302     Rot.m[2][2] = -z_axis.z;
01303     Rot.m[2][3] = 0;
01304 
01305     Rot.m[3][0]      = 0.0f;
01306     Rot.m[3][1] = 0.0f;
01307     Rot.m[3][2] = 0.0f;
01308     Rot.m[3][3] = 1.0f;
01309 
01310     Matrix4x4<T> Trans;
01311     Trans.Translate (-eye.x, -eye.y, -eye.z);
01312 
01313     *this = Rot * Trans;
01314   }
01315 
01317 
01318 // 2/(r-l)  0           0           -(r+l)/(r-l)
01319 // 0        2/(t-b)     0           -(t+b)/(t-b)
01320 // 0        0           -2/(f-n)    -(f+n)/(f-n)
01321 // 0        0           0           1
01322   template <typename T>
01323   void Matrix4x4<T>::Orthographic (T l, T r, T b, T t, T n, T f)
01324   {
01325     T sx = 1 / (r - l);
01326     T sy = 1 / (t - b);
01327     T sz = 1 / (f - n);
01328 
01329     m[0][0] = 2.0f * sx;
01330     m[0][1] = 0.0f;
01331     m[0][2] = 0.0f;
01332     m[0][3] = - (r + l) * sx;
01333 
01334     m[1][0] = 0.0f;
01335     m[1][1] = 2.0f * sy;
01336     m[1][2] = 0.0f;
01337     m[1][3] = - (t + b) * sy;
01338 
01339     m[2][0] = 0.0f;
01340     m[2][1] = 0.0f;
01341     m[2][2] = -2.0f * sz;
01342     m[2][3] = - (f + n) * sz;
01343 
01344     m[3][0] = 0.0f;
01345     m[3][1] = 0.0f;
01346     m[3][2] = 0.0f;
01347     m[3][3] = 1.0f;
01348   }
01349 
01351 // 2*n/(r-l)    0           (r+l)/(r-l)     0
01352 // 0            2*n/(t-b)   (t+b)/(t-b)     0
01353 // 0            0           -(f+n)/(f-n)    -2*f*n/(f-n)
01354 // 0            0           -1              0
01355   template <typename T>
01356   void Matrix4x4<T>::Perspective (T l, T r, T t, T b, T n, T f)
01357   {
01358     m[0][0]   = 2.0f * n / (r - l);
01359     m[0][1] = 0.0f;
01360     m[0][2] = (r + l) / (r - l);
01361     m[0][3] = 0.0f;
01362 
01363     m[1][0] = 0.0f;
01364     m[1][1] = 2.0f * n / (t - b);
01365     m[1][2] = (t + b) / (t - b);
01366     m[1][3] = 0.0f;
01367 
01368     m[2][0] = 0.0f;
01369     m[2][1] = 0.0f;
01370     m[2][2] = - (f + n) / (f - n);
01371     m[2][3] = -2.0f * f * n / (f - n);
01372 
01373     m[3][0] = 0.0f;
01374     m[3][1] = 0.0f;
01375     m[3][2] = -1.0f;
01376     m[3][3] = 0.0f;
01377   }
01378 
01379 // (r-l)/2*n    0           0               (r+l)/(2*n)
01380 // 0            (t-b)/(2*n) 0               (t+b)/(2*n)
01381 // 0            0           0               -1
01382 // 0            0           -(f-n)/(2*f*n)  (f+n)/(2*f*n)
01383   template <typename T>
01384   void Matrix4x4<T>::PerspectiveInverse (T l, T r, T t, T b, T n, T f)
01385   {
01386     m[0][0]   = (r - l) / (2.0f * n);
01387     m[0][1] = 0;
01388     m[0][2] = 0;
01389     m[0][3] = (r + l) / (2.0f * n);
01390 
01391     m[1][0] = 0;
01392     m[1][1] = (t - b) / (2.0f * n);
01393     m[1][2] = (t + b) / (2.0f * n);
01394     m[1][3] = 0;
01395 
01396     m[2][0] = 0;
01397     m[2][1] = 0;
01398     m[2][2] = 0;
01399     m[2][3] = -1;
01400 
01401     m[3][0] = 0;
01402     m[3][1] = 0;
01403     m[3][2] = - (f - n) / (2.0f * f * n);
01404     m[3][3] = (f + n) / (2.0f * f * n);
01405   }
01406 
01408   template <typename T>
01409   void Matrix4x4<T>::Perspective (T FoV, T AspectRatio, T NearPlane, T FarPlane)
01410   {
01411     const T t = tan (FoV * 0.5f) * NearPlane;
01412     const T b = -t;
01413 
01414     const T l = AspectRatio * b;
01415     const T r = AspectRatio * t;
01416 
01417     Perspective (l, r, t, b, NearPlane, FarPlane);
01418   }
01419 
01420   template <typename T>
01421   Matrix4x4<T> Matrix4x4<T>::IDENTITY()
01422   {
01423     Matrix4x4<T> matrix;
01424     matrix.Identity();
01425     return matrix;
01426   }
01427 
01428   template <typename T>
01429   Matrix4x4<T> Matrix4x4<T>::ZERO()
01430   {
01431     Matrix4x4<T> matrix;
01432     matrix.Zero();
01433     return matrix;
01434   }
01435 
01436   template <typename T>
01437   Matrix4x4<T> Matrix4x4<T>::ROTATEX(T angle)
01438   {
01439     Matrix4x4<T> matrix;
01440     matrix.Rotate_x(angle);
01441     return matrix;
01442   }
01443 
01444   template <typename T>
01445   Matrix4x4<T> Matrix4x4<T>::ROTATEY(T angle)
01446   {
01447     Matrix4x4<T> matrix;
01448     matrix.Rotate_y(angle);
01449     return matrix;
01450   }
01451 
01452   template <typename T>
01453   Matrix4x4<T> Matrix4x4<T>::ROTATEZ(T angle)
01454   {
01455     Matrix4x4<T> matrix;
01456     matrix.Rotate_z(angle);
01457     return matrix;
01458   }
01459 
01460   template <typename T>
01461   Matrix4x4<T> Matrix4x4<T>::TRANSLATE(T x, T y, T z)
01462   {
01463     Matrix4x4<T> matrix;
01464     matrix.Translate(x, y, z);
01465     return matrix;
01466   }
01467 
01468   template <typename T>
01469   Matrix4x4<T> Matrix4x4<T>::SCALE(T x, T y, T z)
01470   {
01471     Matrix4x4<T> matrix;
01472     matrix.Scale(x, y, z);
01473     return matrix;
01474   }
01475 
01476   /***************************************************************************************\
01477   Function:       operator *
01478 
01479   Description:    Multiply matrix rhs by constant lhs.
01480                   Allow "f * matrix" operation.
01481 
01482   Parameters:     None.
01483 
01484   Return Value:   Matrix4.
01485 
01486   Comments:       None.
01487   \***************************************************************************************/
01488   template<typename T>
01489   Matrix4x4<T> operator * (const T &lhs, const Matrix4x4<T>& rhs)
01490   {
01491     Matrix4x4<T> oM;
01492 
01493     oM.m[0][0] = rhs.m[0][0] * lhs;
01494     oM.m[0][1] = rhs.m[0][1] * lhs;
01495     oM.m[0][2] = rhs.m[0][2] * lhs;
01496     oM.m[0][3] = rhs.m[0][3] * lhs;
01497     oM.m[1][0] = rhs.m[1][0] * lhs;
01498     oM.m[1][1] = rhs.m[1][1] * lhs;
01499     oM.m[1][2] = rhs.m[1][2] * lhs;
01500     oM.m[1][3] = rhs.m[1][3] * lhs;
01501     oM.m[2][0] = rhs.m[2][0] * lhs;
01502     oM.m[2][1] = rhs.m[2][1] * lhs;
01503     oM.m[2][2] = rhs.m[2][2] * lhs;
01504     oM.m[2][3] = rhs.m[2][3] * lhs;
01505     oM.m[3][0] = rhs.m[3][0] * lhs;
01506     oM.m[3][1] = rhs.m[3][1] * lhs;
01507     oM.m[3][2] = rhs.m[3][2] * lhs;
01508     oM.m[3][3] = rhs.m[3][3] * lhs;
01509 
01510     return oM;
01511   }
01512 
01513   typedef Matrix4x4<float> Matrix4;
01514 
01515 }
01516 
01517 
01518 #endif // MATRIX4_H
01519