ML Reference
MeVis/Foundation/Sources/MLLinearAlgebra/mlMatrix4.h
Go to the documentation of this file.
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