00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef TEDDY__MATHS__MATRIX_H
00032 #define TEDDY__MATHS__MATRIX_H
00033
00034
00035 #if defined(_MSC_VER)
00036 # pragma warning(disable:4786)
00037 #endif
00038
00039
00040 #include "Teddy/Maths/Vector.h"
00041 #include "Teddy/Maths/Vector4.h"
00042 #include "Teddy/Maths/CrossVector4.h"
00043 #include "Teddy/SysSupport/StdMaths.h"
00044 using namespace Teddy::SysSupport;
00045
00046
00047 namespace Teddy {
00048 namespace Maths {
00049
00050
00051 class Quaternion;
00052
00053
00069 class Matrix {
00070 public:
00071 static const Matrix IDENTITY;
00072 static const Matrix SWAP_XY;
00073 static const Matrix SWAP_XZ;
00074 static const Matrix SWAP_YZ;
00075 static const Matrix MIRROR_X;
00076 static const Matrix MIRROR_Y;
00077 static const Matrix MIRROR_Z;
00078 public:
00079
00080
00081
00082
00083
00084 float m[4][4];
00085
00086 Matrix(){}
00087 Matrix( const float f ){ *this = f; }
00088 Matrix( const float *pf ){ *this = pf; }
00089 Matrix( const Quaternion &q ){ *this = q; }
00090
00091
00092 void zeroMatrix(){
00093 m[0][0] = m[0][1] = m[0][2] = m[0][3] =
00094 m[1][0] = m[1][1] = m[1][2] = m[1][3] =
00095 m[2][0] = m[2][1] = m[2][2] = m[2][3] =
00096 m[3][0] = m[3][1] = m[3][2] = m[3][3] = 0;
00097 }
00098
00099 operator float* () { return &m[0][0]; }
00100 float &operator () ( const int i, const int j ) { return m[i][j]; }
00101 operator const float* () const { return &m[0][0]; }
00102 float operator () ( const int i, const int j ) const { return m[i][j]; }
00103
00104 void operator=( const float k ){
00105 float *f;
00106
00107 for( f = &m[0][0]; f != (float *)m+16; f++ ){
00108 *f = k;
00109 }
00110 }
00111
00112 void operator=( const float *pf ){
00113 float *to = &m[0][0];
00114
00115 for( register int i=0; i<16; i++ ){
00116 to[i] = pf[i];
00117 }
00118 }
00119
00120 void operator=( const Quaternion &q );
00121
00122 Matrix operator-() const {
00123 Matrix mat;
00124 const float *from = & m[0][0];
00125 float *to = &mat.m[0][0];
00126
00127 for( register int i=0; i<16; i++ ){
00128 to[i] = -from[i];
00129 }
00130 return mat;
00131 }
00132
00133 Matrix operator* ( const Matrix &mat ) const;
00134 const Matrix &operator*=( const Matrix &mat ){ *this = *this * mat; return *this; }
00135 Vector operator* ( const Vector &vec ) const { return transformVector (vec); }
00136 Vector4 operator* ( const Vector4 &vec ) const { return transformVector4(vec); }
00137
00138 Vector transformVector( const Vector &vec ) const {
00139
00140
00141
00142
00143
00144 return Vector(
00145 (m[0][0]*vec.v[0] + m[1][0]*vec.v[1] + m[2][0]*vec.v[2] + m[3][0]),
00146 (m[0][1]*vec.v[0] + m[1][1]*vec.v[1] + m[2][1]*vec.v[2] + m[3][1]),
00147 (m[0][2]*vec.v[0] + m[1][2]*vec.v[1] + m[2][2]*vec.v[2] + m[3][2])
00148 );
00149 }
00150 Vector4 transformVector4( const Vector4 &vec ) const {
00151 return Vector4(
00152 (m[0][0]*vec.v[0] + m[1][0]*vec.v[1] + m[2][0]*vec.v[2] + m[3][0]*vec.v[3]),
00153 (m[0][1]*vec.v[0] + m[1][1]*vec.v[1] + m[2][1]*vec.v[2] + m[3][1]*vec.v[3]),
00154 (m[0][2]*vec.v[0] + m[1][2]*vec.v[1] + m[2][2]*vec.v[2] + m[3][2]*vec.v[3]),
00155 (m[0][3]*vec.v[0] + m[1][3]*vec.v[1] + m[2][3]*vec.v[2] + m[3][3]*vec.v[3])
00156 );
00157 }
00158
00159 Vector4 getRow ( const int i ) const { return Vector4( m[i][0], m[i][1], m[i][2], m[i][3] ); }
00160 Vector4 getColumn ( const int i ) const { return Vector4( m[0][i], m[1][i], m[2][i], m[3][i] ); }
00161 void setRow ( const int i, const Vector4 &v ) { m[i][0] = (float)v[0]; m[i][1] = (float)v[1]; m[i][2] = (float)v[2]; m[i][3] = (float)v[3]; }
00162 void setColumn ( const int i, const Vector4 &v ) { m[0][i] = (float)v[0]; m[1][i] = (float)v[1]; m[2][i] = (float)v[2]; m[3][i] = (float)v[3]; }
00163 Vector get3Row ( const int i ) const { return Vector ( m[i][0], m[i][1], m[i][2] ); }
00164 Vector get3Column( const int i ) const { return Vector ( m[0][i], m[1][i], m[2][i] ); }
00165 void set3Row ( const int i, const Vector &v ) { m[i][0] = (float)v[0]; m[i][1] = (float)v[1]; m[i][2] = (float)v[2]; }
00166 void set3Column( const int i, const Vector &v ) { m[0][i] = (float)v[0]; m[1][i] = (float)v[1]; m[2][i] = (float)v[2]; }
00167
00169 Vector uniformTransformNormal( const Vector &vec ) const {
00170
00171
00172
00173
00174
00175 return Vector(
00176 (m[0][0]*vec.v[0] + m[1][0]*vec.v[1] + m[2][0]*vec.v[2] ),
00177 (m[0][1]*vec.v[0] + m[1][1]*vec.v[1] + m[2][1]*vec.v[2] ),
00178 (m[0][2]*vec.v[0] + m[1][2]*vec.v[1] + m[2][2]*vec.v[2] )
00179 );
00180 }
00181
00182 void modelMatrix( const Quaternion &q, const Vector &vFrom ){
00183 *this = q;
00184 m[3][0] = (float)vFrom.v[0];
00185 m[3][1] = (float)vFrom.v[1];
00186 m[3][2] = (float)vFrom.v[2];
00187 }
00188
00189 void translateMatrix( const TVector<double> &v ){
00190
00191
00192
00193
00194 m[0][1] = m[0][2] = m[0][3] =
00195 m[1][0] = m[1][2] = m[1][3] =
00196 m[2][0] = m[2][1] = m[2][3] = 0;
00197 m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
00198 m[3][0] = (float)v[0];
00199 m[3][1] = (float)v[1];
00200 m[3][2] = (float)v[2];
00201 }
00202
00203 void translateMatrix( const Vector &v ){
00204
00205
00206
00207
00208 m[0][1] = m[0][2] = m[0][3] =
00209 m[1][0] = m[1][2] = m[1][3] =
00210 m[2][0] = m[2][1] = m[2][3] = 0;
00211 m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
00212 m[3][0] = (float)v[0];
00213 m[3][1] = (float)v[1];
00214 m[3][2] = (float)v[2];
00215 }
00216
00217
00218 void translateMatrix( const float x, const float y, const float z ){
00219
00220
00221
00222
00223 m[0][1] = m[0][2] = m[0][3] =
00224 m[1][0] = m[1][2] = m[1][3] =
00225 m[2][0] = m[2][1] = m[2][3] = 0;
00226 m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
00227 m[3][0] = x;
00228 m[3][1] = y;
00229 m[3][2] = z;
00230 }
00231
00232
00233
00234 void translate( const float x, const float y, const float z ){
00235
00236
00237
00238
00239
00240 m[3][0] = m[0][0]*x + m[1][0]*y + m[2][0]*z + m[3][0];
00241 m[3][1] = m[0][1]*x + m[1][1]*y + m[2][1]*z + m[3][1];
00242 m[3][2] = m[0][2]*x + m[1][2]*y + m[2][2]*z + m[3][2];
00243 }
00244
00245 void translate( const float *pf ){
00246 translate( pf[0], pf[1], pf[2] );
00247 }
00248
00249
00250 void scaleMatrix( const float x, const float y, const float z ){
00251
00252
00253
00254
00255 m[0][1] = m[0][2] = m[0][3] =
00256 m[1][0] = m[1][2] = m[1][3] =
00257 m[2][0] = m[2][1] = m[2][3] =
00258 m[3][0] = m[3][1] = m[3][2] = 0;
00259 m[0][0] = x;
00260 m[1][1] = y;
00261 m[2][2] = z;
00262 m[3][3] = 1;
00263 }
00264
00265 void scaleMatrix( const float *pf ){
00266 scaleMatrix( pf[0], pf[1], pf[2] );
00267 }
00268
00269 void scale( const float x, const float y, const float z ){
00270
00271
00272
00273
00274
00275 m[0][0] *= x; m[1][0] *= y; m[2][0] *= z;
00276 m[0][1] *= x; m[1][1] *= y; m[2][1] *= z;
00277 m[0][2] *= x; m[1][2] *= y; m[2][2] *= z;
00278 }
00279
00280 void scale( const float *pf ){
00281 scale( pf[0], pf[1], pf[2] );
00282 }
00283
00284
00285 void rotateXMatrix( const float radians ){
00286
00287
00288
00289
00290 m[0][1] = m[0][2] = m[0][3] =
00291 m[1][0] = m[1][3] =
00292 m[2][0] = m[2][3] =
00293 m[3][0] = m[3][1] = m[3][2] = 0;
00294 m[0][0] = m[3][3] = 1;
00295
00296 float fCos = cosf( radians );
00297 float fSin = sinf( radians );
00298 m[1][1] = m[2][2] = fCos;
00299 m[1][2] = fSin;
00300 m[2][1] = -fSin;
00301 }
00302
00303 void rotateX( const float radians ){
00304
00305
00306
00307
00308
00309 float fTemp;
00310 float fCos = cosf( radians );
00311 float fSin = sinf( radians );
00312
00313 fTemp = m[1][0]*fCos + m[2][0]*fSin;
00314 m[2][0] = m[2][0]*fCos - m[1][0]*fSin;
00315 m[1][0] = fTemp;
00316 fTemp = m[1][1]*fCos + m[2][1]*fSin;
00317 m[2][1] = m[2][1]*fCos - m[1][1]*fSin;
00318 m[1][1] = fTemp;
00319 fTemp = m[1][2]*fCos + m[2][2]*fSin;
00320 m[2][2] = m[2][2]*fCos - m[1][2]*fSin;
00321 m[1][2] = fTemp;
00322 }
00323
00324 void rotateYMatrix( const float radians ){
00325
00326
00327
00328
00329 m[0][1] = m[0][3] =
00330 m[1][0] = m[1][2] = m[1][3] =
00331 m[2][1] = m[2][3] =
00332 m[3][0] = m[3][1] = m[3][2] = 0;
00333 m[1][1] = m[3][3] = 1;
00334
00335 float fCos = cosf( radians );
00336 float fSin = sinf( radians );
00337 m[0][0] = m[2][2] = fCos;
00338 m[0][2] = -fSin;
00339 m[2][0] = fSin;
00340 }
00341 void rotateY( const float radians ){
00342
00343
00344
00345
00346
00347 float fTemp;
00348 float fCos = cosf( radians );
00349 float fSin = sinf( radians );
00350 fTemp = m[0][0]*fCos - m[2][0]*fSin;
00351 m[2][0] = m[0][0]*fSin + m[2][0]*fCos;
00352 m[0][0] = fTemp;
00353 fTemp = m[0][1]*fCos - m[2][1]*fSin;
00354 m[2][1] = m[0][1]*fSin + m[2][1]*fCos;
00355 m[0][1] = fTemp;
00356 fTemp = m[0][2]*fCos - m[2][2]*fSin;
00357 m[2][2] = m[0][2]*fSin + m[2][2]*fCos;
00358 m[0][2] = fTemp;
00359 }
00360 void rotateZMatrix( const float radians ){
00361
00362
00363
00364
00365 m[0][2] = m[0][3] =
00366 m[1][2] = m[1][3] =
00367 m[2][0] = m[2][1] = m[2][3] =
00368 m[3][0] = m[3][1] = m[3][2] = 0;
00369 m[2][2] = m[3][3] = 1;
00370
00371 float fCos = cosf( radians );
00372 float fSin = sinf( radians );
00373 m[0][0] = m[1][1] = fCos;
00374 m[0][1] = fSin;
00375 m[1][0] = -fSin;
00376 }
00377
00378 void rotateZ( const float radians ){
00379
00380
00381
00382
00383
00384 float fTemp;
00385 float fCos = cosf( radians );
00386 float fSin = sinf( radians );
00387 fTemp = m[0][0]*fCos + m[1][0]*fSin;
00388 m[1][0] = m[1][0]*fCos - m[0][0]*fSin;
00389 m[0][0] = fTemp;
00390 fTemp = m[0][1]*fCos + m[1][1]*fSin;
00391 m[1][1] = m[1][1]*fCos - m[0][1]*fSin;
00392 m[0][1] = fTemp;
00393 fTemp = m[0][2]*fCos + m[1][2]*fSin;
00394 m[1][2] = m[1][2]*fCos - m[0][2]*fSin;
00395 m[0][2] = fTemp;
00396 }
00397
00398 void rotateMatrix( const Vector &vec, const double radians ){
00399
00400 float fCos = (float)cos( radians );
00401 Vector vCos = vec * (1 - fCos);
00402 Vector vSin = vec * (float)sin( radians );
00403
00404 m[0][3] =
00405 m[1][3] =
00406 m[2][3] =
00407 m[3][0] = m[3][1] = m[3][2] = 0;
00408 m[3][3] = 1;
00409
00410 m[0][0] = (float)((vec.v[0] * vCos.v[0]) + fCos);
00411 m[1][0] = (float)((vec.v[0] * vCos.v[1]) - (vSin.v[2]));
00412 m[2][0] = (float)((vec.v[0] * vCos.v[2]) + (vSin.v[1]));
00413 m[0][1] = (float)((vec.v[1] * vCos.v[0]) + (vSin.v[2]));
00414 m[1][1] = (float)((vec.v[1] * vCos.v[1]) + fCos);
00415 m[2][1] = (float)((vec.v[1] * vCos.v[2]) - (vSin.v[0]));
00416 m[0][2] = (float)((vec.v[2] * vCos.v[0]) - (vSin.v[1]));
00417 m[2][1] = (float)((vec.v[2] * vCos.v[1]) + (vSin.v[0]));
00418 m[2][2] = (float)((vec.v[2] * vCos.v[2]) + fCos);
00419 }
00420
00421 void rotate( const Vector &vec, const double f ){
00422
00423 Matrix mat;
00424 mat.rotateMatrix( vec, f );
00425 *this *= mat;
00426 }
00427
00428 void direction( const Vector &vec ){
00429 Vector z = vec;
00430 Vector h;
00431 z.normalize();
00432 if( z[0]< (sqrt(2.0)/2.0) ){
00433 h = Vector(1,0,0);
00434 }else{
00435 h = Vector(0,1,0);
00436 }
00437 Vector x = z ^ h;
00438 Vector y = z ^ x;
00439 x = z ^ y;
00440
00441
00442
00443 setRow( 0, Vector4(x,0) );
00444 setRow( 1, Vector4(y,0) );
00445 setRow( 2, Vector4(z,0) );
00446 setRow( 3, Vector4(0,0,0,1) );
00447 }
00448
00449 bool invert(){
00450 Vector4 x = getColumn( 0 );
00451 Vector4 y = getColumn( 1 );
00452 Vector4 z = getColumn( 2 );
00453 Vector4 w = getColumn( 3 );
00454 Vector4 x1 = CrossVector4( y, z, w );
00455 Vector4 y1 = CrossVector4( z, w, x );
00456 Vector4 z1 = CrossVector4( w, x, y );
00457 Vector4 w1 = CrossVector4( x, y, z );
00458 float lx = x | x1;
00459 float ly = y | y1;
00460 float lz = z | z1;
00461 float lw = w | w1;
00462
00463 if( !lx || !ly || !lz || !lw ){
00464 return false;
00465 }
00466
00467 x1 *= 1.0f/lx;
00468 y1 *= 1.0f/ly;
00469 z1 *= 1.0f/lz;
00470 w1 *= 1.0f/lw;
00471
00472 setRow( 0, x1 );
00473 setRow( 1, y1 );
00474 setRow( 2, z1 );
00475 setRow( 3, w1 );
00476 return true;
00477 }
00478
00479
00480 void transpose(){
00481 # define SWAP(a,b,c) c=a; a=b; b=c
00482 float f;
00483 SWAP(m[0][1], m[1][0], f);
00484 SWAP(m[0][2], m[2][0], f);
00485 SWAP(m[0][3], m[3][0], f);
00486 SWAP(m[1][2], m[2][1], f);
00487 SWAP(m[1][3], m[3][1], f);
00488 SWAP(m[2][3], m[3][2], f);
00489 # undef SWAP
00490 }
00491
00492 };
00493
00494
00495 };
00496 };
00497
00498
00499 #endif // TEDDY__MATHS__MATRIX_H
00500