ML Reference
|
00001 // **InsertLicense** code 00002 //===================================================================================== 00004 00009 //===================================================================================== 00010 00011 #ifndef __mlMatrix4_H 00012 #define __mlMatrix4_H 00013 00014 // Include system independency file and project settings. 00015 #ifndef __mlLinearAlgebraSystem_H 00016 #include "mlLinearAlgebraSystem.h" 00017 #endif 00018 #ifndef __mlLinearAlgebraDefs_H 00019 #include "mlLinearAlgebraDefs.h" 00020 #endif 00021 00022 #ifndef __mlFloatingPointMatrix_H 00023 #include "mlFloatingPointMatrix.h" 00024 #endif 00025 00026 #ifndef __mlMatrix3_H 00027 #include "mlMatrix3.h" 00028 #endif 00029 #ifndef __mlVector4_H 00030 #include "mlVector4.h" 00031 #endif 00032 00033 // All declarations of this header will be in the ML_LA_START_NAMESPACE namespace. 00034 ML_LA_START_NAMESPACE 00035 00036 //--------------------------------------------------------------- 00038 //--------------------------------------------------------------- 00039 template <class DT> 00040 class Tmat4 : public FloatingPointMatrix<Tvec4<DT>, 4> 00041 { 00042 public: 00043 00045 typedef DT ComponentType; 00046 00047 //--------------------------------------------------------------- 00048 // Constructors, set and get methods. 00049 //--------------------------------------------------------------- 00050 // Construct matrix from 16 zero elements. 00051 Tmat4(); 00052 00053 // Build matrix that has the argument at the diagonal values, zero otherwise 00054 Tmat4(const DT diagValue); 00055 00056 // Composes a matrix from the four row vectors row0, row1, row2 and row3. 00057 Tmat4(const Tvec4<DT> &row0, const Tvec4<DT> &row1, const Tvec4<DT> &row2, const Tvec4<DT> &row3); 00058 00059 // Copy constructor from the Tmat4 mat. 00060 Tmat4(const Tmat4<DT> &mat); 00061 00062 // Constructor from 16 floating point values in an array given by mat, row by row. 00063 Tmat4(const float mat[16]); 00064 00065 // Constructor from 16 double values in an array given by mat, row by row. 00066 Tmat4(const double mat[16]); 00067 00068 // Initialize all matrix elements explicitly with scalars, 00069 // filling it row by row. 00070 Tmat4(const double in00, const double in01, const double in02, const double in03, 00071 const double in10, const double in11, const double in12, const double in13, 00072 const double in20, const double in21, const double in22, const double in23, 00073 const double in30, const double in31, const double in32, const double in33); 00074 00075 // Construct matrix from three base vectors n0, ... n3 and a translation t, 00076 // all given as COLUMN vectors. 00077 Tmat4(const Tvec3<DT> &n0, const Tvec3<DT> &n1, const Tvec3<DT> &n3, const Tvec3<DT> &t); 00078 00079 // Copy contents from float array mat into *this, row by row. 00080 void setValues(const float mat[16]); 00081 00082 // Copy contents of *this into floating point matrix mat, row by row. 00083 // Note that range and precision of the float values may not be 00084 // sufficient for double or long double matrix contents. 00085 void getValues(float mat[16]) const; 00086 00087 // Copy contents from double array mat into *this, row by row. 00088 void setValues(const double mat[16]); 00089 00090 // Copy contents of *this into into double matrix mat, row by row. 00091 // Note that range and precision of the double values may not be 00092 // sufficient for long double matrix contents. 00093 void getValues(double mat[16]) const; 00094 00095 // Set diagonal matrix with scale on diagonal. 00096 void setScaleMatrix(const DT scale); 00097 00099 inline Tvec3<DT> transformPoint(const Tvec3<DT>& sourceVec) const 00100 { 00101 return Tvec3<DT>( (*this) * sourceVec.affinePoint(), true); 00102 } 00103 00104 #ifdef ML_DEPRECATED 00105 00106 00107 00108 00109 inline ML_DEPRECATED void TransformPoint(const Tvec3<DT>& sourceVec, Tvec3<DT>& targetVec) const 00110 { 00111 targetVec = transformPoint(sourceVec); 00112 } 00114 #endif 00115 00116 //--------------------------------------------------------------- 00117 // Assignment operators and other simple stuff. 00118 //--------------------------------------------------------------- 00119 // Return a matrix filled with values val. 00120 static Tmat4<DT> getMat(const double val); 00121 00122 // Set all values to val. 00123 void set(const double val); 00124 00127 bool operator<(const Tmat4<DT> &) const { return false; } 00128 00129 // Assignment from a Tmat4. 00130 const Tmat4<DT> &operator=(const Tmat4<DT> &m); 00131 00132 // Incrementation by a Tmat4. 00133 const Tmat4<DT> &operator+=(const Tmat4<DT> &m); 00134 00135 // Decrement by a Tmat4. 00136 const Tmat4<DT> &operator-=(const Tmat4<DT> &m); 00137 00138 00139 // Multiplication by a constant d. 00140 const Tmat4<DT> &operator*=(const DT d); 00141 00142 // Division by a constant d. Division by zero is not handled and must be avoided by caller. 00143 const Tmat4<DT> &operator/=(const DT d); 00144 00145 00146 //--------------------------------------------------------------- 00147 // Special functions 00148 //--------------------------------------------------------------- 00149 // Determine the determinant of a 3x3 matrix given by A,B,C,D,E,F,G,H,I. 00150 DT det3(DT A, DT B, DT C, DT D, DT E, DT F, DT G, DT H, DT I) const; 00151 00152 // Determine the (sub)determinant of columns given by col1, col2 and col3. 00153 DT determinantLower3(const int col1, const int col2, const int col3) const; 00154 00155 // Returns the determinant of this. 00156 DT det() const; 00157 00158 // Return the transposed *this. 00159 Tmat4<DT> transpose() const; 00160 00161 // Returns the inverse. Gauss-Jordan elimination with partial pivoting. 00162 // If a non-NULL Boolean pointer is passed to isInvertible 00163 // then true is returned in *isInvertible in the case of a 00164 // successful inversion or false if the inversion is not possible 00165 // (function return is the identity then). 00166 // If a NULL pointer is passed as isInvertible the matrix must 00167 // be invertible, otherwise errors will occur. 00168 Tmat4<DT> inverse(bool* isInvertible=NULL) const; 00169 00170 // Return identity matrix. 00171 static Tmat4<DT> getIdentity(); 00172 00173 // Apply the function fct to each component. 00174 const Tmat4<DT> &apply(MLDblFuncPtr fct); 00175 00176 }; // end of class *mat4* 00177 00178 //--------------------------------------------------------------- 00180 00181 //--------------------------------------------------------------- 00182 00184 template <class DT> 00185 inline Tmat4<DT>::Tmat4() 00186 { 00187 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::Tmat4()"); 00188 00189 this->v[0] = this->v[1] = this->v[2] = this->v[3] = Tvec4<DT>(0); 00190 } 00191 00192 // Construct matrix that has the argument at the diagonal values, zero otherwise 00193 template <class DT> 00194 inline Tmat4<DT>::Tmat4(const DT diagValue) 00195 { 00196 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::Tmat4(diagValue)"); 00197 00198 this->v[0][0] = this->v[1][1] = this->v[2][2] = this->v[3][3] = diagValue; 00199 this->v[1][0] = this->v[2][0] = this->v[3][0] = this->v[2][1] = this->v[3][1] = this->v[3][2] = 0; 00200 this->v[0][1] = this->v[0][2] = this->v[0][3] = this->v[1][2] = this->v[1][3] = this->v[2][3] = 0; 00201 } 00202 00203 00205 template <class DT> 00206 inline Tmat4<DT>::Tmat4(const Tvec4<DT> &row0, const Tvec4<DT> &row1, const Tvec4<DT> &row2, const Tvec4<DT> &row3) 00207 { 00208 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::Tmat4(const Tvec4<DT> &row0, ..., const Tvec4<DT> &row3)"); 00209 00210 this->v[0] = row0; 00211 this->v[1] = row1; 00212 this->v[2] = row2; 00213 this->v[3] = row3; 00214 } 00215 00217 template <class DT> 00218 inline Tmat4<DT>::Tmat4(const Tmat4<DT> &mat) 00219 { 00220 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::Tmat4(const Tmat4<DT> &mat)"); 00221 00222 this->v[0] = mat.v[0]; 00223 this->v[1] = mat.v[1]; 00224 this->v[2] = mat.v[2]; 00225 this->v[3] = mat.v[3]; 00226 } 00227 00229 template <class DT> 00230 inline Tmat4<DT>::Tmat4(const float mat[16]) 00231 { 00232 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::Tmat4(const float mat[16])"); 00233 00234 setValues(mat); 00235 } 00236 00238 template <class DT> 00239 inline Tmat4<DT>::Tmat4(const double mat[16]) 00240 { 00241 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::Tmat4(const double mat[16])"); 00242 00243 setValues(mat); 00244 } 00245 00247 template <class DT> 00248 inline Tmat4<DT> Tmat4<DT>::getMat(const double val) 00249 { 00250 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::getMat(const double val)"); 00251 00252 return Tmat4<DT>(val, val, val, val, 00253 val, val, val, val, 00254 val, val, val, val, 00255 val, val, val, val); 00256 } 00257 00259 template <class DT> 00260 inline void Tmat4<DT>::set(const double val) 00261 { 00262 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::set(const double val)"); 00263 00264 this->v[0] = this->v[1] = this->v[2] = this->v[3] = Tvec4<DT>(val); 00265 } 00266 00268 template <class DT> 00269 inline const Tmat4<DT> &Tmat4<DT>::operator=(const Tmat4<DT> &m) 00270 { 00271 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::operator=(const Tmat4<DT> &m)"); 00272 00273 if (&m != this){ 00274 this->v[0] = m.v[0]; 00275 this->v[1] = m.v[1]; 00276 this->v[2] = m.v[2]; 00277 this->v[3] = m.v[3]; 00278 } 00279 return *this; 00280 } 00281 00283 template <class DT> 00284 inline const Tmat4<DT> &Tmat4<DT>::operator+=(const Tmat4<DT> &m) 00285 { 00286 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::operator+=(const Tmat4<DT> &m)"); 00287 00288 this->v[0] += m.v[0]; 00289 this->v[1] += m.v[1]; 00290 this->v[2] += m.v[2]; 00291 this->v[3] += m.v[3]; 00292 return *this; 00293 } 00294 00296 template <class DT> 00297 inline const Tmat4<DT> &Tmat4<DT>::operator-=(const Tmat4<DT> &m) 00298 { 00299 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::operator-=(const Tmat4 &m)"); 00300 00301 this->v[0] -= m.v[0]; 00302 this->v[1] -= m.v[1]; 00303 this->v[2] -= m.v[2]; 00304 this->v[3] -= m.v[3]; 00305 return *this; 00306 } 00307 00309 template <class DT> 00310 inline const Tmat4<DT> &Tmat4<DT>::operator*=(const DT d) 00311 { 00312 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::operator*=(const DT d)"); 00313 00314 this->v[0] *= d; 00315 this->v[1] *= d; 00316 this->v[2] *= d; 00317 this->v[3] *= d; 00318 return *this; 00319 } 00320 00322 template <class DT> 00323 inline const Tmat4<DT> &Tmat4<DT>::operator/=(const DT d) 00324 { 00325 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::operator/=(const DT d)"); 00326 ML_TRY 00327 { 00328 this->v[0] /= d; 00329 this->v[1] /= d; 00330 this->v[2] /= d; 00331 this->v[3] /= d; 00332 } 00333 ML_CATCH_RETHROW; 00334 return *this; 00335 } 00336 00338 template <class DT> 00339 inline const Tmat4<DT> &Tmat4<DT>::apply(MLDblFuncPtr fct) 00340 { 00341 ML_TRACE_IN_TIME_CRITICAL("Tmat4<DT>::apply(MLDblFuncPtr fct)"); 00342 00343 this->v[0].apply(fct); 00344 this->v[1].apply(fct); 00345 this->v[2].apply(fct); 00346 this->v[3].apply(fct); 00347 return *this; 00348 } 00350 00351 //--------------------------------------------------------------- 00353 00354 //--------------------------------------------------------------- 00356 #define _ML_MAT4_RC(i, j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + \ 00357 a[i][2]*b[2][j] + a[i][3]*b[3][j] 00358 00360 template <class DT> 00361 inline Tmat4<DT> operator*(const Tmat4<DT> &a, const Tmat4<DT> &b) 00362 { 00363 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator*(const Tmat4<DT> &a, const Tmat4<DT> &b)"); 00364 00365 return Tmat4<DT>( 00366 Tvec4<DT>(_ML_MAT4_RC(0,0), _ML_MAT4_RC(0,1), _ML_MAT4_RC(0,2), _ML_MAT4_RC(0,3)), 00367 Tvec4<DT>(_ML_MAT4_RC(1,0), _ML_MAT4_RC(1,1), _ML_MAT4_RC(1,2), _ML_MAT4_RC(1,3)), 00368 Tvec4<DT>(_ML_MAT4_RC(2,0), _ML_MAT4_RC(2,1), _ML_MAT4_RC(2,2), _ML_MAT4_RC(2,3)), 00369 Tvec4<DT>(_ML_MAT4_RC(3,0), _ML_MAT4_RC(3,1), _ML_MAT4_RC(3,2), _ML_MAT4_RC(3,3)) 00370 ); 00371 } 00372 #undef _ML_MAT4_RC 00373 00374 00376 template <class DT> 00377 inline bool operator==(const Tmat4<DT> &a, const Tmat4<DT> &b) 00378 { 00379 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator==(const Tmat4<DT> &a, const Tmat4<DT> &b)"); 00380 00381 return ((a[0] == b[0]) && 00382 (a[1] == b[1]) && 00383 (a[2] == b[2]) && 00384 (a[3] == b[3])); 00385 } 00386 00388 template <class DT> 00389 inline bool operator!=(const Tmat4<DT>& a, const Tmat4<DT>& b) 00390 { 00391 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator!=(const Tmat4<DT> &a, const Tmat4<DT> &b)"); 00392 00393 return !(a == b); 00394 } 00396 00397 00398 //--------------------------------------------------------------- 00400 00401 //--------------------------------------------------------------- 00403 template <class DT> 00404 inline Tmat4<DT> operator-(const Tmat4<DT> &a) 00405 { 00406 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator-(const Tmat4<DT> &a)"); 00407 00408 return Tmat4<DT>(a) *= static_cast<DT>(-1.0); 00409 } 00410 00412 template <class DT> 00413 inline Tmat4<DT> operator+(const Tmat4<DT> &a, const Tmat4<DT> &b) 00414 { 00415 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator+(const Tmat4<DT> &a, const Tmat4<DT> &b)"); 00416 00417 return Tmat4<DT>(a) += b; 00418 } 00419 00421 template <class DT> 00422 inline Tmat4<DT> operator-(const Tmat4<DT> &a, const Tmat4<DT> &b) 00423 { 00424 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator-(const Tmat4<DT> &a, const Tmat4<DT> &b)"); 00425 00426 return Tmat4<DT>(a) -= b; 00427 } 00428 00430 template <class DT> 00431 inline Tmat4<DT> operator*(const Tmat4<DT> &a, const DT d) 00432 { 00433 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator*(const Tmat4<DT> &a, const DT d)"); 00434 00435 return Tmat4<DT>(a) *= d; 00436 } 00437 00439 template <class DT> 00440 inline Tmat4<DT> operator*(const DT d, const Tmat4<DT> &a) 00441 { 00442 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator*(const DT d, const Tmat4<DT> &a)"); 00443 00444 return Tmat4<DT>(a) *= d; 00445 } 00446 00449 template <class DT> 00450 inline Tmat4<DT> operator/(const Tmat4<DT> &a, const DT d) 00451 { 00452 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: operator/(const Tmat4<DT> &a, const DT d)"); 00453 00454 return Tmat4<DT>(a) /= d; 00455 } 00457 00458 00459 //-------------------------------------------------------------------- 00460 // 00462 00463 // 00464 //-------------------------------------------------------------------- 00465 00466 //-------------------------------------------------------------------- 00468 //-------------------------------------------------------------------- 00469 template <class DT> 00470 inline Tmat4<DT>::Tmat4(const Tvec3<DT> &n0, const Tvec3<DT> &n1, const Tvec3<DT> &n2, const Tvec3<DT> &t) 00471 { 00472 ML_TRACE_IN("Tmat4<DT>::Tmat4(const Tvec3<DT> &n0, ..., const Tvec3<DT> &t)"); 00473 00474 this->v[0][0]=n0[0]; 00475 this->v[1][0]=n0[1]; 00476 this->v[2][0]=n0[2]; 00477 00478 this->v[0][1]=n1[0]; 00479 this->v[1][1]=n1[1]; 00480 this->v[2][1]=n1[2]; 00481 00482 this->v[0][2]=n2[0]; 00483 this->v[1][2]=n2[1]; 00484 this->v[2][2]=n2[2]; 00485 00486 this->v[0][3]=t[0]; 00487 this->v[1][3]=t[1]; 00488 this->v[2][3]=t[2]; 00489 00490 this->v[3][0]=0; 00491 this->v[3][1]=0; 00492 this->v[3][2]=0; 00493 this->v[3][3]=1; 00494 } 00495 00496 //-------------------------------------------------------------------- 00498 //-------------------------------------------------------------------- 00499 template <class DT> 00500 Tmat4<DT>::Tmat4(const double in00, const double in01, const double in02, const double in03, 00501 const double in10, const double in11, const double in12, const double in13, 00502 const double in20, const double in21, const double in22, const double in23, 00503 const double in30, const double in31, const double in32, const double in33) 00504 { 00505 ML_TRACE_IN("Tmat4<DT>::Tmat4(const double in00, ..., const double in33)"); 00506 00507 this->v[0][0]=static_cast<DT>(in00); this->v[0][1]=static_cast<DT>(in01); this->v[0][2]=static_cast<DT>(in02); this->v[0][3]=static_cast<DT>(in03); 00508 this->v[1][0]=static_cast<DT>(in10); this->v[1][1]=static_cast<DT>(in11); this->v[1][2]=static_cast<DT>(in12); this->v[1][3]=static_cast<DT>(in13); 00509 this->v[2][0]=static_cast<DT>(in20); this->v[2][1]=static_cast<DT>(in21); this->v[2][2]=static_cast<DT>(in22); this->v[2][3]=static_cast<DT>(in23); 00510 this->v[3][0]=static_cast<DT>(in30); this->v[3][1]=static_cast<DT>(in31); this->v[3][2]=static_cast<DT>(in32); this->v[3][3]=static_cast<DT>(in33); 00511 } 00512 00513 //-------------------------------------------------------------------- 00515 //-------------------------------------------------------------------- 00516 template <class DT> 00517 void Tmat4<DT>::setValues(const float mat[16]) 00518 { 00519 ML_TRACE_IN( "Tmat4::setValues( )" ); 00520 ML_TRY 00521 { 00522 this->v[0][0] = mat[ 0]; this->v[0][1] = mat[ 1]; this->v[0][2] = mat[ 2]; this->v[0][3] = mat[ 3]; 00523 this->v[1][0] = mat[ 4]; this->v[1][1] = mat[ 5]; this->v[1][2] = mat[ 6]; this->v[1][3] = mat[ 7]; 00524 this->v[2][0] = mat[ 8]; this->v[2][1] = mat[ 9]; this->v[2][2] = mat[10]; this->v[2][3] = mat[11]; 00525 this->v[3][0] = mat[12]; this->v[3][1] = mat[13]; this->v[3][2] = mat[14]; this->v[3][3] = mat[15]; 00526 } 00527 ML_CATCH_RETHROW; 00528 } 00529 00530 //-------------------------------------------------------------------- 00534 //-------------------------------------------------------------------- 00535 template <class DT> 00536 void Tmat4<DT>::getValues(float mat[16]) const 00537 { 00538 ML_TRACE_IN( "Tmat4::setValues( )" ); 00539 ML_TRY 00540 { 00541 mat[ 0] = static_cast<float>(this->v[0][0]); mat[ 1] = static_cast<float>(this->v[0][1]); mat[ 2] = static_cast<float>(this->v[0][2]); mat[ 3] = static_cast<float>(this->v[0][3]); 00542 mat[ 4] = static_cast<float>(this->v[1][0]); mat[ 5] = static_cast<float>(this->v[1][1]); mat[ 6] = static_cast<float>(this->v[1][2]); mat[ 7] = static_cast<float>(this->v[1][3]); 00543 mat[ 8] = static_cast<float>(this->v[2][0]); mat[ 9] = static_cast<float>(this->v[2][1]); mat[10] = static_cast<float>(this->v[2][2]); mat[11] = static_cast<float>(this->v[2][3]); 00544 mat[12] = static_cast<float>(this->v[3][0]); mat[13] = static_cast<float>(this->v[3][1]); mat[14] = static_cast<float>(this->v[3][2]); mat[15] = static_cast<float>(this->v[3][3]); 00545 } 00546 ML_CATCH_RETHROW; 00547 } 00548 00549 //-------------------------------------------------------------------- 00551 //-------------------------------------------------------------------- 00552 template <class DT> 00553 void Tmat4<DT>::setValues(const double mat[16]) 00554 { 00555 ML_TRACE_IN( "Tmat4::setValues( )" ); 00556 ML_TRY 00557 { 00558 this->v[0][0] = static_cast<DT>(mat[ 0]); this->v[0][1] = static_cast<DT>(mat[ 1]); this->v[0][2] = static_cast<DT>(mat[ 2]); this->v[0][3] = static_cast<DT>(mat[ 3]); 00559 this->v[1][0] = static_cast<DT>(mat[ 4]); this->v[1][1] = static_cast<DT>(mat[ 5]); this->v[1][2] = static_cast<DT>(mat[ 6]); this->v[1][3] = static_cast<DT>(mat[ 7]); 00560 this->v[2][0] = static_cast<DT>(mat[ 8]); this->v[2][1] = static_cast<DT>(mat[ 9]); this->v[2][2] = static_cast<DT>(mat[10]); this->v[2][3] = static_cast<DT>(mat[11]); 00561 this->v[3][0] = static_cast<DT>(mat[12]); this->v[3][1] = static_cast<DT>(mat[13]); this->v[3][2] = static_cast<DT>(mat[14]); this->v[3][3] = static_cast<DT>(mat[15]); 00562 } 00563 ML_CATCH_RETHROW; 00564 } 00565 00566 //-------------------------------------------------------------------- 00570 //-------------------------------------------------------------------- 00571 template <class DT> 00572 void Tmat4<DT>::getValues(double mat[16]) const 00573 { 00574 ML_TRACE_IN( "Tmat4::setValues( )" ); 00575 ML_TRY 00576 { 00577 mat[ 0] = static_cast<double>(this->v[0][0]); mat[ 1] = static_cast<double>(this->v[0][1]); mat[ 2] = static_cast<double>(this->v[0][2]); mat[ 3] = static_cast<double>(this->v[0][3]); 00578 mat[ 4] = static_cast<double>(this->v[1][0]); mat[ 5] = static_cast<double>(this->v[1][1]); mat[ 6] = static_cast<double>(this->v[1][2]); mat[ 7] = static_cast<double>(this->v[1][3]); 00579 mat[ 8] = static_cast<double>(this->v[2][0]); mat[ 9] = static_cast<double>(this->v[2][1]); mat[10] = static_cast<double>(this->v[2][2]); mat[11] = static_cast<double>(this->v[2][3]); 00580 mat[12] = static_cast<double>(this->v[3][0]); mat[13] = static_cast<double>(this->v[3][1]); mat[14] = static_cast<double>(this->v[3][2]); mat[15] = static_cast<double>(this->v[3][3]); 00581 } 00582 ML_CATCH_RETHROW; 00583 } 00584 00585 //-------------------------------------------------------------------- 00587 //-------------------------------------------------------------------- 00588 template <class DT> 00589 void Tmat4<DT>::setScaleMatrix(const DT scale) 00590 { 00591 ML_TRACE_IN( "Tmat4::setScaleMatrix(const DT scale)" ); 00592 00593 this->v[0][0] = scale; this->v[0][1] = 0; this->v[0][2] = 0; this->v[0][3] = 0; 00594 this->v[1][0] = 0; this->v[1][1] = scale; this->v[1][2] = 0; this->v[1][3] = 0; 00595 this->v[2][0] = 0; this->v[2][1] = 0; this->v[2][2] = scale; this->v[2][3] = 0; 00596 this->v[3][0] = 0; this->v[3][1] = 0; this->v[3][2] = 0; this->v[3][3] = scale; 00597 } 00598 00599 //-------------------------------------------------------------------- 00601 //-------------------------------------------------------------------- 00602 template <class DT> 00603 inline DT Tmat4<DT>::det3(const DT A, const DT B, const DT C, const DT D, const DT E, const DT F, const DT G, const DT H, const DT I) const 00604 { 00605 ML_TRACE_IN_TIME_CRITICAL("Tmat4::det3()"); 00606 00607 /* Determinant of 3x3 matrix with given entries */ 00608 return ((A*E*I + B*F*G + C*D*H) - (A*F*H + B*D*I + C*E*G)); 00609 } 00610 00611 //-------------------------------------------------------------------- 00613 //-------------------------------------------------------------------- 00614 template <class DT> 00615 DT Tmat4<DT>::determinantLower3(const int col1, const int col2, const int col3) const 00616 { 00617 ML_TRACE_IN_TIME_CRITICAL("Tmat4::determinantLower3()"); 00618 00619 /* Determinant of 3x3 matrix with given entries */ 00620 return det3(this->v[1][col1], this->v[1][col2], this->v[1][col3], 00621 this->v[2][col1], this->v[2][col2], this->v[2][col3], 00622 this->v[3][col1], this->v[3][col2], this->v[3][col3]); 00623 } 00624 00625 //-------------------------------------------------------------------- 00627 //-------------------------------------------------------------------- 00628 template <class DT> 00629 inline DT Tmat4<DT>::det() const 00630 { 00631 ML_TRACE_IN("Tmat4::det()"); 00632 00633 DT determ=0; 00634 ML_TRY 00635 { 00636 determ = ( this->v[0][0] * determinantLower3(1, 2, 3) 00637 - this->v[0][1] * determinantLower3(0, 2, 3) 00638 + this->v[0][2] * determinantLower3(0, 1, 3) 00639 - this->v[0][3] * determinantLower3(0, 1, 2)); 00640 } 00641 ML_CATCH_RETHROW; 00642 return determ; 00643 } 00644 00645 //-------------------------------------------------------------------- 00647 //-------------------------------------------------------------------- 00648 template <class DT> 00649 inline Tmat4<DT> Tmat4<DT>::transpose() const 00650 { 00651 ML_TRACE_IN_TIME_CRITICAL("Tmat4::transpose()"); 00652 00653 return Tmat4<DT>(this->v[0][0], this->v[1][0], this->v[2][0], this->v[3][0], 00654 this->v[0][1], this->v[1][1], this->v[2][1], this->v[3][1], 00655 this->v[0][2], this->v[1][2], this->v[2][2], this->v[3][2], 00656 this->v[0][3], this->v[1][3], this->v[2][3], this->v[3][3]); 00657 } 00658 00659 //-------------------------------------------------------------------- 00661 //-------------------------------------------------------------------- 00662 template <class DT> 00663 inline Tmat4<DT> Tmat4<DT>::getIdentity() 00664 { 00665 ML_TRACE_IN_TIME_CRITICAL("Tmat4::getIdentity()"); 00666 00667 return Tmat4<DT>(1, 0, 0, 0, 00668 0, 1, 0, 0, 00669 0, 0, 1, 0, 00670 0, 0, 0, 1); 00671 } 00672 00673 //-------------------------------------------------------------------- 00676 //-------------------------------------------------------------------- 00677 template <class DT> 00678 Tmat4<DT> identity3D() 00679 { 00680 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: identity3D()"); 00681 00682 return Tmat4<DT>::getIdentity(); 00683 } 00684 00685 //-------------------------------------------------------------------- 00689 //-------------------------------------------------------------------- 00690 template <class DT> 00691 inline Tmat4<DT> translation3D(const Tvec3<DT> &v) 00692 { 00693 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: translation3D(const Tvec3<DT> &v)"); 00694 00695 return Tmat4<DT>(Tvec4<DT>(1.0, 0.0, 0.0, v[0]), 00696 Tvec4<DT>(0.0, 1.0, 0.0, v[1]), 00697 Tvec4<DT>(0.0, 0.0, 1.0, v[2]), 00698 Tvec4<DT>(0.0, 0.0, 0.0, 1.0)); 00699 } 00700 00701 //-------------------------------------------------------------------- 00705 //------------------------------------------------------------------- 00706 template <class DT> 00707 Tmat4<DT> rotation3D(Tvec3<DT> Axis, const DT angleRad) 00708 { 00709 ML_TRACE_IN("mlMatrix4.h: rotation3D(Tvec3<DT> Axis, const DT angleRad)"); 00710 00711 Tmat4<DT> retVal; 00712 ML_TRY 00713 { 00714 const DT c = cos(angleRad); 00715 const DT s = sin(angleRad); 00716 const DT t = 1.0 - c; 00717 00718 Axis.normalize(); 00719 retVal = Tmat4<DT>(Tvec4<DT>(t * Axis[0] * Axis[0] + c, 00720 t * Axis[0] * Axis[1] - s * Axis[2], 00721 t * Axis[0] * Axis[2] + s * Axis[1], 00722 0.0), 00723 Tvec4<DT>(t * Axis[0] * Axis[1] + s * Axis[2], 00724 t * Axis[1] * Axis[1] + c, 00725 t * Axis[1] * Axis[2] - s * Axis[0], 00726 0.0), 00727 Tvec4<DT>(t * Axis[0] * Axis[2] - s * Axis[1], 00728 t * Axis[1] * Axis[2] + s * Axis[0], 00729 t * Axis[2] * Axis[2] + c, 00730 0.0), 00731 Tvec4<DT>(0.0, 0.0, 0.0, 1.0)); 00732 } 00733 ML_CATCH_RETHROW; 00734 return retVal; 00735 } 00736 00737 //-------------------------------------------------------------------- 00739 //-------------------------------------------------------------------- 00740 template <class DT> 00741 inline Tmat4<DT> scaling3D(const Tvec3<DT> &scaleVector) 00742 { 00743 ML_TRACE_IN_TIME_CRITICAL("mlMatrix4.h: scaling3D(const Tvec3<DT> &scaleVector)"); 00744 00745 return Tmat4<DT>(Tvec4<DT>(scaleVector[0], 0.0, 0.0, 0.0), 00746 Tvec4<DT>(0.0, scaleVector[1], 0.0, 0.0), 00747 Tvec4<DT>(0.0, 0.0, scaleVector[2], 0.0), 00748 Tvec4<DT>(0.0, 0.0, 0.0, 1.0)); 00749 } 00750 00751 //-------------------------------------------------------------------- 00755 //-------------------------------------------------------------------- 00756 template <class DT> 00757 inline Tmat4<DT> perspective3D(const DT d) 00758 { 00759 ML_TRACE_IN( "perspective3D( )" ); 00760 00761 Tmat4<DT> retVal; 00762 ML_TRY 00763 { 00764 ML_CHECK_FLOAT_THROW(d); 00765 00766 retVal[0][0] = 1.0; 00767 retVal[1][1] = 1.0; 00768 retVal[2][2] = 1.0; 00769 retVal[3][2] = 1.0/d; 00770 retVal[3][3] = 1.0; 00771 } 00772 ML_CATCH_RETHROW; 00773 return retVal; 00774 } 00775 00776 00777 //-------------------------------------------------------------------- 00785 //-------------------------------------------------------------------- 00786 template <class DT> 00787 Tmat4<DT> Tmat4<DT>::inverse(bool* isInvertible) const 00788 { 00789 ML_TRACE_IN( "Tmat4<DT>::inverse( )" ); 00790 00791 Tmat4<DT> retVal; 00792 ML_TRY 00793 { 00794 // Epsilon for comparison with 0 in inversion process. 00795 static const DT Epsilon = static_cast<DT>(10e-14); 00796 00797 // Use helper function from tools to invert the matrix. 00798 retVal = MLInverseMatHelper(*this, 00799 isInvertible, 00800 Epsilon, 00801 "Tmat4<DT> Tmat4<DT>::inverse(bool* isInvertible) const, matrix not invertable", 00802 getIdentity(), 00803 4); 00804 } 00805 ML_CATCH_RETHROW; 00806 return retVal; 00807 } 00809 00810 00811 //----------------------------------------------------------------------------------- 00813 00814 //----------------------------------------------------------------------------------- 00815 00817 typedef Tmat4<MLfloat> Matrix4f; 00819 typedef Tmat4<MLdouble> Matrix4d; 00821 typedef Tmat4<MLldouble> Matrix4ld; 00823 typedef Tmat4<MLdouble> Matrix4; 00825 00826 00827 #ifdef ML_DEPRECATED 00828 00830 00831 00835 ML_DEPRECATED typedef Tmat4<MLfloat> matf4; 00839 ML_DEPRECATED typedef Tmat4<MLdouble> matd4; 00843 ML_DEPRECATED typedef Tmat4<MLldouble> matld4; 00847 ML_DEPRECATED typedef Tmat4<MLdouble> mat4; 00849 00850 00851 #endif // ML_DEPRECATED 00852 00853 00854 00855 ML_LA_END_NAMESPACE 00856 00857 namespace std 00858 { 00859 //------------------------------------------------------------------- 00861 //------------------------------------------------------------------- 00862 template <class DT> 00863 inline std::ostream &operator<<(std::ostream &os, const ML_LA_NAMESPACE::Tmat4<DT> &m) 00864 { 00865 return os << m[0] << '\n' << m[1] << '\n' << m[2] << '\n' << m[3]; 00866 } 00867 00868 // Input from stream. 00869 template <class DT> 00870 inline std::istream &operator>>(std::istream &is, ML_LA_NAMESPACE::Tmat4<DT> &m) 00871 { 00872 ML_LA_NAMESPACE::Tmat4<DT> m_tmp; 00873 is >> m_tmp[0] >> m_tmp[1] >> m_tmp[2] >> m_tmp[3]; 00874 if (is){ m = m_tmp; } 00875 return is; 00876 } 00878 } 00879 00880 #endif // __mlMatrix4_H 00881 00882 00883 00884