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 #ifndef OPAL_MATRIX44R_H
00029 #define OPAL_MATRIX44R_H
00030
00031
00032 #include "Quaternion.h"
00033 #include "OpalMath.h"
00034 #include "Point3r.h"
00035 #include "Rayr.h"
00036 #include "Vec3r.h"
00037
00038 namespace opal
00039 {
00040
00041
00042
00043
00044
00045 class Matrix44r;
00046 inline Matrix44r operator*( const Matrix44r & lhs, const Matrix44r & rhs );
00047 inline Vec3r operator*( const Matrix44r & m, const Vec3r &v );
00048 inline Matrix44r operator+( const Matrix44r & lhs, const Matrix44r & rhs );
00049 inline Matrix44r operator-( const Matrix44r & lhs, const Matrix44r & rhs );
00050 inline Point3r operator*( const Matrix44r & m, const Point3r &p );
00051 inline Rayr operator*( const Matrix44r & m, const Rayr &r );
00052
00055 inline bool inverse( Matrix44r & dest, const Matrix44r & src );
00056
00058 inline void fastInverse( Matrix44r & dest, const Matrix44r & src );
00059
00061 inline std::ostream& operator<<( std::ostream& o, const Matrix44r& m );
00062
00064
00067 class Matrix44r
00068 {
00069 private:
00070 real mData[ 16 ];
00071
00072 public:
00073 inline friend Matrix44r operator*( real scalar, Matrix44r m );
00074
00076 Matrix44r()
00077 {
00078 makeIdentity();
00079 }
00080
00082 Matrix44r( const Matrix44r & src )
00083 {
00084 memcpy( mData, src.mData, 16 * sizeof( real ) );
00085 }
00086
00088 Matrix44r( real _00, real _10, real _20, real _30,
00089 real _01, real _11, real _21, real _31,
00090 real _02, real _12, real _22, real _32,
00091 real _03, real _13, real _23, real _33 )
00092 {
00093 mData[ 0 ] = _00;
00094 mData[ 1 ] = _01;
00095 mData[ 2 ] = _02;
00096 mData[ 3 ] = _03;
00097
00098 mData[ 4 ] = _10;
00099 mData[ 5 ] = _11;
00100 mData[ 6 ] = _12;
00101 mData[ 7 ] = _13;
00102
00103 mData[ 8 ] = _20;
00104 mData[ 9 ] = _21;
00105 mData[ 10 ] = _22;
00106 mData[ 11 ] = _23;
00107
00108 mData[ 12 ] = _30;
00109 mData[ 13 ] = _31;
00110 mData[ 14 ] = _32;
00111 mData[ 15 ] = _33;
00112 }
00113
00115 Matrix44r( const real * data )
00116 {
00117 memcpy( mData, data, 16 * sizeof( real ) );
00118 }
00119
00121 inline void setPosition( real x, real y, real z )
00122 {
00123 mData[ 12 ] = x;
00124 mData[ 13 ] = y;
00125 mData[ 14 ] = z;
00126 }
00127
00129 inline Point3r getPosition() const
00130 {
00131 return Point3r( mData[ 12 ], mData[ 13 ], mData[ 14 ] );
00132 }
00133
00135 inline Vec3r getTranslation() const
00136 {
00137 return Vec3r( mData[ 12 ], mData[ 13 ], mData[ 14 ] );
00138 }
00139
00141 inline void set( real _00, real _10, real _20, real _30,
00142 real _01, real _11, real _21, real _31,
00143 real _02, real _12, real _22, real _32,
00144 real _03, real _13, real _23, real _33 )
00145 {
00146 mData[ 0 ] = _00;
00147 mData[ 1 ] = _01;
00148 mData[ 2 ] = _02;
00149 mData[ 3 ] = _03;
00150
00151 mData[ 4 ] = _10;
00152 mData[ 5 ] = _11;
00153 mData[ 6 ] = _12;
00154 mData[ 7 ] = _13;
00155
00156 mData[ 8 ] = _20;
00157 mData[ 9 ] = _21;
00158 mData[ 10 ] = _22;
00159 mData[ 11 ] = _23;
00160
00161 mData[ 12 ] = _30;
00162 mData[ 13 ] = _31;
00163 mData[ 14 ] = _32;
00164 mData[ 15 ] = _33;
00165 }
00166
00168 inline void set( const real * data )
00169 {
00170 memcpy( mData, data, 16 * sizeof( real ) );
00171 }
00172
00174 inline void makeZero()
00175 {
00176 memset( mData, 0, 16 * sizeof( real ) );
00177 }
00178
00180 inline void makeIdentity()
00181 {
00182 mData[ 0 ] = 1;
00183 mData[ 1 ] = 0;
00184 mData[ 2 ] = 0;
00185 mData[ 3 ] = 0;
00186
00187 mData[ 4 ] = 0;
00188 mData[ 5 ] = 1;
00189 mData[ 6 ] = 0;
00190 mData[ 7 ] = 0;
00191
00192 mData[ 8 ] = 0;
00193 mData[ 9 ] = 0;
00194 mData[ 10 ] = 1;
00195 mData[ 11 ] = 0;
00196
00197 mData[ 12 ] = 0;
00198 mData[ 13 ] = 0;
00199 mData[ 14 ] = 0;
00200 mData[ 15 ] = 1;
00201 }
00202
00204 inline void makeScale( real s )
00205 {
00206 set( s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1 );
00207 }
00208
00210 inline void makeScale( real x, real y, real z )
00211 {
00212 set( x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 );
00213 }
00214
00216
00222 inline void makeRotation( real degrees, real x, real y, real z )
00223 {
00224 Vec3r axis( x, y, z );
00225 axis.normalize();
00226 x = axis[ 0 ];
00227 y = axis[ 1 ];
00228 z = axis[ 2 ];
00229
00230
00231
00232 real radians = degToRad( degrees );
00233 real c = cos( radians );
00234 real s = sin( radians );
00235 real t = ( real ) 1.0 - c;
00236
00237 ( *this ) ( 0, 0 ) = c + x * x * t;
00238 ( *this ) ( 1, 1 ) = c + y * y * t;
00239 ( *this ) ( 2, 2 ) = c + z * z * t;
00240
00241 real tmp1 = x * y * t;
00242 real tmp2 = z * s;
00243 ( *this ) ( 1, 0 ) = tmp1 + tmp2;
00244 ( *this ) ( 0, 1 ) = tmp1 - tmp2;
00245
00246 tmp1 = x * z * t;
00247 tmp2 = y * s;
00248 ( *this ) ( 2, 0 ) = tmp1 - tmp2;
00249 ( *this ) ( 0, 2 ) = tmp1 + tmp2;
00250
00251 tmp1 = y * z * t;
00252 tmp2 = x * s;
00253 ( *this ) ( 2, 1 ) = tmp1 + tmp2;
00254 ( *this ) ( 1, 2 ) = tmp1 - tmp2;
00255
00256 ( *this ) ( 0, 3 ) = 0;
00257 ( *this ) ( 1, 3 ) = 0;
00258 ( *this ) ( 2, 3 ) = 0;
00259
00260 ( *this ) ( 3, 0 ) = 0;
00261 ( *this ) ( 3, 1 ) = 0;
00262 ( *this ) ( 3, 2 ) = 0;
00263 ( *this ) ( 3, 3 ) = 1;
00264 }
00265
00267 inline void setQuaternion( real w, real x, real y, real z )
00268 {
00269 real angle;
00270 Vec3r axis;
00271 Quaternion q( w, x, y, z );
00272 q.getAngleAxis( angle, axis );
00273
00274 setRotation( angle, axis.x, axis.y, axis.z );
00275 }
00276
00278 inline void setQuaternion( const Quaternion & q )
00279 {
00280 real angle;
00281 Vec3r axis;
00282 q.getAngleAxis( angle, axis );
00283
00284 setRotation( angle, axis.x, axis.y, axis.z );
00285 }
00286
00288
00294 inline void setRotation( real degrees, real x, real y, real z )
00295 {
00296 opal::Point3r p = getPosition();
00297 makeRotation( degrees, x, y, z );
00298 ( *this ) ( 0, 3 ) = p[ 0 ];
00299 ( *this ) ( 1, 3 ) = p[ 1 ];
00300 ( *this ) ( 2, 3 ) = p[ 2 ];
00301 }
00302
00303 inline void makeTranslation( real x, real y, real z )
00304 {
00305 set( 1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1 );
00306 }
00307
00309 inline void scale( real s )
00310 {
00311 Matrix44r m( s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1 );
00312 ( *this ) = ( *this ) * m;
00313 }
00314
00315 inline void scale( real x, real y, real z )
00316 {
00317 Matrix44r m( x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 );
00318 ( *this ) = ( *this ) * m;
00319 }
00320
00321
00322
00323
00324 inline Quaternion getQuaternion() const
00325 {
00326 Quaternion q;
00327 real trace = ( *this ) ( 0, 0 ) + ( *this ) ( 1, 1 ) + ( *this ) ( 2, 2 ) + 1.0f;
00328
00329 if ( !areEqual( trace, 0 ) )
00330 {
00331 real s = 0.5f / sqrt( trace );
00332 q[ 0 ] = 0.25f / s;
00333 q[ 1 ] = ( ( *this ) ( 2, 1 ) - ( *this ) ( 1, 2 ) ) * s;
00334 q[ 2 ] = ( ( *this ) ( 0, 2 ) - ( *this ) ( 2, 0 ) ) * s;
00335 q[ 3 ] = ( ( *this ) ( 1, 0 ) - ( *this ) ( 0, 1 ) ) * s;
00336 }
00337 else
00338 {
00339 if ( ( *this ) ( 0, 0 ) > ( *this ) ( 1, 1 ) && ( *this ) ( 0, 0 ) > ( *this ) ( 2, 2 ) )
00340 {
00341 real s = 2 * sqrt( static_cast<real>( 1 + ( *this ) ( 0, 0 ) -
00342 ( *this ) ( 1, 1 ) - ( *this ) ( 2, 2 ) ) );
00343 q[ 1 ] = 0.25f * s;
00344 q[ 2 ] = ( ( *this ) ( 0, 1 ) + ( *this ) ( 1, 0 ) ) / s;
00345 q[ 3 ] = ( ( *this ) ( 0, 2 ) + ( *this ) ( 2, 0 ) ) / s;
00346 q[ 0 ] = ( ( *this ) ( 1, 2 ) - ( *this ) ( 2, 1 ) ) / s;
00347 }
00348 else if ( ( *this ) ( 1, 1 ) > ( *this ) ( 2, 2 ) )
00349 {
00350 real s = 2 * sqrt( static_cast<real>( 1 + ( *this ) ( 1, 1 ) -
00351 ( *this ) ( 0, 0 ) - ( *this ) ( 2, 2 ) ) );
00352 q[ 1 ] = ( ( *this ) ( 0, 1 ) + ( *this ) ( 1, 0 ) ) / s;
00353 q[ 2 ] = 0.25f * s;
00354 q[ 3 ] = ( ( *this ) ( 1, 2 ) + ( *this ) ( 2, 1 ) ) / s;
00355 q[ 0 ] = ( ( *this ) ( 0, 2 ) - ( *this ) ( 2, 0 ) ) / s;
00356 }
00357 else
00358 {
00359 real s = 2 * sqrt( static_cast<real>( 1 + ( *this ) ( 2, 2 ) -
00360 ( *this ) ( 0, 0 ) - ( *this ) ( 1, 1 ) ) );
00361 q[ 1 ] = ( ( *this ) ( 0, 2 ) + ( *this ) ( 2, 0 ) ) / s;
00362 q[ 2 ] = ( ( *this ) ( 1, 2 ) + ( *this ) ( 2, 1 ) ) / s;
00363 q[ 3 ] = 0.25f * s;
00364 q[ 0 ] = ( ( *this ) ( 0, 1 ) - ( *this ) ( 1, 0 ) ) / s;
00365 }
00366 }
00367
00368 return q;
00369 }
00370
00372
00375 inline Vec3r getEulerXYZ() const
00376 {
00377 Vec3r angles;
00378
00379 angles[ 1 ] = asin( ( *this ) ( 0, 2 ) );
00380 if ( angles[ 1 ] < globals::OPAL_HALF_PI )
00381 {
00382 if ( angles[ 1 ] > -globals::OPAL_HALF_PI )
00383 {
00384 angles[ 0 ] = atan2( -( *this ) ( 1, 2 ), ( *this ) ( 2, 2 ) );
00385 angles[ 2 ] = atan2( -( *this ) ( 0, 1 ), ( *this ) ( 0, 0 ) );
00386 }
00387 else
00388 {
00389
00390 real value = atan2( ( *this ) ( 1, 0 ), ( *this ) ( 1, 1 ) );
00391 angles[ 2 ] = 0;
00392 angles[ 0 ] = angles[ 2 ] - value;
00393 }
00394 }
00395 else
00396 {
00397
00398 real value = atan2( ( *this ) ( 1, 0 ), ( *this ) ( 1, 1 ) );
00399 angles[ 2 ] = 0;
00400 angles[ 0 ] = value - angles[ 2 ];
00401 }
00402
00403
00404 angles[ 0 ] = radToDeg( angles[ 0 ] );
00405 angles[ 1 ] = radToDeg( angles[ 1 ] );
00406 angles[ 2 ] = radToDeg( angles[ 2 ] );
00407
00408
00409 angles[ 0 ] = normalizeDegrees( angles[ 0 ] );
00410 angles[ 1 ] = normalizeDegrees( angles[ 1 ] );
00411 angles[ 2 ] = normalizeDegrees( angles[ 2 ] );
00412
00413 return angles;
00414 }
00415
00417 inline void preScale( real s )
00418 {
00419 Matrix44r m( s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1 );
00420 ( *this ) = m * ( *this );
00421 }
00422
00423 inline void preScale( real x, real y, real z )
00424 {
00425 Matrix44r m( x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 );
00426 ( *this ) = m * ( *this );
00427 }
00428
00430
00438 inline void rotate( real degrees, real x, real y, real z )
00439 {
00440 Matrix44r m;
00441 m.makeRotation( degrees, x, y, z );
00442 ( *this ) = ( *this ) * m;
00443 }
00444
00446
00454 inline void preRotate( real degrees, real x, real y, real z )
00455 {
00456 Matrix44r m;
00457 m.makeRotation( degrees, x, y, z );
00458 ( *this ) = m * ( *this );
00459 }
00460
00461 inline void translate( real x, real y, real z )
00462 {
00463 Matrix44r m( 1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1 );
00464 ( *this ) = ( *this ) * m;
00465 }
00466
00467 inline void preTranslate( real x, real y, real z )
00468 {
00469 Matrix44r m( 1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1 );
00470 ( *this ) = m * ( *this );
00471 }
00472
00473 inline real * getData()
00474 {
00475 return mData;
00476 }
00477
00478 inline const real * getData() const
00479 {
00480 return mData;
00481 }
00482
00483 inline real & operator[] ( unsigned int i )
00484 {
00485 return mData[ i ];
00486 }
00487
00488 inline const real & operator[] ( unsigned int i ) const
00489 {
00490 return mData[ i ];
00491 }
00492
00493 inline real & operator() ( unsigned int row, unsigned int col )
00494 {
00495 return mData[ 4 * col + row ];
00496 }
00497
00498 inline const real & operator() ( unsigned int row, unsigned int col ) const
00499 {
00500 return mData[ 4 * col + row ];
00501 }
00502
00503 inline void operator*=( const Matrix44r &m )
00504 {
00505 ( *this ) = ( *this ) * m;
00506 }
00507
00508 inline bool operator==( const Matrix44r & m ) const
00509 {
00510 for ( int i = 0; i < 16; ++i )
00511 {
00512 if ( mData[ i ] != m[ i ] ) return false;
00513 }
00514
00515 return true;
00516 }
00517
00518 inline bool operator!=( const Matrix44r & m ) const
00519 {
00520 for ( int i = 0; i < 16; ++i )
00521 {
00522 if ( mData[ i ] != m[ i ] ) return true;
00523 }
00524
00525 return false;
00526 }
00527
00528 inline void swap( real & a, real & b )
00529 {
00530 real temp = a;
00531 a = b;
00532 b = temp;
00533 }
00534
00535 inline void transpose()
00536 {
00537 swap( mData[ 1 ], mData[ 4 ] );
00538 swap( mData[ 2 ], mData[ 8 ] );
00539 swap( mData[ 3 ], mData[ 12 ] );
00540
00541 swap( mData[ 6 ], mData[ 9 ] );
00542 swap( mData[ 7 ], mData[ 13 ] );
00543 swap( mData[ 11 ], mData[ 14 ] );
00544 }
00545
00546 inline real determinant() const
00547 {
00548 real det1 = ( *this ) ( 1, 2 ) * ( *this ) ( 2, 3 ) - ( *this ) ( 2, 2 ) *
00549 ( *this ) ( 1, 3 );
00550 real det2 = ( *this ) ( 1, 1 ) * ( *this ) ( 2, 3 ) - ( *this ) ( 2, 1 ) *
00551 ( *this ) ( 1, 3 );
00552 real det3 = ( *this ) ( 1, 1 ) * ( *this ) ( 2, 2 ) - ( *this ) ( 2, 1 ) *
00553 ( *this ) ( 1, 2 );
00554 real det4 = ( *this ) ( 1, 0 ) * ( *this ) ( 2, 3 ) - ( *this ) ( 2, 0 ) *
00555 ( *this ) ( 1, 3 );
00556 real det5 = ( *this ) ( 1, 0 ) * ( *this ) ( 2, 2 ) - ( *this ) ( 2, 0 ) *
00557 ( *this ) ( 1, 2 );
00558 real det6 = ( *this ) ( 1, 0 ) * ( *this ) ( 2, 1 ) - ( *this ) ( 2, 0 ) *
00559 ( *this ) ( 1, 1 );
00560
00561 return -( *this ) ( 3, 0 ) * ( ( *this ) ( 0, 1 ) * det1 - ( *this ) ( 0, 2 ) *
00562 det2 + ( *this ) ( 0, 3 ) * det3 ) + ( *this ) ( 3, 1 ) * ( ( *this ) ( 0, 0 ) *
00563 det1 - ( *this ) ( 0, 2 ) * det4 + ( *this ) ( 0, 3 ) * det5 ) -
00564 ( *this ) ( 3, 2 ) * ( ( *this ) ( 0, 0 ) * det2 - ( *this ) ( 0, 1 ) * det4 +
00565 ( *this ) ( 0, 3 ) * det6 ) + ( *this ) ( 3, 3 ) * ( ( *this ) ( 0, 0 ) * det3 -
00566 ( *this ) ( 0, 1 ) * det5 + ( *this ) ( 0, 2 ) * det6 );
00567 }
00568
00569 inline bool invert()
00570 {
00571 return inverse( *this, *this );
00572 }
00573
00574 inline void fastInvert()
00575 {
00576 fastInverse( *this, *this );
00577 }
00578
00580 inline Vec3r getForward() const
00581 {
00582 return ( *this ) * Vec3r( 0, 0, -1 );
00583 }
00584
00586 inline Vec3r getUp() const
00587 {
00588 return ( *this ) * Vec3r( 0, 1, 0 );
00589 }
00590
00592 inline Vec3r getRight() const
00593 {
00594 return ( *this ) * Vec3r( 1, 0, 0 );
00595 }
00596 };
00597
00598 inline bool inverse( Matrix44r & dest, const Matrix44r & src )
00599 {
00600 real det = src.determinant();
00601 if ( areEqual( det, 0 ) )
00602 {
00603 return false;
00604 }
00605 dest = ( ( real ) 1.0 / det ) * src;
00606 return true;
00607 }
00608
00609 inline void fastInverse( Matrix44r & result, const Matrix44r & source )
00610 {
00611
00612
00613 Matrix44r src = source;
00614
00615
00616
00617 for ( int x = 0; x < 3; ++x )
00618 {
00619 for ( int y = 0; y < 3; ++y )
00620 {
00621 result( x, y ) = src( y, x );
00622 }
00623 }
00624
00625 real l0 = Vec3r( result( 0, 0 ), result( 0, 1 ),
00626 result( 0, 2 ) ).lengthSquared();
00627 real l1 = Vec3r( result( 1, 0 ), result( 1, 1 ),
00628 result( 1, 2 ) ).lengthSquared();
00629 real l2 = Vec3r( result( 2, 0 ), result( 2, 1 ),
00630 result( 2, 2 ) ).lengthSquared();
00631
00632 if ( !areEqual( l0, 0 ) )
00633 {
00634 l0 = 1.0f / l0;
00635 }
00636
00637 if ( !areEqual( l1, 0 ) )
00638 {
00639 l1 = 1.0f / l1;
00640 }
00641
00642 if ( !areEqual( l2, 0 ) )
00643 {
00644 l2 = 1.0f / l2;
00645 }
00646
00647
00648
00649
00650 result( 0, 0 ) *= l0;
00651 result( 0, 1 ) *= l0;
00652 result( 0, 2 ) *= l0;
00653 result( 1, 0 ) *= l1;
00654 result( 1, 1 ) *= l1;
00655 result( 1, 2 ) *= l1;
00656 result( 2, 0 ) *= l2;
00657 result( 2, 1 ) *= l2;
00658 result( 2, 2 ) *= l2;
00659
00660
00661
00662 result( 3, 0 ) = result( 3, 1 ) = result( 3, 2 ) = 0;
00663
00664
00665 const real& tx = src( 0, 3 );
00666 const real& ty = src( 1, 3 );
00667 const real& tz = src( 2, 3 );
00668
00669
00670
00671 const real tw = !areEqual( src( 3, 3 ), 0 )
00672 ? 1.0f / src( 3, 3 ) : 0.0f;
00673
00674
00675 result( 0, 3 ) = -( result( 0, 0 ) * tx + result( 0, 1 ) * ty +
00676 result( 0, 2 ) * tz ) * tw;
00677 result( 1, 3 ) = -( result( 1, 0 ) * tx + result( 1, 1 ) * ty +
00678 result( 1, 2 ) * tz ) * tw;
00679 result( 2, 3 ) = -( result( 2, 0 ) * tx + result( 2, 1 ) * ty +
00680 result( 2, 2 ) * tz ) * tw;
00681 result( 3, 3 ) = tw;
00682 }
00683
00684 inline Matrix44r operator*( real scalar, Matrix44r m )
00685 {
00686 for ( unsigned int i = 0; i < 16; ++i )
00687 {
00688 m.mData[ i ] *= scalar;
00689 }
00690
00691 return m;
00692 }
00693
00694 inline Matrix44r operator*( const Matrix44r & lhs, const Matrix44r & rhs )
00695 {
00696 Matrix44r res;
00697 res.makeZero();
00698
00699
00700
00701
00702 for ( unsigned int i = 0; i < 4; ++i )
00703 for ( unsigned int j = 0; j < 4; ++j )
00704 for ( unsigned int k = 0; k < 4; ++k )
00705 res( i, j ) += lhs( i, k ) * rhs( k, j );
00706 return res;
00707 }
00708
00709 inline Vec3r operator*( const Matrix44r & m, const Vec3r &v )
00710 {
00711 return Vec3r( m( 0, 0 ) * v[ 0 ] + m( 0, 1 ) * v[ 1 ] + m( 0, 2 ) * v[ 2 ],
00712 m( 1, 0 ) * v[ 0 ] + m( 1, 1 ) * v[ 1 ] + m( 1, 2 ) * v[ 2 ],
00713 m( 2, 0 ) * v[ 0 ] + m( 2, 1 ) * v[ 1 ] + m( 2, 2 ) * v[ 2 ] );
00714 }
00715
00716 inline Point3r operator*( const Matrix44r & m, const Point3r &p )
00717 {
00718 return Point3r(
00719 m( 0, 0 ) * p[ 0 ] + m( 0, 1 ) * p[ 1 ] + m( 0, 2 ) * p[ 2 ] + m( 0, 3 ),
00720 m( 1, 0 ) * p[ 0 ] + m( 1, 1 ) * p[ 1 ] + m( 1, 2 ) * p[ 2 ] + m( 1, 3 ),
00721 m( 2, 0 ) * p[ 0 ] + m( 2, 1 ) * p[ 1 ] + m( 2, 2 ) * p[ 2 ] + m( 2, 3 ) );
00722 }
00723
00724 inline Matrix44r operator+( const Matrix44r & lhs, const Matrix44r & rhs )
00725 {
00726 Matrix44r res;
00727 for ( unsigned int i = 0; i < 16; ++i )
00728 {
00729 res[ i ] = lhs[ i ] + rhs[ i ];
00730 }
00731 return res;
00732 }
00733
00734 inline Matrix44r operator-( const Matrix44r & lhs, const Matrix44r & rhs )
00735 {
00736 Matrix44r res;
00737 for ( unsigned int i = 0; i < 16; ++i )
00738 {
00739 res[ i ] = lhs[ i ] - rhs[ i ];
00740 }
00741 return res;
00742 }
00743
00744 inline Rayr operator*( const Matrix44r & m, const Rayr & r )
00745 {
00746 Rayr ray( m * r.getOrigin(), m * r.getDir() );
00747 return ray;
00748 }
00749
00750 inline std::ostream& operator<<( std::ostream& o, const Matrix44r& m )
00751 {
00752 return o
00753 << "[" << m[ 0 ] << " " << m[ 1 ] << " " << m[ 2 ] << " " << m[ 3 ]
00754 << "]" << std::endl
00755 << "[" << m[ 4 ] << " " << m[ 5 ] << " " << m[ 6 ] << " " << m[ 7 ]
00756 << "]" << std::endl
00757 << "[" << m[ 8 ] << " " << m[ 9 ] << " " << m[ 10 ] << " " << m[ 11 ]
00758 << "]" << std::endl
00759 << "[" << m[ 12 ] << " " << m[ 13 ] << " " << m[ 14 ] << " " << m[ 15 ]
00760 << "]";
00761 }
00762 }
00763
00764 #endif