D:/Zythum/DinoKod/Common/Matrix.h

00001 #ifndef __MATRIX_H__
00002 #define __MATRIX_H__
00003 
00004 #include "Common/CommonDll.h"
00005 #include <math.h>
00006 #include <memory.h>
00007 #include "Common/Types.h"
00008 
00009 //---------------------------------------------------------------------------------------------------------------------
00010 class COMMON_API KMatrix
00011 {
00012 protected:
00013         inline void lubksb( KMatrix& a, int *indx, float *b)
00014         {
00015                 int                     i, j, ii = -1, ip;
00016                 float           sum;
00017                 
00018                 for (i=0; i<4; i++)
00019                 {
00020                         ip = indx[i];
00021                         sum = b[ip];
00022                         b[ip] = b[i];
00023                         if (ii>=0)
00024                         {
00025                                 for (j=ii; j<=i-1; j++)
00026                                 {
00027                                         sum -= a.m_Matrix[i][j] * b[j];
00028                                 }
00029                         }
00030                         else
00031                         if (sum != 0.0)
00032                         {
00033                                 ii = i;
00034                         }
00035 
00036                         b[i] = sum;
00037                 }
00038                 
00039                 for (i=3; i>=0; i--)
00040                 {
00041                         sum = b[i];
00042                         
00043                         for (j=i+1; j<4; j++)
00044                         {
00045                                 sum -= a.m_Matrix[i][j] * b[j];
00046                         }
00047                         
00048                         b[i] = sum/a.m_Matrix[i][i];
00049                 }
00050         }
00051         
00052         inline void ludcmp( KMatrix &a, int *indx, float *d)
00053         {
00054                 float           vv[4];
00055                 float           big, dum, sum, tmp;
00056                 int                     i, imax, j, k;
00057                 
00058                 *d = 1.0f;
00059                 
00060                 for (i=0; i<4; i++)
00061                 {
00062                         big = 0.0f;
00063                         for (j=0; j<4; j++)
00064                         {
00065                                 if ((tmp = (float) fabs(a.m_Matrix[i][j])) > big)
00066                                 {
00067                                         big = tmp;
00068                                 }
00069                         }
00070                         /* if (big == 0.0f) { printf("ludcmp(): singular matrix found...\n"); exit(1); } */
00071                         
00072                         vv[i] = 1.0f/big;
00073                 }
00074                 
00075                 for (j=0; j<4; j++)
00076                 {
00077                         for (i=0; i<j; i++)
00078                         {
00079                                 sum = a.m_Matrix[i][j];
00080                                 for (k=0; k<i; k++)
00081                                 {
00082                                         sum -= a.m_Matrix[i][k] * a.m_Matrix[k][j];
00083                                 } a.m_Matrix[i][j] = sum;
00084                         }
00085                         
00086                         big = 0.0f;
00087                         for (i=j; i<4; i++)
00088                         {
00089                                 sum = a.m_Matrix[i][j];
00090                                 for (k=0; k<j; k++)
00091                                 {
00092                                         sum -= a.m_Matrix[i][k]*a.m_Matrix[k][j];
00093                                 }
00094                                 
00095                                 a.m_Matrix[i][j] = sum;
00096                                 
00097                                 if ((dum = vv[i] * (float)fabs(sum)) >= big)
00098                                 {
00099                                         big = dum; imax = i;
00100                                 }
00101                         }
00102                         
00103                         if (j != imax)
00104                         {
00105                                 for (k=0; k<4; k++)
00106                                 {
00107                                         dum = a.m_Matrix[imax][k];
00108                                         a.m_Matrix[imax][k] = a.m_Matrix[j][k];
00109                                         a.m_Matrix[j][k] = dum;
00110                                 }
00111                                 
00112                                 *d = -(*d);
00113                                 vv[imax] = vv[j];
00114                         }
00115                         
00116                         indx[j] = imax;
00117                         
00118                         if (a.m_Matrix[j][j] == 0.0f)
00119                         {
00120                                 a.m_Matrix[j][j] = 1.0e-20f;      /* can be 0.0 also... */
00121                         }
00122                         
00123                         if (j != 3)
00124                         {
00125                                 dum = 1.0f/a.m_Matrix[j][j];
00126                                 for (i=j+1; i<4; i++)
00127                                 {
00128                                         a.m_Matrix[i][j] *= dum;
00129                                 }
00130                         }
00131                 }
00132         }
00133 
00134 
00135 
00136 public:
00137         union
00138         {
00139                 struct
00140                 {
00141                         float   _11, _12, _13, _14;
00142                         float   _21, _22, _23, _24;
00143                         float   _31, _32, _33, _34;
00144                         float   _41, _42, _43, _44;
00145                 };
00146                 struct
00147                 {
00148                         float   m_Matrix[4][4];
00149                 };
00150         };
00152         // Constructeur
00154         inline KMatrix()
00155         {
00156                 _11 = _12 = _13 = _14 = 0.0f;
00157                 _21 = _22 = _23 = _24 = 0.0f;
00158                 _31 = _32 = _33 = _34 = 0.0f;
00159                 _41 = _42 = _43 = _44 = 0.0f;
00160         }
00161 
00162         inline KMatrix( float _11, float _12, float _13, float _14,
00163                                         float _21, float _22, float _23, float _24,
00164                                         float _31, float _32, float _33, float _34,
00165                                         float _41, float _42, float _43, float _44 )
00166         {
00167                 this->_11 = _11, this->_12 = _12, this->_13 = _13, this->_14 = _14;
00168                 this->_21 = _21, this->_22 = _22, this->_23 = _23, this->_24 = _24;
00169                 this->_31 = _31, this->_32 = _32, this->_33 = _33, this->_34 = _34;
00170                 this->_41 = _41, this->_42 = _42, this->_43 = _43, this->_44 = _44;
00171         }
00172 
00174         // Operateur
00176         inline KMatrix operator * ( KMatrix& matrix )
00177         {
00178                 KMatrix result;
00179 
00180                 result._11 = _11 * matrix._11 + _12 * matrix._21 + _13 * matrix._31 + _14 * matrix._41;
00181                 result._12 = _11 * matrix._12 + _12 * matrix._22 + _13 * matrix._32 + _14 * matrix._42;
00182                 result._13 = _11 * matrix._13 + _12 * matrix._23 + _13 * matrix._33 + _14 * matrix._43;
00183                 result._14 = _11 * matrix._14 + _12 * matrix._24 + _13 * matrix._34 + _14 * matrix._44;
00184         
00185                 result._21 = _21 * matrix._11 + _22 * matrix._21 + _23 * matrix._31 + _24 * matrix._41;
00186                 result._22 = _21 * matrix._12 + _22 * matrix._22 + _23 * matrix._32 + _24 * matrix._42;
00187                 result._23 = _21 * matrix._13 + _22 * matrix._23 + _23 * matrix._33 + _24 * matrix._43;
00188                 result._24 = _21 * matrix._14 + _22 * matrix._24 + _23 * matrix._34 + _24 * matrix._44;
00189 
00190                 result._31 = _31 * matrix._11 + _32 * matrix._21 + _33 * matrix._31 + _34 * matrix._41;
00191                 result._32 = _31 * matrix._12 + _32 * matrix._22 + _33 * matrix._32 + _34 * matrix._42;
00192                 result._33 = _31 * matrix._13 + _32 * matrix._23 + _33 * matrix._33 + _34 * matrix._43;
00193                 result._34 = _31 * matrix._14 + _32 * matrix._24 + _33 * matrix._34 + _34 * matrix._44;
00194 
00195                 result._41 = _41 * matrix._11 + _42 * matrix._21 + _43 * matrix._31 + _44 * matrix._41;
00196                 result._42 = _41 * matrix._12 + _42 * matrix._22 + _43 * matrix._32 + _44 * matrix._42;
00197                 result._43 = _41 * matrix._13 + _42 * matrix._23 + _43 * matrix._33 + _44 * matrix._43;
00198                 result._44 = _41 * matrix._14 + _42 * matrix._24 + _43 * matrix._34 + _44 * matrix._44;
00199 
00200                 return result;
00201         }
00202 
00203         inline void operator *= ( KMatrix& matrix )
00204         {
00205                 KMatrix result;
00206                 
00207                 result._11 = _11 * matrix._11 + _12 * matrix._21 + _13 * matrix._31 + _14 * matrix._41;
00208                 result._12 = _11 * matrix._12 + _12 * matrix._22 + _13 * matrix._32 + _14 * matrix._42;
00209                 result._13 = _11 * matrix._13 + _12 * matrix._23 + _13 * matrix._33 + _14 * matrix._43;
00210                 result._14 = _11 * matrix._14 + _12 * matrix._24 + _13 * matrix._34 + _14 * matrix._44;
00211         
00212                 result._21 = _21 * matrix._11 + _22 * matrix._21 + _23 * matrix._31 + _24 * matrix._41;
00213                 result._22 = _21 * matrix._12 + _22 * matrix._22 + _23 * matrix._32 + _24 * matrix._42;
00214                 result._23 = _21 * matrix._13 + _22 * matrix._23 + _23 * matrix._33 + _24 * matrix._43;
00215                 result._24 = _21 * matrix._14 + _22 * matrix._24 + _23 * matrix._34 + _24 * matrix._44;
00216 
00217                 result._31 = _31 * matrix._11 + _32 * matrix._21 + _33 * matrix._31 + _34 * matrix._41;
00218                 result._32 = _31 * matrix._12 + _32 * matrix._22 + _33 * matrix._32 + _34 * matrix._42;
00219                 result._33 = _31 * matrix._13 + _32 * matrix._23 + _33 * matrix._33 + _34 * matrix._43;
00220                 result._34 = _31 * matrix._14 + _32 * matrix._24 + _33 * matrix._34 + _34 * matrix._44;
00221 
00222                 result._41 = _41 * matrix._11 + _42 * matrix._21 + _43 * matrix._31 + _44 * matrix._41;
00223                 result._42 = _41 * matrix._12 + _42 * matrix._22 + _43 * matrix._32 + _44 * matrix._42;
00224                 result._43 = _41 * matrix._13 + _42 * matrix._23 + _43 * matrix._33 + _44 * matrix._43;
00225                 result._44 = _41 * matrix._14 + _42 * matrix._24 + _43 * matrix._34 + _44 * matrix._44;
00226 
00227                 *this = result;
00228         }
00229 
00230         bool operator == ( KMatrix& matrix )
00231         {
00232                 return( memcmp( &matrix, this, sizeof( KMatrix ) ) == 0 );
00233         }
00234 
00235         bool operator != ( KMatrix& matrix )
00236         {
00237                 return( memcmp( &matrix, this, sizeof( KMatrix ) ) != 0 );
00238         }
00239 
00240         inline KVector MultiplyAdd( KVector& v )
00241         {
00242                 KVector Result;
00243 
00244                 Result.x        = _11 * v.x + _21 * v.y + _31 * v.z + _41;
00245                 Result.y        = _12 * v.x + _22 * v.y + _32 * v.z + _42;
00246                 Result.z        = _13 * v.x + _23 * v.y + _33 * v.z + _43;
00247                 
00248                 return Result;
00249         }
00250 
00251         inline KVector Transform( KVector& v, float* pRhw = NULL )
00252         {
00253                 KVector Result;
00254                 float   rhw;
00255 
00256                 Result.x        = _11 * v.x + _21 * v.y + _31 * v.z + _41;
00257                 Result.y        = _12 * v.x + _22 * v.y + _32 * v.z + _42;
00258                 Result.z        = _13 * v.x + _23 * v.y + _33 * v.z + _43;
00259                 rhw                     = _14 * v.x + _24 * v.y + _34 * v.z + _44;
00260                 
00261                 if( rhw )
00262                 {
00263                         rhw = 1.0f / rhw;
00264                         Result.x *= rhw;
00265                         Result.y *= rhw;
00266                         Result.z *= rhw;
00267                 }
00268 
00269                 if( pRhw )
00270                         *pRhw = rhw;
00271 
00272                 return Result;
00273         }
00274 
00276         // Fonctions matricielles
00278         inline void LoadIdentity()
00279         {
00280                 _11 = _22 = _33 = _44 = 1.0f;
00281                 _12 = _13 = _14 = 0.0f;
00282                 _21 = _23 = _24 = 0.0f;
00283                 _31 = _32 = _34 = 0.0f;
00284                 _41 = _42 = _43 = 0.0f;
00285         }
00286 
00287         inline void Inverse2()
00288         {
00289                 int                     i, j, indx[4];
00290                 float           d, col[4];
00291                 KMatrix         n;
00292 
00293                 n = *this;
00294                 ludcmp( n, indx, &d );
00295 
00296                 for(j = 0;j < 4;j ++)
00297                 {
00298                         for(i = 0;i < 4;i ++)
00299                         {
00300                                 col[i] = 0.0f;
00301                         }
00302                         col[j] = 1.0f;
00303                         
00304                         lubksb(n, indx, col);
00305                         for(i = 0;i < 4;i ++)
00306                         {
00307                                 m_Matrix[i][j] = col[i];
00308                         }
00309                 }
00310         }
00311 
00312         //------------------------------
00313         inline float det2x2( float a, float b, float c, float d )
00314         {
00315                 return a*d - b*c;
00316         }
00317 
00318         inline float det3x3( float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3 )
00319         {
00320                 return  a1 * det2x2(b2, b3, c2, c3)     - b1 * det2x2(a2, a3, c2, c3) + c1 * det2x2(a2, a3, b2, b3);
00321         }
00322 
00323         float Determinant ( const KMatrix& m )
00324         {
00325                 float a1 = m._11;       float a2 = m._21;       float a3 = m._31;       float a4 = m._41;
00326                 float b1 = m._12;       float b2 = m._22;       float b3 = m._32;       float b4 = m._42;
00327                 float c1 = m._13;       float c2 = m._23;       float c3 = m._33;       float c4 = m._43;
00328                 float d1 = m._14;       float d2 = m._24;       float d3 = m._34;       float d4 = m._44;
00329 
00330                 return  a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
00331                         -       b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
00332                         +       c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
00333                         -       d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
00334         }
00335 
00336         KMatrix Adjoint( const KMatrix& m )
00337         {
00338                 float a1 = m._11;       float a2 = m._12;       float a3 = m._13;       float a4 = m._14;
00339                 float b1 = m._21;       float b2 = m._22;       float b3 = m._23;       float b4 = m._24;
00340                 float c1 = m._31;       float c2 = m._32;       float c3 = m._33;       float c4 = m._34;
00341                 float d1 = m._41;       float d2 = m._42;       float d3 = m._43;       float d4 = m._44;
00342 
00343                 // Adjoint(x,y) = -1^(x+y) * a(y,x)
00344                 // Where a(i,j) is the 3x3 determinant of m with row i and col j removed
00345                 KMatrix retVal;
00346                 retVal._11 = det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
00347                 retVal._12 = -det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
00348                 retVal._13 = det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
00349                 retVal._14 = -det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
00350                 
00351                 retVal._21 = -det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
00352                 retVal._22 = det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
00353                 retVal._23 = -det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
00354                 retVal._24 = det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
00355                 
00356                 retVal._31 = det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
00357                 retVal._32 = -det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
00358                 retVal._33 = det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
00359                 retVal._34 = -det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
00360                 
00361                 retVal._41 = -det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
00362                 retVal._42 = det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
00363                 retVal._43 = -det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
00364                 retVal._44 = det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
00365         
00366                 return retVal;
00367         }
00368 
00369         inline void Inverse()
00370         {
00371                 float det = Determinant( *this );
00372 //              KASSERT( det );
00373 
00374                 *this = Adjoint( *this );
00375                 
00376                 for( int i = 0; i < 4; ++i )
00377                 {
00378                         for( int j = 0; j < 4; ++j )
00379                         {
00380                                 m_Matrix[i][j] /= det;
00381                         }
00382                 }
00383         }
00384 
00385         inline void Transpose()
00386         {
00387                 float x;
00388                 
00389                 x = _21;
00390                 _21     = _12;
00391                 _12 = x;
00392 
00393                 x = _31;
00394                 _31 = _13;
00395                 _13 = x;
00396 
00397                 x = _41;
00398                 _41 = _14;
00399                 _14 = x;
00400 
00401                 x = _32;
00402                 _32 = _23;
00403                 _23 = x;
00404 
00405                 x = _42;
00406                 _42 = _24;
00407                 _24 = x;
00408 
00409                 x = _43;
00410                 _43 = _34;
00411                 _34 = x;
00412         }
00413 
00415         // Fonctions transformation
00417         inline void RotX( float Angle )
00418         {
00419                 float           cosine;
00420                 float           sine;
00421 
00422                 cosine  = (float)cos( Angle );
00423                 sine    = (float)sin( Angle );
00424 
00425                 KMatrix Mat;
00426                 Mat.LoadIdentity();
00427                 Mat._22 = cosine;
00428                 Mat._23 = sine;
00429                 Mat._32 = -sine;
00430                 Mat._33 = cosine;
00431 
00432                 *this *= Mat;
00433         }
00434 
00435         inline void RotY( float Angle )
00436         {
00437                 float           cosine;
00438                 float           sine;
00439 
00440                 cosine  = (float)cos( Angle );
00441                 sine    = (float)sin( Angle );
00442 
00443                 KMatrix         Mat;
00444                 Mat.LoadIdentity();
00445                 Mat._11 = cosine;
00446                 Mat._13 = sine;
00447                 Mat._31 = -sine;
00448                 Mat._33 = cosine;
00449                 
00450                 *this *= Mat;
00451         }
00452 
00453         inline void RotZ( float Angle )
00454         {
00455                 float           cosine;
00456                 float           sine;
00457 
00458                 cosine  = (float)cos( Angle );
00459                 sine    = (float)sin( Angle );
00460 
00461                 KMatrix         Mat;
00462                 Mat.LoadIdentity();
00463                 Mat._11 = cosine;
00464                 Mat._12 = -sine;
00465                 Mat._21 = sine;
00466                 Mat._22 = cosine;
00467                 
00468                 *this *= Mat;
00469         }
00470 
00471         inline void Trans( float x, float y, float z )
00472         {
00473                 _41 += x;
00474                 _42 += y;
00475                 _43 += z;
00476         }
00477         
00478         inline void Scale( float x, float y, float z )
00479         {
00480                 KMatrix         Mat;
00481                 Mat.LoadIdentity();
00482                 Mat._11 = x;
00483                 Mat._22 = y;
00484                 Mat._33 = z;
00485                 
00486                 *this *= Mat;
00487         }
00488 };
00489 
00490 #endif // __MATRIX_H__

Generated on Sun Mar 25 20:02:10 2007 for Zythum Project by  doxygen 1.5.1-p1