Wm4Matrix4.inl

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.1 (2006/08/19)
00016 
00017 namespace Wm4
00018 {
00019 //----------------------------------------------------------------------------
00020 template <class Real>
00021 Matrix4<Real>::Matrix4 (bool bZero)
00022 {
00023     if (bZero)
00024     {
00025         MakeZero();
00026     }
00027     else
00028     {
00029         MakeIdentity();
00030     }
00031 }
00032 //----------------------------------------------------------------------------
00033 template <class Real>
00034 Matrix4<Real>::Matrix4 (const Matrix4& rkM)
00035 {
00036     m_afEntry[ 0] = rkM.m_afEntry[ 0];
00037     m_afEntry[ 1] = rkM.m_afEntry[ 1];
00038     m_afEntry[ 2] = rkM.m_afEntry[ 2];
00039     m_afEntry[ 3] = rkM.m_afEntry[ 3];
00040     m_afEntry[ 4] = rkM.m_afEntry[ 4];
00041     m_afEntry[ 5] = rkM.m_afEntry[ 5];
00042     m_afEntry[ 6] = rkM.m_afEntry[ 6];
00043     m_afEntry[ 7] = rkM.m_afEntry[ 7];
00044     m_afEntry[ 8] = rkM.m_afEntry[ 8];
00045     m_afEntry[ 9] = rkM.m_afEntry[ 9];
00046     m_afEntry[10] = rkM.m_afEntry[10];
00047     m_afEntry[11] = rkM.m_afEntry[11];
00048     m_afEntry[12] = rkM.m_afEntry[12];
00049     m_afEntry[13] = rkM.m_afEntry[13];
00050     m_afEntry[14] = rkM.m_afEntry[14];
00051     m_afEntry[15] = rkM.m_afEntry[15];
00052 }
00053 //----------------------------------------------------------------------------
00054 template <class Real>
00055 Matrix4<Real>::Matrix4 (Real fM00, Real fM01, Real fM02, Real fM03,
00056     Real fM10, Real fM11, Real fM12, Real fM13, Real fM20, Real fM21,
00057     Real fM22, Real fM23, Real fM30, Real fM31, Real fM32, Real fM33)
00058 {
00059     m_afEntry[ 0] = fM00;
00060     m_afEntry[ 1] = fM01;
00061     m_afEntry[ 2] = fM02;
00062     m_afEntry[ 3] = fM03;
00063     m_afEntry[ 4] = fM10;
00064     m_afEntry[ 5] = fM11;
00065     m_afEntry[ 6] = fM12;
00066     m_afEntry[ 7] = fM13;
00067     m_afEntry[ 8] = fM20;
00068     m_afEntry[ 9] = fM21;
00069     m_afEntry[10] = fM22;
00070     m_afEntry[11] = fM23;
00071     m_afEntry[12] = fM30;
00072     m_afEntry[13] = fM31;
00073     m_afEntry[14] = fM32;
00074     m_afEntry[15] = fM33;
00075 }
00076 //----------------------------------------------------------------------------
00077 template <class Real>
00078 Matrix4<Real>::Matrix4 (const Real afEntry[16], bool bRowMajor)
00079 {
00080     if (bRowMajor)
00081     {
00082         m_afEntry[ 0] = afEntry[ 0];
00083         m_afEntry[ 1] = afEntry[ 1];
00084         m_afEntry[ 2] = afEntry[ 2];
00085         m_afEntry[ 3] = afEntry[ 3];
00086         m_afEntry[ 4] = afEntry[ 4];
00087         m_afEntry[ 5] = afEntry[ 5];
00088         m_afEntry[ 6] = afEntry[ 6];
00089         m_afEntry[ 7] = afEntry[ 7];
00090         m_afEntry[ 8] = afEntry[ 8];
00091         m_afEntry[ 9] = afEntry[ 9];
00092         m_afEntry[10] = afEntry[10];
00093         m_afEntry[11] = afEntry[11];
00094         m_afEntry[12] = afEntry[12];
00095         m_afEntry[13] = afEntry[13];
00096         m_afEntry[14] = afEntry[14];
00097         m_afEntry[15] = afEntry[15];
00098     }
00099     else
00100     {
00101         m_afEntry[ 0] = afEntry[ 0];
00102         m_afEntry[ 1] = afEntry[ 4];
00103         m_afEntry[ 2] = afEntry[ 8];
00104         m_afEntry[ 3] = afEntry[12];
00105         m_afEntry[ 4] = afEntry[ 1];
00106         m_afEntry[ 5] = afEntry[ 5];
00107         m_afEntry[ 6] = afEntry[ 9];
00108         m_afEntry[ 7] = afEntry[13];
00109         m_afEntry[ 8] = afEntry[ 2];
00110         m_afEntry[ 9] = afEntry[ 6];
00111         m_afEntry[10] = afEntry[10];
00112         m_afEntry[11] = afEntry[14];
00113         m_afEntry[12] = afEntry[ 3];
00114         m_afEntry[13] = afEntry[ 7];
00115         m_afEntry[14] = afEntry[11];
00116         m_afEntry[15] = afEntry[15];
00117     }
00118 }
00119 //----------------------------------------------------------------------------
00120 template <class Real>
00121 Matrix4<Real>::operator const Real* () const
00122 {
00123     return m_afEntry;
00124 }
00125 //----------------------------------------------------------------------------
00126 template <class Real>
00127 Matrix4<Real>::operator Real* ()
00128 {
00129     return m_afEntry;
00130 }
00131 //----------------------------------------------------------------------------
00132 template <class Real>
00133 const Real* Matrix4<Real>::operator[] (int iRow) const
00134 {
00135     return &m_afEntry[4*iRow];
00136 }
00137 //----------------------------------------------------------------------------
00138 template <class Real>
00139 Real* Matrix4<Real>::operator[] (int iRow)
00140 {
00141     return &m_afEntry[4*iRow];
00142 }
00143 //----------------------------------------------------------------------------
00144 template <class Real>
00145 Real Matrix4<Real>::operator() (int iRow, int iCol) const
00146 {
00147     return m_afEntry[iCol+4*iRow];
00148 }
00149 //----------------------------------------------------------------------------
00150 template <class Real>
00151 Real& Matrix4<Real>::operator() (int iRow, int iCol)
00152 {
00153     return m_afEntry[iCol+4*iRow];
00154 }
00155 //----------------------------------------------------------------------------
00156 template <class Real>
00157 void Matrix4<Real>::MakeZero ()
00158 {
00159     m_afEntry[ 0] = (Real)0.0;
00160     m_afEntry[ 1] = (Real)0.0;
00161     m_afEntry[ 2] = (Real)0.0;
00162     m_afEntry[ 3] = (Real)0.0;
00163     m_afEntry[ 4] = (Real)0.0;
00164     m_afEntry[ 5] = (Real)0.0;
00165     m_afEntry[ 6] = (Real)0.0;
00166     m_afEntry[ 7] = (Real)0.0;
00167     m_afEntry[ 8] = (Real)0.0;
00168     m_afEntry[ 9] = (Real)0.0;
00169     m_afEntry[10] = (Real)0.0;
00170     m_afEntry[11] = (Real)0.0;
00171     m_afEntry[12] = (Real)0.0;
00172     m_afEntry[13] = (Real)0.0;
00173     m_afEntry[14] = (Real)0.0;
00174     m_afEntry[15] = (Real)0.0;
00175 }
00176 //----------------------------------------------------------------------------
00177 template <class Real>
00178 void Matrix4<Real>::MakeIdentity ()
00179 {
00180     m_afEntry[ 0] = (Real)1.0;
00181     m_afEntry[ 1] = (Real)0.0;
00182     m_afEntry[ 2] = (Real)0.0;
00183     m_afEntry[ 3] = (Real)0.0;
00184     m_afEntry[ 4] = (Real)0.0;
00185     m_afEntry[ 5] = (Real)1.0;
00186     m_afEntry[ 6] = (Real)0.0;
00187     m_afEntry[ 7] = (Real)0.0;
00188     m_afEntry[ 8] = (Real)0.0;
00189     m_afEntry[ 9] = (Real)0.0;
00190     m_afEntry[10] = (Real)1.0;
00191     m_afEntry[11] = (Real)0.0;
00192     m_afEntry[12] = (Real)0.0;
00193     m_afEntry[13] = (Real)0.0;
00194     m_afEntry[14] = (Real)0.0;
00195     m_afEntry[15] = (Real)1.0;
00196 }
00197 //----------------------------------------------------------------------------
00198 template <class Real>
00199 void Matrix4<Real>::SetRow (int iRow, const Vector4<Real>& rkV)
00200 {
00201     int i0 = 4*iRow, i1 = i0+1, i2 = i1+1, i3 = i2+1;
00202     m_afEntry[i0] = rkV[0];
00203     m_afEntry[i1] = rkV[1];
00204     m_afEntry[i2] = rkV[2];
00205     m_afEntry[i3] = rkV[3];
00206 }
00207 //----------------------------------------------------------------------------
00208 template <class Real>
00209 Vector4<Real> Matrix4<Real>::GetRow (int iRow) const
00210 {
00211     int i0 = 4*iRow, i1 = i0+1, i2 = i1+1, i3 = i2+1;
00212     return Vector4<Real>(m_afEntry[i0],m_afEntry[i1],m_afEntry[i2],
00213         m_afEntry[i3]);
00214 }
00215 //----------------------------------------------------------------------------
00216 template <class Real>
00217 void Matrix4<Real>::SetColumn (int iCol, const Vector4<Real>& rkV)
00218 {
00219     m_afEntry[iCol] = rkV[0];
00220     m_afEntry[iCol+4] = rkV[1];
00221     m_afEntry[iCol+8] = rkV[2];
00222     m_afEntry[iCol+12] = rkV[3];
00223 }
00224 //----------------------------------------------------------------------------
00225 template <class Real>
00226 Vector4<Real> Matrix4<Real>::GetColumn (int iCol) const
00227 {
00228     return Vector4<Real>(m_afEntry[iCol],m_afEntry[iCol+4],m_afEntry[iCol+8],
00229         m_afEntry[iCol+12]);
00230 }
00231 //----------------------------------------------------------------------------
00232 template <class Real>
00233 void Matrix4<Real>::GetColumnMajor (Real* afCMajor) const
00234 {
00235     afCMajor[ 0] = m_afEntry[ 0];
00236     afCMajor[ 1] = m_afEntry[ 4];
00237     afCMajor[ 2] = m_afEntry[ 8];
00238     afCMajor[ 3] = m_afEntry[12];
00239     afCMajor[ 4] = m_afEntry[ 1];
00240     afCMajor[ 5] = m_afEntry[ 5];
00241     afCMajor[ 6] = m_afEntry[ 9];
00242     afCMajor[ 7] = m_afEntry[13];
00243     afCMajor[ 8] = m_afEntry[ 2];
00244     afCMajor[ 9] = m_afEntry[ 6];
00245     afCMajor[10] = m_afEntry[10];
00246     afCMajor[11] = m_afEntry[14];
00247     afCMajor[12] = m_afEntry[ 3];
00248     afCMajor[13] = m_afEntry[ 7];
00249     afCMajor[14] = m_afEntry[11];
00250     afCMajor[15] = m_afEntry[15];
00251 }
00252 //----------------------------------------------------------------------------
00253 template <class Real>
00254 Matrix4<Real>& Matrix4<Real>::operator= (const Matrix4& rkM)
00255 {
00256     m_afEntry[ 0] = rkM.m_afEntry[ 0];
00257     m_afEntry[ 1] = rkM.m_afEntry[ 1];
00258     m_afEntry[ 2] = rkM.m_afEntry[ 2];
00259     m_afEntry[ 3] = rkM.m_afEntry[ 3];
00260     m_afEntry[ 4] = rkM.m_afEntry[ 4];
00261     m_afEntry[ 5] = rkM.m_afEntry[ 5];
00262     m_afEntry[ 6] = rkM.m_afEntry[ 6];
00263     m_afEntry[ 7] = rkM.m_afEntry[ 7];
00264     m_afEntry[ 8] = rkM.m_afEntry[ 8];
00265     m_afEntry[ 9] = rkM.m_afEntry[ 9];
00266     m_afEntry[10] = rkM.m_afEntry[10];
00267     m_afEntry[11] = rkM.m_afEntry[11];
00268     m_afEntry[12] = rkM.m_afEntry[12];
00269     m_afEntry[13] = rkM.m_afEntry[13];
00270     m_afEntry[14] = rkM.m_afEntry[14];
00271     m_afEntry[15] = rkM.m_afEntry[15];
00272     return *this;
00273 }
00274 //----------------------------------------------------------------------------
00275 template <class Real>
00276 int Matrix4<Real>::CompareArrays (const Matrix4& rkM) const
00277 {
00278     return memcmp(m_afEntry,rkM.m_afEntry,16*sizeof(Real));
00279 }
00280 //----------------------------------------------------------------------------
00281 template <class Real>
00282 bool Matrix4<Real>::operator== (const Matrix4& rkM) const
00283 {
00284     return CompareArrays(rkM) == 0;
00285 }
00286 //----------------------------------------------------------------------------
00287 template <class Real>
00288 bool Matrix4<Real>::operator!= (const Matrix4& rkM) const
00289 {
00290     return CompareArrays(rkM) != 0;
00291 }
00292 //----------------------------------------------------------------------------
00293 template <class Real>
00294 bool Matrix4<Real>::operator<  (const Matrix4& rkM) const
00295 {
00296     return CompareArrays(rkM) < 0;
00297 }
00298 //----------------------------------------------------------------------------
00299 template <class Real>
00300 bool Matrix4<Real>::operator<= (const Matrix4& rkM) const
00301 {
00302     return CompareArrays(rkM) <= 0;
00303 }
00304 //----------------------------------------------------------------------------
00305 template <class Real>
00306 bool Matrix4<Real>::operator>  (const Matrix4& rkM) const
00307 {
00308     return CompareArrays(rkM) > 0;
00309 }
00310 //----------------------------------------------------------------------------
00311 template <class Real>
00312 bool Matrix4<Real>::operator>= (const Matrix4& rkM) const
00313 {
00314     return CompareArrays(rkM) >= 0;
00315 }
00316 //----------------------------------------------------------------------------
00317 template <class Real>
00318 Matrix4<Real> Matrix4<Real>::operator+ (const Matrix4& rkM) const
00319 {
00320     return Matrix4<Real>(
00321         m_afEntry[ 0] + rkM.m_afEntry[ 0],
00322         m_afEntry[ 1] + rkM.m_afEntry[ 1],
00323         m_afEntry[ 2] + rkM.m_afEntry[ 2],
00324         m_afEntry[ 3] + rkM.m_afEntry[ 3],
00325         m_afEntry[ 4] + rkM.m_afEntry[ 4],
00326         m_afEntry[ 5] + rkM.m_afEntry[ 5],
00327         m_afEntry[ 6] + rkM.m_afEntry[ 6],
00328         m_afEntry[ 7] + rkM.m_afEntry[ 7],
00329         m_afEntry[ 8] + rkM.m_afEntry[ 8],
00330         m_afEntry[ 9] + rkM.m_afEntry[ 9],
00331         m_afEntry[10] + rkM.m_afEntry[10],
00332         m_afEntry[11] + rkM.m_afEntry[11],
00333         m_afEntry[12] + rkM.m_afEntry[12],
00334         m_afEntry[13] + rkM.m_afEntry[13],
00335         m_afEntry[14] + rkM.m_afEntry[14],
00336         m_afEntry[15] + rkM.m_afEntry[15]);
00337 }
00338 //----------------------------------------------------------------------------
00339 template <class Real>
00340 Matrix4<Real> Matrix4<Real>::operator- (const Matrix4& rkM) const
00341 {
00342     return Matrix4<Real>(
00343         m_afEntry[ 0] - rkM.m_afEntry[ 0],
00344         m_afEntry[ 1] - rkM.m_afEntry[ 1],
00345         m_afEntry[ 2] - rkM.m_afEntry[ 2],
00346         m_afEntry[ 3] - rkM.m_afEntry[ 3],
00347         m_afEntry[ 4] - rkM.m_afEntry[ 4],
00348         m_afEntry[ 5] - rkM.m_afEntry[ 5],
00349         m_afEntry[ 6] - rkM.m_afEntry[ 6],
00350         m_afEntry[ 7] - rkM.m_afEntry[ 7],
00351         m_afEntry[ 8] - rkM.m_afEntry[ 8],
00352         m_afEntry[ 9] - rkM.m_afEntry[ 9],
00353         m_afEntry[10] - rkM.m_afEntry[10],
00354         m_afEntry[11] - rkM.m_afEntry[11],
00355         m_afEntry[12] - rkM.m_afEntry[12],
00356         m_afEntry[13] - rkM.m_afEntry[13],
00357         m_afEntry[14] - rkM.m_afEntry[14],
00358         m_afEntry[15] - rkM.m_afEntry[15]);
00359 }
00360 //----------------------------------------------------------------------------
00361 template <class Real>
00362 Matrix4<Real> Matrix4<Real>::operator* (const Matrix4& rkM) const
00363 {
00364     return Matrix4<Real>(
00365         m_afEntry[ 0]*rkM.m_afEntry[ 0] +
00366         m_afEntry[ 1]*rkM.m_afEntry[ 4] +
00367         m_afEntry[ 2]*rkM.m_afEntry[ 8] +
00368         m_afEntry[ 3]*rkM.m_afEntry[12],
00369 
00370         m_afEntry[ 0]*rkM.m_afEntry[ 1] +
00371         m_afEntry[ 1]*rkM.m_afEntry[ 5] +
00372         m_afEntry[ 2]*rkM.m_afEntry[ 9] +
00373         m_afEntry[ 3]*rkM.m_afEntry[13],
00374 
00375         m_afEntry[ 0]*rkM.m_afEntry[ 2] +
00376         m_afEntry[ 1]*rkM.m_afEntry[ 6] +
00377         m_afEntry[ 2]*rkM.m_afEntry[10] +
00378         m_afEntry[ 3]*rkM.m_afEntry[14],
00379 
00380         m_afEntry[ 0]*rkM.m_afEntry[ 3] +
00381         m_afEntry[ 1]*rkM.m_afEntry[ 7] +
00382         m_afEntry[ 2]*rkM.m_afEntry[11] +
00383         m_afEntry[ 3]*rkM.m_afEntry[15],
00384 
00385         m_afEntry[ 4]*rkM.m_afEntry[ 0] +
00386         m_afEntry[ 5]*rkM.m_afEntry[ 4] +
00387         m_afEntry[ 6]*rkM.m_afEntry[ 8] +
00388         m_afEntry[ 7]*rkM.m_afEntry[12],
00389 
00390         m_afEntry[ 4]*rkM.m_afEntry[ 1] +
00391         m_afEntry[ 5]*rkM.m_afEntry[ 5] +
00392         m_afEntry[ 6]*rkM.m_afEntry[ 9] +
00393         m_afEntry[ 7]*rkM.m_afEntry[13],
00394 
00395         m_afEntry[ 4]*rkM.m_afEntry[ 2] +
00396         m_afEntry[ 5]*rkM.m_afEntry[ 6] +
00397         m_afEntry[ 6]*rkM.m_afEntry[10] +
00398         m_afEntry[ 7]*rkM.m_afEntry[14],
00399 
00400         m_afEntry[ 4]*rkM.m_afEntry[ 3] +
00401         m_afEntry[ 5]*rkM.m_afEntry[ 7] +
00402         m_afEntry[ 6]*rkM.m_afEntry[11] +
00403         m_afEntry[ 7]*rkM.m_afEntry[15],
00404 
00405         m_afEntry[ 8]*rkM.m_afEntry[ 0] +
00406         m_afEntry[ 9]*rkM.m_afEntry[ 4] +
00407         m_afEntry[10]*rkM.m_afEntry[ 8] +
00408         m_afEntry[11]*rkM.m_afEntry[12],
00409 
00410         m_afEntry[ 8]*rkM.m_afEntry[ 1] +
00411         m_afEntry[ 9]*rkM.m_afEntry[ 5] +
00412         m_afEntry[10]*rkM.m_afEntry[ 9] +
00413         m_afEntry[11]*rkM.m_afEntry[13],
00414 
00415         m_afEntry[ 8]*rkM.m_afEntry[ 2] +
00416         m_afEntry[ 9]*rkM.m_afEntry[ 6] +
00417         m_afEntry[10]*rkM.m_afEntry[10] +
00418         m_afEntry[11]*rkM.m_afEntry[14],
00419 
00420         m_afEntry[ 8]*rkM.m_afEntry[ 3] +
00421         m_afEntry[ 9]*rkM.m_afEntry[ 7] +
00422         m_afEntry[10]*rkM.m_afEntry[11] +
00423         m_afEntry[11]*rkM.m_afEntry[15],
00424 
00425         m_afEntry[12]*rkM.m_afEntry[ 0] +
00426         m_afEntry[13]*rkM.m_afEntry[ 4] +
00427         m_afEntry[14]*rkM.m_afEntry[ 8] +
00428         m_afEntry[15]*rkM.m_afEntry[12],
00429 
00430         m_afEntry[12]*rkM.m_afEntry[ 1] +
00431         m_afEntry[13]*rkM.m_afEntry[ 5] +
00432         m_afEntry[14]*rkM.m_afEntry[ 9] +
00433         m_afEntry[15]*rkM.m_afEntry[13],
00434 
00435         m_afEntry[12]*rkM.m_afEntry[ 2] +
00436         m_afEntry[13]*rkM.m_afEntry[ 6] +
00437         m_afEntry[14]*rkM.m_afEntry[10] +
00438         m_afEntry[15]*rkM.m_afEntry[14],
00439 
00440         m_afEntry[12]*rkM.m_afEntry[ 3] +
00441         m_afEntry[13]*rkM.m_afEntry[ 7] +
00442         m_afEntry[14]*rkM.m_afEntry[11] +
00443         m_afEntry[15]*rkM.m_afEntry[15]);
00444 }
00445 //----------------------------------------------------------------------------
00446 template <class Real>
00447 Matrix4<Real> Matrix4<Real>::operator* (Real fScalar) const
00448 {
00449     return Matrix4<Real>(
00450         fScalar*m_afEntry[ 0],
00451         fScalar*m_afEntry[ 1],
00452         fScalar*m_afEntry[ 2],
00453         fScalar*m_afEntry[ 3],
00454         fScalar*m_afEntry[ 4],
00455         fScalar*m_afEntry[ 5],
00456         fScalar*m_afEntry[ 6],
00457         fScalar*m_afEntry[ 7],
00458         fScalar*m_afEntry[ 8],
00459         fScalar*m_afEntry[ 9],
00460         fScalar*m_afEntry[10],
00461         fScalar*m_afEntry[11],
00462         fScalar*m_afEntry[12],
00463         fScalar*m_afEntry[13],
00464         fScalar*m_afEntry[14],
00465         fScalar*m_afEntry[15]);
00466 }
00467 //----------------------------------------------------------------------------
00468 template <class Real>
00469 Matrix4<Real> Matrix4<Real>::operator/ (Real fScalar) const
00470 {
00471     if (fScalar != (Real)0.0)
00472     {
00473         Real fInvScalar = ((Real)1.0)/fScalar;
00474         return Matrix4<Real>(
00475             fInvScalar*m_afEntry[ 0],
00476             fInvScalar*m_afEntry[ 1],
00477             fInvScalar*m_afEntry[ 2],
00478             fInvScalar*m_afEntry[ 3],
00479             fInvScalar*m_afEntry[ 4],
00480             fInvScalar*m_afEntry[ 5],
00481             fInvScalar*m_afEntry[ 6],
00482             fInvScalar*m_afEntry[ 7],
00483             fInvScalar*m_afEntry[ 8],
00484             fInvScalar*m_afEntry[ 9],
00485             fInvScalar*m_afEntry[10],
00486             fInvScalar*m_afEntry[11],
00487             fInvScalar*m_afEntry[12],
00488             fInvScalar*m_afEntry[13],
00489             fInvScalar*m_afEntry[14],
00490             fInvScalar*m_afEntry[15]);
00491     }
00492 
00493     return Matrix4<Real>(
00494         Math<Real>::MAX_REAL,
00495         Math<Real>::MAX_REAL,
00496         Math<Real>::MAX_REAL,
00497         Math<Real>::MAX_REAL,
00498         Math<Real>::MAX_REAL,
00499         Math<Real>::MAX_REAL,
00500         Math<Real>::MAX_REAL,
00501         Math<Real>::MAX_REAL,
00502         Math<Real>::MAX_REAL,
00503         Math<Real>::MAX_REAL,
00504         Math<Real>::MAX_REAL,
00505         Math<Real>::MAX_REAL,
00506         Math<Real>::MAX_REAL,
00507         Math<Real>::MAX_REAL,
00508         Math<Real>::MAX_REAL,
00509         Math<Real>::MAX_REAL);
00510 }
00511 //----------------------------------------------------------------------------
00512 template <class Real>
00513 Matrix4<Real> Matrix4<Real>::operator- () const
00514 {
00515     return Matrix4<Real>(
00516         -m_afEntry[ 0],
00517         -m_afEntry[ 1],
00518         -m_afEntry[ 2],
00519         -m_afEntry[ 3],
00520         -m_afEntry[ 4],
00521         -m_afEntry[ 5],
00522         -m_afEntry[ 6],
00523         -m_afEntry[ 7],
00524         -m_afEntry[ 8],
00525         -m_afEntry[ 9],
00526         -m_afEntry[10],
00527         -m_afEntry[11],
00528         -m_afEntry[12],
00529         -m_afEntry[13],
00530         -m_afEntry[14],
00531         -m_afEntry[15]);
00532 }
00533 //----------------------------------------------------------------------------
00534 template <class Real>
00535 Matrix4<Real>& Matrix4<Real>::operator+= (const Matrix4& rkM)
00536 {
00537     m_afEntry[ 0] += rkM.m_afEntry[ 0];
00538     m_afEntry[ 1] += rkM.m_afEntry[ 1];
00539     m_afEntry[ 2] += rkM.m_afEntry[ 2];
00540     m_afEntry[ 3] += rkM.m_afEntry[ 3];
00541     m_afEntry[ 4] += rkM.m_afEntry[ 4];
00542     m_afEntry[ 5] += rkM.m_afEntry[ 5];
00543     m_afEntry[ 6] += rkM.m_afEntry[ 6];
00544     m_afEntry[ 7] += rkM.m_afEntry[ 7];
00545     m_afEntry[ 8] += rkM.m_afEntry[ 8];
00546     m_afEntry[ 9] += rkM.m_afEntry[ 9];
00547     m_afEntry[10] += rkM.m_afEntry[10];
00548     m_afEntry[11] += rkM.m_afEntry[11];
00549     m_afEntry[12] += rkM.m_afEntry[12];
00550     m_afEntry[13] += rkM.m_afEntry[13];
00551     m_afEntry[14] += rkM.m_afEntry[14];
00552     m_afEntry[15] += rkM.m_afEntry[15];
00553     return *this;
00554 }
00555 //----------------------------------------------------------------------------
00556 template <class Real>
00557 Matrix4<Real>& Matrix4<Real>::operator-= (const Matrix4& rkM)
00558 {
00559     m_afEntry[ 0] -= rkM.m_afEntry[ 0];
00560     m_afEntry[ 1] -= rkM.m_afEntry[ 1];
00561     m_afEntry[ 2] -= rkM.m_afEntry[ 2];
00562     m_afEntry[ 3] -= rkM.m_afEntry[ 3];
00563     m_afEntry[ 4] -= rkM.m_afEntry[ 4];
00564     m_afEntry[ 5] -= rkM.m_afEntry[ 5];
00565     m_afEntry[ 6] -= rkM.m_afEntry[ 6];
00566     m_afEntry[ 7] -= rkM.m_afEntry[ 7];
00567     m_afEntry[ 8] -= rkM.m_afEntry[ 8];
00568     m_afEntry[ 9] -= rkM.m_afEntry[ 9];
00569     m_afEntry[10] -= rkM.m_afEntry[10];
00570     m_afEntry[11] -= rkM.m_afEntry[11];
00571     m_afEntry[12] -= rkM.m_afEntry[12];
00572     m_afEntry[13] -= rkM.m_afEntry[13];
00573     m_afEntry[14] -= rkM.m_afEntry[14];
00574     m_afEntry[15] -= rkM.m_afEntry[15];
00575     return *this;
00576 }
00577 //----------------------------------------------------------------------------
00578 template <class Real>
00579 Matrix4<Real>& Matrix4<Real>::operator*= (Real fScalar)
00580 {
00581     m_afEntry[ 0] *= fScalar;
00582     m_afEntry[ 1] *= fScalar;
00583     m_afEntry[ 2] *= fScalar;
00584     m_afEntry[ 3] *= fScalar;
00585     m_afEntry[ 4] *= fScalar;
00586     m_afEntry[ 5] *= fScalar;
00587     m_afEntry[ 6] *= fScalar;
00588     m_afEntry[ 7] *= fScalar;
00589     m_afEntry[ 8] *= fScalar;
00590     m_afEntry[ 9] *= fScalar;
00591     m_afEntry[10] *= fScalar;
00592     m_afEntry[11] *= fScalar;
00593     m_afEntry[12] *= fScalar;
00594     m_afEntry[13] *= fScalar;
00595     m_afEntry[14] *= fScalar;
00596     m_afEntry[15] *= fScalar;
00597     return *this;
00598 }
00599 //----------------------------------------------------------------------------
00600 template <class Real>
00601 Matrix4<Real>& Matrix4<Real>::operator/= (Real fScalar)
00602 {
00603     int i;
00604 
00605     if (fScalar != (Real)0.0)
00606     {
00607         Real fInvScalar = ((Real)1.0)/fScalar;
00608         m_afEntry[ 0] *= fInvScalar;
00609         m_afEntry[ 1] *= fInvScalar;
00610         m_afEntry[ 2] *= fInvScalar;
00611         m_afEntry[ 3] *= fInvScalar;
00612         m_afEntry[ 4] *= fInvScalar;
00613         m_afEntry[ 5] *= fInvScalar;
00614         m_afEntry[ 6] *= fInvScalar;
00615         m_afEntry[ 7] *= fInvScalar;
00616         m_afEntry[ 8] *= fInvScalar;
00617         m_afEntry[ 9] *= fInvScalar;
00618         m_afEntry[10] *= fInvScalar;
00619         m_afEntry[11] *= fInvScalar;
00620         m_afEntry[12] *= fInvScalar;
00621         m_afEntry[13] *= fInvScalar;
00622         m_afEntry[14] *= fInvScalar;
00623         m_afEntry[15] *= fInvScalar;
00624     }
00625     else
00626     {
00627         m_afEntry[ 0] = Math<Real>::MAX_REAL;
00628         m_afEntry[ 1] = Math<Real>::MAX_REAL;
00629         m_afEntry[ 2] = Math<Real>::MAX_REAL;
00630         m_afEntry[ 3] = Math<Real>::MAX_REAL;
00631         m_afEntry[ 4] = Math<Real>::MAX_REAL;
00632         m_afEntry[ 5] = Math<Real>::MAX_REAL;
00633         m_afEntry[ 6] = Math<Real>::MAX_REAL;
00634         m_afEntry[ 7] = Math<Real>::MAX_REAL;
00635         m_afEntry[ 8] = Math<Real>::MAX_REAL;
00636         m_afEntry[ 9] = Math<Real>::MAX_REAL;
00637         m_afEntry[10] = Math<Real>::MAX_REAL;
00638         m_afEntry[11] = Math<Real>::MAX_REAL;
00639         m_afEntry[12] = Math<Real>::MAX_REAL;
00640         m_afEntry[13] = Math<Real>::MAX_REAL;
00641         m_afEntry[14] = Math<Real>::MAX_REAL;
00642         m_afEntry[15] = Math<Real>::MAX_REAL;
00643     }
00644 
00645     return *this;
00646 }
00647 //----------------------------------------------------------------------------
00648 template <class Real>
00649 Vector4<Real> Matrix4<Real>::operator* (const Vector4<Real>& rkV) const
00650 {
00651     return Vector4<Real>(
00652         m_afEntry[ 0]*rkV[0] +
00653         m_afEntry[ 1]*rkV[1] +
00654         m_afEntry[ 2]*rkV[2] +
00655         m_afEntry[ 3]*rkV[3],
00656 
00657         m_afEntry[ 4]*rkV[0] +
00658         m_afEntry[ 5]*rkV[1] +
00659         m_afEntry[ 6]*rkV[2] +
00660         m_afEntry[ 7]*rkV[3],
00661 
00662         m_afEntry[ 8]*rkV[0] +
00663         m_afEntry[ 9]*rkV[1] +
00664         m_afEntry[10]*rkV[2] +
00665         m_afEntry[11]*rkV[3],
00666 
00667         m_afEntry[12]*rkV[0] +
00668         m_afEntry[13]*rkV[1] +
00669         m_afEntry[14]*rkV[2] +
00670         m_afEntry[15]*rkV[3]);
00671 }
00672 //----------------------------------------------------------------------------
00673 template <class Real>
00674 Matrix4<Real> Matrix4<Real>::Transpose () const
00675 {
00676     return Matrix4<Real>(
00677         m_afEntry[ 0],
00678         m_afEntry[ 4],
00679         m_afEntry[ 8],
00680         m_afEntry[12],
00681         m_afEntry[ 1],
00682         m_afEntry[ 5],
00683         m_afEntry[ 9],
00684         m_afEntry[13],
00685         m_afEntry[ 2],
00686         m_afEntry[ 6],
00687         m_afEntry[10],
00688         m_afEntry[14],
00689         m_afEntry[ 3],
00690         m_afEntry[ 7],
00691         m_afEntry[11],
00692         m_afEntry[15]);
00693 }
00694 //----------------------------------------------------------------------------
00695 template <class Real>
00696 Matrix4<Real> Matrix4<Real>::TransposeTimes (const Matrix4& rkM) const
00697 {
00698     // P = A^T*B
00699     return Matrix4<Real>(
00700         m_afEntry[ 0]*rkM.m_afEntry[ 0] +
00701         m_afEntry[ 4]*rkM.m_afEntry[ 4] +
00702         m_afEntry[ 8]*rkM.m_afEntry[ 8] +
00703         m_afEntry[12]*rkM.m_afEntry[12],
00704 
00705         m_afEntry[ 0]*rkM.m_afEntry[ 1] +
00706         m_afEntry[ 4]*rkM.m_afEntry[ 5] +
00707         m_afEntry[ 8]*rkM.m_afEntry[ 9] +
00708         m_afEntry[12]*rkM.m_afEntry[13],
00709 
00710         m_afEntry[ 0]*rkM.m_afEntry[ 2] +
00711         m_afEntry[ 4]*rkM.m_afEntry[ 6] +
00712         m_afEntry[ 8]*rkM.m_afEntry[10] +
00713         m_afEntry[12]*rkM.m_afEntry[14],
00714 
00715         m_afEntry[ 0]*rkM.m_afEntry[ 3] +
00716         m_afEntry[ 4]*rkM.m_afEntry[ 7] +
00717         m_afEntry[ 8]*rkM.m_afEntry[11] +
00718         m_afEntry[12]*rkM.m_afEntry[15],
00719 
00720         m_afEntry[ 1]*rkM.m_afEntry[ 0] +
00721         m_afEntry[ 5]*rkM.m_afEntry[ 4] +
00722         m_afEntry[ 9]*rkM.m_afEntry[ 8] +
00723         m_afEntry[13]*rkM.m_afEntry[12],
00724 
00725         m_afEntry[ 1]*rkM.m_afEntry[ 1] +
00726         m_afEntry[ 5]*rkM.m_afEntry[ 5] +
00727         m_afEntry[ 9]*rkM.m_afEntry[ 9] +
00728         m_afEntry[13]*rkM.m_afEntry[13],
00729 
00730         m_afEntry[ 1]*rkM.m_afEntry[ 2] +
00731         m_afEntry[ 5]*rkM.m_afEntry[ 6] +
00732         m_afEntry[ 9]*rkM.m_afEntry[10] +
00733         m_afEntry[13]*rkM.m_afEntry[14],
00734 
00735         m_afEntry[ 1]*rkM.m_afEntry[ 3] +
00736         m_afEntry[ 5]*rkM.m_afEntry[ 7] +
00737         m_afEntry[ 9]*rkM.m_afEntry[11] +
00738         m_afEntry[13]*rkM.m_afEntry[15],
00739 
00740         m_afEntry[ 2]*rkM.m_afEntry[ 0] +
00741         m_afEntry[ 6]*rkM.m_afEntry[ 4] +
00742         m_afEntry[10]*rkM.m_afEntry[ 8] +
00743         m_afEntry[14]*rkM.m_afEntry[12],
00744 
00745         m_afEntry[ 2]*rkM.m_afEntry[ 1] +
00746         m_afEntry[ 6]*rkM.m_afEntry[ 5] +
00747         m_afEntry[10]*rkM.m_afEntry[ 9] +
00748         m_afEntry[14]*rkM.m_afEntry[13],
00749 
00750         m_afEntry[ 2]*rkM.m_afEntry[ 2] +
00751         m_afEntry[ 6]*rkM.m_afEntry[ 6] +
00752         m_afEntry[10]*rkM.m_afEntry[10] +
00753         m_afEntry[14]*rkM.m_afEntry[14],
00754 
00755         m_afEntry[ 2]*rkM.m_afEntry[ 3] +
00756         m_afEntry[ 6]*rkM.m_afEntry[ 7] +
00757         m_afEntry[10]*rkM.m_afEntry[11] +
00758         m_afEntry[14]*rkM.m_afEntry[15],
00759 
00760         m_afEntry[ 3]*rkM.m_afEntry[ 0] +
00761         m_afEntry[ 7]*rkM.m_afEntry[ 4] +
00762         m_afEntry[11]*rkM.m_afEntry[ 8] +
00763         m_afEntry[15]*rkM.m_afEntry[12],
00764 
00765         m_afEntry[ 3]*rkM.m_afEntry[ 1] +
00766         m_afEntry[ 7]*rkM.m_afEntry[ 5] +
00767         m_afEntry[11]*rkM.m_afEntry[ 9] +
00768         m_afEntry[15]*rkM.m_afEntry[13],
00769 
00770         m_afEntry[ 3]*rkM.m_afEntry[ 2] +
00771         m_afEntry[ 7]*rkM.m_afEntry[ 6] +
00772         m_afEntry[11]*rkM.m_afEntry[10] +
00773         m_afEntry[15]*rkM.m_afEntry[14],
00774 
00775         m_afEntry[ 3]*rkM.m_afEntry[ 3] +
00776         m_afEntry[ 7]*rkM.m_afEntry[ 7] +
00777         m_afEntry[11]*rkM.m_afEntry[11] +
00778         m_afEntry[15]*rkM.m_afEntry[15]);
00779 }
00780 //----------------------------------------------------------------------------
00781 template <class Real>
00782 Matrix4<Real> Matrix4<Real>::TimesTranspose (const Matrix4& rkM) const
00783 {
00784     // P = A*B^T
00785     return Matrix4<Real>(
00786         m_afEntry[ 0]*rkM.m_afEntry[ 0] +
00787         m_afEntry[ 1]*rkM.m_afEntry[ 1] +
00788         m_afEntry[ 2]*rkM.m_afEntry[ 2] +
00789         m_afEntry[ 3]*rkM.m_afEntry[ 3],
00790 
00791         m_afEntry[ 0]*rkM.m_afEntry[ 4] +
00792         m_afEntry[ 1]*rkM.m_afEntry[ 5] +
00793         m_afEntry[ 2]*rkM.m_afEntry[ 6] +
00794         m_afEntry[ 3]*rkM.m_afEntry[ 7],
00795 
00796         m_afEntry[ 0]*rkM.m_afEntry[ 8] +
00797         m_afEntry[ 1]*rkM.m_afEntry[ 9] +
00798         m_afEntry[ 2]*rkM.m_afEntry[10] +
00799         m_afEntry[ 3]*rkM.m_afEntry[11],
00800 
00801         m_afEntry[ 0]*rkM.m_afEntry[12] +
00802         m_afEntry[ 1]*rkM.m_afEntry[13] +
00803         m_afEntry[ 2]*rkM.m_afEntry[14] +
00804         m_afEntry[ 3]*rkM.m_afEntry[15],
00805 
00806         m_afEntry[ 4]*rkM.m_afEntry[ 0] +
00807         m_afEntry[ 5]*rkM.m_afEntry[ 1] +
00808         m_afEntry[ 6]*rkM.m_afEntry[ 2] +
00809         m_afEntry[ 7]*rkM.m_afEntry[ 3],
00810 
00811         m_afEntry[ 4]*rkM.m_afEntry[ 4] +
00812         m_afEntry[ 5]*rkM.m_afEntry[ 5] +
00813         m_afEntry[ 6]*rkM.m_afEntry[ 6] +
00814         m_afEntry[ 7]*rkM.m_afEntry[ 7],
00815 
00816         m_afEntry[ 4]*rkM.m_afEntry[ 8] +
00817         m_afEntry[ 5]*rkM.m_afEntry[ 9] +
00818         m_afEntry[ 6]*rkM.m_afEntry[10] +
00819         m_afEntry[ 7]*rkM.m_afEntry[11],
00820 
00821         m_afEntry[ 4]*rkM.m_afEntry[12] +
00822         m_afEntry[ 5]*rkM.m_afEntry[13] +
00823         m_afEntry[ 6]*rkM.m_afEntry[14] +
00824         m_afEntry[ 7]*rkM.m_afEntry[15],
00825 
00826         m_afEntry[ 8]*rkM.m_afEntry[ 0] +
00827         m_afEntry[ 9]*rkM.m_afEntry[ 1] +
00828         m_afEntry[10]*rkM.m_afEntry[ 2] +
00829         m_afEntry[11]*rkM.m_afEntry[ 3],
00830 
00831         m_afEntry[ 8]*rkM.m_afEntry[ 4] +
00832         m_afEntry[ 9]*rkM.m_afEntry[ 5] +
00833         m_afEntry[10]*rkM.m_afEntry[ 6] +
00834         m_afEntry[11]*rkM.m_afEntry[ 7],
00835 
00836         m_afEntry[ 8]*rkM.m_afEntry[ 8] +
00837         m_afEntry[ 9]*rkM.m_afEntry[ 9] +
00838         m_afEntry[10]*rkM.m_afEntry[10] +
00839         m_afEntry[11]*rkM.m_afEntry[11],
00840 
00841         m_afEntry[ 8]*rkM.m_afEntry[12] +
00842         m_afEntry[ 9]*rkM.m_afEntry[13] +
00843         m_afEntry[10]*rkM.m_afEntry[14] +
00844         m_afEntry[11]*rkM.m_afEntry[15],
00845 
00846         m_afEntry[12]*rkM.m_afEntry[ 0] +
00847         m_afEntry[13]*rkM.m_afEntry[ 1] +
00848         m_afEntry[14]*rkM.m_afEntry[ 2] +
00849         m_afEntry[15]*rkM.m_afEntry[ 3],
00850 
00851         m_afEntry[12]*rkM.m_afEntry[ 4] +
00852         m_afEntry[13]*rkM.m_afEntry[ 5] +
00853         m_afEntry[14]*rkM.m_afEntry[ 6] +
00854         m_afEntry[15]*rkM.m_afEntry[ 7],
00855 
00856         m_afEntry[12]*rkM.m_afEntry[ 8] +
00857         m_afEntry[13]*rkM.m_afEntry[ 9] +
00858         m_afEntry[14]*rkM.m_afEntry[10] +
00859         m_afEntry[15]*rkM.m_afEntry[11],
00860 
00861         m_afEntry[12]*rkM.m_afEntry[12] +
00862         m_afEntry[13]*rkM.m_afEntry[13] +
00863         m_afEntry[14]*rkM.m_afEntry[14] +
00864         m_afEntry[15]*rkM.m_afEntry[15]);
00865 }
00866 //----------------------------------------------------------------------------
00867 template <class Real>
00868 Matrix4<Real> Matrix4<Real>::Inverse () const
00869 {
00870     Real fA0 = m_afEntry[ 0]*m_afEntry[ 5] - m_afEntry[ 1]*m_afEntry[ 4];
00871     Real fA1 = m_afEntry[ 0]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 4];
00872     Real fA2 = m_afEntry[ 0]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 4];
00873     Real fA3 = m_afEntry[ 1]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 5];
00874     Real fA4 = m_afEntry[ 1]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 5];
00875     Real fA5 = m_afEntry[ 2]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 6];
00876     Real fB0 = m_afEntry[ 8]*m_afEntry[13] - m_afEntry[ 9]*m_afEntry[12];
00877     Real fB1 = m_afEntry[ 8]*m_afEntry[14] - m_afEntry[10]*m_afEntry[12];
00878     Real fB2 = m_afEntry[ 8]*m_afEntry[15] - m_afEntry[11]*m_afEntry[12];
00879     Real fB3 = m_afEntry[ 9]*m_afEntry[14] - m_afEntry[10]*m_afEntry[13];
00880     Real fB4 = m_afEntry[ 9]*m_afEntry[15] - m_afEntry[11]*m_afEntry[13];
00881     Real fB5 = m_afEntry[10]*m_afEntry[15] - m_afEntry[11]*m_afEntry[14];
00882 
00883     Real fDet = fA0*fB5-fA1*fB4+fA2*fB3+fA3*fB2-fA4*fB1+fA5*fB0;
00884     if (Math<Real>::FAbs(fDet) <= Math<Real>::ZERO_TOLERANCE)
00885     {
00886         return Matrix4<Real>::ZERO;
00887     }
00888 
00889     Matrix4 kInv;
00890     kInv.m_afEntry[ 0] =
00891         + m_afEntry[ 5]*fB5 - m_afEntry[ 6]*fB4 + m_afEntry[ 7]*fB3;
00892     kInv.m_afEntry[ 4] =
00893         - m_afEntry[ 4]*fB5 + m_afEntry[ 6]*fB2 - m_afEntry[ 7]*fB1;
00894     kInv.m_afEntry[ 8] =
00895         + m_afEntry[ 4]*fB4 - m_afEntry[ 5]*fB2 + m_afEntry[ 7]*fB0;
00896     kInv.m_afEntry[12] =
00897         - m_afEntry[ 4]*fB3 + m_afEntry[ 5]*fB1 - m_afEntry[ 6]*fB0;
00898     kInv.m_afEntry[ 1] =
00899         - m_afEntry[ 1]*fB5 + m_afEntry[ 2]*fB4 - m_afEntry[ 3]*fB3;
00900     kInv.m_afEntry[ 5] =
00901         + m_afEntry[ 0]*fB5 - m_afEntry[ 2]*fB2 + m_afEntry[ 3]*fB1;
00902     kInv.m_afEntry[ 9] =
00903         - m_afEntry[ 0]*fB4 + m_afEntry[ 1]*fB2 - m_afEntry[ 3]*fB0;
00904     kInv.m_afEntry[13] =
00905         + m_afEntry[ 0]*fB3 - m_afEntry[ 1]*fB1 + m_afEntry[ 2]*fB0;
00906     kInv.m_afEntry[ 2] =
00907         + m_afEntry[13]*fA5 - m_afEntry[14]*fA4 + m_afEntry[15]*fA3;
00908     kInv.m_afEntry[ 6] =
00909         - m_afEntry[12]*fA5 + m_afEntry[14]*fA2 - m_afEntry[15]*fA1;
00910     kInv.m_afEntry[10] =
00911         + m_afEntry[12]*fA4 - m_afEntry[13]*fA2 + m_afEntry[15]*fA0;
00912     kInv.m_afEntry[14] =
00913         - m_afEntry[12]*fA3 + m_afEntry[13]*fA1 - m_afEntry[14]*fA0;
00914     kInv.m_afEntry[ 3] =
00915         - m_afEntry[ 9]*fA5 + m_afEntry[10]*fA4 - m_afEntry[11]*fA3;
00916     kInv.m_afEntry[ 7] =
00917         + m_afEntry[ 8]*fA5 - m_afEntry[10]*fA2 + m_afEntry[11]*fA1;
00918     kInv.m_afEntry[11] =
00919         - m_afEntry[ 8]*fA4 + m_afEntry[ 9]*fA2 - m_afEntry[11]*fA0;
00920     kInv.m_afEntry[15] =
00921         + m_afEntry[ 8]*fA3 - m_afEntry[ 9]*fA1 + m_afEntry[10]*fA0;
00922 
00923     Real fInvDet = ((Real)1.0)/fDet;
00924     kInv.m_afEntry[ 0] *= fInvDet;
00925     kInv.m_afEntry[ 1] *= fInvDet;
00926     kInv.m_afEntry[ 2] *= fInvDet;
00927     kInv.m_afEntry[ 3] *= fInvDet;
00928     kInv.m_afEntry[ 4] *= fInvDet;
00929     kInv.m_afEntry[ 5] *= fInvDet;
00930     kInv.m_afEntry[ 6] *= fInvDet;
00931     kInv.m_afEntry[ 7] *= fInvDet;
00932     kInv.m_afEntry[ 8] *= fInvDet;
00933     kInv.m_afEntry[ 9] *= fInvDet;
00934     kInv.m_afEntry[10] *= fInvDet;
00935     kInv.m_afEntry[11] *= fInvDet;
00936     kInv.m_afEntry[12] *= fInvDet;
00937     kInv.m_afEntry[13] *= fInvDet;
00938     kInv.m_afEntry[14] *= fInvDet;
00939     kInv.m_afEntry[15] *= fInvDet;
00940 
00941     return kInv;
00942 }
00943 //----------------------------------------------------------------------------
00944 template <class Real>
00945 Matrix4<Real> Matrix4<Real>::Adjoint () const
00946 {
00947     Real fA0 = m_afEntry[ 0]*m_afEntry[ 5] - m_afEntry[ 1]*m_afEntry[ 4];
00948     Real fA1 = m_afEntry[ 0]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 4];
00949     Real fA2 = m_afEntry[ 0]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 4];
00950     Real fA3 = m_afEntry[ 1]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 5];
00951     Real fA4 = m_afEntry[ 1]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 5];
00952     Real fA5 = m_afEntry[ 2]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 6];
00953     Real fB0 = m_afEntry[ 8]*m_afEntry[13] - m_afEntry[ 9]*m_afEntry[12];
00954     Real fB1 = m_afEntry[ 8]*m_afEntry[14] - m_afEntry[10]*m_afEntry[12];
00955     Real fB2 = m_afEntry[ 8]*m_afEntry[15] - m_afEntry[11]*m_afEntry[12];
00956     Real fB3 = m_afEntry[ 9]*m_afEntry[14] - m_afEntry[10]*m_afEntry[13];
00957     Real fB4 = m_afEntry[ 9]*m_afEntry[15] - m_afEntry[11]*m_afEntry[13];
00958     Real fB5 = m_afEntry[10]*m_afEntry[15] - m_afEntry[11]*m_afEntry[14];
00959 
00960     return Matrix4<Real>(
00961         + m_afEntry[ 5]*fB5 - m_afEntry[ 6]*fB4 + m_afEntry[ 7]*fB3,
00962         - m_afEntry[ 1]*fB5 + m_afEntry[ 2]*fB4 - m_afEntry[ 3]*fB3,
00963         + m_afEntry[13]*fA5 - m_afEntry[14]*fA4 + m_afEntry[15]*fA3,
00964         - m_afEntry[ 9]*fA5 + m_afEntry[10]*fA4 - m_afEntry[11]*fA3,
00965         - m_afEntry[ 4]*fB5 + m_afEntry[ 6]*fB2 - m_afEntry[ 7]*fB1,
00966         + m_afEntry[ 0]*fB5 - m_afEntry[ 2]*fB2 + m_afEntry[ 3]*fB1,
00967         - m_afEntry[12]*fA5 + m_afEntry[14]*fA2 - m_afEntry[15]*fA1,
00968         + m_afEntry[ 8]*fA5 - m_afEntry[10]*fA2 + m_afEntry[11]*fA1,
00969         + m_afEntry[ 4]*fB4 - m_afEntry[ 5]*fB2 + m_afEntry[ 7]*fB0,
00970         - m_afEntry[ 0]*fB4 + m_afEntry[ 1]*fB2 - m_afEntry[ 3]*fB0,
00971         + m_afEntry[12]*fA4 - m_afEntry[13]*fA2 + m_afEntry[15]*fA0,
00972         - m_afEntry[ 8]*fA4 + m_afEntry[ 9]*fA2 - m_afEntry[11]*fA0,
00973         - m_afEntry[ 4]*fB3 + m_afEntry[ 5]*fB1 - m_afEntry[ 6]*fB0,
00974         + m_afEntry[ 0]*fB3 - m_afEntry[ 1]*fB1 + m_afEntry[ 2]*fB0,
00975         - m_afEntry[12]*fA3 + m_afEntry[13]*fA1 - m_afEntry[14]*fA0,
00976         + m_afEntry[ 8]*fA3 - m_afEntry[ 9]*fA1 + m_afEntry[10]*fA0);
00977 }
00978 //----------------------------------------------------------------------------
00979 template <class Real>
00980 Real Matrix4<Real>::Determinant () const
00981 {
00982     Real fA0 = m_afEntry[ 0]*m_afEntry[ 5] - m_afEntry[ 1]*m_afEntry[ 4];
00983     Real fA1 = m_afEntry[ 0]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 4];
00984     Real fA2 = m_afEntry[ 0]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 4];
00985     Real fA3 = m_afEntry[ 1]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 5];
00986     Real fA4 = m_afEntry[ 1]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 5];
00987     Real fA5 = m_afEntry[ 2]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 6];
00988     Real fB0 = m_afEntry[ 8]*m_afEntry[13] - m_afEntry[ 9]*m_afEntry[12];
00989     Real fB1 = m_afEntry[ 8]*m_afEntry[14] - m_afEntry[10]*m_afEntry[12];
00990     Real fB2 = m_afEntry[ 8]*m_afEntry[15] - m_afEntry[11]*m_afEntry[12];
00991     Real fB3 = m_afEntry[ 9]*m_afEntry[14] - m_afEntry[10]*m_afEntry[13];
00992     Real fB4 = m_afEntry[ 9]*m_afEntry[15] - m_afEntry[11]*m_afEntry[13];
00993     Real fB5 = m_afEntry[10]*m_afEntry[15] - m_afEntry[11]*m_afEntry[14];
00994     Real fDet = fA0*fB5-fA1*fB4+fA2*fB3+fA3*fB2-fA4*fB1+fA5*fB0;
00995     return fDet;
00996 }
00997 //----------------------------------------------------------------------------
00998 template <class Real>
00999 Real Matrix4<Real>::QForm (const Vector4<Real>& rkU,
01000     const Vector4<Real>& rkV) const
01001 {
01002     return rkU.Dot((*this)*rkV);
01003 }
01004 //----------------------------------------------------------------------------
01005 template <class Real>
01006 void Matrix4<Real>::MakeObliqueProjection (const Vector3<Real>& rkNormal,
01007     const Vector3<Real>& rkPoint, const Vector3<Real>& rkDirection)
01008 {
01009     // The projection plane is Dot(N,X-P) = 0 where N is a 3-by-1 unit-length
01010     // normal vector and P is a 3-by-1 point on the plane.  The projection
01011     // is oblique to the plane, in the direction of the 3-by-1 vector D.
01012     // Necessarily Dot(N,D) is not zero for this projection to make sense.
01013     // Given a 3-by-1 point U, compute the intersection of the line U+t*D
01014     // with the plane to obtain t = -Dot(N,U-P)/Dot(N,D).  Then
01015     //
01016     //   projection(U) = P + [I - D*N^T/Dot(N,D)]*(U-P)
01017     //
01018     // A 4-by-4 homogeneous transformation representing the projection is
01019     //
01020     //       +-                               -+
01021     //   M = | D*N^T - Dot(N,D)*I   -Dot(N,P)D |
01022     //       |          0^T          -Dot(N,D) |
01023     //       +-                               -+
01024     //
01025     // where M applies to [U^T 1]^T by M*[U^T 1]^T.  The matrix is chosen so
01026     // that M[3][3] > 0 whenever Dot(N,D) < 0 (projection is onto the
01027     // "positive side" of the plane).
01028 
01029     Real fNdD = rkNormal.Dot(rkDirection);
01030     Real fNdP = rkNormal.Dot(rkPoint);
01031     m_afEntry[ 0] = rkDirection[0]*rkNormal[0] - fNdD;
01032     m_afEntry[ 1] = rkDirection[0]*rkNormal[1];
01033     m_afEntry[ 2] = rkDirection[0]*rkNormal[2];
01034     m_afEntry[ 3] = -fNdP*rkDirection[0];
01035     m_afEntry[ 4] = rkDirection[1]*rkNormal[0];
01036     m_afEntry[ 5] = rkDirection[1]*rkNormal[1] - fNdD;
01037     m_afEntry[ 6] = rkDirection[1]*rkNormal[2];
01038     m_afEntry[ 7] = -fNdP*rkDirection[1];
01039     m_afEntry[ 8] = rkDirection[2]*rkNormal[0];
01040     m_afEntry[ 9] = rkDirection[2]*rkNormal[1];
01041     m_afEntry[10] = rkDirection[2]*rkNormal[2] - fNdD;
01042     m_afEntry[11] = -fNdP*rkDirection[2];
01043     m_afEntry[12] = 0.0f;
01044     m_afEntry[13] = 0.0f;
01045     m_afEntry[14] = 0.0f;
01046     m_afEntry[15] = -fNdD;
01047 }
01048 //----------------------------------------------------------------------------
01049 template <class Real>
01050 void Matrix4<Real>::MakePerspectiveProjection (const Vector3<Real>& rkNormal,
01051     const Vector3<Real>& rkPoint, const Vector3<Real>& rkEye)
01052 {
01053     //     +-                                                 -+
01054     // M = | Dot(N,E-P)*I - E*N^T    -(Dot(N,E-P)*I - E*N^T)*E |
01055     //     |        -N^t                      Dot(N,E)         |
01056     //     +-                                                 -+
01057     //
01058     // where E is the eye point, P is a point on the plane, and N is a
01059     // unit-length plane normal.
01060 
01061     Real fNdEmP = rkNormal.Dot(rkEye-rkPoint);
01062 
01063     m_afEntry[ 0] = fNdEmP - rkEye[0]*rkNormal[0];
01064     m_afEntry[ 1] = -rkEye[0]*rkNormal[1];
01065     m_afEntry[ 2] = -rkEye[0]*rkNormal[2];
01066     m_afEntry[ 3] = -(m_afEntry[0]*rkEye[0] + m_afEntry[1]*rkEye[1] +
01067         m_afEntry[2]*rkEye[2]);
01068     m_afEntry[ 4] = -rkEye[1]*rkNormal[0];
01069     m_afEntry[ 5] = fNdEmP - rkEye[1]*rkNormal[1];
01070     m_afEntry[ 6] = -rkEye[1]*rkNormal[2];
01071     m_afEntry[ 7] = -(m_afEntry[4]*rkEye[0] + m_afEntry[5]*rkEye[1] +
01072         m_afEntry[6]*rkEye[2]);
01073     m_afEntry[ 8] = -rkEye[2]*rkNormal[0];
01074     m_afEntry[ 9] = -rkEye[2]*rkNormal[1];
01075     m_afEntry[10] = fNdEmP- rkEye[2]*rkNormal[2];
01076     m_afEntry[11] = -(m_afEntry[8]*rkEye[0] + m_afEntry[9]*rkEye[1] +
01077         m_afEntry[10]*rkEye[2]);
01078     m_afEntry[12] = -rkNormal[0];
01079     m_afEntry[13] = -rkNormal[1];
01080     m_afEntry[14] = -rkNormal[2];
01081     m_afEntry[15] = rkNormal.Dot(rkEye);
01082 }
01083 //----------------------------------------------------------------------------
01084 template <class Real>
01085 void Matrix4<Real>::MakeReflection (const Vector3<Real>& rkNormal,
01086     const Vector3<Real>& rkPoint)
01087 {
01088     //     +-                         -+
01089     // M = | I-2*N*N^T    2*Dot(N,P)*N |
01090     //     |     0^T            1      |
01091     //     +-                         -+
01092     //
01093     // where P is a point on the plane and N is a unit-length plane normal.
01094 
01095     Real fTwoNdP = ((Real)2.0)*(rkNormal.Dot(rkPoint));
01096 
01097     m_afEntry[ 0] = (Real)1.0 - ((Real)2.0)*rkNormal[0]*rkNormal[0];
01098     m_afEntry[ 1] = -((Real)2.0)*rkNormal[0]*rkNormal[1];
01099     m_afEntry[ 2] = -((Real)2.0)*rkNormal[0]*rkNormal[2];
01100     m_afEntry[ 3] = fTwoNdP*rkNormal[0];
01101     m_afEntry[ 4] = -((Real)2.0)*rkNormal[1]*rkNormal[0];
01102     m_afEntry[ 5] = (Real)1.0 - ((Real)2.0)*rkNormal[1]*rkNormal[1];
01103     m_afEntry[ 6] = -((Real)2.0)*rkNormal[1]*rkNormal[2];
01104     m_afEntry[ 7] = fTwoNdP*rkNormal[1];
01105     m_afEntry[ 8] = -((Real)2.0)*rkNormal[2]*rkNormal[0];
01106     m_afEntry[ 9] = -((Real)2.0)*rkNormal[2]*rkNormal[1];
01107     m_afEntry[10] = (Real)1.0 - ((Real)2.0)*rkNormal[2]*rkNormal[2];
01108     m_afEntry[11] = fTwoNdP*rkNormal[2];
01109     m_afEntry[12] = (Real)0.0;
01110     m_afEntry[13] = (Real)0.0;
01111     m_afEntry[14] = (Real)0.0;
01112     m_afEntry[15] = (Real)1.0;
01113 }
01114 //----------------------------------------------------------------------------
01115 template <class Real>
01116 Matrix4<Real> operator* (Real fScalar, const Matrix4<Real>& rkM)
01117 {
01118     return rkM*fScalar;
01119 }
01120 //----------------------------------------------------------------------------
01121 template <class Real>
01122 Vector4<Real> operator* (const Vector4<Real>& rkV, const Matrix4<Real>& rkM)
01123 {
01124     return Vector4<Real>(
01125         rkV[0]*rkM[0][0]+rkV[1]*rkM[1][0]+rkV[2]*rkM[2][0]+rkV[3]*rkM[3][0],
01126         rkV[0]*rkM[0][1]+rkV[1]*rkM[1][1]+rkV[2]*rkM[2][1]+rkV[3]*rkM[3][1],
01127         rkV[0]*rkM[0][2]+rkV[1]*rkM[1][2]+rkV[2]*rkM[2][2]+rkV[3]*rkM[3][2],
01128         rkV[0]*rkM[0][3]+rkV[1]*rkM[1][3]+rkV[2]*rkM[2][3]+rkV[3]*rkM[3][3]);
01129 }
01130 //----------------------------------------------------------------------------
01131 } //namespace Wm4

Generated on Wed Nov 23 19:01:06 2011 for FreeCAD by  doxygen 1.6.1