nux-0.9.46
|
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 t_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 t_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 01231 01232 // note: adapted from david eberly's code without permission 01233 //TODO: make sure it is correct 01234 /*if (axis.LengthSquared() < EpsilonMicro) 01235 { 01236 Identity(); 01237 } 01238 else 01239 { 01240 axis.Normalize(); 01241 01242 T fCos = (T) cos(angle); 01243 T fSin = (T) sin(angle); 01244 T fOneMinusCos = 1.0f-fCos; 01245 T fX2 = axis.x*axis.x; 01246 T fY2 = axis.y*axis.y; 01247 T fZ2 = axis.z*axis.z; 01248 T fXYM = axis.x*axis.y*fOneMinusCos; 01249 T fXZM = axis.x*axis.z*fOneMinusCos; 01250 T fYZM = axis.y*axis.z*fOneMinusCos; 01251 T fXSin = axis.x*fSin; 01252 T fYSin = axis.y*fSin; 01253 T fZSin = axis.z*fSin; 01254 01255 m[0][0] = fX2*fOneMinusCos+fCos; 01256 m[0][1] = fXYM-fZSin; 01257 m[0][2] = fXZM+fYSin; 01258 m[0][3] = 0; 01259 01260 m[1][0] = fXYM+fZSin; 01261 m[1][1] = fY2*fOneMinusCos+fCos; 01262 m[1][2] = fYZM-fXSin; 01263 m[1][3] = 0; 01264 01265 m[2][0] = fXZM-fYSin; 01266 m[2][1] = fYZM+fXSin; 01267 m[2][2] = fZ2*fOneMinusCos+fCos; 01268 m[2][3] = 0; 01269 01270 m[3][0] = 0; 01271 m[3][1] = 0; 01272 m[3][2] = 0; 01273 m[3][3] = 1; 01274 } 01275 */ 01276 } 01277 01278 template <typename T> 01279 void Matrix4x4<T>::LookAt (const Vector3 &eye, const Vector3 &at, const Vector3 &up) 01280 { 01281 // left handed 01282 01283 Vector3 z_axis = at - eye; 01284 Vector3 x_axis = z_axis.CrossProduct (up); 01285 Vector3 y_axis = x_axis.CrossProduct (z_axis); 01286 01287 x_axis.Normalize(); 01288 y_axis.Normalize(); 01289 z_axis.Normalize(); 01290 01291 Matrix4x4<T> Rot; 01292 Rot.m[0][0] = x_axis.x; 01293 Rot.m[0][1] = x_axis.y; 01294 Rot.m[0][2] = x_axis.z; 01295 Rot.m[0][3] = 0; 01296 01297 Rot.m[1][0] = y_axis.x; 01298 Rot.m[1][1] = y_axis.y; 01299 Rot.m[1][2] = y_axis.z; 01300 Rot.m[1][3] = 0; 01301 01302 Rot.m[2][0] = -z_axis.x; 01303 Rot.m[2][1] = -z_axis.y; 01304 Rot.m[2][2] = -z_axis.z; 01305 Rot.m[2][3] = 0; 01306 01307 Rot.m[3][0] = 0.0f; 01308 Rot.m[3][1] = 0.0f; 01309 Rot.m[3][2] = 0.0f; 01310 Rot.m[3][3] = 1.0f; 01311 01312 Matrix4x4<T> Trans; 01313 Trans.Translate (-eye.x, -eye.y, -eye.z); 01314 01315 *this = Rot * Trans; 01316 } 01317 01319 01320 // 2/(r-l) 0 0 -(r+l)/(r-l) 01321 // 0 2/(t-b) 0 -(t+b)/(t-b) 01322 // 0 0 -2/(f-n) -(f+n)/(f-n) 01323 // 0 0 0 1 01324 template <typename T> 01325 void Matrix4x4<T>::Orthographic (T l, T r, T b, T t, T n, T f) 01326 { 01327 T sx = 1 / (r - l); 01328 T sy = 1 / (t - b); 01329 T sz = 1 / (f - n); 01330 01331 m[0][0] = 2.0f * sx; 01332 m[0][1] = 0.0f; 01333 m[0][2] = 0.0f; 01334 m[0][3] = - (r + l) * sx; 01335 01336 m[1][0] = 0.0f; 01337 m[1][1] = 2.0f * sy; 01338 m[1][2] = 0.0f; 01339 m[1][3] = - (t + b) * sy; 01340 01341 m[2][0] = 0.0f; 01342 m[2][1] = 0.0f; 01343 m[2][2] = -2.0f * sz; 01344 m[2][3] = - (f + n) * sz; 01345 01346 m[3][0] = 0.0f; 01347 m[3][1] = 0.0f; 01348 m[3][2] = 0.0f; 01349 m[3][3] = 1.0f; 01350 } 01351 01353 // 2*n/(r-l) 0 (r+l)/(r-l) 0 01354 // 0 2*n/(t-b) (t+b)/(t-b) 0 01355 // 0 0 -(f+n)/(f-n) -2*f*n/(f-n) 01356 // 0 0 -1 0 01357 template <typename T> 01358 void Matrix4x4<T>::Perspective (T l, T r, T t, T b, T n, T f) 01359 { 01360 m[0][0] = 2.0f * n / (r - l); 01361 m[0][1] = 0.0f; 01362 m[0][2] = (r + l) / (r - l); 01363 m[0][3] = 0.0f; 01364 01365 m[1][0] = 0.0f; 01366 m[1][1] = 2.0f * n / (t - b); 01367 m[1][2] = (t + b) / (t - b); 01368 m[1][3] = 0.0f; 01369 01370 m[2][0] = 0.0f; 01371 m[2][1] = 0.0f; 01372 m[2][2] = - (f + n) / (f - n); 01373 m[2][3] = -2.0f * f * n / (f - n); 01374 01375 m[3][0] = 0.0f; 01376 m[3][1] = 0.0f; 01377 m[3][2] = -1.0f; 01378 m[3][3] = 0.0f; 01379 } 01380 01381 // (r-l)/2*n 0 0 (r+l)/(2*n) 01382 // 0 (t-b)/(2*n) 0 (t+b)/(2*n) 01383 // 0 0 0 -1 01384 // 0 0 -(f-n)/(2*f*n) (f+n)/(2*f*n) 01385 template <typename T> 01386 void Matrix4x4<T>::PerspectiveInverse (T l, T r, T t, T b, T n, T f) 01387 { 01388 m[0][0] = (r - l) / (2.0f * n); 01389 m[0][1] = 0; 01390 m[0][2] = 0; 01391 m[0][3] = (r + l) / (2.0f * n); 01392 01393 m[1][0] = 0; 01394 m[1][1] = (t - b) / (2.0f * n); 01395 m[1][2] = (t + b) / (2.0f * n); 01396 m[1][3] = 0; 01397 01398 m[2][0] = 0; 01399 m[2][1] = 0; 01400 m[2][2] = 0; 01401 m[2][3] = -1; 01402 01403 m[3][0] = 0; 01404 m[3][1] = 0; 01405 m[3][2] = - (f - n) / (2.0f * f * n); 01406 m[3][3] = (f + n) / (2.0f * f * n); 01407 } 01408 01410 template <typename T> 01411 void Matrix4x4<T>::Perspective (T FoV, T AspectRatio, T NearPlane, T FarPlane) 01412 { 01413 const T t = tan (FoV * 0.5f) * NearPlane; 01414 const T b = -t; 01415 01416 const T l = AspectRatio * b; 01417 const T r = AspectRatio * t; 01418 01419 Perspective (l, r, t, b, NearPlane, FarPlane); 01420 } 01421 01422 template <typename T> 01423 Matrix4x4<T> Matrix4x4<T>::IDENTITY() 01424 { 01425 Matrix4x4<T> matrix; 01426 matrix.Identity(); 01427 return matrix; 01428 } 01429 01430 template <typename T> 01431 Matrix4x4<T> Matrix4x4<T>::ZERO() 01432 { 01433 Matrix4x4<T> matrix; 01434 matrix.Zero(); 01435 return matrix; 01436 } 01437 01438 template <typename T> 01439 Matrix4x4<T> Matrix4x4<T>::ROTATEX(T angle) 01440 { 01441 Matrix4x4<T> matrix; 01442 matrix.Rotate_x(angle); 01443 return matrix; 01444 } 01445 01446 template <typename T> 01447 Matrix4x4<T> Matrix4x4<T>::ROTATEY(T angle) 01448 { 01449 Matrix4x4<T> matrix; 01450 matrix.Rotate_y(angle); 01451 return matrix; 01452 } 01453 01454 template <typename T> 01455 Matrix4x4<T> Matrix4x4<T>::ROTATEZ(T angle) 01456 { 01457 Matrix4x4<T> matrix; 01458 matrix.Rotate_z(angle); 01459 return matrix; 01460 } 01461 01462 template <typename T> 01463 Matrix4x4<T> Matrix4x4<T>::TRANSLATE(T x, T y, T z) 01464 { 01465 Matrix4x4<T> matrix; 01466 matrix.Translate(x, y, z); 01467 return matrix; 01468 } 01469 01470 template <typename T> 01471 Matrix4x4<T> Matrix4x4<T>::SCALE(T x, T y, T z) 01472 { 01473 Matrix4x4<T> matrix; 01474 matrix.Scale(x, y, z); 01475 return matrix; 01476 } 01477 01478 /***************************************************************************************\ 01479 Function: operator * 01480 01481 Description: Multiply matrix rhs by constant lhs. 01482 Allow "f * matrix" operation. 01483 01484 Parameters: None. 01485 01486 Return Value: Matrix4. 01487 01488 Comments: None. 01489 \***************************************************************************************/ 01490 template<typename T> 01491 Matrix4x4<T> operator * (const T &lhs, const Matrix4x4<T>& rhs) 01492 { 01493 Matrix4x4<T> oM; 01494 01495 oM.m[0][0] = rhs.m[0][0] * lhs; 01496 oM.m[0][1] = rhs.m[0][1] * lhs; 01497 oM.m[0][2] = rhs.m[0][2] * lhs; 01498 oM.m[0][3] = rhs.m[0][3] * lhs; 01499 oM.m[1][0] = rhs.m[1][0] * lhs; 01500 oM.m[1][1] = rhs.m[1][1] * lhs; 01501 oM.m[1][2] = rhs.m[1][2] * lhs; 01502 oM.m[1][3] = rhs.m[1][3] * lhs; 01503 oM.m[2][0] = rhs.m[2][0] * lhs; 01504 oM.m[2][1] = rhs.m[2][1] * lhs; 01505 oM.m[2][2] = rhs.m[2][2] * lhs; 01506 oM.m[2][3] = rhs.m[2][3] * lhs; 01507 oM.m[3][0] = rhs.m[3][0] * lhs; 01508 oM.m[3][1] = rhs.m[3][1] * lhs; 01509 oM.m[3][2] = rhs.m[3][2] * lhs; 01510 oM.m[3][3] = rhs.m[3][3] * lhs; 01511 01512 return oM; 01513 } 01514 01515 typedef Matrix4x4<float> Matrix4; 01516 01517 } 01518 01519 01520 #endif // MATRIX4_H 01521