00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __VMML__MATRIX4__H__
00019 #define __VMML__MATRIX4__H__
00020
00021
00022
00023
00024
00025 #include <cmath>
00026 #include <cstdlib>
00027 #include <iomanip>
00028 #include <iostream>
00029 #include <algorithm>
00030 #include <cassert>
00031 #include <string>
00032 #include <vector>
00033
00034
00035
00036
00037
00038
00039
00040 namespace vmml
00041 {
00042 template< typename T > class Matrix3;
00043 template< typename T > class Vector3;
00044 template< typename T > class Vector4;
00045
00046 template< typename T >
00047 class Matrix4
00048 {
00049 public:
00050 union
00051 {
00052 struct
00053 {
00061 T m00, m10, m20, m30, m01, m11, m21, m31,
00062 m02, m12, m22, m32, m03, m13, m23, m33;
00063 };
00064 struct
00065 {
00066 T rot00, rot10, rot20, d30,
00067 rot01, rot11, rot21, d31,
00068 rot02, rot12, rot22, d32,
00069 x, y, z, d33;
00070 };
00071
00076 T ml[16];
00077 T array[16];
00078
00086 T m[4][4];
00087 };
00088
00089 Matrix4();
00090 Matrix4( T v00, T v01, T v02, T v03,
00091 T v10, T v11, T v12, T v13,
00092 T v20, T v21, T v22, T v23,
00093 T v30, T v31, T v32, T v33 );
00094 Matrix4( const Vector4<T>& v0, const Vector4<T>& v1,
00095 const Vector4<T>& v2, const Vector4<T>& v3,
00096 bool columnVectors = false );
00097
00098 Matrix4( const Matrix4& other );
00099
00100 template< typename U >
00101 Matrix4( const Matrix4< U >& other );
00102
00103
00104 Matrix4( const float* values );
00105 Matrix4( const double* values );
00106
00107 inline const Matrix4& operator= ( const Matrix4& other );
00108 template< typename U >
00109 inline const Matrix4& operator= ( const Matrix4< U >& other );
00110
00111 inline bool operator== ( const Matrix4& other ) const;
00112 inline bool operator!= ( const Matrix4& other ) const;
00113
00114 void set( const Matrix4& other );
00115
00116
00117
00118 void set( const float* other );
00119 void set( const double* other );
00120 void set( T v00, T v01, T v02, T v03, T v10, T v11, T v12, T v13,
00121 T v20, T v21, T v22, T v23, T v30, T v31, T v32, T v33 );
00122
00123
00124
00125
00126
00127 bool set( const std::string& values, char delimiter = ' ' );
00128
00129 bool set( const std::vector< std::string >& values );
00130
00131 const T& getElement( const size_t row, const size_t col ) const;
00132 void setElement( const size_t row, const size_t col, const T& value ) const;
00133
00134 Vector4< T > getColumn( const size_t column ) const;
00135 Vector4< T > getRow( const size_t row ) const;
00136
00137
00138 void setColumn( const size_t column, const Vector3< T >& columnvec );
00139 void setRow( const size_t row, const Vector3< T >& rowvec );
00140
00141 void setColumn( const size_t column, const Vector4< T >& columnvec );
00142 void setRow( const size_t row, const Vector4< T >& rowvec );
00143
00144
00145 template< typename U >
00146 void set3x3SubMatrix( const Matrix3< U >& m3x3, size_t columnOffset = 0,
00147 size_t rowOffset = 0 );
00148 void get3x3SubMatrix( Matrix3< T >& result, size_t rowOffset = 0,
00149 size_t colOffset = 0 ) const;
00150
00151
00152 Matrix4 operator+ ( const Matrix4& other ) const;
00153 Matrix4 operator- ( const Matrix4& other ) const;
00154 Matrix4 operator* ( const Matrix4& other ) const;
00155 Matrix4 operator* ( T scalar ) const;
00156 inline Matrix4 operator/ ( T scalar ) const
00157 { scalar = 1.0 / scalar; return operator*(scalar); };
00158
00159
00160 Vector3< T > operator* ( const Vector3< T >& other ) const;
00161 Vector4< T > operator* ( const Vector4< T >& other ) const;
00162
00163 Matrix4& operator+= ( const Matrix4& other );
00164 Matrix4& operator-= ( const Matrix4& other );
00165 Matrix4& operator*= ( const Matrix4& other );
00166 Matrix4& operator*= ( T scalar );
00167 inline Matrix4& operator/= ( T scalar )
00168 { scalar = 1.0 / scalar; return operator*=( scalar ); };
00169
00170 Matrix4 negate() const;
00171 Matrix4 operator-() const;
00172
00173 Matrix4 getTransposed() const;
00174
00175 T getDeterminant() const;
00176 inline T det() const;
00177
00178 Matrix4 getAdjugate() const;
00179 inline Matrix4 getAdjoint() const;
00180
00181 Matrix4 getInverse( bool& isInvertible, T limit = 0.0000000001 ) const;
00182 inline bool getInverse( Matrix4& result, T limit = 0.0000000001 ) const;
00183
00188 void rotate( const T angle, const Vector3< T >& axis );
00189
00190 void rotateX( const T angle );
00191 void rotateY( const T angle );
00192 void rotateZ( const T angle );
00193 void preRotateX( const T angle );
00194 void preRotateY( const T angle );
00195 void preRotateZ( const T angle );
00196 void scale( const T scale[3] );
00197 void scale( const T x, const T y, const T z );
00198 void scale( const Vector3< T >& scale_ );
00199 void scaleTranslation( const T scale_[3] );
00200 void scaleTranslation( const Vector3< T >& scale_ );
00201 void setTranslation( const T x, const T y, const T z );
00202 void setTranslation( const T trans[3] );
00203 void setTranslation( const Vector3< T >& trans );
00204 Vector3< T > getTranslation() const;
00205
00206 void tensor( const Vector3< T >& u, const Vector3< T >& v );
00207 void tensor( const Vector4< T >& u, const Vector4< T >& v );
00208
00209
00210
00211
00212 T getMinor( const size_t row0, const size_t row1, const size_t row2,
00213 const size_t col0, const size_t col1, const size_t col2 ) const;
00214
00215 T getMinor( const size_t removeRow, const size_t removeCol ) const;
00216
00217
00218
00219 bool getString( std::string& result, const std::string& delimiter = " " ) const;
00220
00221 friend std::ostream& operator << ( std::ostream& os, const Matrix4& m )
00222 {
00223 const std::ios::fmtflags flags = os.flags();
00224 const int prec = os.precision();
00225
00226 os.setf( std::ios::right, std::ios::adjustfield );
00227 os.precision( 5 );
00228 os << std::endl << "|"
00229 << std::setw(10) << m.m00 << " "
00230 << std::setw(10) << m.m01 << " "
00231 << std::setw(10) << m.m02 << " "
00232 << std::setw(10) << m.m03 << "|"
00233 << std::endl << "|"
00234 << std::setw(10) << m.m10 << " "
00235 << std::setw(10) << m.m11 << " "
00236 << std::setw(10) << m.m12 << " "
00237 << std::setw(10) << m.m13 << "|"
00238 << std::endl << "|"
00239 << std::setw(10) << m.m20 << " "
00240 << std::setw(10) << m.m21 << " "
00241 << std::setw(10) << m.m22 << " "
00242 << std::setw(10) << m.m23 << "|"
00243 << std::endl << "|"
00244 << std::setw(10) << m.m30 << " "
00245 << std::setw(10) << m.m31 << " "
00246 << std::setw(10) << m.m32 << " "
00247 << std::setw(10) << m.m33 << "|" << std::endl;
00248 os.precision( prec );
00249 os.setf( flags );
00250 return os;
00251 };
00252
00253 static const Matrix4 IDENTITY;
00254 static const Matrix4 ZERO;
00255
00256 };
00257
00258
00259 typedef Matrix4< float > Matrix4f;
00260 typedef Matrix4< double > Matrix4d;
00261
00262 typedef Matrix4< float > mat4f;
00263 typedef Matrix4< double > mat4d;
00264
00265 }
00266
00267
00268
00269
00270
00271
00272 #include <vmmlib/matrix3.h>
00273 #include <vmmlib/vector3.h>
00274 #include <vmmlib/vector4.h>
00275 #include <vmmlib/stringUtils.h>
00276
00277 namespace vmml
00278 {
00279
00280 template< typename T >
00281 const Matrix4< T > Matrix4< T >::IDENTITY( 1, 0, 0, 0, 0, 1, 0, 0,
00282 0, 0, 1, 0, 0, 0, 0, 1 );
00283
00284 template< typename T >
00285 const Matrix4< T > Matrix4< T >::ZERO( 0, 0, 0, 0, 0, 0, 0, 0,
00286 0, 0, 0, 0, 0, 0, 0, 0 );
00287
00288
00289 template< typename T >
00290 Matrix4< T >::Matrix4()
00291 {}
00292
00293
00294
00295 template< typename T >
00296 Matrix4< T >::Matrix4( T v00, T v01, T v02, T v03,
00297 T v10, T v11, T v12, T v13,
00298 T v20, T v21, T v22, T v23,
00299 T v30, T v31, T v32, T v33 )
00300 : m00( v00 )
00301 , m10( v10 )
00302 , m20( v20 )
00303 , m30( v30 )
00304 , m01( v01 )
00305 , m11( v11 )
00306 , m21( v21 )
00307 , m31( v31 )
00308 , m02( v02 )
00309 , m12( v12 )
00310 , m22( v22 )
00311 , m32( v32 )
00312 , m03( v03 )
00313 , m13( v13 )
00314 , m23( v23 )
00315 , m33( v33 )
00316 {}
00317
00318
00319
00320 template< typename T >
00321 Matrix4< T >::Matrix4( const Matrix4& other )
00322 {
00323 memcpy(ml,other.ml, 16 * sizeof( T ) );
00324 }
00325
00326
00327
00328 template< typename T >
00329 template< typename U >
00330 Matrix4< T >::Matrix4( const Matrix4< U >& other )
00331 {
00332 for ( size_t i = 0; i < 16; ++i )
00333 ml[i] = static_cast< T > ( other.ml[i] );
00334 }
00335
00336
00337
00338 template< typename T >
00339 Matrix4< T >::Matrix4( const Vector4< T >& v0, const Vector4< T >& v1,
00340 const Vector4< T >& v2, const Vector4< T >& v3,
00341 bool columnVectors )
00342 {
00343 if ( columnVectors )
00344 for ( size_t i = 0; i < 4; ++i )
00345 {
00346 m[0][i] = v0[i];
00347 m[1][i] = v1[i];
00348 m[2][i] = v2[i];
00349 m[3][i] = v3[i];
00350 }
00351 else
00352 for ( size_t i = 0; i < 4; ++i )
00353 {
00354 m[i][0] = v0[i];
00355 m[i][1] = v1[i];
00356 m[i][2] = v2[i];
00357 m[i][3] = v3[i];
00358 }
00359 }
00360
00361
00362
00363 template< typename T >
00364 const T& Matrix4< T >::getElement( const size_t row, const size_t col ) const
00365 {
00366 return m[col][row];
00367 }
00368
00369
00370
00371 template< typename T >
00372 void Matrix4< T >::setElement( const size_t row, const size_t col,
00373 const T& value ) const
00374 {
00375 m[col][row] = value;
00376 }
00377
00378
00379
00380 template< typename T >
00381 Matrix4< T >::Matrix4( const float* values )
00382 {
00383 assert( values && "Matrix4: Initialisation of a Matrix from a Nullpointer was requested." );
00384 for ( size_t i = 0; i < 16; ++i )
00385 ml[i] = static_cast< T > ( values[i] );
00386 }
00387
00388
00389
00390 template< typename T >
00391 Matrix4< T >::Matrix4( const double* values )
00392 {
00393 assert( values && "Matrix4: Initialisation of a Matrix from a Nullpointer was requested." );
00394 for ( size_t i = 0; i < 16; ++i )
00395 ml[i] = static_cast< T > ( values[i] );
00396 }
00397
00398
00399
00400 template< typename T >
00401 const Matrix4< T >& Matrix4< T >::operator= ( const Matrix4< T >& other )
00402 {
00403 memcpy( ml, other.ml, 16 * sizeof( T ) );
00404 return *this;
00405 }
00406
00407
00408
00409 template< typename T >
00410 template< typename U >
00411 const Matrix4< T >& Matrix4< T >::operator= ( const Matrix4< U >& other )
00412 {
00413 ml[ 0 ] = static_cast< T > ( other.ml[ 0 ] );
00414 ml[ 1 ] = static_cast< T > ( other.ml[ 1 ] );
00415 ml[ 2 ] = static_cast< T > ( other.ml[ 2 ] );
00416 ml[ 3 ] = static_cast< T > ( other.ml[ 3 ] );
00417 ml[ 4 ] = static_cast< T > ( other.ml[ 4 ] );
00418 ml[ 5 ] = static_cast< T > ( other.ml[ 5 ] );
00419 ml[ 6 ] = static_cast< T > ( other.ml[ 6 ] );
00420 ml[ 7 ] = static_cast< T > ( other.ml[ 7 ] );
00421 ml[ 8 ] = static_cast< T > ( other.ml[ 8 ] );
00422 ml[ 9 ] = static_cast< T > ( other.ml[ 9 ] );
00423 ml[ 10 ] = static_cast< T > ( other.ml[ 10 ] );
00424 ml[ 11 ] = static_cast< T > ( other.ml[ 11 ] );
00425 ml[ 12 ] = static_cast< T > ( other.ml[ 12 ] );
00426 ml[ 13 ] = static_cast< T > ( other.ml[ 13 ] );
00427 ml[ 14 ] = static_cast< T > ( other.ml[ 14 ] );
00428 ml[ 15 ] = static_cast< T > ( other.ml[ 15 ] );
00429 return *this;
00430 }
00431
00432
00433
00434 template< typename T >
00435 bool Matrix4< T >::operator== (const Matrix4< T >& other) const
00436 {
00437 for( size_t i = 0; i < 16; ++i )
00438 {
00439 if( ml[i] != other.ml[i] )
00440 return false;
00441 }
00442 return true;
00443 }
00444
00445
00446
00447 template< typename T >
00448 inline bool Matrix4< T >::operator!= (const Matrix4< T >& other) const
00449 {
00450 return !operator==(other);
00451 }
00452
00453
00454
00455 template< typename T >
00456 void Matrix4< T >::set( const Matrix4& other )
00457 {
00458 memcpy( ml, other.ml, 16 * sizeof( T ) );
00459 }
00460
00461
00462
00463 template< typename T >
00464 void Matrix4< T >::set( const float* values )
00465 {
00466 assert( values && "Matrix4: Nullpointer argument as source for initialisation!" );
00467 for ( size_t i = 0; i < 16; ++i )
00468 ml[i] = static_cast< T > ( values[i] );
00469 }
00470
00471
00472
00473 template< typename T >
00474 void Matrix4< T >::set( const double* values )
00475 {
00476 assert( values && "Matrix4: Nullpointer argument as source for initialisation!" );
00477 for ( size_t i = 0; i < 16; ++i )
00478 ml[i] = static_cast< T > ( values[i] );
00479 }
00480
00481
00482
00483 template< typename T >
00484 void Matrix4< T >::set( T v00, T v01, T v02, T v03, T v10, T v11, T v12, T v13,
00485 T v20, T v21, T v22, T v23, T v30, T v31, T v32, T v33 )
00486 {
00487 m00 = v00;
00488 m10 = v10;
00489 m20 = v20;
00490 m30 = v30;
00491 m01 = v01;
00492 m11 = v11;
00493 m21 = v21;
00494 m31 = v31;
00495 m02 = v02;
00496 m12 = v12;
00497 m22 = v22;
00498 m32 = v32;
00499 m03 = v03;
00500 m13 = v13;
00501 m23 = v23;
00502 m33 = v33;
00503
00504 }
00505
00506
00507
00508
00509
00510
00511
00512 template< typename T >
00513 bool
00514 Matrix4< T >::set( const std::string& values, char delimiter )
00515 {
00516 std::vector< std::string > tokens;
00517 stringUtils::split( values, tokens, delimiter );
00518 return set( tokens );
00519 }
00520
00521
00522
00523
00524
00525
00526
00527 template< typename T >
00528 bool
00529 Matrix4< T >::set( const std::vector< std::string >& values )
00530 {
00531 bool ok = true;
00532
00533 if ( values.size() < 16 )
00534 return false;
00535
00536 std::vector< std::string >::const_iterator it = values.begin();
00537
00538 for( size_t row = 0; row < 4; ++row )
00539 {
00540 for( size_t col = 0; ok && col < 4; ++col, ++it )
00541 {
00542
00543 ok = stringUtils::fromString< T >( *it, m[ col ][ row ] );
00544 }
00545 }
00546
00547 return ok;
00548 }
00549
00550
00551 template< typename T >
00552 Vector4< T > Matrix4< T >::getColumn( size_t column ) const
00553 {
00554 assert( column < 4 && "Matrix4: Requested Column ( getColumn ) with invalid index!" );
00555 return Vector4< T >( m[column] );
00556 }
00557
00558
00559
00560 template< typename T >
00561 Vector4< T > Matrix4< T >::getRow( size_t row ) const
00562 {
00563 assert( row < 4 && "Matrix4: Requested Row ( getRow ) with invalid index!");
00564 return Vector4< T > ( ml[0+row], ml[4+row], ml[8+row], ml[12+row] );
00565 }
00566
00567
00568
00569 template< typename T >
00570 void Matrix4< T >::setColumn( size_t column, const Vector4< T >& columnvec )
00571 {
00572 assert( column < 4 && "Matrix4: Writing Column ( setColumn ) with invalid index!" );
00573 m[column][0] = columnvec[0];
00574 m[column][1] = columnvec[1];
00575 m[column][2] = columnvec[2];
00576 m[column][3] = columnvec[3];
00577 }
00578
00579
00580
00581 template< typename T >
00582 void Matrix4< T >::setRow( size_t row, const Vector4< T >& rowvec )
00583 {
00584 assert( row < 4 && "Matrix4: Writing Row ( setRow ) with invalid index!" );
00585 m[0][row] = rowvec[0];
00586 m[1][row] = rowvec[1];
00587 m[2][row] = rowvec[2];
00588 m[3][row] = rowvec[3];
00589 }
00590
00591
00592
00593 template< typename T >
00594 void Matrix4< T >::setColumn( size_t column, const Vector3< T >& columnvec )
00595 {
00596 assert( column < 4 && "Matrix4: Writing Column ( setColumn ) with invalid index!" );
00597 m[column][0] = columnvec[0];
00598 m[column][1] = columnvec[1];
00599 m[column][2] = columnvec[2];
00600 }
00601
00602
00603
00604 template< typename T >
00605 void Matrix4< T >::setRow( size_t row, const Vector3< T >& rowvec )
00606 {
00607 assert( row < 4 && "Matrix4: Writing Row ( setRow ) with invalid index!" );
00608 m[0][row] = rowvec[0];
00609 m[1][row] = rowvec[1];
00610 m[2][row] = rowvec[2];
00611 }
00612
00613
00614
00615 template< typename T >
00616 Matrix4< T > Matrix4< T >::operator+ (const Matrix4< T >& other) const
00617 {
00618 Matrix4< T > result;
00619 for ( size_t i = 0; i < 16; ++i )
00620 result.ml[i] = ml[i] + other.ml[i];
00621 return result;
00622 }
00623
00624
00625
00626 template< typename T >
00627 Matrix4< T > Matrix4< T >::operator- (const Matrix4< T >& other) const
00628 {
00629 Matrix4< T > result;
00630 for( size_t i = 0; i < 16; ++i )
00631 result.ml[i] = ml[i] - other.ml[i];
00632 return result;
00633 }
00634
00635
00636
00637 template< typename T >
00638 Matrix4< T > Matrix4< T >::operator* (const Matrix4< T >& o) const
00639 {
00640 Matrix4< T > r;
00641
00642 r.m00 = m00*o.m00 + m01*o.m10 + m02*o.m20 + m03*o.m30;
00643 r.m10 = m10*o.m00 + m11*o.m10 + m12*o.m20 + m13*o.m30;
00644 r.m20 = m20*o.m00 + m21*o.m10 + m22*o.m20 + m23*o.m30;
00645 r.m30 = m30*o.m00 + m31*o.m10 + m32*o.m20 + m33*o.m30;
00646
00647 r.m01 = m00*o.m01 + m01*o.m11 + m02*o.m21 + m03*o.m31;
00648 r.m11 = m10*o.m01 + m11*o.m11 + m12*o.m21 + m13*o.m31;
00649 r.m21 = m20*o.m01 + m21*o.m11 + m22*o.m21 + m23*o.m31;
00650 r.m31 = m30*o.m01 + m31*o.m11 + m32*o.m21 + m33*o.m31;
00651
00652 r.m02 = m00*o.m02 + m01*o.m12 + m02*o.m22 + m03*o.m32;
00653 r.m12 = m10*o.m02 + m11*o.m12 + m12*o.m22 + m13*o.m32;
00654 r.m22 = m20*o.m02 + m21*o.m12 + m22*o.m22 + m23*o.m32;
00655 r.m32 = m30*o.m02 + m31*o.m12 + m32*o.m22 + m33*o.m32;
00656
00657 r.m03 = m00*o.m03 + m01*o.m13 + m02*o.m23 + m03*o.m33;
00658 r.m13 = m10*o.m03 + m11*o.m13 + m12*o.m23 + m13*o.m33;
00659 r.m23 = m20*o.m03 + m21*o.m13 + m22*o.m23 + m23*o.m33;
00660 r.m33 = m30*o.m03 + m31*o.m13 + m32*o.m23 + m33*o.m33;
00661
00662 return r;
00663 }
00664
00665
00666
00667 template< typename T >
00668 Matrix4< T > Matrix4< T >::operator* ( T scalar ) const
00669 {
00670 Matrix4< T > result;
00671 for ( size_t i = 0; i < 16; ++i )
00672 result.ml[i] = ml[i] * scalar;
00673 return result;
00674 }
00675
00676
00677
00678 template< typename T >
00679 Matrix4< T >& Matrix4< T >::operator+= (const Matrix4< T >& other)
00680 {
00681 for ( size_t i = 0; i < 16; ++i )
00682 ml[i] += other.ml[i];
00683 return *this;
00684 }
00685
00686
00687
00688 template< typename T >
00689 Matrix4< T >& Matrix4< T >::operator-= ( const Matrix4& other )
00690 {
00691 for ( size_t i = 0; i < 16; ++i )
00692 ml[i] -= other.ml[i];
00693 return *this;
00694 }
00695
00696
00697
00698 template< typename T >
00699 Matrix4< T >& Matrix4< T >::operator*= ( const Matrix4& other )
00700 {
00701 Matrix4< T > r;
00702
00703 r.m00 = m00*other.m00 + m01*other.m10 + m02*other.m20 + m03*other.m30;
00704 r.m10 = m10*other.m00 + m11*other.m10 + m12*other.m20 + m13*other.m30;
00705 r.m20 = m20*other.m00 + m21*other.m10 + m22*other.m20 + m23*other.m30;
00706 r.m30 = m30*other.m00 + m31*other.m10 + m32*other.m20 + m33*other.m30;
00707
00708 r.m01 = m00*other.m01 + m01*other.m11 + m02*other.m21 + m03*other.m31;
00709 r.m11 = m10*other.m01 + m11*other.m11 + m12*other.m21 + m13*other.m31;
00710 r.m21 = m20*other.m01 + m21*other.m11 + m22*other.m21 + m23*other.m31;
00711 r.m31 = m30*other.m01 + m31*other.m11 + m32*other.m21 + m33*other.m31;
00712
00713 r.m02 = m00*other.m02 + m01*other.m12 + m02*other.m22 + m03*other.m32;
00714 r.m12 = m10*other.m02 + m11*other.m12 + m12*other.m22 + m13*other.m32;
00715 r.m22 = m20*other.m02 + m21*other.m12 + m22*other.m22 + m23*other.m32;
00716 r.m32 = m30*other.m02 + m31*other.m12 + m32*other.m22 + m33*other.m32;
00717
00718 r.m03 = m00*other.m03 + m01*other.m13 + m02*other.m23 + m03*other.m33;
00719 r.m13 = m10*other.m03 + m11*other.m13 + m12*other.m23 + m13*other.m33;
00720 r.m23 = m20*other.m03 + m21*other.m13 + m22*other.m23 + m23*other.m33;
00721 r.m33 = m30*other.m03 + m31*other.m13 + m32*other.m23 + m33*other.m33;
00722
00723 *this = r;
00724 return *this;
00725 }
00726
00727
00728
00729 template< typename T >
00730 Matrix4< T >& Matrix4< T >::operator*= ( T scalar )
00731 {
00732
00733 for ( size_t i = 0; i < 16; ++i )
00734 ml[i] *= scalar;
00735 return *this;
00736 }
00737
00738
00739
00740 template< typename T >
00741 Vector4< T > Matrix4< T >::operator* (const Vector4< T >& other) const
00742 {
00743 return Vector4< T >( other[0] * m00 + other[1] * m01 + other[2] * m02 + other[3] * m03,
00744 other[0] * m10 + other[1] * m11 + other[2] * m12 + other[3] * m13,
00745 other[0] * m20 + other[1] * m21 + other[2] * m22 + other[3] * m23,
00746 other[0] * m30 + other[1] * m31 + other[2] * m32 + other[3] * m33);
00747 }
00748
00749
00750
00751 template< typename T >
00752 Vector3< T > Matrix4< T >::operator* (const Vector3< T >& other) const
00753 {
00754 const Vector4< T > result( other[0] * m00 + other[1] * m01 + other[2] * m02 + m03,
00755 other[0] * m10 + other[1] * m11 + other[2] * m12 + m13,
00756 other[0] * m20 + other[1] * m21 + other[2] * m22 + m23,
00757 other[0] * m30 + other[1] * m31 + other[2] * m32 + m33 );
00758 return Vector3<T>( result );
00759 }
00760
00761
00762
00763 template< typename T >
00764 Matrix4< T > Matrix4< T >::getTransposed() const
00765 {
00766 Matrix4< T > result;
00767 for ( size_t i = 0; i < 4; ++i )
00768 for ( size_t j = 0; j < 4; ++j )
00769 result.m[i][j] = m[j][i];
00770 return result;
00771 }
00772
00773
00774
00775 template< typename T >
00776 inline T Matrix4< T >::det() const
00777 {
00778 return getDeterminant();
00779 }
00780
00781
00782
00783 template< typename T >
00784 T Matrix4< T >::getDeterminant() const
00785 {
00786 return m00 * getMinor( 1, 2, 3, 1, 2, 3 )
00787 - m01 * getMinor( 1, 2, 3, 0, 2, 3 )
00788 + m02 * getMinor( 1, 2, 3, 0, 1, 3 )
00789 - m03 * getMinor( 1, 2, 3, 0, 1, 2 );
00790 }
00791
00792
00793
00794 template< typename T >
00795 inline Matrix4< T > Matrix4< T >::getAdjoint() const
00796 {
00797 return getAdjugate();
00798 }
00799
00800
00801
00802 template< typename T >
00803 Matrix4< T > Matrix4< T >::getAdjugate() const
00804 {
00805 return Matrix4(
00806 getMinor( 1, 2, 3, 1, 2, 3 ),
00807 -getMinor( 0, 2, 3, 1, 2, 3 ),
00808 getMinor( 0, 1, 3, 1, 2, 3 ),
00809 -getMinor( 0, 1, 2, 1, 2, 3 ),
00810 -getMinor( 1, 2, 3, 0, 2, 3 ),
00811 getMinor( 0, 2, 3, 0, 2, 3 ),
00812 -getMinor( 0, 1, 3, 0, 2, 3 ),
00813 getMinor( 0, 1, 2, 0, 2, 3 ),
00814 getMinor( 1, 2, 3, 0, 1, 3 ),
00815 -getMinor( 0, 2, 3, 0, 1, 3 ),
00816 getMinor( 0, 1, 3, 0, 1, 3 ),
00817 -getMinor( 0, 1, 2, 0, 1, 3 ),
00818 -getMinor( 1, 2, 3, 0, 1, 2 ),
00819 getMinor( 0, 2, 3, 0, 1, 2 ),
00820 -getMinor( 0, 1, 3, 0, 1, 2 ),
00821 getMinor( 0, 1, 2, 0, 1, 2 )
00822 );
00823
00824 #if 0
00825
00826 return Matrix4(
00827 getMinor( 1, 2, 3, 1, 2, 3 ),
00828 -getMinor( 1, 2, 3, 0, 2, 3 ),
00829 getMinor( 1, 2, 3, 0, 1, 3 ),
00830 -getMinor( 1, 2, 3, 0, 1, 2 ),
00831 -getMinor( 0, 2, 3, 1, 2, 3 ),
00832 getMinor( 0, 2, 3, 0, 2, 3 ),
00833 -getMinor( 0, 2, 3, 0, 1, 3 ),
00834 getMinor( 0, 2, 3, 0, 1, 2 ),
00835 getMinor( 0, 1, 3, 1, 2, 3 ),
00836 -getMinor( 0, 1, 3, 0, 2, 3 ),
00837 getMinor( 0, 1, 3, 0, 1, 3 ),
00838 -getMinor( 0, 1, 3, 0, 1, 2 ),
00839 -getMinor( 0, 1, 2, 1, 2, 3 ),
00840 getMinor( 0, 1, 2, 0, 2, 3 ),
00841 -getMinor( 0, 1, 2, 0, 1, 3 ),
00842 getMinor( 0, 1, 2, 0, 1, 2 )
00843 );
00844 #endif
00845 }
00846
00847
00848
00849 template< typename T >
00850 Matrix4< T > Matrix4< T >::getInverse( bool& isInvertible, T limit ) const
00851 {
00852 Matrix4< T > tmp;
00853 isInvertible = getInverse( tmp, limit );
00854 return tmp;
00855 }
00856
00857
00858
00859 template< typename T >
00860 bool Matrix4< T >::getInverse( Matrix4< T >& result, T limit ) const
00861 {
00862 #if 0
00863 T det = getDeterminant();
00864 if ( fabs(det) <= limit )
00865 return false;
00866 else
00867 result = getAdjugate() * ( 1. / det );
00868 return true;
00869 #else // tuned version from Claude Knaus
00870
00871 const T t1[6] = { ml[ 2] * ml[ 7] - ml[ 6] * ml[ 3],
00872 ml[ 2] * ml[11] - ml[10] * ml[ 3],
00873 ml[ 2] * ml[15] - ml[14] * ml[ 3],
00874 ml[ 6] * ml[11] - ml[10] * ml[ 7],
00875 ml[ 6] * ml[15] - ml[14] * ml[ 7],
00876 ml[10] * ml[15] - ml[14] * ml[11] };
00877
00878
00879 result.ml[0] = ml[ 5] * t1[5] - ml[ 9] * t1[4] + ml[13] * t1[3];
00880 result.ml[1] = ml[ 9] * t1[2] - ml[13] * t1[1] - ml[ 1] * t1[5];
00881 result.ml[2] = ml[13] * t1[0] - ml[ 5] * t1[2] + ml[ 1] * t1[4];
00882 result.ml[3] = ml[ 5] * t1[1] - ml[ 1] * t1[3] - ml[ 9] * t1[0];
00883 result.ml[4] = ml[ 8] * t1[4] - ml[ 4] * t1[5] - ml[12] * t1[3];
00884 result.ml[5] = ml[ 0] * t1[5] - ml[ 8] * t1[2] + ml[12] * t1[1];
00885 result.ml[6] = ml[ 4] * t1[2] - ml[12] * t1[0] - ml[ 0] * t1[4];
00886 result.ml[7] = ml[ 0] * t1[3] - ml[ 4] * t1[1] + ml[ 8] * t1[0];
00887
00888
00889 const T t2[6] = { ml[ 0] * ml[ 5] - ml[ 4] * ml[ 1],
00890 ml[ 0] * ml[ 9] - ml[ 8] * ml[ 1],
00891 ml[ 0] * ml[13] - ml[12] * ml[ 1],
00892 ml[ 4] * ml[ 9] - ml[ 8] * ml[ 5],
00893 ml[ 4] * ml[13] - ml[12] * ml[ 5],
00894 ml[ 8] * ml[13] - ml[12] * ml[ 9] };
00895
00896
00897 result.ml[8] = ml[ 7] * t2[5] - ml[11] * t2[4] + ml[15] * t2[3];
00898 result.ml[9] = ml[11] * t2[2] - ml[15] * t2[1] - ml[ 3] * t2[5];
00899 result.ml[10] = ml[15] * t2[0] - ml[ 7] * t2[2] + ml[ 3] * t2[4];
00900 result.ml[11] = ml[ 7] * t2[1] - ml[ 3] * t2[3] - ml[11] * t2[0];
00901 result.ml[12] = ml[10] * t2[4] - ml[ 6] * t2[5] - ml[14] * t2[3];
00902 result.ml[13] = ml[ 2] * t2[5] - ml[10] * t2[2] + ml[14] * t2[1];
00903 result.ml[14] = ml[ 6] * t2[2] - ml[14] * t2[0] - ml[ 2] * t2[4];
00904 result.ml[15] = ml[ 2] * t2[3] - ml[ 6] * t2[1] + ml[10] * t2[0];
00905
00906
00907 const T determinant = ml[0] * result.ml[0] + ml[4] * result.ml[1] +
00908 ml[8] * result.ml[2] + ml[12] * result.ml[3];
00909
00910 if( fabs( determinant ) <= limit )
00911 return false;
00912
00913
00914 const T detinv = 1.0 / determinant;
00915 for( unsigned i = 0; i != 16; ++i )
00916 result.ml[i] *= detinv;
00917
00918 return true;
00919 #endif
00920 }
00921
00922
00923
00924 template< typename T >
00925 void
00926 Matrix4<T>::rotate( const T angle, const Vector3< T >& axis )
00927 {
00928 T sinus = sin( angle );
00929 T cosin = cos( angle );
00930
00931
00932
00933
00934
00935
00936 T two = 2.0;
00937
00938 ml[0] = cosin + ( 1.0 - cosin ) * pow( axis.x, two );
00939 ml[1] = (1.0 - cosin ) * axis.x * axis.y + sinus * axis.z;
00940 ml[2] = (1.0 - cosin ) * axis.x * axis.z - sinus * axis.y;
00941 ml[3] = 0;
00942
00943 ml[4] = ( 1.0 - cosin ) * axis.x * axis.y - sinus * axis.z;
00944 ml[5] = cosin + ( 1.0 - cosin ) * pow( axis.y, two );
00945 ml[6] = ( 1.0 - cosin ) * axis.y * axis.z + sinus * axis.x;
00946 ml[7] = 0;
00947
00948 ml[8] = ( 1.0 - cosin ) * axis.x * axis.z + sinus * axis.y;
00949 ml[9] = ( 1.0 - cosin ) * axis.y * axis.z - sinus * axis.x;
00950 ml[10] = cosin + ( 1.0 - cosin ) * pow( axis.z, two );
00951 ml[11] = 0;
00952
00953 ml[12] = 0;
00954 ml[13] = 0;
00955 ml[14] = 0;
00956 ml[15] = 1;
00957 }
00958
00959
00960
00961 template< typename T >
00962 void Matrix4<T>::rotateX( const T angle )
00963 {
00964
00965 const T sinus = sin(angle);
00966 const T cosin = cos(angle);
00967
00968 T tmp = m01*cosin + m02*sinus;
00969 m02 = -m01*sinus + m02*cosin;
00970 m01 = tmp;
00971
00972 tmp = m11*cosin + m12*sinus;
00973 m12 = -m11*sinus + m12*cosin;
00974 m11 = tmp;
00975
00976 tmp = m21*cosin + m22*sinus;
00977 m22 = -m21*sinus + m22*cosin;
00978 m21 = tmp;
00979
00980 tmp = m31*cosin + m32*sinus;
00981 m32 = -m31*sinus + m32*cosin;
00982 m31 = tmp;
00983 }
00984
00985
00986
00987 template<>
00988 inline void Matrix4<float>::rotateX( const float angle )
00989 {
00990
00991 const float sinus = sinf(angle);
00992 const float cosin = cosf(angle);
00993
00994 float tmp = m01*cosin + m02*sinus;
00995 m02 = -m01*sinus + m02*cosin;
00996 m01 = tmp;
00997
00998 tmp = m11*cosin + m12*sinus;
00999 m12 = -m11*sinus + m12*cosin;
01000 m11 = tmp;
01001
01002 tmp = m21*cosin + m22*sinus;
01003 m22 = -m21*sinus + m22*cosin;
01004 m21 = tmp;
01005
01006 tmp = m31*cosin + m32*sinus;
01007 m32 = -m31*sinus + m32*cosin;
01008 m31 = tmp;
01009 }
01010
01011
01012
01013 template< typename T >
01014 void Matrix4<T>::rotateY( const T angle )
01015 {
01016
01017 const T sinus = sin(angle);
01018 const T cosin = cos(angle);
01019
01020 T tmp = m00*cosin - m02*sinus;
01021 m02 = m00*sinus + m02*cosin;
01022 m00 = tmp;
01023
01024 tmp = m10*cosin - m12*sinus;
01025 m12 = m10*sinus + m12*cosin;
01026 m10 = tmp;
01027
01028 tmp = m20*cosin - m22*sinus;
01029 m22 = m20*sinus + m22*cosin;
01030 m20 = tmp;
01031
01032 tmp = m30*cosin - m32*sinus;
01033 m32 = m30*sinus + m32*cosin;
01034 m30 = tmp;
01035 }
01036
01037
01038
01039 template<>
01040 inline void Matrix4<float>::rotateY( const float angle )
01041 {
01042
01043 const float sinus = sinf(angle);
01044 const float cosin = cosf(angle);
01045
01046 float tmp = m00*cosin - m02*sinus;
01047 m02 = m00*sinus + m02*cosin;
01048 m00 = tmp;
01049
01050 tmp = m10*cosin - m12*sinus;
01051 m12 = m10*sinus + m12*cosin;
01052 m10 = tmp;
01053
01054 tmp = m20*cosin - m22*sinus;
01055 m22 = m20*sinus + m22*cosin;
01056 m20 = tmp;
01057
01058 tmp = m30*cosin - m32*sinus;
01059 m32 = m30*sinus + m32*cosin;
01060 m30 = tmp;
01061 }
01062
01063
01064
01065 template< typename T >
01066 void Matrix4<T>::rotateZ( const T angle )
01067 {
01068
01069 const T sinus = sin(angle);
01070 const T cosin = cos(angle);
01071
01072 T tmp = m00*cosin + m01*sinus;
01073 m01 = -m00*sinus + m01*cosin;
01074 m00 = tmp;
01075
01076 tmp = m10*cosin + m11*sinus;
01077 m11 = -m10*sinus + m11*cosin;
01078 m10 = tmp;
01079
01080 tmp = m20*cosin + m21*sinus;
01081 m21 = -m20*sinus + m21*cosin;
01082 m20 = tmp;
01083
01084 tmp = m30*cosin + m31*sinus;
01085 m31 = -m30*sinus + m31*cosin;
01086 m30 = tmp;
01087 }
01088
01089
01090
01091 template<>
01092 inline void Matrix4<float>::rotateZ( const float angle )
01093 {
01094
01095 const float sinus = sinf(angle);
01096 const float cosin = cosf(angle);
01097
01098 float tmp = m00*cosin + m01*sinus;
01099 m01 = -m00*sinus + m01*cosin;
01100 m00 = tmp;
01101
01102 tmp = m10*cosin + m11*sinus;
01103 m11 = -m10*sinus + m11*cosin;
01104 m10 = tmp;
01105
01106 tmp = m20*cosin + m21*sinus;
01107 m21 = -m20*sinus + m21*cosin;
01108 m20 = tmp;
01109
01110 tmp = m30*cosin + m31*sinus;
01111 m31 = -m30*sinus + m31*cosin;
01112 m30 = tmp;
01113 }
01114
01115
01116
01117 template< typename T >
01118 void Matrix4<T>::preRotateX( const T angle )
01119 {
01120 const T sinus = sin(angle);
01121 const T cosin = cos(angle);
01122
01123 T temp = m00;
01124 m00 = m00 * cosin - m20 * sinus;
01125 m20 = temp * sinus + m20 * cosin;
01126
01127 temp = m01;
01128 m01 = m01 * cosin - m21 * sinus;
01129 m21 = temp * sinus + m21 * cosin;
01130
01131 temp = m02;
01132 m02 = m02 * cosin - m22 * sinus;
01133 m22 = temp * sinus + m22 * cosin;
01134
01135 temp = m03;
01136 m03 = m03 * cosin - m23 * sinus;
01137 m23 = temp * sinus + m23 * cosin;
01138 }
01139
01140
01141
01142 template<>
01143 inline void Matrix4<float>::preRotateX( const float angle )
01144 {
01145
01146 const float sinus = sinf(angle);
01147 const float cosin = cosf(angle);
01148
01149 float temp = m00;
01150 m00 = m00 * cosin - m20 * sinus;
01151 m20 = temp * sinus + m20 * cosin;
01152
01153 temp = m01;
01154 m01 = m01 * cosin - m21 * sinus;
01155 m21 = temp * sinus + m21 * cosin;
01156
01157 temp = m02;
01158 m02 = m02 * cosin - m22 * sinus;
01159 m22 = temp * sinus + m22 * cosin;
01160
01161 temp = m03;
01162 m03 = m03 * cosin - m23 * sinus;
01163 m23 = temp * sinus + m23 * cosin;
01164 }
01165
01166
01167
01168 template< typename T >
01169 void Matrix4<T>::preRotateY( const T angle )
01170 {
01171
01172 const T sinus = sin(angle);
01173 const T cosin = cos(angle);
01174
01175 T temp = m10;
01176 m10 = m10 * cosin + m20 * sinus;
01177 m20 = temp * -sinus + m20 * cosin;
01178
01179 temp = m11;
01180 m11 = m11 * cosin + m21 * sinus;
01181 m21 = temp * -sinus + m21 * cosin;
01182
01183 temp = m12;
01184 m12 = m12 * cosin + m22 * sinus;
01185 m22 = temp * -sinus + m22 * cosin;
01186
01187 temp = m13;
01188 m13 = m13 * cosin + m23 * sinus;
01189 m23 = temp * -sinus + m23 * cosin;
01190 }
01191
01192
01193
01194 template<>
01195 inline void Matrix4<float>::preRotateY( const float angle )
01196 {
01197
01198 const float sinus = sinf(angle);
01199 const float cosin = cosf(angle);
01200
01201 float temp = m10;
01202 m10 = m10 * cosin + m20 * sinus;
01203 m20 = temp * -sinus + m20 * cosin;
01204
01205 temp = m11;
01206 m11 = m11 * cosin + m21 * sinus;
01207 m21 = temp * -sinus + m21 * cosin;
01208
01209 temp = m12;
01210 m12 = m12 * cosin + m22 * sinus;
01211 m22 = temp * -sinus + m22 * cosin;
01212
01213 temp = m13;
01214 m13 = m13 * cosin + m23 * sinus;
01215 m23 = temp * -sinus + m23 * cosin;
01216 }
01217
01218
01219
01220 template< typename T >
01221 void Matrix4<T>::preRotateZ( const T angle )
01222 {
01223
01224 const T sinus = sin(angle);
01225 const T cosin = cos(angle);
01226
01227 T temp = m00;
01228 m00 = m00 * cosin + m10 * sinus;
01229 m10 = temp * -sinus + m10 * cosin;
01230
01231 temp = m01;
01232 m01 = m01 * cosin + m11 * sinus;
01233 m11 = temp * -sinus + m11 * cosin;
01234
01235 temp = m02;
01236 m02 = m02 * cosin + m12 * sinus;
01237 m12 = temp * -sinus + m12 * cosin;
01238
01239 temp = m03;
01240 m03 = m03 * cosin + m13 * sinus;
01241 m13 = temp * -sinus + m13 * cosin;
01242 }
01243
01244
01245
01246 template<>
01247 inline void Matrix4<float>::preRotateZ( const float angle )
01248 {
01249
01250 const float sinus = sinf(angle);
01251 const float cosin = cosf(angle);
01252
01253 float temp = m00;
01254 m00 = m00 * cosin + m10 * sinus;
01255 m10 = temp * -sinus + m10 * cosin;
01256
01257 temp = m01;
01258 m01 = m01 * cosin + m11 * sinus;
01259 m11 = temp * -sinus + m11 * cosin;
01260
01261 temp = m02;
01262 m02 = m02 * cosin + m12 * sinus;
01263 m12 = temp * -sinus + m12 * cosin;
01264
01265 temp = m03;
01266 m03 = m03 * cosin + m13 * sinus;
01267 m13 = temp * -sinus + m13 * cosin;
01268 }
01269
01270
01271
01272 template< typename T >
01273 void Matrix4<T>::scale( const T s[3] )
01274 {
01275 ml[0] *= s[0];
01276 ml[1] *= s[0];
01277 ml[2] *= s[0];
01278 ml[3] *= s[0];
01279 ml[4] *= s[1];
01280 ml[5] *= s[1];
01281 ml[6] *= s[1];
01282 ml[7] *= s[1];
01283 ml[8] *= s[2];
01284 ml[9] *= s[2];
01285 ml[10] *= s[2];
01286 ml[11] *= s[2];
01287 }
01288
01289
01290
01291 template< typename T >
01292 void Matrix4<T>::scale( const T xScale, const T yScale, const T zScale )
01293 {
01294 ml[0] *= xScale;
01295 ml[1] *= xScale;
01296 ml[2] *= xScale;
01297 ml[3] *= xScale;
01298 ml[4] *= yScale;
01299 ml[5] *= yScale;
01300 ml[6] *= yScale;
01301 ml[7] *= yScale;
01302 ml[8] *= zScale;
01303 ml[9] *= zScale;
01304 ml[10] *= zScale;
01305 ml[11] *= zScale;
01306 }
01307
01308
01309
01310 template< typename T >
01311 void Matrix4<T>::scale( const Vector3< T >& scale_ )
01312 {
01313 ml[0] *= scale_[0];
01314 ml[1] *= scale_[0];
01315 ml[2] *= scale_[0];
01316 ml[3] *= scale_[0];
01317 ml[4] *= scale_[1];
01318 ml[5] *= scale_[1];
01319 ml[6] *= scale_[1];
01320 ml[7] *= scale_[1];
01321 ml[8] *= scale_[2];
01322 ml[9] *= scale_[2];
01323 ml[10] *= scale_[2];
01324 ml[11] *= scale_[2];
01325 }
01326
01327
01328
01329 template< typename T >
01330 void Matrix4<T>::scaleTranslation( const T scale_[3] )
01331 {
01332 ml[12] *= scale_[0];
01333 ml[13] *= scale_[1];
01334 ml[14] *= scale_[2];
01335 }
01336
01337
01338
01339 template< typename T >
01340 void Matrix4<T>::scaleTranslation( const Vector3< T >& scale_ )
01341 {
01342 ml[12] *= scale_[0];
01343 ml[13] *= scale_[1];
01344 ml[14] *= scale_[2];
01345 }
01346
01347
01348
01349 template< typename T >
01350 void Matrix4<T>::setTranslation( const T xTrans, const T yTrans, const T zTrans)
01351 {
01352 ml[12] = xTrans;
01353 ml[13] = yTrans;
01354 ml[14] = zTrans;
01355 }
01356
01357
01358
01359 template< typename T >
01360 void Matrix4<T>::setTranslation( const T trans[3] )
01361 {
01362 ml[12] = trans[0];
01363 ml[13] = trans[1];
01364 ml[14] = trans[2];
01365 }
01366
01367
01368
01369 template< typename T >
01370 void Matrix4<T>::setTranslation( const Vector3<T>& trans )
01371 {
01372 ml[12] = trans.x;
01373 ml[13] = trans.y;
01374 ml[14] = trans.z;
01375 }
01376
01377
01378
01379 template< typename T >
01380 Vector3< T >
01381 Matrix4< T >::getTranslation() const
01382 {
01383 return Vector3< T > ( ml[12], ml[13], ml[14] );
01384 }
01385
01386
01387
01388
01389 template< typename T >
01390 void Matrix4< T >::tensor( const Vector3< T >& u, const Vector3< T >& v )
01391 {
01392 int i, j;
01393 for (j = 0; j < 3; j++)
01394 {
01395 for (i = 0; i < 3; i++)
01396 m[i][j] = u[j] * v[i];
01397 m[3][j] = u[j];
01398 }
01399 for (i = 0; i < 3; i++)
01400 m[i][3] = v[i];
01401 m[3][3] = 1.0;
01402 }
01403
01404
01405
01406 template< typename T >
01407 void Matrix4< T >::tensor( const Vector4< T >& u, const Vector4< T >& v )
01408 {
01409 int i, j;
01410 for (j = 0; j < 4; j++)
01411 for (i = 0; i < 4; i++)
01412 m[i][j] = u[j] * v[i];
01413
01414 }
01415
01416
01417
01418 template< typename T >
01419 T Matrix4< T >::getMinor( const size_t removeRow, const size_t removeCol ) const
01420 {
01421 size_t col[3], c = 0;
01422 size_t row[3], r = 0;
01423 for ( size_t i = 0; i < 3; ++i )
01424 {
01425 if ( c == removeCol )
01426 ++c;
01427 col[i] = c++;
01428 if ( r == removeRow )
01429 ++r;
01430 row[i] = r++;
01431 }
01432
01433 Matrix3< T > minorm( m[col[0]][row[0]], m[col[1]][row[0]], m[col[2]][row[0]],
01434 m[col[0]][row[1]], m[col[1]][row[1]], m[col[2]][row[1]],
01435 m[col[0]][row[2]], m[col[1]][row[2]], m[col[2]][row[2]] );
01436 return minorm.det();
01437 }
01438
01439
01440
01441 template< typename T >
01442 T Matrix4< T >::getMinor( const size_t row0, const size_t row1,
01443 const size_t row2, const size_t col0,
01444 const size_t col1, const size_t col2 ) const
01445 {
01446 Matrix3< T > minorm( m[col0][row0], m[col1][row0], m[col2][row0],
01447 m[col0][row1], m[col1][row1], m[col2][row1],
01448 m[col0][row2], m[col1][row2], m[col2][row2] );
01449 return minorm.det();
01450 }
01451
01452
01453
01454 template< typename T >
01455 Matrix4< T > Matrix4< T >::operator-() const
01456 {
01457 Matrix4< T > result( *this );
01458 result *= -1.0;
01459 return result;
01460 }
01461
01462
01463
01464 template< typename T >
01465 Matrix4< T > Matrix4< T >::negate() const
01466 {
01467 Matrix4< T > result( *this );
01468 result *= -1.0;
01469 return result;
01470 }
01471
01472
01473
01474 template< typename T >
01475 template< typename U >
01476 void
01477 Matrix4< T >::set3x3SubMatrix( const Matrix3< U >& sourceMatrix, size_t columnOffset,
01478 size_t rowOffset )
01479 {
01480 assert( rowOffset < 2 && columnOffset < 2 );
01481
01482 for( size_t row = rowOffset, i = 0; i < 3; ++i, ++row )
01483 for( size_t col = columnOffset, j = 0; j < 3; ++j, ++col )
01484 {
01485 m[ row ][ col ] = sourceMatrix.m[ i ][ j ];
01486 }
01487 }
01488
01489
01490
01491 template< typename T >
01492 void
01493 Matrix4< T >::get3x3SubMatrix( Matrix3< T >& result, size_t rowOffset,
01494 size_t columnOffset ) const
01495 {
01496 for( size_t row = rowOffset, i = 0; i < 3; ++i, ++row )
01497 for( size_t col = columnOffset, j = 0; j < 3; ++j, ++col )
01498 {
01499 result.m[ i ][ j ] = m[ row ][ col ];
01500 }
01501 }
01502
01503
01504
01505
01506 template< typename T >
01507 bool
01508 Matrix4< T >::getString( std::string& result, const std::string& delimiter ) const
01509 {
01510 std::string tmp;
01511 bool ok = true;
01512 for( size_t row = 0; row < 4; ++row )
01513 {
01514 for( size_t col = 0; ok && col < 4; ++col )
01515 {
01516 ok = stringUtils::toString< T >( m[ col ][ row ], tmp );
01517 result += tmp;
01518 result += delimiter;
01519 }
01520 }
01521 return ok;
01522 }
01523
01524
01525
01526
01527
01528 }
01529
01530 #endif