00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #pragma once
00025
00026 #include "cinder/Cinder.h"
00027 #include "cinder/CinderMath.h"
00028 #include "cinder/Vector.h"
00029
00030 #include "cinder/Matrix22.h"
00031 #include "cinder/Matrix33.h"
00032 #include "cinder/MatrixAffine2.h"
00033
00034 #include <iomanip>
00035
00036 namespace cinder {
00037
00039
00040 template< typename T >
00041 class Matrix44
00042 {
00043 public:
00044 typedef T TYPE;
00045 typedef T value_type;
00046
00047 static const size_t DIM = 4;
00048 static const size_t DIM_SQ = DIM*DIM;
00049 static const size_t MEM_LEN = sizeof(T)*DIM_SQ;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 union {
00066 T m[16];
00067 struct {
00068
00069
00070
00071 T m00, m10, m20, m30;
00072 T m01, m11, m21, m31;
00073 T m02, m12, m22, m32;
00074 T m03, m13, m23, m33;
00075 };
00076
00077 T mcols[4][4];
00078 };
00079
00080 Matrix44();
00081
00082 Matrix44( T s );
00083
00084
00085 Matrix44( const T *dt, bool srcIsRowMajor = false );
00086
00087
00088 Matrix44( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, T d9, T d10, T d11, T d12, T d13, T d14, T d15, bool srcIsRowMajor = false );
00089
00090
00091 Matrix44( const Vec3<T> &vx, const Vec3<T> &vy, const Vec3<T> &vz );
00092 Matrix44( const Vec4<T> &vx, const Vec4<T> &vy, const Vec4<T> &vz, const Vec4<T> &vw = Vec4<T>( 0, 0, 0, 1 ) );
00093
00094 template< typename FromT >
00095 Matrix44( const Matrix44<FromT>& src );
00096
00097 Matrix44( const Matrix22<T>& src );
00098 explicit Matrix44( const MatrixAffine2<T> &src );
00099 Matrix44( const Matrix33<T>& src );
00100
00101 Matrix44( const Matrix44<T>& src );
00102
00103 operator T*() { return (T*)m; }
00104 operator const T*() const { return (const T*)m; }
00105
00106 Matrix44<T>& operator=( const Matrix44<T>& rhs );
00107 Matrix44<T>& operator=( T rhs );
00108
00109 template< typename FromT >
00110 Matrix44<T>& operator=( const Matrix44<FromT>& rhs );
00111
00112
00113 Matrix44<T>& operator=( const Matrix22<T>& rhs );
00114 Matrix44<T>& operator=( const MatrixAffine2<T>& rhs );
00115 Matrix44<T>& operator=( const Matrix33<T>& rhs );
00116
00117 bool equalCompare( const Matrix44<T>& rhs, T epsilon ) const;
00118 bool operator==( const Matrix44<T> &rhs ) const { return equalCompare( rhs, (T)EPSILON ); }
00119 bool operator!=( const Matrix44<T> &rhs ) const { return ! ( *this == rhs ); }
00120
00121 Matrix44<T>& operator*=( const Matrix44<T> &rhs );
00122 Matrix44<T>& operator+=( const Matrix44<T> &rhs );
00123 Matrix44<T>& operator-=( const Matrix44<T> &rhs );
00124
00125 Matrix44<T>& operator*=( T rhs );
00126 Matrix44<T>& operator/=( T rhs );
00127 Matrix44<T>& operator+=( T rhs );
00128 Matrix44<T>& operator-=( T rhs );
00129
00130 const Matrix44<T> operator*( const Matrix44<T> &rhs ) const;
00131 const Matrix44<T> operator+( const Matrix44<T> &rhs ) const;
00132 const Matrix44<T> operator-( const Matrix44<T> &rhs ) const;
00133
00134
00135 const Vec3<T> operator*( const Vec3<T> &rhs ) const;
00136
00137
00138 const Vec4<T> operator*( const Vec4<T> &rhs ) const;
00139
00140 const Matrix44<T> operator*( T rhs ) const;
00141 const Matrix44<T> operator/( T rhs ) const;
00142 const Matrix44<T> operator+( T rhs ) const;
00143 const Matrix44<T> operator-( T rhs ) const;
00144
00145
00146 T& at( int row, int col );
00147 const T& at( int row, int col ) const;
00148
00149
00150 void set( const T *dt, bool srcIsRowMajor = false );
00151
00152 void set( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, T d9, T d10, T d11, T d12, T d13, T d14, T d15, bool srcIsRowMajor = false );
00153
00154 Vec4<T> getColumn( int col ) const;
00155 void setColumn( int col, const Vec4<T> &v );
00156
00157 Vec4<T> getRow( int row ) const;
00158 void setRow( int row, const Vec4<T> &v );
00159
00160 void getColumns( Vec4<T> *c0, Vec4<T> *c1, Vec4<T> *c2, Vec4<T> *c3 ) const;
00161 void setColumns( const Vec4<T> &c0, const Vec4<T> &c1, const Vec4<T> &c2, const Vec4<T> &c3 );
00162
00163 void getRows( Vec4<T> *r0, Vec4<T> *r1, Vec4<T> *r2, Vec4<T> *r3 ) const;
00164 void setRows( const Vec4<T> &r0, const Vec4<T> &r1, const Vec4<T> &r2, const Vec4<T> &r3 );
00165
00166
00167 Matrix22<T> subMatrix22( int row, int col ) const;
00168 Matrix33<T> subMatrix33( int row, int col ) const;
00169
00170 void setToNull();
00171 void setToIdentity();
00172
00173 T determinant() const;
00174
00175 T trace( bool fullTrace = false ) const;
00176
00177 Matrix44<T> diagonal() const;
00178
00179 Matrix44<T> lowerTriangular() const;
00180 Matrix44<T> upperTriangular() const;
00181
00182 void transpose();
00183 Matrix44<T> transposed() const;
00184
00185 void invert (T epsilon = EPSILON ) { *this = inverted( epsilon ); }
00186 Matrix44<T> inverted( T epsilon = EPSILON ) const;
00187
00188
00189 Vec3<T> preMultiply( const Vec3<T> &v ) const;
00190 Vec4<T> preMultiply( const Vec4<T> &v ) const;
00191
00192
00193 Vec3<T> postMultiply( const Vec3<T> &v ) const;
00194 Vec4<T> postMultiply( const Vec4<T> &v ) const;
00195
00197 void affineInvert(){ *this = affineInverted(); }
00198 Matrix44<T> affineInverted() const;
00199
00201 void orthonormalInvert();
00202 Matrix44<T> orthonormalInverted() const { Matrix44<T> result( *this ); result.orthonormalInvert(); return result; }
00203
00204
00205 Vec3<T> transformPoint( const Vec3<T> &rhs ) const;
00206
00207
00208 Vec3<T> transformPointAffine( const Vec3<T> &rhs ) const;
00209
00210
00211 Vec3<T> transformVec( const Vec3<T> &rhs ) const;
00212 Vec4<T> transformVec( const Vec4<T> &rhs ) const { return transformVec( rhs.xyz() ); }
00213
00214
00215 Vec4<T> getTranslate() const { return Vec4<T>( m03, m13, m23, m33 ); }
00216
00217 void setTranslate( const Vec3<T>& v ) { m03 = v.x; m13 = v.y; m23 = v.z; }
00218 void setTranslate( const Vec4<T>& v ) { setTranslate( v.xyz() ); }
00219
00220
00221 void translate( const Vec3<T> &tr ) { *this *= createTranslation( tr ); }
00222 void translate( const Vec4<T> &tr ) { *this *= createTranslation( tr ); }
00223
00224
00225 void rotate( const Vec3<T> &axis, T radians ) { *this *= createRotation( axis, radians ); }
00226 void rotate( const Vec4<T> &axis, T radians ) { *this *= createRotation( axis, radians ); }
00227
00228 void rotate( const Vec3<T> &eulerRadians ) { *this *= createRotation( eulerRadians ); }
00229 void rotate( const Vec4<T> &eulerRadians ) { *this *= createRotation( eulerRadians ); }
00230
00231 void rotate( const Vec3<T> &from, const Vec3<T> &to, const Vec3<T> &worldUp ) { *this *= createRotation( from, to, worldUp ); }
00232 void rotate( const Vec4<T> &from, const Vec4<T> &to, const Vec4<T> &worldUp ) { *this *= createRotation( from, to, worldUp ); }
00233
00234
00235 void scale( T s ) { Matrix44 op = createScale( s ); Matrix44 mat = *this; *this = op*mat; }
00236 void scale( const Vec2<T> &v ) { *this *= createScale( v ); }
00237 void scale( const Vec3<T> &v ) { *this *= createScale( v ); }
00238 void scale( const Vec4<T> &v ) { *this *= createScale( v ); }
00239
00240
00241 Matrix44<T> invertTransform() const;
00242
00243
00244 static Matrix44<T> identity() { return Matrix44( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); }
00245
00246 static Matrix44<T> one() { return Matrix44( (T)1 ); }
00247
00248 static Matrix44<T> zero() { return Matrix44( (T)0 ); }
00249
00250
00251 static Matrix44<T> createTranslation( const Vec3<T> &v, T w = 1 );
00252 static Matrix44<T> createTranslation( const Vec4<T> &v ) { return createTranslation( v.xyz(), v.w );}
00253
00254
00255 static Matrix44<T> createRotation( const Vec3<T> &axis, T radians );
00256 static Matrix44<T> createRotation( const Vec4<T> &axis, T radians ) { return createRotation( axis.xyz(), radians ); }
00257 static Matrix44<T> createRotation( const Vec3<T> &from, const Vec3<T> &to, const Vec3<T> &worldUp );
00258 static Matrix44<T> createRotation( const Vec4<T> &from, const Vec4<T> &to, const Vec4<T> &worldUp ) { return createRotation( from.xyz(), to.xyz(), worldUp.xyz() ); }
00259
00260 static Matrix44<T> createRotation( const Vec3<T> &eulerRadians );
00261 static Matrix44<T> createRotation( const Vec4<T> &eulerRadians ) { return createRotation( eulerRadians.xyz() ); }
00262
00263 static Matrix44<T> createRotationOnb( const Vec3<T>& u, const Vec3<T>& v, const Vec3<T>& w );
00264 static Matrix44<T> createRotationOnb( const Vec4<T>& u, const Vec4<T>& v, const Vec4<T>& w ) { return createRotationOnb( u.xyz(), v.xyz(), w.xyz() ); }
00265
00266
00267 static Matrix44<T> createScale( T s );
00268 static Matrix44<T> createScale( const Vec2<T> &v );
00269 static Matrix44<T> createScale( const Vec3<T> &v );
00270 static Matrix44<T> createScale( const Vec4<T> &v );
00271
00272
00273 static Matrix44<T> alignZAxisWithTarget( Vec3<T> targetDir, Vec3<T> upDir );
00274 static Matrix44<T> alignZAxisWithTarget( Vec4<T> targetDir, Vec4<T> upDir ) { return alignZAxisWithTarget( targetDir.xyz(), upDir.xyz() ); }
00275
00276 friend std::ostream& operator<<( std::ostream &lhs, const Matrix44<T> &rhs ) {
00277 for( int i = 0; i < 4; i++) {
00278 lhs << " |";
00279 for( int j = 0; j < 4; j++) {
00280 lhs << std::setw( 12 ) << std::setprecision( 6 ) << rhs.m[j*4+i];
00281 }
00282 lhs << "|" << std::endl;
00283 }
00284
00285 return lhs;
00286 }
00287 };
00288
00289 template< typename T >
00290 Matrix44<T>::Matrix44()
00291 {
00292 setToIdentity();
00293 }
00294
00295 template< typename T >
00296 Matrix44<T>::Matrix44( T s )
00297 {
00298 for( int i = 0; i < DIM_SQ; ++i ) {
00299 m[i] = s;
00300 }
00301 }
00302
00303 template< typename T >
00304 Matrix44<T>::Matrix44( const T *dt, bool srcIsRowMajor )
00305 {
00306 set( dt, srcIsRowMajor );
00307 }
00308
00309 template< typename T >
00310 Matrix44<T>::Matrix44( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, T d9, T d10, T d11, T d12, T d13, T d14, T d15, bool srcIsRowMajor )
00311 {
00312 set( d0, d1, d2, d3,
00313 d4, d5, d6, d7,
00314 d8, d9, d10, d11,
00315 d12, d13, d14, d15, srcIsRowMajor );
00316 }
00317
00318 template< typename T >
00319 Matrix44<T>::Matrix44( const Vec3<T> &vx, const Vec3<T> &vy, const Vec3<T> &vz )
00320 {
00321 m[0] = vx.x; m[4] = vy.x; m[ 8] = vz.x; m[12] = 0;
00322 m[1] = vx.y; m[5] = vy.y; m[ 9] = vz.y; m[13] = 0;
00323 m[2] = vx.z; m[6] = vy.z; m[10] = vz.z; m[14] = 0;
00324 m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1;
00325 }
00326
00327 template< typename T >
00328 Matrix44<T>::Matrix44( const Vec4<T> &vx, const Vec4<T> &vy, const Vec4<T> &vz, const Vec4<T> &vw )
00329 {
00330 m[0] = vx.x; m[4] = vy.x; m[ 8] = vz.x; m[12] = vw.x;
00331 m[1] = vx.y; m[5] = vy.y; m[ 9] = vz.y; m[13] = vw.y;
00332 m[2] = vx.z; m[6] = vy.z; m[10] = vz.z; m[14] = vw.z;
00333 m[3] = vx.w; m[7] = vy.w; m[11] = vz.w; m[15] = vw.w;
00334 }
00335
00336 template< typename T >
00337 template< typename FromT >
00338 Matrix44<T>::Matrix44( const Matrix44<FromT>& src )
00339 {
00340 for( int i = 0; i < DIM_SQ; ++i ) {
00341 m[i] = static_cast<T>( src.m[i] );
00342 }
00343 }
00344
00345 template< typename T >
00346 Matrix44<T>::Matrix44( const Matrix22<T>& src )
00347 {
00348 setToIdentity();
00349 m00 = src.m00; m01 = src.m01;
00350 m10 = src.m10; m11 = src.m11;
00351 }
00352
00353 template< typename T >
00354 Matrix44<T>::Matrix44( const MatrixAffine2<T>& src )
00355 {
00356 m[ 0] = src.m[0]; m[ 4] = src.m[2]; m[ 8] = 0; m[12] = src.m[4];
00357 m[ 1] = src.m[1]; m[ 5] = src.m[3]; m[ 9] = 0; m[13] = src.m[5];
00358 m[ 2] = 0; m[ 6] = 0; m[10] = 1; m[14] = 0;
00359 m[ 3] = 0; m[ 7] = 0; m[11] = 0; m[15] = 1;
00360 }
00361
00362 template< typename T >
00363 Matrix44<T>::Matrix44( const Matrix33<T>& src )
00364 {
00365 setToIdentity();
00366 m00 = src.m00; m01 = src.m01; m02 = src.m02;
00367 m10 = src.m10; m11 = src.m11; m12 = src.m12;
00368 m20 = src.m20; m21 = src.m21; m22 = src.m22;
00369 }
00370
00371 template< typename T >
00372 Matrix44<T>::Matrix44( const Matrix44<T>& src )
00373 {
00374 std::memcpy( m, src.m, MEM_LEN );
00375 }
00376
00377 template< typename T >
00378 Matrix44<T>& Matrix44<T>::operator=( const Matrix44<T>& rhs )
00379 {
00380 std::memcpy( m, rhs.m, MEM_LEN );
00381 return *this;
00382 }
00383
00384 template< typename T >
00385 Matrix44<T>& Matrix44<T>::operator=( T rhs )
00386 {
00387 for( int i = 0; i < DIM_SQ; i++ ) {
00388 m[i] = rhs;
00389 }
00390 return *this;
00391 }
00392
00393 template< typename T >
00394 template< typename FromT >
00395 Matrix44<T>& Matrix44<T>::operator=( const Matrix44<FromT>& rhs )
00396 {
00397 for( int i = 0; i < DIM_SQ; i++ ) {
00398 m[i] = static_cast<T>(rhs.m[i]);
00399 }
00400 return *this;
00401 }
00402
00403 template< typename T >
00404 Matrix44<T>& Matrix44<T>::operator=( const Matrix22<T>& rhs )
00405 {
00406 setToIdentity();
00407 m00 = rhs.m00; m01 = rhs.m01;
00408 m10 = rhs.m10; m11 = rhs.m11;
00409 return *this;
00410 }
00411
00412 template< typename T >
00413 Matrix44<T>& Matrix44<T>::operator=( const MatrixAffine2<T>& rhs )
00414 {
00415 m[ 0] = rhs.m[0]; m[ 4] = rhs.m[2]; m[ 8] = 0; m[12] = rhs.m[4];
00416 m[ 1] = rhs.m[1]; m[ 5] = rhs.m[3]; m[ 9] = 0; m[13] = rhs.m[5];
00417 m[ 2] = 0; m[ 6] = 0; m[10] = 1; m[14] = 0;
00418 m[ 3] = 0; m[ 7] = 0; m[11] = 0; m[15] = 1;
00419 return *this;
00420 }
00421
00422
00423
00424 template< typename T >
00425 Matrix44<T>& Matrix44<T>::operator=( const Matrix33<T>& rhs )
00426 {
00427 setToIdentity();
00428 m00 = rhs.m00; m01 = rhs.m01; m02 = rhs.m02;
00429 m10 = rhs.m10; m11 = rhs.m11; m12 = rhs.m12;
00430 m20 = rhs.m20; m21 = rhs.m21; m22 = rhs.m22;
00431 return *this;
00432 }
00433
00434 template< typename T >
00435 bool Matrix44<T>::equalCompare( const Matrix44<T>& rhs, T epsilon ) const
00436 {
00437 for( int i = 0; i < DIM_SQ; ++i ) {
00438 if( math<T>::abs(m[i] - rhs.m[i]) >= epsilon )
00439 return false;
00440 }
00441 return true;
00442 }
00443
00444 template< typename T >
00445 inline Matrix44<T>& Matrix44<T>::operator*=( const Matrix44<T> &rhs )
00446 {
00447 Matrix44<T> ret;
00448
00449 ret.m[ 0] = m[ 0]*rhs.m[ 0] + m[ 4]*rhs.m[ 1] + m[ 8]*rhs.m[ 2] + m[12]*rhs.m[ 3];
00450 ret.m[ 1] = m[ 1]*rhs.m[ 0] + m[ 5]*rhs.m[ 1] + m[ 9]*rhs.m[ 2] + m[13]*rhs.m[ 3];
00451 ret.m[ 2] = m[ 2]*rhs.m[ 0] + m[ 6]*rhs.m[ 1] + m[10]*rhs.m[ 2] + m[14]*rhs.m[ 3];
00452 ret.m[ 3] = m[ 3]*rhs.m[ 0] + m[ 7]*rhs.m[ 1] + m[11]*rhs.m[ 2] + m[15]*rhs.m[ 3];
00453
00454 ret.m[ 4] = m[ 0]*rhs.m[ 4] + m[ 4]*rhs.m[ 5] + m[ 8]*rhs.m[ 6] + m[12]*rhs.m[ 7];
00455 ret.m[ 5] = m[ 1]*rhs.m[ 4] + m[ 5]*rhs.m[ 5] + m[ 9]*rhs.m[ 6] + m[13]*rhs.m[ 7];
00456 ret.m[ 6] = m[ 2]*rhs.m[ 4] + m[ 6]*rhs.m[ 5] + m[10]*rhs.m[ 6] + m[14]*rhs.m[ 7];
00457 ret.m[ 7] = m[ 3]*rhs.m[ 4] + m[ 7]*rhs.m[ 5] + m[11]*rhs.m[ 6] + m[15]*rhs.m[ 7];
00458
00459 ret.m[ 8] = m[ 0]*rhs.m[ 8] + m[ 4]*rhs.m[ 9] + m[ 8]*rhs.m[10] + m[12]*rhs.m[11];
00460 ret.m[ 9] = m[ 1]*rhs.m[ 8] + m[ 5]*rhs.m[ 9] + m[ 9]*rhs.m[10] + m[13]*rhs.m[11];
00461 ret.m[10] = m[ 2]*rhs.m[ 8] + m[ 6]*rhs.m[ 9] + m[10]*rhs.m[10] + m[14]*rhs.m[11];
00462 ret.m[11] = m[ 3]*rhs.m[ 8] + m[ 7]*rhs.m[ 9] + m[11]*rhs.m[10] + m[15]*rhs.m[11];
00463
00464 ret.m[12] = m[ 0]*rhs.m[12] + m[ 4]*rhs.m[13] + m[ 8]*rhs.m[14] + m[12]*rhs.m[15];
00465 ret.m[13] = m[ 1]*rhs.m[12] + m[ 5]*rhs.m[13] + m[ 9]*rhs.m[14] + m[13]*rhs.m[15];
00466 ret.m[14] = m[ 2]*rhs.m[12] + m[ 6]*rhs.m[13] + m[10]*rhs.m[14] + m[14]*rhs.m[15];
00467 ret.m[15] = m[ 3]*rhs.m[12] + m[ 7]*rhs.m[13] + m[11]*rhs.m[14] + m[15]*rhs.m[15];
00468
00469 for( int i = 0; i < DIM_SQ; ++i ) {
00470 m[i] = ret.m[i];
00471 }
00472
00473 return *this;
00474 }
00475
00476 template< typename T >
00477 Matrix44<T>& Matrix44<T>::operator+=( const Matrix44<T> &rhs )
00478 {
00479 for( int i = 0; i < DIM_SQ; ++i ) {
00480 m[i] += rhs.m[i];
00481 }
00482 return *this;
00483 }
00484
00485 template< typename T >
00486 Matrix44<T>& Matrix44<T>::operator-=( const Matrix44<T> &rhs )
00487 {
00488 for( int i = 0; i < DIM_SQ; ++i ) {
00489 m[i] -= rhs.m[i];
00490 }
00491 return *this;
00492 }
00493
00494 template< typename T >
00495 Matrix44<T>& Matrix44<T>::operator*=( T rhs )
00496 {
00497 for( int i = 0; i < DIM_SQ; ++i ) {
00498 m[i] *= rhs;
00499 }
00500 return *this;
00501 }
00502
00503 template< typename T >
00504 Matrix44<T>& Matrix44<T>::operator/=( T rhs )
00505 {
00506 T invS = (T)1/rhs;
00507 for( int i = 0; i < DIM_SQ; ++i ) {
00508 m[i] *= invS;
00509 }
00510 return *this;
00511 }
00512
00513 template< typename T >
00514 Matrix44<T>& Matrix44<T>::operator+=( T rhs )
00515 {
00516 for( int i = 0; i < DIM_SQ; ++i ) {
00517 m[i] += rhs;
00518 }
00519 return *this;
00520 }
00521
00522 template< typename T >
00523 Matrix44<T>& Matrix44<T>::operator-=( T rhs )
00524 {
00525 for( int i = 0; i < DIM_SQ; ++i ) {
00526 m[i] -= rhs;
00527 }
00528 return *this;
00529 }
00530
00531 template< typename T >
00532 inline const Matrix44<T> Matrix44<T>::operator*( const Matrix44<T> &rhs ) const
00533 {
00534 Matrix44<T> ret;
00535
00536 ret.m[ 0] = m[ 0]*rhs.m[ 0] + m[ 4]*rhs.m[ 1] + m[ 8]*rhs.m[ 2] + m[12]*rhs.m[ 3];
00537 ret.m[ 1] = m[ 1]*rhs.m[ 0] + m[ 5]*rhs.m[ 1] + m[ 9]*rhs.m[ 2] + m[13]*rhs.m[ 3];
00538 ret.m[ 2] = m[ 2]*rhs.m[ 0] + m[ 6]*rhs.m[ 1] + m[10]*rhs.m[ 2] + m[14]*rhs.m[ 3];
00539 ret.m[ 3] = m[ 3]*rhs.m[ 0] + m[ 7]*rhs.m[ 1] + m[11]*rhs.m[ 2] + m[15]*rhs.m[ 3];
00540
00541 ret.m[ 4] = m[ 0]*rhs.m[ 4] + m[ 4]*rhs.m[ 5] + m[ 8]*rhs.m[ 6] + m[12]*rhs.m[ 7];
00542 ret.m[ 5] = m[ 1]*rhs.m[ 4] + m[ 5]*rhs.m[ 5] + m[ 9]*rhs.m[ 6] + m[13]*rhs.m[ 7];
00543 ret.m[ 6] = m[ 2]*rhs.m[ 4] + m[ 6]*rhs.m[ 5] + m[10]*rhs.m[ 6] + m[14]*rhs.m[ 7];
00544 ret.m[ 7] = m[ 3]*rhs.m[ 4] + m[ 7]*rhs.m[ 5] + m[11]*rhs.m[ 6] + m[15]*rhs.m[ 7];
00545
00546 ret.m[ 8] = m[ 0]*rhs.m[ 8] + m[ 4]*rhs.m[ 9] + m[ 8]*rhs.m[10] + m[12]*rhs.m[11];
00547 ret.m[ 9] = m[ 1]*rhs.m[ 8] + m[ 5]*rhs.m[ 9] + m[ 9]*rhs.m[10] + m[13]*rhs.m[11];
00548 ret.m[10] = m[ 2]*rhs.m[ 8] + m[ 6]*rhs.m[ 9] + m[10]*rhs.m[10] + m[14]*rhs.m[11];
00549 ret.m[11] = m[ 3]*rhs.m[ 8] + m[ 7]*rhs.m[ 9] + m[11]*rhs.m[10] + m[15]*rhs.m[11];
00550
00551 ret.m[12] = m[ 0]*rhs.m[12] + m[ 4]*rhs.m[13] + m[ 8]*rhs.m[14] + m[12]*rhs.m[15];
00552 ret.m[13] = m[ 1]*rhs.m[12] + m[ 5]*rhs.m[13] + m[ 9]*rhs.m[14] + m[13]*rhs.m[15];
00553 ret.m[14] = m[ 2]*rhs.m[12] + m[ 6]*rhs.m[13] + m[10]*rhs.m[14] + m[14]*rhs.m[15];
00554 ret.m[15] = m[ 3]*rhs.m[12] + m[ 7]*rhs.m[13] + m[11]*rhs.m[14] + m[15]*rhs.m[15];
00555
00556 return ret;
00557 }
00558
00559 template< typename T >
00560 const Matrix44<T> Matrix44<T>::operator+( const Matrix44<T> &rhs ) const
00561 {
00562 Matrix44<T> ret;
00563 for( int i = 0; i < DIM_SQ; ++i ) {
00564 ret.m[i] = m[i] + rhs.m[i];
00565 }
00566 return ret;
00567 }
00568
00569 template< typename T >
00570 const Matrix44<T> Matrix44<T>::operator-( const Matrix44<T> &rhs ) const
00571 {
00572 Matrix44<T> ret;
00573 for( int i = 0; i < DIM_SQ; ++i ) {
00574 ret.m[i] = m[i] - rhs.m[i];
00575 }
00576 return ret;
00577 }
00578
00579 template< typename T >
00580 const Vec3<T> Matrix44<T>::operator*( const Vec3<T> &rhs ) const
00581 {
00582 T x = m[ 0]*rhs.x + m[ 4]*rhs.y + m[ 8]*rhs.z + m[12];
00583 T y = m[ 1]*rhs.x + m[ 5]*rhs.y + m[ 9]*rhs.z + m[13];
00584 T z = m[ 2]*rhs.x + m[ 6]*rhs.y + m[10]*rhs.z + m[14];
00585 T w = m[ 3]*rhs.x + m[ 7]*rhs.y + m[11]*rhs.z + m[15];
00586
00587 return Vec3<T>( x/w, y/w, z/w );
00588 }
00589
00590 template< typename T >
00591 const Vec4<T> Matrix44<T>::operator*( const Vec4<T> &rhs ) const
00592 {
00593 return Vec4<T>(
00594 m[ 0]*rhs.x + m[ 4]*rhs.y + m[ 8]*rhs.z + m[12]*rhs.w,
00595 m[ 1]*rhs.x + m[ 5]*rhs.y + m[ 9]*rhs.z + m[13]*rhs.w,
00596 m[ 2]*rhs.x + m[ 6]*rhs.y + m[10]*rhs.z + m[14]*rhs.w,
00597 m[ 3]*rhs.x + m[ 7]*rhs.y + m[11]*rhs.z + m[15]*rhs.w
00598 );
00599 }
00600
00601 template< typename T >
00602 const Matrix44<T> Matrix44<T>::operator*( T rhs ) const
00603 {
00604 Matrix44<T> ret;
00605 for( int i = 0; i < DIM_SQ; ++i ) {
00606 ret.m[i] = m[i]*rhs;
00607 }
00608 return ret;
00609 }
00610
00611 template< typename T >
00612 const Matrix44<T> Matrix44<T>::operator/( T rhs ) const
00613 {
00614 Matrix44<T> ret;
00615 T s = (T)1/rhs;
00616 for( int i = 0; i < DIM_SQ; ++i ) {
00617 ret.m[i] = m[i]*s;
00618 }
00619 return ret;
00620 }
00621
00622 template< typename T >
00623 const Matrix44<T> Matrix44<T>::operator+( T rhs ) const
00624 {
00625 Matrix44<T> ret;
00626 for( int i = 0; i < DIM_SQ; ++i ) {
00627 ret.m[i] = m[i] + rhs;
00628 }
00629 return ret;
00630 }
00631
00632 template< typename T >
00633 const Matrix44<T> Matrix44<T>::operator-( T rhs ) const
00634 {
00635 Matrix44<T> ret;
00636 for( int i = 0; i < DIM_SQ; ++i ) {
00637 ret.m[i] = m[i] - rhs;
00638 }
00639 return ret;
00640 }
00641
00642 template< typename T >
00643 T& Matrix44<T>::at( int row, int col )
00644 {
00645 assert(row >= 0 && row < DIM);
00646 assert(col >= 0 && col < DIM);
00647 return m[col*DIM + row];
00648 }
00649
00650 template< typename T >
00651 const T& Matrix44<T>::at( int row, int col ) const
00652 {
00653 assert(row >= 0 && row < DIM);
00654 assert(col >= 0 && col < DIM);
00655 return m[col*DIM + row];
00656 }
00657
00658 template< typename T >
00659 void Matrix44<T>::set( const T *dt, bool srcIsRowMajor )
00660 {
00661 if( srcIsRowMajor ) {
00662 m[0] = dt[ 0]; m[4] = dt[ 1]; m[ 8] = dt[ 2]; m[12] = dt[ 3];
00663 m[1] = dt[ 4]; m[5] = dt[ 5]; m[ 9] = dt[ 6]; m[13] = dt[ 7];
00664 m[2] = dt[ 8]; m[6] = dt[ 9]; m[10] = dt[10]; m[14] = dt[11];
00665 m[3] = dt[12]; m[7] = dt[13]; m[11] = dt[14]; m[15] = dt[15];
00666 }
00667 else {
00668 std::memcpy( m, dt, MEM_LEN );
00669 }
00670 }
00671
00672 template< typename T >
00673 void Matrix44<T>::set( T d0, T d1, T d2, T d3, T d4, T d5, T d6, T d7, T d8, T d9, T d10, T d11, T d12, T d13, T d14, T d15, bool srcIsRowMajor )
00674 {
00675 if( srcIsRowMajor ) {
00676 m[0] = d0; m[4] = d1; m[ 8] = d2; m[12] = d3;
00677 m[1] = d4; m[5] = d5; m[ 9] = d6; m[13] = d7;
00678 m[2] = d8; m[6] = d9; m[10] = d10; m[14] = d11;
00679 m[3] = d12; m[7] = d13; m[11] = d14; m[15] = d15;
00680 }
00681 else {
00682 m[0] = d0; m[4] = d4; m[ 8] = d8; m[12] = d12;
00683 m[1] = d1; m[5] = d5; m[ 9] = d9; m[13] = d13;
00684 m[2] = d2; m[6] = d6; m[10] = d10; m[14] = d14;
00685 m[3] = d3; m[7] = d7; m[11] = d11; m[15] = d15;
00686 }
00687 }
00688
00689 template< typename T >
00690 Vec4<T> Matrix44<T>::getColumn( int col ) const
00691 {
00692 size_t i = col*DIM;
00693 return Vec4<T>(
00694 m[i + 0],
00695 m[i + 1],
00696 m[i + 2],
00697 m[i + 3]
00698 );
00699 }
00700
00701 template< typename T >
00702 void Matrix44<T>::setColumn( int col, const Vec4<T> &v )
00703 {
00704 size_t i = col*DIM;
00705 m[i + 0] = v.x;
00706 m[i + 1] = v.y;
00707 m[i + 2] = v.z;
00708 m[i + 3] = v.w;
00709 }
00710
00711 template< typename T >
00712 Vec4<T> Matrix44<T>::getRow( int row ) const
00713 {
00714 return Vec4<T>(
00715 m[row + 0],
00716 m[row + 4],
00717 m[row + 8],
00718 m[row + 12]
00719 );
00720 }
00721
00722 template< typename T >
00723 void Matrix44<T>::setRow( int row, const Vec4<T> &v )
00724 {
00725 m[row + 0] = v.x;
00726 m[row + 4] = v.y;
00727 m[row + 8] = v.z;
00728 m[row + 12] = v.w;
00729 }
00730
00731 template< typename T >
00732 void Matrix44<T>::getColumns( Vec4<T> *c0, Vec4<T> *c1, Vec4<T> *c2, Vec4<T> *c3 ) const
00733 {
00734 *c0 = getColumn( 0 );
00735 *c1 = getColumn( 1 );
00736 *c2 = getColumn( 2 );
00737 *c3 = getColumn( 3 );
00738 }
00739
00740 template< typename T >
00741 void Matrix44<T>::setColumns( const Vec4<T> &c0, const Vec4<T> &c1, const Vec4<T> &c2, const Vec4<T> &c3 )
00742 {
00743 setColumn( 0, c0 );
00744 setColumn( 1, c1 );
00745 setColumn( 2, c2 );
00746 setColumn( 3, c3 );
00747 }
00748
00749 template< typename T >
00750 void Matrix44<T>::getRows( Vec4<T> *r0, Vec4<T> *r1, Vec4<T> *r2, Vec4<T> *r3 ) const
00751 {
00752 *r0 = getRow( 0 );
00753 *r1 = getRow( 1 );
00754 *r2 = getRow( 2 );
00755 *r3 = getRow( 3 );
00756 }
00757
00758 template< typename T >
00759 void Matrix44<T>::setRows( const Vec4<T> &r0, const Vec4<T> &r1, const Vec4<T> &r2, const Vec4<T> &r3 )
00760 {
00761 setRow( 0, r0 );
00762 setRow( 1, r1 );
00763 setRow( 2, r2 );
00764 setRow( 3, r3 );
00765 }
00766
00767 template< typename T >
00768 Matrix22<T> Matrix44<T>::subMatrix22( int row, int col ) const
00769 {
00770 Matrix22<T> ret;
00771 ret.setToNull();
00772
00773 for( int i = 0; i < 2; ++i ) {
00774 int r = row + i;
00775 if( r >= 4 ) {
00776 continue;
00777 }
00778 for( int j = 0; j < 2; ++j ) {
00779 int c = col + j;
00780 if( c >= 4 ) {
00781 continue;
00782 }
00783 ret.at( i, j ) = at( r, c );
00784 }
00785 }
00786
00787 return ret;
00788 }
00789
00790 template< typename T >
00791 Matrix33<T> Matrix44<T>::subMatrix33( int row, int col ) const
00792 {
00793 Matrix33<T> ret;
00794 ret.setToNull();
00795
00796 for( int i = 0; i < 3; ++i ) {
00797 int r = row + i;
00798 if( r >= 4 ) {
00799 continue;
00800 }
00801 for( int j = 0; j < 3; ++j ) {
00802 int c = col + j;
00803 if( c >= 4 ) {
00804 continue;
00805 }
00806 ret.at( i, j ) = at( r, c );
00807 }
00808 }
00809
00810 return ret;
00811 }
00812
00813 template< typename T >
00814 void Matrix44<T>::setToNull()
00815 {
00816 std::memset( m, 0, MEM_LEN );
00817 }
00818
00819 template< typename T >
00820 void Matrix44<T>::setToIdentity()
00821 {
00822 m[ 0] = 1; m[ 4] = 0; m[ 8] = 0; m[12] = 0;
00823 m[ 1] = 0; m[ 5] = 1; m[ 9] = 0; m[13] = 0;
00824 m[ 2] = 0; m[ 6] = 0; m[10] = 1; m[14] = 0;
00825 m[ 3] = 0; m[ 7] = 0; m[11] = 0; m[15] = 1;
00826 }
00827
00828 template< typename T >
00829 T Matrix44<T>::determinant() const
00830 {
00831 T a0 = m[ 0]*m[ 5] - m[ 1]*m[ 4];
00832 T a1 = m[ 0]*m[ 6] - m[ 2]*m[ 4];
00833 T a2 = m[ 0]*m[ 7] - m[ 3]*m[ 4];
00834 T a3 = m[ 1]*m[ 6] - m[ 2]*m[ 5];
00835 T a4 = m[ 1]*m[ 7] - m[ 3]*m[ 5];
00836 T a5 = m[ 2]*m[ 7] - m[ 3]*m[ 6];
00837 T b0 = m[ 8]*m[13] - m[ 9]*m[12];
00838 T b1 = m[ 8]*m[14] - m[10]*m[12];
00839 T b2 = m[ 8]*m[15] - m[11]*m[12];
00840 T b3 = m[ 9]*m[14] - m[10]*m[13];
00841 T b4 = m[ 9]*m[15] - m[11]*m[13];
00842 T b5 = m[10]*m[15] - m[11]*m[14];
00843
00844 T det = a0*b5 - a1*b4 + a2*b3 + a3*b2 - a4*b1 + a5*b0;
00845
00846 return det;
00847 }
00848
00849 template< typename T >
00850 T Matrix44<T>::trace( bool fullTrace ) const
00851 {
00852 if( fullTrace ) {
00853 return m00 + m11 + m22 + m33;
00854 }
00855
00856 return m00 + m11 + m22;
00857 }
00858
00859 template< typename T >
00860 Matrix44<T> Matrix44<T>::diagonal() const
00861 {
00862 Matrix44 ret;
00863 ret.m00 = m00; ret.m01 = 0; ret.m02 = 0; ret.m03 = 0;
00864 ret.m10 = 0; ret.m11 = m11; ret.m12 = 0; ret.m13 = 0;
00865 ret.m20 = 0; ret.m21 = 0; ret.m22 = m22; ret.m23 = 0;
00866 ret.m30 = 0; ret.m31 = 0; ret.m32 = 0; ret.m33 = m33;
00867 return ret;
00868 }
00869
00870 template< typename T >
00871 Matrix44<T> Matrix44<T>::lowerTriangular() const
00872 {
00873 Matrix44 ret;
00874 ret.m00 = m00; ret.m01 = 0; ret.m02 = 0; ret.m03 = 0;
00875 ret.m10 = m10; ret.m11 = m11; ret.m12 = 0; ret.m13 = 0;
00876 ret.m20 = m20; ret.m21 = m21; ret.m22 = m22; ret.m23 = 0;
00877 ret.m30 = m30; ret.m31 = m31; ret.m32 = m32; ret.m33 = m33;
00878 return ret;
00879 }
00880
00881 template< typename T >
00882 Matrix44<T> Matrix44<T>::upperTriangular() const
00883 {
00884 Matrix44 ret;
00885 ret.m00 = m00; ret.m01 = m01; ret.m02 = m02; ret.m03 = m03;
00886 ret.m10 = 0; ret.m11 = m11; ret.m12 = m12; ret.m13 = m13;
00887 ret.m20 = 0; ret.m21 = 0; ret.m22 = m22; ret.m23 = m23;
00888 ret.m30 = 0; ret.m31 = 0; ret.m32 = 0; ret.m33 = m33;
00889 return ret;
00890 }
00891
00892 template< typename T >
00893 void Matrix44<T>::transpose()
00894 {
00895 T t;
00896 t = m01; m01 = m10; m10 = t;
00897 t = m02; m02 = m20; m20 = t;
00898 t = m03; m03 = m30; m30 = t;
00899 t = m12; m12 = m21; m21 = t;
00900 t = m13; m13 = m31; m31 = t;
00901 t = m23; m23 = m32; m32 = t;
00902 }
00903
00904 template< typename T >
00905 Matrix44<T> Matrix44<T>::transposed() const
00906 {
00907 return Matrix44<T>(
00908 m[ 0], m[ 4], m[ 8], m[12],
00909 m[ 1], m[ 5], m[ 9], m[13],
00910 m[ 2], m[ 6], m[10], m[14],
00911 m[ 3], m[ 7], m[11], m[15]
00912 );
00913 }
00914
00915 template< typename T >
00916 inline Matrix44<T> Matrix44<T>::inverted( T epsilon ) const
00917 {
00918 Matrix44<T> inv( (T)0 );
00919
00920 T a0 = m[ 0]*m[ 5] - m[ 1]*m[ 4];
00921 T a1 = m[ 0]*m[ 6] - m[ 2]*m[ 4];
00922 T a2 = m[ 0]*m[ 7] - m[ 3]*m[ 4];
00923 T a3 = m[ 1]*m[ 6] - m[ 2]*m[ 5];
00924 T a4 = m[ 1]*m[ 7] - m[ 3]*m[ 5];
00925 T a5 = m[ 2]*m[ 7] - m[ 3]*m[ 6];
00926 T b0 = m[ 8]*m[13] - m[ 9]*m[12];
00927 T b1 = m[ 8]*m[14] - m[10]*m[12];
00928 T b2 = m[ 8]*m[15] - m[11]*m[12];
00929 T b3 = m[ 9]*m[14] - m[10]*m[13];
00930 T b4 = m[ 9]*m[15] - m[11]*m[13];
00931 T b5 = m[10]*m[15] - m[11]*m[14];
00932
00933 T det = a0*b5 - a1*b4 + a2*b3 + a3*b2 - a4*b1 + a5*b0;
00934
00935 if( fabs( det ) > epsilon ) {
00936 inv.m[ 0] = + m[ 5]*b5 - m[ 6]*b4 + m[ 7]*b3;
00937 inv.m[ 4] = - m[ 4]*b5 + m[ 6]*b2 - m[ 7]*b1;
00938 inv.m[ 8] = + m[ 4]*b4 - m[ 5]*b2 + m[ 7]*b0;
00939 inv.m[12] = - m[ 4]*b3 + m[ 5]*b1 - m[ 6]*b0;
00940 inv.m[ 1] = - m[ 1]*b5 + m[ 2]*b4 - m[ 3]*b3;
00941 inv.m[ 5] = + m[ 0]*b5 - m[ 2]*b2 + m[ 3]*b1;
00942 inv.m[ 9] = - m[ 0]*b4 + m[ 1]*b2 - m[ 3]*b0;
00943 inv.m[13] = + m[ 0]*b3 - m[ 1]*b1 + m[ 2]*b0;
00944 inv.m[ 2] = + m[13]*a5 - m[14]*a4 + m[15]*a3;
00945 inv.m[ 6] = - m[12]*a5 + m[14]*a2 - m[15]*a1;
00946 inv.m[10] = + m[12]*a4 - m[13]*a2 + m[15]*a0;
00947 inv.m[14] = - m[12]*a3 + m[13]*a1 - m[14]*a0;
00948 inv.m[ 3] = - m[ 9]*a5 + m[10]*a4 - m[11]*a3;
00949 inv.m[ 7] = + m[ 8]*a5 - m[10]*a2 + m[11]*a1;
00950 inv.m[11] = - m[ 8]*a4 + m[ 9]*a2 - m[11]*a0;
00951 inv.m[15] = + m[ 8]*a3 - m[ 9]*a1 + m[10]*a0;
00952
00953 T invDet = ((T)1)/det;
00954 inv.m[ 0] *= invDet;
00955 inv.m[ 1] *= invDet;
00956 inv.m[ 2] *= invDet;
00957 inv.m[ 3] *= invDet;
00958 inv.m[ 4] *= invDet;
00959 inv.m[ 5] *= invDet;
00960 inv.m[ 6] *= invDet;
00961 inv.m[ 7] *= invDet;
00962 inv.m[ 8] *= invDet;
00963 inv.m[ 9] *= invDet;
00964 inv.m[10] *= invDet;
00965 inv.m[11] *= invDet;
00966 inv.m[12] *= invDet;
00967 inv.m[13] *= invDet;
00968 inv.m[14] *= invDet;
00969 inv.m[15] *= invDet;
00970 }
00971
00972 return inv;
00973 }
00974
00975 template< typename T >
00976 Vec3<T> Matrix44<T>::preMultiply( const Vec3<T> &v ) const
00977 {
00978 return Vec3<T>(
00979 v.x*m00 + v.y*m10 + v.z*m20,
00980 v.x*m01 + v.y*m11 + v.z*m21,
00981 v.x*m02 + v.y*m12 + v.z*m22
00982 );
00983 }
00984
00985 template< typename T >
00986 Vec4<T> Matrix44<T>::preMultiply( const Vec4<T> &v ) const
00987 {
00988 return Vec4<T>(
00989 v.x*m00 + v.y*m10 + v.z*m20 + v.w*m30,
00990 v.x*m01 + v.y*m11 + v.z*m21 + v.w*m31,
00991 v.x*m02 + v.y*m12 + v.z*m22 + v.w*m32,
00992 v.x*m03 + v.y*m13 + v.z*m23 + v.w*m33
00993 );
00994 }
00995
00996 template< typename T >
00997 Vec3<T> Matrix44<T>::postMultiply( const Vec3<T> &v ) const
00998 {
00999 return Vec3<T>(
01000 m00*v.x + m01*v.y + m02*v.z,
01001 m10*v.x + m11*v.y + m12*v.z,
01002 m20*v.x + m21*v.y + m22*v.z
01003 );
01004 }
01005
01006 template< typename T >
01007 Vec4<T> Matrix44<T>::postMultiply( const Vec4<T> &v ) const
01008 {
01009 return Vec4<T>(
01010 m00*v.x + m01*v.y + m02*v.z + m03*v.w,
01011 m10*v.x + m11*v.y + m12*v.z + m13*v.w,
01012 m20*v.x + m21*v.y + m22*v.z + m23*v.w,
01013 m30*v.x + m31*v.y + m32*v.z + m33*v.w
01014 );
01015 }
01016
01017 template< typename T >
01018 Matrix44<T> Matrix44<T>::affineInverted() const
01019 {
01020 Matrix44<T> ret;
01021
01022
01023 T cofactor0 = m[ 5]*m[10] - m[6]*m[ 9];
01024 T cofactor4 = m[ 2]*m[ 9] - m[1]*m[10];
01025 T cofactor8 = m[ 1]*m[ 6] - m[2]*m[ 5];
01026 T det = m[0]*cofactor0 + m[4]*cofactor4 + m[8]*cofactor8;
01027 if( fabs( det ) <= EPSILON ) {
01028 return ret;
01029 }
01030
01031
01032 T invDet = ((T)1.0) / det;
01033 ret.m[ 0] = invDet*cofactor0;
01034 ret.m[ 1] = invDet*cofactor4;
01035 ret.m[ 2] = invDet*cofactor8;
01036
01037 ret.m[ 4] = invDet*(m[ 6]*m[ 8] - m[ 4]*m[10]);
01038 ret.m[ 5] = invDet*(m[ 0]*m[10] - m[ 2]*m[ 8]);
01039 ret.m[ 6] = invDet*(m[ 2]*m[ 4] - m[ 0]*m[ 6]);
01040
01041 ret.m[ 8] = invDet*(m[ 4]*m[ 9] - m[ 5]*m[ 8]);
01042 ret.m[ 9] = invDet*(m[ 1]*m[ 8] - m[ 0]*m[ 9]);
01043 ret.m[10] = invDet*(m[ 0]*m[ 5] - m[ 1]*m[ 4]);
01044
01045
01046 ret.m[12] = -ret.m[ 0]*m[12] - ret.m[ 4]*m[13] - ret.m[ 8]*m[14];
01047 ret.m[13] = -ret.m[ 1]*m[12] - ret.m[ 5]*m[13] - ret.m[ 9]*m[14];
01048 ret.m[14] = -ret.m[ 2]*m[12] - ret.m[ 6]*m[13] - ret.m[10]*m[14];
01049
01050 return ret;
01051 }
01052
01053 template< typename T >
01054 Vec3<T> Matrix44<T>::transformPoint( const Vec3<T> &rhs ) const
01055 {
01056 T x = m00*rhs.x + m01*rhs.y + m02*rhs.z + m03;
01057 T y = m10*rhs.x + m11*rhs.y + m12*rhs.z + m13;
01058 T z = m20*rhs.x + m21*rhs.y + m22*rhs.z + m23;
01059 T w = m30*rhs.x + m31*rhs.y + m32*rhs.z + m33;
01060
01061 return Vec3<T>( x / w, y / w, z / w );
01062 }
01063
01064 template< typename T >
01065 Vec3<T> Matrix44<T>::transformPointAffine( const Vec3<T> &rhs ) const
01066 {
01067 T x = m00*rhs.x + m01*rhs.y + m02*rhs.z + m03;
01068 T y = m10*rhs.x + m11*rhs.y + m12*rhs.z + m13;
01069 T z = m20*rhs.x + m21*rhs.y + m22*rhs.z + m23;
01070
01071 return Vec3<T>( x, y, z );
01072 }
01073
01074 template< typename T >
01075 Vec3<T> Matrix44<T>::transformVec( const Vec3<T> &rhs ) const
01076 {
01077 T x = m00*rhs.x + m01*rhs.y + m02*rhs.z;
01078 T y = m10*rhs.x + m11*rhs.y + m12*rhs.z;
01079 T z = m20*rhs.x + m21*rhs.y + m22*rhs.z;
01080
01081 return Vec3<T>( x, y, z );
01082 }
01083
01084 template< typename T >
01085 void Matrix44<T>::orthonormalInvert()
01086 {
01087
01088 std::swap( at(0,1), at(1,0) );
01089 std::swap( at(0,2), at(2,0) );
01090 std::swap( at(1,2), at(2,1) );
01091
01092
01093 Vec3f newT( transformVec( Vec3f(-at(0,3),-at(1,3),-at(2,3)) ) );
01094 at(0,3) = newT.x;
01095 at(1,3) = newT.y;
01096 at(2,3) = newT.z;
01097 }
01098
01099 template<typename T>
01100 Matrix44<T> Matrix44<T>::createTranslation( const Vec3<T> &v, T w )
01101 {
01102 Matrix44 ret;
01103 ret.m[12] = v.x;
01104 ret.m[13] = v.y;
01105 ret.m[14] = v.z;
01106 ret.m[15] = w;
01107
01108 return ret;
01109 }
01110
01112
01113 template<typename T>
01114 Matrix44<T> Matrix44<T>::createRotation( const Vec3<T> &from, const Vec3<T> &to, const Vec3<T> &worldUp )
01115 {
01116
01117
01118
01119
01120
01121
01122
01123 if( from.lengthSquared() == 0 ) {
01124 return Matrix44<T>();
01125 }
01126 else {
01127 Matrix44<T> zAxis2FromDir = alignZAxisWithTarget( from, Vec3<T>::yAxis() );
01128 Matrix44<T> fromDir2zAxis = zAxis2FromDir.transposed();
01129 Matrix44<T> zAxis2ToDir = alignZAxisWithTarget( to, worldUp );
01130 return fromDir2zAxis * zAxis2ToDir;
01131 }
01132 }
01133
01134 template<typename T>
01135 Matrix44<T> Matrix44<T>::createRotation( const Vec3<T> &axis, T angle )
01136 {
01137 Vec3<T> unit( axis.normalized() );
01138 T sine = math<T>::sin( angle );
01139 T cosine = math<T>::cos( angle );
01140
01141 Matrix44<T> ret;
01142
01143 ret.m[ 0] = unit.x * unit.x * (1 - cosine) + cosine;
01144 ret.m[ 1] = unit.x * unit.y * (1 - cosine) + unit.z * sine;
01145 ret.m[ 2] = unit.x * unit.z * (1 - cosine) - unit.y * sine;
01146 ret.m[ 3] = 0;
01147
01148 ret.m[ 4] = unit.x * unit.y * (1 - cosine) - unit.z * sine;
01149 ret.m[ 5] = unit.y * unit.y * (1 - cosine) + cosine;
01150 ret.m[ 6] = unit.y * unit.z * (1 - cosine) + unit.x * sine;
01151 ret.m[ 7] = 0;
01152
01153 ret.m[ 8] = unit.x * unit.z * (1 - cosine) + unit.y * sine;
01154 ret.m[ 9] = unit.y * unit.z * (1 - cosine) - unit.x * sine;
01155 ret.m[10] = unit.z * unit.z * (1 - cosine) + cosine;
01156 ret.m[11] = 0;
01157
01158 ret.m[12] = 0;
01159 ret.m[13] = 0;
01160 ret.m[14] = 0;
01161 ret.m[15] = 1;
01162
01163 return ret;
01164 }
01165
01166 template<typename T>
01167 Matrix44<T> Matrix44<T>::createRotation( const Vec3<T> &eulerRadians )
01168 {
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 Matrix44<T> ret;
01179 T cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
01180
01181 cos_rx = math<T>::cos( eulerRadians.x );
01182 cos_ry = math<T>::cos( eulerRadians.y );
01183 cos_rz = math<T>::cos( eulerRadians.z );
01184
01185 sin_rx = math<T>::sin( eulerRadians.x );
01186 sin_ry = math<T>::sin( eulerRadians.y );
01187 sin_rz = math<T>::sin( eulerRadians.z );
01188
01189 ret.m[ 0] = cos_rz*cos_ry;
01190 ret.m[ 1] = sin_rz*cos_ry;
01191 ret.m[ 2] = -sin_ry;
01192 ret.m[ 3] = 0;
01193
01194 ret.m[ 4] = -sin_rz*cos_rx + cos_rz*sin_ry*sin_rx;
01195 ret.m[ 5] = cos_rz*cos_rx + sin_rz*sin_ry*sin_rx;
01196 ret.m[ 6] = cos_ry*sin_rx;
01197 ret.m[ 7] = 0;
01198
01199 ret.m[ 8] = sin_rz*sin_rx + cos_rz*sin_ry*cos_rx;
01200 ret.m[ 9] = -cos_rz*sin_rx + sin_rz*sin_ry*cos_rx;
01201 ret.m[10] = cos_ry*cos_rx;
01202 ret.m[11] = 0;
01203
01204 ret.m[12] = 0;
01205 ret.m[13] = 0;
01206 ret.m[14] = 0;
01207 ret.m[15] = 1;
01208
01209 return ret;
01210 }
01211
01212 template<typename T>
01213 Matrix44<T> Matrix44<T>::createRotationOnb( const Vec3<T>& u, const Vec3<T>& v, const Vec3<T>& w )
01214 {
01215 return Matrix44<T>(
01216 u.x, u.y, u.z, 0,
01217 v.x, v.y, v.z, 0,
01218 w.x, w.y, w.z, 0,
01219 0, 0, 0, 1
01220 );
01221 }
01222
01223 template<typename T>
01224 Matrix44<T> Matrix44<T>::createScale( T s )
01225 {
01226 Matrix44<T> ret;
01227 ret.setToIdentity();
01228 ret.at(0,0) = s;
01229 ret.at(1,1) = s;
01230 ret.at(2,2) = s;
01231 ret.at(3,3) = s;
01232 return ret;
01233 }
01234
01235 template<typename T>
01236 Matrix44<T> Matrix44<T>::createScale( const Vec2<T> &v )
01237 {
01238 Matrix44<T> ret;
01239 ret.setToIdentity();
01240 ret.at(0,0) = v.x;
01241 ret.at(1,1) = v.y;
01242 ret.at(2,2) = 1;
01243 ret.at(3,3) = 1;
01244 return ret;
01245 }
01246
01247 template<typename T>
01248 Matrix44<T> Matrix44<T>::createScale( const Vec3<T> &v )
01249 {
01250 Matrix44<T> ret;
01251 ret.setToIdentity();
01252 ret.at(0,0) = v.x;
01253 ret.at(1,1) = v.y;
01254 ret.at(2,2) = v.z;
01255 ret.at(3,3) = 1;
01256 return ret;
01257 }
01258
01259 template<typename T>
01260 Matrix44<T> Matrix44<T>::createScale( const Vec4<T> &v )
01261 {
01262 Matrix44<T> ret;
01263 ret.setToIdentity();
01264 ret.at(0,0) = v.x;
01265 ret.at(1,1) = v.y;
01266 ret.at(2,2) = v.z;
01267 ret.at(3,3) = v.w;
01268 return ret;
01269 }
01270
01271 template<typename T>
01272 Matrix44<T> Matrix44<T>::alignZAxisWithTarget( Vec3<T> targetDir, Vec3<T> upDir )
01273 {
01274
01275 if( targetDir.lengthSquared() == 0 )
01276 targetDir = Vec3<T>::zAxis();
01277
01278
01279 if( upDir.lengthSquared() == 0 )
01280 upDir = Vec3<T>::yAxis();
01281
01282
01283
01284
01285 if( upDir.cross( targetDir ).lengthSquared() == 0 ) {
01286 upDir = targetDir.cross( Vec3<T>::xAxis() );
01287 if( upDir.lengthSquared() == 0 )
01288 upDir = targetDir.cross( Vec3<T>::zAxis() );
01289 }
01290
01291
01292 Vec3<T> targetPerpDir = upDir.cross( targetDir );
01293 Vec3<T> targetUpDir = targetDir.cross( targetPerpDir );
01294
01295
01296
01297
01298
01299 Vec3<T> row[3];
01300 row[0] = targetPerpDir.normalized();
01301 row[1] = targetUpDir.normalized();
01302 row[2] = targetDir.normalized();
01303
01304 Matrix44<T> mat( row[0].x, row[0].y, row[0].z, 0,
01305 row[1].x, row[1].y, row[1].z, 0,
01306 row[2].x, row[2].y, row[2].z, 0,
01307 0, 0, 0, 1 );
01308
01309 return mat;
01310 }
01311
01313
01314 typedef Matrix44<float> Matrix44f;
01315 typedef Matrix44<double> Matrix44d;
01316
01317 }