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
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;
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
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
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
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
00344
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
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
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__