00001
00002
00003
00004
00005
00006 #ifndef _GMTL_MATRIX_H_
00007 #define _GMTL_MATRIX_H_
00008
00009 #include <gmtl/Defines.h>
00010 #include <gmtl/Math.h>
00011 #include <gmtl/Util/Assert.h>
00012 #include <gmtl/Util/StaticAssert.h>
00013
00014 namespace gmtl
00015 {
00016
00106 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00107 class Matrix
00108 {
00109 public:
00110
00111
00112
00113
00114 #if defined(__MACH__) && defined(__APPLE_CC__) && defined(__GNUC__) && \
00115 __GNUC__ == 3 && __GNUC_MINOR__ == 3
00116 bool dummy_;
00117 #endif
00118
00121 typedef DATA_TYPE DataType;
00122 enum Params
00123 {
00124 Rows = ROWS, Cols = COLS
00125 };
00126
00131 class RowAccessor
00132 {
00133 public:
00134 typedef DATA_TYPE DataType;
00135
00136 RowAccessor(Matrix<DATA_TYPE,ROWS,COLS>* mat, const unsigned row)
00137 : mMat(mat), mRow(row)
00138 {
00139 gmtlASSERT(row < ROWS);
00140 gmtlASSERT(NULL != mat);
00141 }
00142
00143 DATA_TYPE& operator[](const unsigned column)
00144 {
00145 gmtlASSERT(column < COLS);
00146 return (*mMat)(mRow,column);
00147 }
00148
00149 Matrix<DATA_TYPE,ROWS,COLS>* mMat;
00150 unsigned mRow;
00151 };
00152
00157 class ConstRowAccessor
00158 {
00159 public:
00160 typedef DATA_TYPE DataType;
00161
00162 ConstRowAccessor( const Matrix<DATA_TYPE,ROWS,COLS>* mat,
00163 const unsigned row )
00164 : mMat( mat ), mRow( row )
00165 {
00166 gmtlASSERT( row < ROWS );
00167 gmtlASSERT( NULL != mat );
00168 }
00169
00170 const DATA_TYPE& operator[](const unsigned column) const
00171 {
00172 gmtlASSERT(column < COLS);
00173 return (*mMat)(mRow,column);
00174 }
00175
00176 const Matrix<DATA_TYPE,ROWS,COLS>* mMat;
00177 unsigned mRow;
00178 };
00179
00181 enum XformState
00182 {
00183
00184 IDENTITY = 1,
00185
00186
00187 TRANS = 2,
00188
00189
00190 ORTHOGONAL = 4,
00191
00192
00193
00194
00195
00196
00197
00198 AFFINE = 16,
00199
00200
00201
00202 NON_UNISCALE = 32,
00203
00204
00205
00206 FULL = 64,
00207
00208
00209 XFORM_ERROR = 128
00210 };
00211
00213 Matrix()
00214 {
00216 for (unsigned int r = 0; r < ROWS; ++r)
00217 {
00218 for (unsigned int c = 0; c < COLS; ++c)
00219 { this->operator()( r, c ) = (DATA_TYPE)0.0; }
00220 }
00221
00223 for (unsigned int x = 0; x < Math::Min( COLS, ROWS ); ++x)
00224 { this->operator()( x, x ) = (DATA_TYPE)1.0; }
00225
00227 mState = IDENTITY;
00228 }
00229
00231 Matrix( const Matrix<DATA_TYPE, ROWS, COLS>& matrix )
00232 {
00233 this->set( matrix.getData() );
00234 mState = matrix.mState;
00235 }
00236
00241 void set( DATA_TYPE v00, DATA_TYPE v01,
00242 DATA_TYPE v10, DATA_TYPE v11 )
00243 {
00244 GMTL_STATIC_ASSERT( (ROWS == 2 && COLS == 2), Set_called_when_Matrix_not_of_size_2_2 );
00245 mData[0] = v00;
00246 mData[1] = v10;
00247 mData[2] = v01;
00248 mData[3] = v11;
00249 mState = FULL;
00250 }
00251
00255 void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02,
00256 DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12 )
00257 {
00258 GMTL_STATIC_ASSERT( (ROWS == 2 && COLS == 3), Set_called_when_Matrix_not_of_size_2_3 );
00259 mData[0] = v00;
00260 mData[1] = v10;
00261 mData[2] = v01;
00262 mData[3] = v11;
00263 mData[4] = v02;
00264 mData[5] = v12;
00265 mState = FULL;
00266 }
00267
00271 void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02,
00272 DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12,
00273 DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22)
00274 {
00275 GMTL_STATIC_ASSERT( (ROWS == 3 && COLS == 3), Set_called_when_Matrix_not_of_size_3_3 );
00276 mData[0] = v00;
00277 mData[1] = v10;
00278 mData[2] = v20;
00279
00280 mData[3] = v01;
00281 mData[4] = v11;
00282 mData[5] = v21;
00283
00284 mData[6] = v02;
00285 mData[7] = v12;
00286 mData[8] = v22;
00287 mState = FULL;
00288 }
00289
00293 void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v03,
00294 DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12, DATA_TYPE v13,
00295 DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22, DATA_TYPE v23)
00296 {
00297 GMTL_STATIC_ASSERT( (ROWS == 3 && COLS == 4), Set_called_when_Matrix_not_of_size_3_4 );
00298 mData[0] = v00;
00299 mData[1] = v10;
00300 mData[2] = v20;
00301 mData[3] = v01;
00302 mData[4] = v11;
00303 mData[5] = v21;
00304 mData[6] = v02;
00305 mData[7] = v12;
00306 mData[8] = v22;
00307
00308
00309 mData[9] = v03;
00310 mData[10] = v13;
00311 mData[11] = v23;
00312 mState = FULL;
00313 }
00314
00318 void set( DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v03,
00319 DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12, DATA_TYPE v13,
00320 DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22, DATA_TYPE v23,
00321 DATA_TYPE v30, DATA_TYPE v31, DATA_TYPE v32, DATA_TYPE v33 )
00322 {
00323 GMTL_STATIC_ASSERT( (ROWS == 4 && COLS == 4), Set_called_when_Matrix_not_of_size_4_4 );
00324 mData[0] = v00;
00325 mData[1] = v10;
00326 mData[2] = v20;
00327 mData[4] = v01;
00328 mData[5] = v11;
00329 mData[6] = v21;
00330 mData[8] = v02;
00331 mData[9] = v12;
00332 mData[10] = v22;
00333
00334
00335 mData[12] = v03;
00336 mData[13] = v13;
00337 mData[14] = v23;
00338
00339
00340 mData[3] = v30;
00341 mData[7] = v31;
00342 mData[11] = v32;
00343 mData[15] = v33;
00344 mState = FULL;
00345 }
00346
00350
00351
00370 void set( const DATA_TYPE* data )
00371 {
00373 for (unsigned int x = 0; x < ROWS * COLS; ++x)
00374 mData[x] = data[x];
00375 mState = FULL;
00376 }
00377
00400 void setTranspose( const DATA_TYPE* data )
00401 {
00403 for (unsigned int r = 0; r < ROWS; ++r)
00404 for (unsigned int c = 0; c < COLS; ++c)
00405 this->operator()( r, c ) = data[(r * COLS) + c];
00406 mState = FULL;
00407 }
00408
00417 DATA_TYPE& operator()( const unsigned row, const unsigned column )
00418 {
00419 gmtlASSERT( (row < ROWS) && (column < COLS) );
00420 return mData[column*ROWS + row];
00421 }
00422
00424 const DATA_TYPE& operator()( const unsigned row, const unsigned column ) const
00425 {
00426 gmtlASSERT( (row < ROWS) && (column < COLS) );
00427 return mData[column*ROWS + row];
00428 }
00429
00438 RowAccessor operator[]( const unsigned row )
00439 {
00440 return RowAccessor(this, row);
00441 }
00442
00444 ConstRowAccessor operator[]( const unsigned row ) const
00445 {
00446 return ConstRowAccessor( this, row );
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00461 const DATA_TYPE* getData() const { return (DATA_TYPE*)mData; }
00462
00463 bool isError()
00464 {
00465 return mState & XFORM_ERROR;
00466 }
00467 void setError()
00468 {
00469 mState |= XFORM_ERROR;
00470 }
00471
00472 void setState(int state)
00473 { mState = state; }
00474
00475 public:
00485 DATA_TYPE mData[COLS*ROWS];
00486
00488 int mState;
00489 };
00490
00491 typedef Matrix<float, 2, 2> Matrix22f;
00492 typedef Matrix<double, 2, 2> Matrix22d;
00493 typedef Matrix<float, 2, 3> Matrix23f;
00494 typedef Matrix<double, 2, 3> Matrix23d;
00495 typedef Matrix<float, 3, 3> Matrix33f;
00496 typedef Matrix<double, 3, 3> Matrix33d;
00497 typedef Matrix<float, 3, 4> Matrix34f;
00498 typedef Matrix<double, 3, 4> Matrix34d;
00499 typedef Matrix<float, 4, 4> Matrix44f;
00500 typedef Matrix<double, 4, 4> Matrix44d;
00501
00503 const Matrix22f MAT_IDENTITY22F = Matrix22f();
00504
00506 const Matrix22d MAT_IDENTITY22D = Matrix22d();
00507
00509 const Matrix23f MAT_IDENTITY23F = Matrix23f();
00510
00512 const Matrix23d MAT_IDENTITY23D = Matrix23d();
00513
00515 const Matrix33f MAT_IDENTITY33F = Matrix33f();
00516
00518 const Matrix33d MAT_IDENTITY33D = Matrix33d();
00519
00521 const Matrix34f MAT_IDENTITY34F = Matrix34f();
00522
00524 const Matrix34d MAT_IDENTITY34D = Matrix34d();
00525
00527 const Matrix44f MAT_IDENTITY44F = Matrix44f();
00528
00530 const Matrix44d MAT_IDENTITY44D = Matrix44d();
00531
00536 inline int combineMatrixStates( int state1, int state2 )
00537 {
00538 switch (state1)
00539 {
00540 case Matrix44f::IDENTITY:
00541 switch (state2)
00542 {
00543 case Matrix44f::XFORM_ERROR: return state2;
00544 case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00545 default: return state2;
00546 }
00547 case Matrix44f::TRANS:
00548 switch (state2)
00549 {
00550 case Matrix44f::IDENTITY: return state1;
00551 case Matrix44f::ORTHOGONAL: return Matrix44f::AFFINE;
00552 case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00553 default: return state2;
00554 }
00555 case Matrix44f::ORTHOGONAL:
00556 switch (state2)
00557 {
00558 case Matrix44f::IDENTITY: return state1;
00559 case Matrix44f::TRANS: return Matrix44f::AFFINE;
00560 case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00561 default: return state2;
00562 }
00563 case Matrix44f::AFFINE:
00564 switch (state2)
00565 {
00566 case Matrix44f::IDENTITY:
00567 case Matrix44f::TRANS:
00568 case Matrix44f::ORTHOGONAL: return state1;
00569 case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00570 case Matrix44f::AFFINE | Matrix44f::NON_UNISCALE:
00571 default: return state2;
00572 }
00573 case Matrix44f::AFFINE | Matrix44f::NON_UNISCALE:
00574 switch (state2)
00575 {
00576 case Matrix44f::IDENTITY:
00577 case Matrix44f::TRANS:
00578 case Matrix44f::ORTHOGONAL:
00579 case Matrix44f::AFFINE: return state1;
00580 case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00581 default: return state2;
00582 }
00583 case Matrix44f::FULL:
00584 switch (state2)
00585 {
00586 case Matrix44f::XFORM_ERROR: return state2;
00587 case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
00588 default: return state1;
00589 }
00590 break;
00591 default:
00592 return Matrix44f::XFORM_ERROR;
00593 }
00594 }
00595
00596 }
00597
00598
00599
00600 #endif