00001
00002 #include "Matrix.h"
00003 #include "Error.h"
00004 #include "RenderTools.h"
00006 #ifndef RT_AS3
00007 # ifndef RT_GLES1
00008 # include "Program.h"
00009 # endif
00010 #endif
00011
00012 namespace RenderTools {
00013
00015
00016 float smallest( float a, float b ){
00017 return( a < b ? a : b );
00018 }
00019
00020 float largest( float a, float b ){
00021 return( a < b ? a : b );
00022 }
00023
00024 double smallest( double a, double b ){
00025 return( a < b ? a : b );
00026 }
00027
00028 double largest( double a, double b ){
00029 return( a > b ? a : b );
00030 }
00031
00032 float smallest( float a, double b ){
00033 return( a < ( float )b ? a : ( float )b );
00034 }
00035
00036 float largest( float a, double b ){
00037 return( a > ( float )b ? a : ( float )b );
00038 }
00039
00040 float smallest( double a, float b ){
00041 return( ( float )a < b ? ( float )a : b );
00042 }
00043
00044 float largest( double a, float b ){
00045 return( ( float )a > b ? ( float )a : b );
00046 }
00047
00048 float clamp( float v, float min, float max ){
00049 if( v < min ){
00050 v = min;
00051 }
00052 else if( v > max ){
00053 v = max;
00054 }
00055 return( v );
00056 }
00057
00058 float clampMin( float x, float min ){
00059 return( ( x < min ) ? min : x );
00060 }
00061
00062 float clampMax( float x, float max ){
00063 return( ( x > max ) ? max : x );
00064 }
00065
00066 float sgn( float v ){
00067 return( v < 0.0f ? -1.0f : 1.0f );
00068 }
00069
00070 float toRadians( float degrees ){
00071 return( ( degrees / 180.0f ) * M_PI );
00072 }
00073
00074 float toDegrees( float radians ){
00075 return( 180.0f * ( radians / M_PI ) );
00076 }
00077
00078 float distance( const Vec2 & v1, const Vec2 & v2 ){
00079 return( length( v2 - v1 ) );
00080 }
00081
00082 float distance( const Vec3 & v1, const Vec3 & v2 ){
00083 return( length( v2 - v1 ) );
00084 }
00085
00086 float distance( const Vec4 & v1, const Vec4 & v2 ){
00087 return( length( v2 - v1 ) );
00088 }
00089
00090 float distance2( const Vec2 & v1, const Vec2 & v2 ){
00091 return( length2( v2 - v1 ) );
00092 }
00093
00094 float distance2( const Vec3 & v1, const Vec3 & v2 ){
00095 return( length2( v2 - v1 ) );
00096 }
00097
00098 float distance2( const Vec4 & v1, const Vec4 & v2 ){
00099 return( length2( v2 - v1 ) );
00100 }
00101
00102 float length( const Vec2 & v ){
00103 return( v.len() );
00104 }
00105
00106 float length( const Vec3 & v ){
00107 return( v.len() );
00108 }
00109
00110 float length( const Vec4 & v ){
00111 return( v.len() );
00112 }
00113
00114 float length2( const Vec2 & v ){
00115 return( v.hyp() );
00116 }
00117
00118 float length2( const Vec3 & v ){
00119 return( v.hyp() );
00120 }
00121
00122 float length2( const Vec4 & v ){
00123 return( v.hyp() );
00124 }
00125
00126 Vec2 normalize( const Vec2 & v ){
00127 return( v.normalized() );
00128 }
00129
00130 Vec3 normalize( const Vec3 & v ){
00131 return( v.normalized() );
00132 }
00133
00134 Vec4 normalize( const Vec4 & v ){
00135 return( v.normalized() );
00136 }
00137
00138 float dot( const Vec2 & v1, const Vec2 & v2 ){
00139 return( v1.dot( v2 ) );
00140 }
00141
00142 float dot( const Vec3 & v1, const Vec3 & v2 ){
00143 return( v1.dot( v2 ) );
00144 }
00145
00146 float dot( const Vec4 & v1, const Vec4 & v2 ){
00147 return( v1.dot( v2 ) );
00148 }
00149
00150 float cross( const Vec2 & v1, const Vec2 & v2 ){
00151 return( dot( v1.cross(), v2 ) );
00152 }
00153
00154 Vec3 cross( const Vec3 & v1, const Vec3 & v2 ){
00155 return( v1.cross( v2 ) );
00156 }
00157
00158 float mix( float f1, float f2, float f ){
00159 return( f2 * f + f1 * ( 1.0f - f ) );
00160 }
00161
00162 Vec2 mix( const Vec2 & v1, const Vec2 & v2, float f ){
00163 return( v2 * f + v1 * ( 1.0f - f ) );
00164 }
00165
00166 Vec3 mix( const Vec3 & v1, const Vec3 & v2, float f ){
00167 return( v2 * f + v1 * ( 1.0f - f ) );
00168 }
00169
00170 Vec4 mix( const Vec4 & v1, const Vec4 & v2, float f ){
00171 return( v2 * f + v1 * ( 1.0f - f ) );
00172 }
00173
00174 Mat2 mix( const Mat2 & m1, const Mat2 & m2, float f ){
00175 Mat2 m;
00176 int i = 0;
00177 for( i = 0; i < 4; i++ ){
00178 m[i] = f * m2[i] + ( 1.0f - f ) * m1[i];
00179 }
00180 return( m );
00181 }
00182
00183 Mat3 mix( const Mat3 & m1, const Mat3 & m2, float f ){
00184 Mat3 m;
00185 int i = 0;
00186 for( i = 0; i < 9; i++ ){
00187 m[i] = f * m2[i] + ( 1.0f - f ) * m1[i];
00188 }
00189 return( m );
00190 }
00191
00192 Mat4 mix( const Mat4 & m1, const Mat4 & m2, float f ){
00193 Mat4 m;
00194 int i = 0;
00195 for( i = 0; i < 16; i++ ){
00196 m[i] = f * m2[i] + ( 1.0f - f ) * m1[i];
00197 }
00198 return( m );
00199 }
00200
00201 Vec2 operator * ( float s, const Vec2 & v ){
00202 return( v * s );
00203 }
00204
00205 Vec3 operator * ( float s, const Vec3 & v ){
00206 return( v * s );
00207 }
00208
00209 Vec4 operator * ( float s, const Vec4 & v ){
00210 return( v * s );
00211 }
00212
00213 istream & operator >> ( istream & s, Vec2 & v ){
00214 s >> v[0] >> v[1];
00215 return s;
00216 }
00217
00218 istream & operator >> ( istream & s, Vec3 & v ){
00219 s >> v[0] >> v[1] >> v[2];
00220 return s;
00221 }
00222
00223 istream & operator >> ( istream & s, Vec4 & v ){
00224 s >> v[0] >> v[1] >> v[2] >> v[3];
00225 return s;
00226 }
00227
00228 istream & operator >> ( istream & s, Quat & v ){
00229 s >> v[0] >> v[1] >> v[2] >> v[3];
00230 return s;
00231 }
00232
00233 istream & operator >> ( istream & s, Mat2 & v ){
00234 s >> v[0] >> v[1] >> v[2] >> v[3] >> v[4];
00235 return s;
00236 }
00237
00238 istream & operator >> ( istream & s, Mat3 & v ){
00239 s >> v[0] >> v[1] >> v[2];
00240 s >> v[3] >> v[4] >> v[5];
00241 s >> v[6] >> v[7] >> v[8];
00242 return s;
00243 }
00244
00245 istream & operator >> ( istream & s, Mat4 & v ){
00246 s >> v[0] >> v[1] >> v[2] >> v[3];
00247 s >> v[4] >> v[5] >> v[6] >> v[7];
00248 s >> v[8] >> v[9] >> v[10] >> v[11];
00249 s >> v[12] >> v[13] >> v[14] >> v[15];
00250 return s;
00251 }
00252
00253 ostream & operator << ( ostream & s, const Vec2 & v ) {
00254 static char txt[256];
00255 sprintf( txt, "%g %g", v[0], v[1] );
00256 s << txt;
00257 return s;
00258 }
00259
00260 ostream & operator << ( ostream & s, const Vec3 & v ) {
00261 static char txt[256];
00262 sprintf( txt, "%g %g %g", v[0], v[1], v[2] );
00263 s << txt;
00264 return s;
00265 }
00266
00267 ostream & operator << ( ostream & s, const Vec4 & v ) {
00268 static char txt[256];
00269 sprintf( txt, "%g %g %g %g", v[0], v[1], v[2], v[3] );
00270 s << txt;
00271 return s;
00272 }
00273
00274 ostream & operator << ( ostream & s, const Quat & v ) {
00275 static char txt[256];
00276 sprintf( txt, "%g %g %g %g", v[0], v[1], v[2], v[3] );
00277 s << txt;
00278 return s;
00279 }
00280
00281 ostream & operator << ( ostream & s, const Mat2 & v ) {
00282 static char txt[256];
00283 sprintf( txt, "%g %g %g %g", \
00284 v[0], v[1], \
00285 v[2], v[3] );
00286 s << txt;
00287 return s;
00288 }
00289
00290 ostream & operator << ( ostream & s, const Mat3 & v ) {
00291 static char txt[256];
00292 sprintf( txt, "%g %g %g %g %g %g %g %g %g", \
00293 v[0], v[1], v[2], \
00294 v[3], v[4], v[5], \
00295 v[6], v[7], v[8] );
00296 s << txt;
00297 return s;
00298 }
00299
00300 ostream & operator << ( ostream & s, const Mat4 & v ) {
00301 static char txt[256];
00302 sprintf( txt, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g", \
00303 v[0], v[1], v[2], v[3], \
00304 v[4], v[5], v[6], v[7], \
00305 v[8], v[9], v[10], v[11], \
00306 v[12], v[13], v[14], v[15] );
00307 s << txt;
00308 return s;
00309 }
00310
00312
00313 Vec2::Vec2( float v0, float v1 ){
00314 m_v[0] = v0;
00315 m_v[1] = v1;
00316 }
00317
00318 Vec2::Vec2( float xy ){
00319 m_v[0] = xy;
00320 m_v[1] = xy;
00321 }
00322
00323 Vec2::Vec2( const float * v ){
00324 memcpy( m_v, v, 2 * sizeof( float ) );
00325 }
00326
00327 bool Vec2::operator < ( const float v ) const {
00328 return( hyp() < v * v);
00329 }
00330
00331 bool Vec2::operator < ( const Vec2 & v ) const {
00332 return( hyp() < v.hyp() );
00333 }
00334
00335 bool Vec2::operator < ( const Vec3 & v ) const {
00336 return( hyp() < v.hyp() );
00337 }
00338
00339 bool Vec2::operator < ( const Vec4 & v ) const {
00340 return( hyp() < v.hyp() );
00341 }
00342
00343 Vec2 Vec2::operator - () const {
00344 return( Vec2( -m_v[0], -m_v[1] ) );
00345 }
00346
00347 Vec2 Vec2::operator + ( const Vec2 & b ) const {
00348 Vec2 a;
00349 a[0] = m_v[0] + b[0];
00350 a[1] = m_v[1] + b[1];
00351 return( a );
00352 }
00353
00354 Vec2 Vec2::operator - ( const Vec2 & b ) const {
00355 Vec2 a;
00356 a[0] = m_v[0] - b[0];
00357 a[1] = m_v[1] - b[1];
00358 return( a );
00359 }
00360
00361 Vec2 Vec2::operator * ( float b ) const {
00362 Vec2 a;
00363 a[0] = m_v[0] * b;
00364 a[1] = m_v[1] * b;
00365 return( a );
00366 }
00367
00368 Vec2 Vec2::operator * ( const Vec2 & b ) const {
00369 Vec2 a;
00370 a[0] = m_v[0] * b[0];
00371 a[1] = m_v[1] * b[1];
00372 return( a );
00373 }
00374
00375 Vec2 Vec2::operator / ( const Vec2 & b ) const {
00376 Vec2 a;
00377 a[0] = m_v[0] / b[0];
00378 a[1] = m_v[1] / b[1];
00379 return( a );
00380 }
00381
00382 Vec2 Vec2::operator / ( float b ) const {
00383 Vec2 a;
00384 a[0] = m_v[0] / b;
00385 a[1] = m_v[1] / b;
00386 return( a );
00387 }
00388
00389 Vec2 & Vec2::operator += ( const Vec2 & b ){
00390 return( * this = * this + b );
00391 }
00392
00393 Vec2 & Vec2::operator -= ( const Vec2 & b ){
00394 return( * this = * this - b );
00395 }
00396
00397 Vec2 & Vec2::operator *= ( float b ){
00398 return( * this = * this * b );
00399 }
00400
00401 Vec2 & Vec2::operator /= ( float b ){
00402 return( * this = * this / b );
00403 }
00404
00405 Vec2 & Vec2::operator /= ( const Vec2 & b ){
00406 return( * this = * this / b );
00407 }
00408
00409 float & Vec2::operator [] ( int index ) {
00410 return( m_v[ index ] );
00411 }
00412
00413 const float & Vec2::operator [] ( const int index ) const {
00414 return( m_v[ index ] );
00415 }
00416
00417 const float * Vec2::operator * ( void ) const {
00418 return( m_v );
00419 }
00420
00421 bool Vec2::operator == ( const Vec2 & b ) const {
00422 return( equals( b ) );
00423 }
00424
00425 float Vec2::hyp( void ) const {
00426 return( m_v[0] * m_v[0] + m_v[1] * m_v[1] );
00427 }
00428
00429 float Vec2::len( void ) const {
00430 float h = hyp() + 0.000001f;
00431 return( sqrt( h ) );
00432 }
00433
00434 void Vec2::normalize( void ){
00435 float l = len();
00436 m_v[0] /= l;
00437 m_v[1] /= l;
00438 }
00439
00440 Vec2 Vec2::normalized( void ) const {
00441 float l = len();
00442 return( Vec2( m_v[0] / l, m_v[1] / l ) );
00443 }
00444
00445 float Vec2::dot( const Vec2 & b ) const {
00446 return( m_v[0] * b[0] + m_v[1] * b[1] );
00447 }
00448
00449 Vec2 Vec2::abs( void ) const {
00450 return( Vec2( fabs( m_v[0] ), fabs( m_v[1] ) ) );
00451 }
00452
00453 Vec2 Vec2::sgn( void ) const {
00454 return( Vec2( m_v[0] < 0.0 ? -1.0 : 1.0, m_v[1] < 0.0 ? -1.0 : 1.0 ) );
00455 }
00456
00457 Vec2 Vec2::clamp( float min, float max ) const {
00458 Vec2 v( * this );
00459 for( int i = 0; i < 2; i++ ){
00460 if( v[i] < min ){
00461 v[i] = min;
00462 }
00463 else if( v[i] > max ){
00464 v[i] = max;
00465 }
00466 }
00467 return( v );
00468 }
00469
00470 Vec2 Vec2::cross( void ) const {
00471 Vec2 a;
00472 a[0] = -m_v[1];
00473 a[1] = m_v[0];
00474 return( a );
00475 }
00476
00477 float Vec2::cross( const Vec2 & v ) const {
00478 return( v.dot( cross() ) );
00479 }
00480
00481 Vec2 Vec2::fromAngle( float rad ) {
00482 return( Vec2( cos( rad ), sin( rad ) ) );
00483 }
00484
00485 Vec3 Vec3::fromAxisAngle( const Vec3 & cp, const Vec3 & axis, float angle ) {
00486 Vec3 p( cp );
00487 Vec3 v( 0.0, 0.0, 0.0 );
00488 float ca, sa;
00489
00490 ca = cos( angle );
00491 sa = sin( angle );
00492
00493 v[0] += ( ca + ( 1.0f - ca ) * axis[0] * axis[0] ) * p[0];
00494 v[0] += ( ( 1.0f - ca ) * axis[0] * axis[1] - axis[2] * sa ) * p[1];
00495 v[0] += ( ( 1.0f - ca ) * axis[0] * axis[2] + axis[1] * sa ) * p[2];
00496
00497 v[1] += ( ( 1.0f - ca ) * axis[0] * axis[1] + axis[2] * sa ) * p[0];
00498 v[1] += ( ca + ( 1.0f - ca ) * axis[1] * axis[1] ) * p[1];
00499 v[1] += ( ( 1.0f - ca ) * axis[1] * axis[2] - axis[0] * sa ) * p[2];
00500
00501 v[2] += ( ( 1.0f - ca ) * axis[0] * axis[2] - axis[1] * sa ) * p[0];
00502 v[2] += ( ( 1.0f - ca ) * axis[1] * axis[2] + axis[0] * sa ) * p[1];
00503 v[2] += ( ca + ( 1.0f - ca ) * axis[2] * axis[2] ) * p[2];
00504
00505 return( v );
00506 }
00507
00508 float Vec2::toAngle( void ) const {
00509 float a;
00510 float vx = RenderTools::sgn( m_v[0] ) * fmod( fabs( m_v[0] ), 1.0f );
00511 a = acos( vx );
00512 if( m_v[1] < 0.0f ){
00513 a = 2.0f * M_PI - a;
00514 }
00515 return( a );
00516 }
00517
00518 bool Vec2::equals( const Vec2 & compare, float epsilon ) const {
00519 return( equals( *compare, epsilon ) );
00520 }
00521
00522 bool Vec2::equals( const float * compare, float epsilon ) const {
00523 for( int i = 0; i < 2; i++ ){
00524 if( fabs( compare[i] - m_v[i] ) > epsilon ){
00525 return( false );
00526 }
00527 }
00528 return( true );
00529 }
00530
00532
00533 Mat2::Mat2( float v00, float v01, float v10, float v11 ){
00534 m_v[0] = v00;
00535 m_v[1] = v01;
00536 m_v[2] = v10;
00537 m_v[3] = v11;
00538 }
00539
00540 Mat2::Mat2( const float * v ){
00541 memcpy( m_v, v, 4 * sizeof( float ) );
00542 }
00543
00544 Vec2 Mat2::operator * ( const Vec2 & b ) const {
00545 Vec2 a;
00546 a[0] = m_v[0] * b[0] + m_v[2] * b[1];
00547 a[1] = m_v[1] * b[0] + m_v[3] * b[1];
00548 return( a );
00549 }
00550
00551 Mat2 Mat2::operator * ( const Mat2 & b ) const {
00552 Mat2 a;
00553 a[0] = m_v[0] * b[0] + m_v[2] * b[1];
00554 a[2] = m_v[0] * b[2] + m_v[2] * b[3];
00555 a[1] = m_v[1] * b[0] + m_v[3] * b[1];
00556 a[3] = m_v[1] * b[2] + m_v[3] * b[3];
00557 return( a );
00558 }
00559
00560 Mat2 & Mat2::operator *= ( const Mat2 & b ){
00561 return( * this = * this * b );
00562 }
00563
00564 Mat2 & Mat2::operator /= ( float b ){
00565 return( * this = * this / b );
00566 }
00567
00568 Mat2 Mat2::operator * ( float b ) const {
00569 Mat2 a;
00570 a[0] = m_v[0] * b;
00571 a[1] = m_v[1] * b;
00572 a[2] = m_v[2] * b;
00573 a[3] = m_v[3] * b;
00574 return( a );
00575 }
00576
00577 Mat2 Mat2::operator / ( float b ) const {
00578 Mat2 a;
00579 a[0] = m_v[0] / b;
00580 a[1] = m_v[1] / b;
00581 a[2] = m_v[2] / b;
00582 a[3] = m_v[3] / b;
00583 return( a );
00584 }
00585
00586 float & Mat2::operator [] ( int index ) {
00587 return( m_v[ index ] );
00588 }
00589
00590 const float & Mat2::operator [] ( const int index ) const {
00591 return( m_v[ index ] );
00592 }
00593
00594 const float * Mat2::operator * ( void ) const {
00595 return( m_v );
00596 }
00597
00598 const float & Mat2::getElement( int column, int row ) const {
00599 return( m_v[ column * 2 + row ] );
00600 }
00601
00602 float & Mat2::getElement( int column, int row ){
00603 return( m_v[ column * 2 + row ] );
00604 }
00605
00606 void Mat2::setElement( int col, int row, float v ){
00607 m_v[ col * 2 + row ] = v;
00608 }
00609
00610 bool Mat2::operator == ( const Mat2 & b ) const{
00611 return( equals( b ) );
00612 }
00613
00614 Vec2 Mat2::getRow( int index ) const{
00615 return( Vec2( m_v[ index ], m_v[ 2 + index ] ) );
00616 }
00617
00618 Vec2 Mat2::getCol( int index ) const{
00619 return( Vec2( m_v[ index * 2 + 0 ], m_v[ index * 2 + 1 ] ) );
00620 }
00621
00622 void Mat2::setRow( int index, const Vec2 & row ){
00623 m_v[ index ] = row[0];
00624 m_v[ 2 + index ] = row[1];
00625 }
00626
00627 void Mat2::setCol( int index, const Vec2 & col ){
00628 m_v[ index * 2 + 0 ] = col[0];
00629 m_v[ index * 2 + 1 ] = col[1];
00630 }
00631
00632 bool Mat2::equals( const Mat2 & compare, float epsilon ) const {
00633 return( equals( *compare, epsilon ) );
00634 }
00635
00636 bool Mat2::equals( const float * compare, float epsilon ) const {
00637 for( int i = 0; i < 4; i++ ){
00638 if( fabs( compare[i] - m_v[i] ) > epsilon ){
00639 return( false );
00640 }
00641 }
00642 return( true );
00643 }
00644
00645 Mat2 Mat2::transpose() const {
00646 return( Mat2( m_v[0], m_v[2], m_v[1], m_v[3] ) );
00647 }
00648
00649 float Mat2::determinant() const {
00650 return( m_v[0] * m_v[3] - m_v[1] * m_v[2] );
00651 }
00652
00653 Mat2 Mat2::inverse() const {
00654 float d = determinant();
00655
00656 if( d == 0.0f ){
00657 Error::warning( Error::INVALID_VALUE, __FILE__, __LINE__, "matrix is singular" );
00658 return( Mat2::fromIdentity() );
00659 }
00660
00661 Mat2 r;
00662 r[0] = m_v[3]; r[2] = -m_v[2];
00663 r[1] = -m_v[1]; r[3] = m_v[0];
00664 r /= d;
00665
00666 return( r );
00667 }
00668
00669 void Mat2::setIdentity( void ){
00670 m_v[0] = 1.0f;
00671 m_v[1] = 0.0f;
00672 m_v[2] = 0.0f;
00673 m_v[3] = 1.0f;
00674 }
00675
00676 Mat2 Mat2::fromIdentity( void ){
00677 Mat2 m;
00678 m.setIdentity();
00679 return( m );
00680 }
00681
00683
00684 Vec3::Vec3( float x, float y, float z ){
00685 m_v[0] = x;
00686 m_v[1] = y;
00687 m_v[2] = z;
00688 }
00689
00690 Vec3::Vec3( float xyz ){
00691 m_v[0] = xyz;
00692 m_v[1] = xyz;
00693 m_v[2] = xyz;
00694 }
00695
00696 Vec3::Vec3( const float * v ){
00697 memcpy( m_v, v, 3 * sizeof( float ) );
00698 }
00699
00700 Vec3::Vec3( const Vec2 & xy, float z ){
00701 m_v[0] = xy[0];
00702 m_v[1] = xy[1];
00703 m_v[2] = z;
00704 }
00705
00706
00707 bool Vec3::operator < ( const float v ) const {
00708 return( hyp() < v * v );
00709 }
00710
00711 bool Vec3::operator < ( const Vec2 & v ) const {
00712 return( hyp() < v.hyp() );
00713 }
00714
00715 bool Vec3::operator < ( const Vec3 & v ) const {
00716 return( hyp() < v.hyp() );
00717 }
00718
00719 bool Vec3::operator < ( const Vec4 & v ) const {
00720 return( hyp() < v.hyp() );
00721 }
00722
00723 Vec3 Vec3::operator - () const {
00724 return( Vec3( -m_v[0], -m_v[1], -m_v[2] ) );
00725 }
00726
00727 Vec3 Vec3::operator + ( const Vec3 & b ) const {
00728 Vec3 a;
00729 a[0] = m_v[0] + b[0];
00730 a[1] = m_v[1] + b[1];
00731 a[2] = m_v[2] + b[2];
00732 return( a );
00733 }
00734
00735 Vec3 Vec3::operator - ( const Vec3 & b ) const {
00736 Vec3 a;
00737 a[0] = m_v[0] - b[0];
00738 a[1] = m_v[1] - b[1];
00739 a[2] = m_v[2] - b[2];
00740 return( a );
00741 }
00742
00743 Vec3 Vec3::operator * ( float b ) const {
00744 Vec3 a;
00745 a[0] = m_v[0] * b;
00746 a[1] = m_v[1] * b;
00747 a[2] = m_v[2] * b;
00748 return( a );
00749 }
00750
00751 Vec3 Vec3::operator * ( const Vec3 & b ) const {
00752 Vec3 a;
00753 a[0] = m_v[0] * b[0];
00754 a[1] = m_v[1] * b[1];
00755 a[2] = m_v[2] * b[2];
00756 return( a );
00757 }
00758
00759 Vec3 Vec3::operator / ( const Vec3 & b ) const {
00760 Vec3 a;
00761 a[0] = m_v[0] / b[0];
00762 a[1] = m_v[1] / b[1];
00763 a[2] = m_v[2] / b[2];
00764 return( a );
00765 }
00766
00767 Vec3 Vec3::operator / ( float b ) const {
00768 if( b == 0.0f ){
00769 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
00770 return( Vec3() );
00771 }
00772 Vec3 a;
00773 a[0] = m_v[0] / b;
00774 a[1] = m_v[1] / b;
00775 a[2] = m_v[2] / b;
00776 return( a );
00777 }
00778
00779 Vec3 & Vec3::operator += ( const Vec3 & b ){
00780 return( * this = * this + b );
00781 }
00782
00783 Vec3 & Vec3::operator -= ( const Vec3 & b ){
00784 return( *( ( Vec3 * )this ) = * this - b );
00785 }
00786
00787 Vec3 & Vec3::operator *= ( float b ){
00788 return( *( ( Vec3 * )this ) = * this * b );
00789 }
00790
00791 Vec3 & Vec3::operator /= ( float b ){
00792 return( *( ( Vec3 * )this ) = * this / b );
00793 }
00794
00795 Vec3 & Vec3::operator /= ( const Vec3 & b ){
00796 return( *( ( Vec3 * )this ) = * this / b );
00797 }
00798
00799 float & Vec3::operator [] ( int index ) {
00800 return( m_v[ index ] );
00801 }
00802
00803 const float & Vec3::operator [] ( const int index ) const {
00804 return( m_v[ index ] );
00805 }
00806
00807 const float * Vec3::operator * ( void ) const {
00808 return( m_v );
00809 }
00810
00811 bool Vec3::operator == ( const Vec3 & b ) const {
00812 return( equals( b ) );
00813 }
00814
00815 float Vec3::hyp( void ) const {
00816 return( m_v[0] * m_v[0] + m_v[1] * m_v[1] + m_v[2] * m_v[2] );
00817 }
00818
00819 float Vec3::len( void ) const {
00820 return( sqrt( hyp() ) );
00821 }
00822
00823 void Vec3::normalize( void ){
00824 float l = len();
00825 if( l == 0.0f ){
00826 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
00827 return;
00828 }
00829 m_v[0] /= l;
00830 m_v[1] /= l;
00831 m_v[2] /= l;
00832 }
00833
00834 Vec3 Vec3::normalized( void ) const {
00835 float l = len();
00836 if( l == 0.0f ){
00837 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
00838 return( Vec3() );
00839 }
00840 return( Vec3( m_v[0] / l, m_v[1] / l, m_v[2] / l ) );
00841 }
00842
00843 Vec2 Vec3::toPolar( void ) const {
00844 Vec2 p;
00845 if( m_v[0] == 0.0f ){
00846 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
00847 return( Vec2() );
00848 }
00849 p[0] = atan2( m_v[1], m_v[0] );
00850 p[1] = acos( RenderTools::clamp( m_v[2], -1.0f, 1.0f ) );
00851 return( p );
00852 }
00853
00854 float Vec3::getAngle( const Vec3 & x, const Vec3 & y ) const {
00855 float a = acos( RenderTools::clamp( RenderTools::dot( x, *this ), -1.0f, 1.0f ) );
00856 if( RenderTools::dot( y, * this ) < 0.0f ) a = 2.0f * M_PI - a;
00857 return( a );
00858 }
00859
00860 float Vec3::dot( const Vec3 & b ) const {
00861 return( m_v[0] * b[0] + m_v[1] * b[1] + m_v[2] * b[2] );
00862 }
00863
00864 Vec3 Vec3::abs( void ) const {
00865 return( Vec3( fabs( m_v[0] ), fabs( m_v[1] ), fabs( m_v[2] ) ) );
00866 }
00867
00868 Vec3 Vec3::sgn( void ) const {
00869 return( Vec3( m_v[0] < 0.0f ? -1.0f : 1.0f, m_v[1] < 0.0f ? -1.0f : 1.0f, m_v[2] < 0.0f ? -1.0f : 1.0f ) );
00870 }
00871
00872 Vec3 Vec3::clamp( float min, float max ) const {
00873 Vec3 v( *this );
00874 for( int i = 0; i < 3; i++ ){
00875 if( v[i] < min ){
00876 v[i] = min;
00877 }
00878 else if( v[i] > max ){
00879 v[i] = max;
00880 }
00881 }
00882 return( v );
00883 }
00884
00885 Vec3 Vec3::cross( const Vec3 & b ) const {
00886 Vec3 a;
00887 a[0] = m_v[1] * b[2] - m_v[2] * b[1];
00888 a[1] = m_v[2] * b[0] - m_v[0] * b[2];
00889 a[2] = m_v[0] * b[1] - m_v[1] * b[0];
00890 return( a );
00891 }
00892
00893 bool Vec3::equals( const Vec3 & compare, float epsilon ) const {
00894 return( equals( *compare, epsilon ) );
00895 }
00896
00897 bool Vec3::equals( const float * compare, float epsilon ) const {
00898 for( int i = 0; i < 3; i++ ){
00899 if( fabs( compare[i] - m_v[i] ) > epsilon ){
00900 return( false );
00901 }
00902 }
00903 return( true );
00904 }
00905
00906 Vec2 Vec3::xy() const {
00907 return( Vec2( m_v[0], m_v[1] ) );
00908 }
00909
00910 Vec3 Vec3::fromPolar( const Vec2 & polar ){
00911 float sx = sin( polar[0] );
00912 float cx = cos( polar[0] );
00913 float sy = sin( polar[1] );
00914 float cy = cos( polar[1] );
00915 Vec3 p;
00916 p[0] = sy * cx;
00917 p[1] = sy * sx;
00918 p[2] = cy;
00919 return( p );
00920 }
00921
00923
00924 Mat3::Mat3( float v00, float v01, float v02,
00925 float v10, float v11, float v12,
00926 float v20, float v21, float v22 ){
00927 m_v[0] = v00;
00928 m_v[1] = v01;
00929 m_v[2] = v02;
00930 m_v[3] = v10;
00931 m_v[4] = v11;
00932 m_v[5] = v12;
00933 m_v[6] = v20;
00934 m_v[7] = v21;
00935 m_v[8] = v22;
00936 }
00937
00938
00939 Mat3::Mat3( const float * v ){
00940 memcpy( m_v, v, 9 * sizeof( float ) );
00941 }
00942
00943 Mat3::Mat3( const Vec3 & c0, const Vec3 & c1, const Vec3 & c2 ){
00944 m_v[0] = c0[0];
00945 m_v[1] = c0[1];
00946 m_v[2] = c0[2];
00947 m_v[3] = c1[0];
00948 m_v[4] = c1[1];
00949 m_v[5] = c1[2];
00950 m_v[6] = c2[0];
00951 m_v[7] = c2[1];
00952 m_v[8] = c2[2];
00953 }
00954
00955 Vec3 Mat3::operator * ( const Vec3 & b ) const {
00956 Vec3 a;
00957 a[0] = m_v[0] * b[0] + m_v[3] * b[1] + m_v[6] * b[2];
00958 a[1] = m_v[1] * b[0] + m_v[4] * b[1] + m_v[7] * b[2];
00959 a[2] = m_v[2] * b[0] + m_v[5] * b[1] + m_v[8] * b[2];
00960 return( a );
00961 }
00962
00963 Mat3 Mat3::operator * ( const Mat3 & b ) const {
00964 Mat3 a;
00965
00966 a[0] = m_v[0] * b[0] + m_v[3] * b[1] + m_v[6] * b[2];
00967 a[3] = m_v[0] * b[3] + m_v[3] * b[4] + m_v[6] * b[5];
00968 a[6] = m_v[0] * b[6] + m_v[3] * b[7] + m_v[6] * b[8];
00969
00970 a[1] = m_v[1] * b[0] + m_v[4] * b[1] + m_v[7] * b[2];
00971 a[4] = m_v[1] * b[3] + m_v[4] * b[4] + m_v[7] * b[5];
00972 a[7] = m_v[1] * b[6] + m_v[4] * b[7] + m_v[7] * b[8];
00973
00974 a[2] = m_v[2] * b[0] + m_v[5] * b[1] + m_v[8] * b[2];
00975 a[5] = m_v[2] * b[3] + m_v[5] * b[4] + m_v[8] * b[5];
00976 a[8] = m_v[2] * b[6] + m_v[5] * b[7] + m_v[8] * b[8];
00977
00978 return( a );
00979 }
00980
00981 Mat3 Mat3::operator * ( float b ) const {
00982 Mat3 a;
00983 a[0] = m_v[0] * b;
00984 a[1] = m_v[1] * b;
00985 a[2] = m_v[2] * b;
00986 a[3] = m_v[3] * b;
00987 a[4] = m_v[4] * b;
00988 a[5] = m_v[5] * b;
00989 a[6] = m_v[6] * b;
00990 a[7] = m_v[7] * b;
00991 a[8] = m_v[8] * b;
00992 return( a );
00993 }
00994
00995 Mat3 Mat3::operator / ( float b ) const {
00996 Mat3 a;
00997 a[0] = m_v[0] / b;
00998 a[1] = m_v[1] / b;
00999 a[2] = m_v[2] / b;
01000 a[3] = m_v[3] / b;
01001 a[4] = m_v[4] / b;
01002 a[5] = m_v[5] / b;
01003 a[6] = m_v[6] / b;
01004 a[7] = m_v[7] / b;
01005 a[8] = m_v[8] / b;
01006 return( a );
01007 }
01008
01009 Mat3 & Mat3::operator *= ( const Mat3 & b ){
01010 return( * this = * this * b );
01011 }
01012
01013 Mat3 & Mat3::operator *= ( float b ){
01014 return( * this = * this * b );
01015 }
01016
01017 Mat3 & Mat3::operator /= ( float b ){
01018 return( * this = * this / b );
01019 }
01020
01021 float & Mat3::operator [] ( int index ) {
01022 return( m_v[ index ] );
01023 }
01024
01025 const float & Mat3::operator [] ( const int index ) const {
01026 return( m_v[ index ] );
01027 }
01028
01029 const float * Mat3::operator * ( void ) const {
01030 return( m_v );
01031 }
01032
01033 const float & Mat3::getElement( int column, int row ) const {
01034 return( m_v[ column * 3 + row ] );
01035 }
01036
01037 float & Mat3::getElement( int column, int row ){
01038 return( m_v[ column * 3 + row ] );
01039 }
01040
01041 void Mat3::setElement( int col, int row, float v ){
01042 m_v[ col * 3 + row ] = v;
01043 }
01044
01045 bool Mat3::operator == ( const Mat3 & b ) const {
01046 return( equals( b ) );
01047 }
01048
01049 Vec3 Mat3::getRow( int index ) const {
01050 return( Vec3( m_v[ index ], m_v[ 3 + index ], m_v[ 6 + index ] ) );
01051 }
01052
01053 Vec3 Mat3::getCol( int index ) const {
01054 return( Vec3( m_v[ index * 3 + 0 ], m_v[ index * 3 + 1 ], m_v[ index * 3 + 2 ] ) );
01055 }
01056
01057 void Mat3::setRow( int index, const Vec3 & row ){
01058 m_v[ index ] = row[0];
01059 m_v[ 3 + index ] = row[1];
01060 m_v[ 6 + index ] = row[2];
01061 }
01062
01063 void Mat3::setCol( int index, const Vec3 & col ){
01064 m_v[ index * 3 + 0 ] = col[0];
01065 m_v[ index * 3 + 1 ] = col[1];
01066 m_v[ index * 3 + 2 ] = col[2];
01067 }
01068
01069 bool Mat3::equals( const Mat3 & compare, float epsilon ) const {
01070 return( equals( * compare, epsilon ) );
01071 }
01072
01073 bool Mat3::equals( const float * compare, float epsilon ) const {
01074 for( int i = 0; i < 9; i++ ){
01075 if( fabs( compare[i] - m_v[i] ) > epsilon ){
01076 return( false );
01077 }
01078 }
01079 return( true );
01080 }
01081
01082 Mat3 Mat3::transpose( void ) const {
01083
01084 Mat3 a;
01085
01086 a[0] = m_v[0];
01087 a[3] = m_v[1];
01088 a[6] = m_v[2];
01089
01090 a[1] = m_v[3];
01091 a[4] = m_v[4];
01092 a[7] = m_v[5];
01093
01094 a[2] = m_v[6];
01095 a[5] = m_v[7];
01096 a[8] = m_v[8];
01097
01098 return( a );
01099
01100 }
01101
01102 Mat3 Mat3::adjugate( void ) const {
01103
01104 Vec3 x = getRow( 1 ).cross( getRow( 2 ) );
01105 Vec3 y = getRow( 2 ).cross( getRow( 0 ) );
01106 Vec3 z = getRow( 0 ).cross( getRow( 1 ) );
01107
01108 return( Mat3( x, y, z ) );
01109 }
01110
01111 float Mat3::determinant( void ) const {
01112 return( m_v[0] * ( ( m_v[4] * m_v[8] ) - ( m_v[5] * m_v[7] ) ) -
01113 m_v[1] * ( ( m_v[3] * m_v[8] ) - ( m_v[5] * m_v[6] ) ) +
01114 m_v[2] * ( ( m_v[3] * m_v[7] ) - ( m_v[4] * m_v[6] ) ) );
01115 }
01116
01117 float Mat3::trace( void ) const {
01118 return( m_v[0] + m_v[4] + m_v[8] );
01119 }
01120
01121 Mat3 Mat3::inverse( void ) const {
01122 float d = determinant();
01123
01124 if( d == 0.0f ){
01125 Error::warning( Error::INVALID_VALUE, __FILE__, __LINE__, "matrix is singular" );
01126 return( Mat3::fromIdentity() );
01127 }
01128
01129 return( adjugate().transpose() / d );
01130 }
01131
01132 void Mat3::setIdentity( void ){
01133 m_v[0] = 1.0f;
01134 m_v[1] = 0.0f;
01135 m_v[2] = 0.0f;
01136 m_v[3] = 0.0f;
01137 m_v[4] = 1.0f;
01138 m_v[5] = 0.0f;
01139 m_v[6] = 0.0f;
01140 m_v[7] = 0.0f;
01141 m_v[8] = 1.0f;
01142 }
01143
01144 Mat3 Mat3::fromIdentity(){
01145 Mat3 m;
01146 m.setIdentity();
01147 return( m );
01148 }
01149
01151
01152
01153 Vec4::Vec4( float x, float y, float z, float w ){
01154 m_v[0] = x;
01155 m_v[1] = y;
01156 m_v[2] = z;
01157 m_v[3] = w;
01158 }
01159
01160 Vec4::Vec4( float xyzw ){
01161 m_v[0] = xyzw;
01162 m_v[1] = xyzw;
01163 m_v[2] = xyzw;
01164 m_v[3] = xyzw;
01165 }
01166
01167 Vec4::Vec4( const float * v ){
01168 memcpy( m_v, v, 4 * sizeof( float ) );
01169 }
01170
01171 Vec4::Vec4( const Vec2 & xy, float z, float w ){
01172 m_v[0] = xy[0];
01173 m_v[1] = xy[1];
01174 m_v[2] = z;
01175 m_v[3] = w;
01176 }
01177
01178 Vec4::Vec4( const Vec3 & xyz, float w ){
01179 m_v[0] = xyz[0];
01180 m_v[1] = xyz[1];
01181 m_v[2] = xyz[2];
01182 m_v[3] = w;
01183 }
01184
01185 Vec4::Vec4( const Vec2 & xy, const Vec2 & zw ){
01186 m_v[0] = xy[0];
01187 m_v[1] = xy[1];
01188 m_v[2] = zw[0];
01189 m_v[3] = zw[1];
01190 }
01191
01192 Vec4::Vec4( float x, const Vec3 & yzw ){
01193 m_v[0] = x;
01194 m_v[1] = yzw[0];
01195 m_v[2] = yzw[1];
01196 m_v[3] = yzw[2];
01197 }
01198
01199 Vec4::Vec4( float x, float y, const Vec2 & zw ){
01200 m_v[0] = x;
01201 m_v[1] = y;
01202 m_v[2] = zw[0];
01203 m_v[3] = zw[1];
01204 }
01205
01206
01207 bool Vec4::operator < ( const float v ) const {
01208 return( hyp() < v * v );
01209 }
01210
01211 bool Vec4::operator < ( const Vec2 & v ) const {
01212 return( hyp() < v.hyp() );
01213 }
01214
01215 bool Vec4::operator < ( const Vec3 & v ) const {
01216 return( hyp() < v.hyp() );
01217 }
01218
01219 bool Vec4::operator < ( const Vec4 & v ) const {
01220 return( hyp() < v.hyp() );
01221 }
01222
01223 Vec4 Vec4::operator - () const {
01224 return( Vec4( -m_v[0], -m_v[1], -m_v[2], -m_v[3] ) );
01225 }
01226
01227 Vec4 Vec4::operator + ( const Vec4 & b ) const {
01228 Vec4 a;
01229 a[0] = m_v[0] + b[0];
01230 a[1] = m_v[1] + b[1];
01231 a[2] = m_v[2] + b[2];
01232 a[3] = m_v[3] + b[3];
01233 return( a );
01234 }
01235
01236 Vec4 Vec4::operator - ( const Vec4 & b ) const {
01237 Vec4 a;
01238 a[0] = m_v[0] - b[0];
01239 a[1] = m_v[1] - b[1];
01240 a[2] = m_v[2] - b[2];
01241 a[3] = m_v[3] - b[3];
01242 return( a );
01243 }
01244
01245 Vec4 Vec4::operator * ( const float b ) const {
01246 Vec4 a;
01247 a[0] = m_v[0] * b;
01248 a[1] = m_v[1] * b;
01249 a[2] = m_v[2] * b;
01250 a[3] = m_v[3] * b;
01251 return( a );
01252 }
01253
01254 Vec4 Vec4::operator * ( const Vec4 & b ) const {
01255 Vec4 a;
01256 a[0] = m_v[0] * b[0];
01257 a[1] = m_v[1] * b[1];
01258 a[2] = m_v[2] * b[2];
01259 a[3] = m_v[3] * b[3];
01260 return( a );
01261 }
01262
01263 Vec4 Vec4::operator / ( const Vec4 & b ) const {
01264 Vec4 a;
01265 a[0] = m_v[0] / b[0];
01266 a[1] = m_v[1] / b[1];
01267 a[2] = m_v[2] / b[2];
01268 a[3] = m_v[3] / b[3];
01269 return( a );
01270 }
01271
01272 Vec4 Vec4::operator / ( float b ) const {
01273 Vec4 a;
01274 a[0] = m_v[0] / b;
01275 a[1] = m_v[1] / b;
01276 a[2] = m_v[2] / b;
01277 a[3] = m_v[3] / b;
01278 return( a );
01279 }
01280
01281 Vec4 & Vec4::operator += ( const Vec4 & b ){
01282 return( * this = * this + b );
01283 }
01284
01285 Vec4 & Vec4::operator -= ( const Vec4 & b ){
01286 return( * this = * this - b );
01287 }
01288
01289 Vec4 & Vec4::operator *= ( float b ){
01290 return( * this = * this * b );
01291 }
01292
01293 Vec4 & Vec4::operator /= ( float b ){
01294 return( * this = * this / b );
01295 }
01296
01297 Vec4 & Vec4::operator /= ( const Vec4 & b ){
01298 return( * this = * this / b );
01299 }
01300
01301 float & Vec4::operator [] ( int index ) {
01302 return( m_v[ index ] );
01303 }
01304
01305 const float & Vec4::operator [] ( const int index ) const {
01306 return( m_v[ index ] );
01307 }
01308
01309 const float * Vec4::operator * ( void ) const {
01310 return( m_v );
01311 }
01312
01313 bool Vec4::operator == ( const Vec4 & b ) const {
01314 return( equals( b ) );
01315 }
01316
01317 Vec2 Vec4::xy() const {
01318 return( Vec2( m_v[0], m_v[1] ) );
01319 }
01320
01321 Vec2 Vec4::zw() const {
01322 return( Vec2( m_v[2], m_v[3] ) );
01323 }
01324
01325 Vec3 Vec4::xyz() const {
01326 return( Vec3( m_v[0], m_v[1], m_v[2] ) );
01327 }
01328
01329 float Vec4::hyp( void ) const {
01330 return( m_v[0] * m_v[0] + m_v[1] * m_v[1] + m_v[2] * m_v[2] + m_v[3] * m_v[3] );
01331 }
01332
01333 float Vec4::len( void ) const {
01334 float h = hyp() + 0.000001f;
01335 return( sqrt( h ) );
01336 }
01337
01338 void Vec4::normalize( void ){
01339 float l = len();
01340 if( l == 0.0f ){
01341 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
01342 return;
01343 }
01344 m_v[0] /= l;
01345 m_v[1] /= l;
01346 m_v[2] /= l;
01347 m_v[3] /= l;
01348 }
01349
01350 Vec4 Vec4::normalized( void ) const {
01351 float l = len();
01352 return( Vec4( m_v[0] / l, m_v[1] / l, m_v[2] / l, m_v[3] / l ) );
01353 }
01354
01355 float Vec4::dot( const Vec4 & b ) const {
01356 return( m_v[0] * b[0] + m_v[1] * b[1] + m_v[2] * b[2] + m_v[3] * b[3] );
01357 }
01358
01359 Vec4 Vec4::abs( void ) const {
01360 return( Vec4( fabs( m_v[0] ), fabs( m_v[1] ), fabs( m_v[2] ), fabs( m_v[3] ) ) );
01361 }
01362
01363 Vec4 Vec4::sgn( void ) const {
01364 return( Vec4( m_v[0] < 0.0 ? -1.0 : 1.0, m_v[1] < 0.0 ? -1.0 : 1.0, m_v[2] < 0.0 ? -1.0 : 1.0, m_v[3] < 0.0 ? -1.0 : 1.0 ) );
01365 }
01366
01367 Vec4 Vec4::clamp( float min, float max ) const {
01368 Vec4 v( *this );
01369 for( int i = 0; i < 4; i++ ){
01370 if( v[i] < min ){
01371 v[i] = min;
01372 }
01373 else if( v[i] > max ){
01374 v[i] = max;
01375 }
01376 }
01377 return( v );
01378 }
01379
01380 bool Vec4::equals( const Vec4 & compare, float epsilon ) const {
01381 return( equals( * compare, epsilon ) );
01382 }
01383
01384 bool Vec4::equals( const float * compare, float epsilon ) const {
01385 for( int i = 0; i < 4; i++ ){
01386 if( fabs( compare[i] - m_v[i] ) > epsilon ){
01387 return( false );
01388 }
01389 }
01390 return( true );
01391 }
01392
01394
01395 Quat::Quat( float x, float y, float z, float w ){
01396 m_v[0] = x;
01397 m_v[1] = y;
01398 m_v[2] = z;
01399 m_v[3] = w;
01400 }
01401
01402 Quat::Quat( const float * v ){
01403 memcpy( m_v, v, 4 * sizeof( float ) );
01404 }
01405
01406 Vec2 Quat::xy() const {
01407 return( Vec2( m_v[0], m_v[1] ) );
01408 }
01409
01410 Vec2 Quat::zw() const {
01411 return( Vec2( m_v[2], m_v[3] ) );
01412 }
01413
01414 Vec3 Quat::xyz() const {
01415 return( Vec3( m_v[0], m_v[1], m_v[2] ) );
01416 }
01417
01418 bool Quat::equals( const Quat & compare, float epsilon ) const {
01419 return( equals( *compare, epsilon ) );
01420 }
01421
01422 bool Quat::equals( const float * compare, float epsilon ) const {
01423 for( int i = 0; i < 4; i++ ){
01424 if( fabs( compare[i] - m_v[i] ) > epsilon ){
01425 return( false );
01426 }
01427 }
01428 return( true );
01429 }
01430
01431 float & Quat::operator [] ( int index ) {
01432 return( m_v[ index ] );
01433 }
01434
01435 const float & Quat::operator [] ( const int index ) const {
01436 return( m_v[ index ] );
01437 }
01438
01439 bool Quat::operator == ( const Quat & q ) const {
01440 return( equals( q ) );
01441 }
01442
01443 bool Quat::operator != ( const Quat & q ) const {
01444 return( ! equals( q ) );
01445 }
01446
01447 Quat Quat::operator + ( const Quat & q ) const {
01448 Quat result;
01449 for( int i = 0; i < 4; ++i ){
01450 result.m_v[i] = m_v[i] + q.m_v[i];
01451 }
01452 return( result );
01453 }
01454
01455 Quat Quat::operator - ( const Quat & q ) const {
01456 Quat result;
01457 for( int i = 0; i < 4; ++i ){
01458 result.m_v[i] = m_v[i] - q.m_v[i];
01459 }
01460 return( result );
01461 }
01462
01463 Quat Quat::operator * ( const Quat & q ) const {
01464
01465 Quat result;
01466
01467 result.m_v[0] =
01468 m_v[0] * q.m_v[0] -
01469 m_v[1] * q.m_v[1] -
01470 m_v[2] * q.m_v[2] -
01471 m_v[3] * q.m_v[3];
01472
01473 result.m_v[1] =
01474 m_v[0] * q.m_v[1] +
01475 m_v[1] * q.m_v[0] +
01476 m_v[2] * q.m_v[3] -
01477 m_v[3] * q.m_v[2];
01478
01479 result.m_v[2] =
01480 m_v[0] * q.m_v[2] +
01481 m_v[2] * q.m_v[0] +
01482 m_v[3] * q.m_v[1] -
01483 m_v[1] * q.m_v[3];
01484
01485 result.m_v[3] =
01486 m_v[0] * q.m_v[3] +
01487 m_v[3] * q.m_v[0] +
01488 m_v[1] * q.m_v[2] -
01489 m_v[2] * q.m_v[1];
01490
01491 return( result );
01492 }
01493
01494 Quat Quat::operator * ( float scalar ) const {
01495 Quat result;
01496 for( int i = 0; i < 4; ++i ){
01497 result.m_v[i] = scalar * m_v[i];
01498 }
01499 return( result );
01500 }
01501
01502 Quat Quat::operator / ( float scalar ) const {
01503 Quat result;
01504 int i;
01505
01506 if( scalar != 0 ){
01507 for( i = 0; i < 4; ++i ){
01508 result.m_v[i] = m_v[i] / scalar;
01509 }
01510 }
01511 else{
01512 for( i = 0; i < 4; ++i ){
01513 result.m_v[i] = 0.0f;
01514 }
01515 }
01516
01517 return( result );
01518 }
01519
01520 Quat Quat::operator - () const {
01521 Quat result;
01522 for( int i = 0; i < 4; ++i ){
01523 result.m_v[i] = -m_v[i];
01524 }
01525 return( result );
01526 }
01527
01528 Quat & Quat::operator += ( const Quat & q ){
01529 for( int i = 0; i < 4; ++i ){
01530 m_v[i] += q.m_v[i];
01531 }
01532 return( * this );
01533 }
01534
01535 Quat & Quat::operator -= ( const Quat & q ){
01536 for( int i = 0; i < 4; ++i ){
01537 m_v[i] -= q.m_v[i];
01538 }
01539 return( * this );
01540 }
01541
01542 Quat & Quat::operator *= ( float scalar ){
01543 for( int i = 0; i < 4; ++i ){
01544 m_v[i] *= scalar;
01545 }
01546 return( * this );
01547 }
01548
01549 Quat & Quat::operator /= ( float scalar ){
01550 int i;
01551
01552 if( scalar != 0.0f ){
01553 for( i = 0; i < 4; ++i ){
01554 m_v[i] /= scalar;
01555 }
01556 }
01557 else{
01558 for( i = 0; i < 4; ++i ){
01559 m_v[i] = 0.0f;
01560 }
01561 }
01562
01563 return( * this );
01564 }
01565
01566 const float * Quat::operator * ( void ) const {
01567 return( m_v );
01568 }
01569
01570 Quat Quat::fromMat3( const Mat3 & rot ){
01571
01572
01573
01574 Quat q;
01575 const int next[3] = { 1, 2, 0 };
01576
01577 float trace = rot.trace();
01578 float root;
01579
01580 if( trace > 0.0f ){
01581 root = sqrt( trace + 1.0f );
01582 q.m_v[0] = root / 2.0f;
01583 root = 0.5f / root;
01584 q.m_v[1] = ( rot[7] - rot[5] ) * root;
01585 q.m_v[2] = ( rot[2] - rot[6] ) * root;
01586 q.m_v[3] = ( rot[3] - rot[1] ) * root;
01587 }
01588 else{
01589 int i = 0;
01590 if( rot[4] > rot[0] ){
01591 i = 1;
01592 }
01593 if( rot[8] > rot[ i * 3 + i ] ){
01594 i = 2;
01595 }
01596 int j = next[i];
01597 int k = next[j];
01598
01599 root = sqrt( rot[ i * 3 + i ] - rot[ j * 3 + j ] - rot[ k * 3 + k ] + 1.0f );
01600 float * quat[3] = { & q.m_v[1], & q.m_v[2], & q.m_v[3] };
01601 * quat[i] = root / 2.0f;
01602 root = 0.5f / root;
01603 q.m_v[0] = ( rot[ k * 3 + j ] - rot[ j * 3 + k ] ) * root;
01604 *quat[j] = ( rot[ j * 3 + i ] + rot[ i * 3 + j ] ) * root;
01605 *quat[k] = ( rot[ k * 3 + i ] + rot[ i * 3 + k ] ) * root;
01606 }
01607 return( q );
01608 }
01609
01610 Mat3 Quat::toMat3( void ) const {
01611 Mat3 rot;
01612 float x = 2.0f * m_v[1];
01613 float y = 2.0f * m_v[2];
01614 float z = 2.0f * m_v[3];
01615 float wx = x * m_v[0];
01616 float wy = y * m_v[0];
01617 float wz = z * m_v[0];
01618 float xx = x * m_v[1];
01619 float xy = y * m_v[1];
01620 float xz = z * m_v[1];
01621 float yy = y * m_v[2];
01622 float yz = z * m_v[2];
01623 float zz = z * m_v[3];
01624
01625 rot[0] = 1.0f - ( yy + zz );
01626 rot[1] = xy - wz;
01627 rot[2] = xz + wy;
01628 rot[3] = xy + wz;
01629 rot[4] = 1.0f - ( xx + zz );
01630 rot[5] = yz - wx;
01631 rot[6] = xz - wy;
01632 rot[7] = yz + wx;
01633 rot[8] = 1.0f - ( xx + yy );
01634 return( rot );
01635 }
01636
01637 Quat Quat::fromAxisAngle( const Vec3 & axis, float angle ){
01638 Quat q;
01639 float halfAngle = 0.5f * angle;
01640 float sn = sin( halfAngle );
01641 q.m_v[0] = cos( halfAngle );
01642 q.m_v[1] = sn * axis[0];
01643 q.m_v[2] = sn * axis[1];
01644 q.m_v[3] = sn * axis[2];
01645 return( q );
01646 }
01647
01648 void Quat::toAxisAngle( Vec3 & axis, float & angle ) const {
01649
01650 float sqrLength = m_v[1] * m_v[1] + m_v[2] * m_v[2] + m_v[3] * m_v[3];
01651
01652 if( sqrLength > 0.00000f ){
01653 angle = 2.0f * acos( m_v[0] );
01654
01655 float length = sqrt( sqrLength );
01656 axis[0] = m_v[1] / length;
01657 axis[1] = m_v[2] / length;
01658 axis[2] = m_v[3] / length;
01659 }
01660 else{
01661 angle = 0.0f;
01662
01663 axis[0] = 1.0f;
01664 axis[1] = 0.0f;
01665 axis[2] = 0.0f;
01666 }
01667 }
01668
01669 float Quat::len() const {
01670 return( sqrt( m_v[0]*m_v[0] + m_v[1]*m_v[1] + \
01671 m_v[2]*m_v[2] + m_v[3]*m_v[3] ) );
01672 }
01673
01674 float Quat::hyp() const {
01675 return( m_v[0] * m_v[0] + m_v[1] * m_v[1] + \
01676 m_v[2] * m_v[2] + m_v[3] * m_v[3] );
01677 }
01678
01679 float Quat::dot( const Quat & q ) const {
01680 return( m_v[0] * q.m_v[0] + m_v[1] * q.m_v[1] + \
01681 m_v[2] * q.m_v[2] + m_v[3] * q.m_v[3] );
01682 }
01683
01684 void Quat::normalize(){
01685
01686 float length = len();
01687
01688 if( length == 0.0f ){
01689 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
01690 return;
01691 }
01692 m_v[0] /= length;
01693 m_v[1] /= length;
01694 m_v[2] /= length;
01695 m_v[3] /= length;
01696 }
01697
01698
01699 Quat Quat::normalized() const {
01700 Quat norm;
01701
01702 float length = len();
01703
01704 if( length == 0.0f ){
01705 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
01706 return( Quat() );
01707 }
01708 norm[0] = m_v[0] / length;
01709 norm[1] = m_v[1] / length;
01710 norm[2] = m_v[2] / length;
01711 norm[3] = m_v[3] / length;
01712
01713 return( norm );
01714 }
01715
01716 Quat Quat::inverse() const {
01717 Quat inverse;
01718
01719 float norm = hyp();
01720
01721 if( norm > 0.0f ){
01722 inverse.m_v[0] = m_v[0] / norm;
01723 inverse.m_v[1] = -m_v[1] / norm;
01724 inverse.m_v[2] = -m_v[2] / norm;
01725 inverse.m_v[3] = -m_v[3] / norm;
01726 }
01727 else{
01728 Error::warning( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
01729 return( Quat() );
01730 }
01731
01732 return( inverse );
01733 }
01734
01735 Quat Quat::conjugate() const {
01736 return( Quat( m_v[0], -m_v[1], -m_v[2], -m_v[3] ) );
01737 }
01738
01739 Quat Quat::exp() const {
01740
01741 Quat result;
01742
01743 float angle = sqrt( m_v[1] * m_v[1] + m_v[2] * m_v[2] + m_v[3] * m_v[3] );
01744
01745 float sn = sin( angle );
01746 result.m_v[0] = cos( angle );
01747
01748 int i;
01749
01750 if( fabs( sn ) >= 0.00000f ){
01751 float coeff = sn / angle;
01752 for( i = 1; i < 4; ++i ){
01753 result.m_v[i] = coeff * m_v[i];
01754 }
01755 }
01756 else{
01757 for( i = 1; i < 4; ++i ){
01758 result.m_v[i] = m_v[i];
01759 }
01760 }
01761
01762 return( result );
01763 }
01764
01765 Quat Quat::log() const {
01766 Quat result;
01767 result.m_v[0] = 0.0f;
01768
01769 int i;
01770
01771 if( fabs( m_v[0] ) < 1.0f ){
01772 float angle = acos( m_v[0] );
01773 float sn = sin( angle );
01774 if( fabs( sn ) >= 0.00000f ){
01775 float coeff = angle / sn;
01776 for( i = 1; i < 4; ++i ){
01777 result.m_v[i] = coeff * m_v[i];
01778 }
01779 return result;
01780 }
01781 }
01782
01783 for( i = 1; i < 4; ++i ){
01784 result.m_v[i] = m_v[i];
01785 }
01786
01787 return( result );
01788 }
01789
01791
01792 Mat4::Mat4( float v00, float v01, float v02, float v03,
01793 float v10, float v11, float v12, float v13,
01794 float v20, float v21, float v22, float v23,
01795 float v30, float v31, float v32, float v33 ){
01796
01797 m_v[0] = v00;
01798 m_v[1] = v01;
01799 m_v[2] = v02;
01800 m_v[3] = v03;
01801 m_v[4] = v10;
01802 m_v[5] = v11;
01803 m_v[6] = v12;
01804 m_v[7] = v13;
01805 m_v[8] = v20;
01806 m_v[9] = v21;
01807 m_v[10] = v22;
01808 m_v[11] = v23;
01809 m_v[12] = v30;
01810 m_v[13] = v31;
01811 m_v[14] = v32;
01812 m_v[15] = v33;
01813 }
01814
01815 Mat4::Mat4( const float * v ){
01816 memcpy( m_v, v, 16 * sizeof( float ) );
01817 }
01818
01820 Vec3 Mat4::operator * ( const Vec3 & b ) const {
01821 Vec3 a;
01822 a[0] = b[0] * m_v[0] + b[1] * m_v[4] + b[2] * m_v[8] + m_v[12];
01823 a[1] = b[0] * m_v[1] + b[1] * m_v[5] + b[2] * m_v[9] + m_v[13];
01824 a[2] = b[0] * m_v[2] + b[1] * m_v[6] + b[2] * m_v[10] + m_v[14];
01825 return( a );
01826 }
01827
01829 Vec4 Mat4::operator * ( const Vec4 & b ) const {
01830 Vec4 a;
01831 a[0] = b[0] * m_v[0] + b[1] * m_v[4] + b[2] * m_v[8] + b[3] * m_v[12];
01832 a[1] = b[0] * m_v[1] + b[1] * m_v[5] + b[2] * m_v[9] + b[3] * m_v[13];
01833 a[2] = b[0] * m_v[2] + b[1] * m_v[6] + b[2] * m_v[10] + b[3] * m_v[14];
01834 a[3] = b[0] * m_v[3] + b[1] * m_v[7] + b[2] * m_v[11] + b[3] * m_v[15];
01835 return( a );
01836 }
01837
01839 Mat3 Mat4::operator * ( const Mat3 & b ) const {
01840 Mat3 a;
01841
01842 a[0] = m_v[0] * b[0] + m_v[4] * b[1] + m_v[8] * b[2];
01843 a[3] = m_v[0] * b[3] + m_v[4] * b[4] + m_v[8] * b[5];
01844 a[6] = m_v[0] * b[6] + m_v[4] * b[7] + m_v[8] * b[8];
01845
01846 a[1] = m_v[1] * b[0] + m_v[5] * b[1] + m_v[9] * b[2];
01847 a[4] = m_v[1] * b[3] + m_v[5] * b[4] + m_v[9] * b[5];
01848 a[7] = m_v[1] * b[6] + m_v[5] * b[7] + m_v[9] * b[8];
01849
01850 a[2] = m_v[2] * b[0] + m_v[6] * b[1] + m_v[10] * b[2];
01851 a[5] = m_v[2] * b[3] + m_v[6] * b[4] + m_v[10] * b[5];
01852 a[8] = m_v[2] * b[6] + m_v[6] * b[7] + m_v[10] * b[8];
01853
01854 return( a );
01855 }
01856
01858 Mat4 Mat4::operator * ( const Mat4 & b ) const {
01859 Mat4 a;
01860
01861 unsigned int i;
01862 for( i = 0; i < 4; i++ ){
01863 const float ai0 = m_v[ i ], ai1 = m_v[ 4 + i ], ai2 = m_v[ 8 + i ], ai3 = m_v[ 12 + i ];
01864 a[ i ] = ai0 * b[ 0 ] + ai1 * b[ 1 ] + ai2 * b[ 2 ] + ai3 * b[ 3 ];
01865 a[ 4 + i ] = ai0 * b[ 4 ] + ai1 * b[ 5 ] + ai2 * b[ 6 ] + ai3 * b[ 7 ];
01866 a[ 8 + i ] = ai0 * b[ 8 ] + ai1 * b[ 9 ] + ai2 * b[ 10 ] + ai3 * b[ 11 ];
01867 a[ 12 + i ] = ai0 * b[ 12 ] + ai1 * b[ 13 ] + ai2 * b[ 14 ] + ai3 * b[ 15 ];
01868 }
01869
01870 return( a );
01871 }
01872
01873 Mat4 Mat4::operator * ( float f ) const {
01874 Mat4 m( m_v );
01875
01876 m.m_v[0] *= f;
01877 m.m_v[1] *= f;
01878 m.m_v[2] *= f;
01879
01880 m.m_v[4] *= f;
01881 m.m_v[5] *= f;
01882 m.m_v[6] *= f;
01883
01884 m.m_v[8] *= f;
01885 m.m_v[9] *= f;
01886 m.m_v[10] *= f;
01887
01888 return( m );
01889 }
01890
01891 Mat4 & Mat4::operator *= ( const Mat4 & b ){
01892 return( * this = * this * b );
01893 }
01894
01895 Mat4 & Mat4::operator *= ( float f ){
01896 m_v[0] *= f;
01897 m_v[1] *= f;
01898 m_v[2] *= f;
01899
01900 m_v[4] *= f;
01901 m_v[5] *= f;
01902 m_v[6] *= f;
01903
01904 m_v[8] *= f;
01905 m_v[9] *= f;
01906 m_v[10] *= f;
01907
01908 return( * this );
01909 }
01910
01911 Mat4 & Mat4::operator *= ( const Vec3 & v ){
01912 m_v[0] *= v[0];
01913 m_v[1] *= v[0];
01914 m_v[2] *= v[0];
01915
01916 m_v[4] *= v[1];
01917 m_v[5] *= v[1];
01918 m_v[6] *= v[1];
01919
01920 m_v[8] *= v[2];
01921 m_v[9] *= v[2];
01922 m_v[10] *= v[2];
01923
01924 return( * this );
01925 }
01926
01929 Mat4 Mat4::operator + ( const Vec2 & v ) const {
01930 Mat4 m( m_v );
01931
01932 m.m_v[12] += v[0];
01933 m.m_v[13] += v[1];
01934
01935 return( m );
01936 }
01937
01939 Mat4 Mat4::operator + ( const Vec3 & v ) const {
01940 Mat4 m( m_v );
01941
01942 m.m_v[12] += v[0];
01943 m.m_v[13] += v[1];
01944 m.m_v[14] += v[2];
01945
01946 return( m );
01947 }
01948
01949 Mat4 & Mat4::operator += ( const Vec2 & v ){
01950 m_v[12] += v[0];
01951 m_v[13] += v[1];
01952 return( * this );
01953 }
01954
01955 Mat4 & Mat4::operator += ( const Vec3 & v ){
01956 m_v[12] += v[0];
01957 m_v[13] += v[1];
01958 m_v[14] += v[2];
01959 return( * this );
01960 }
01961
01962 float & Mat4::operator [] ( int index ) {
01963 return( m_v[ index ] );
01964 }
01965
01966 const float & Mat4::operator [] ( const int index ) const {
01967 return( m_v[ index ] );
01968 }
01969
01970 const float * Mat4::operator * ( void ) const {
01971 return( m_v );
01972 }
01973
01974 const float & Mat4::getElement( int column, int row ) const {
01975 return( m_v[ column * 4 + row ] );
01976 }
01977
01978 float & Mat4::getElement( int column, int row ){
01979 return( m_v[ column * 4 + row ] );
01980 }
01981
01982 void Mat4::setElement( int col, int row, float v ){
01983 m_v[ col * 4 + row ] = v;
01984 }
01985
01986 bool Mat4::operator == ( const Mat4 & b ) const {
01987 return( equals( b ) );
01988 }
01989
01990 Mat4 & Mat4::operator = ( const Mat3 & b ){
01991 m_v[0] = b[0];
01992 m_v[1] = b[1];
01993 m_v[2] = b[2];
01994 m_v[4] = b[3];
01995 m_v[5] = b[4];
01996 m_v[6] = b[5];
01997 m_v[8] = b[6];
01998 m_v[9] = b[7];
01999 m_v[10] = b[8];
02000 return( * this );
02001 }
02002
02003 Mat4 & Mat4::operator = ( const Vec3 & b ){
02004 m_v[12] = b[0];
02005 m_v[13] = b[1];
02006 m_v[14] = b[2];
02007 return( * this );
02008 }
02009
02010 Vec4 Mat4::getRow( int index ) const {
02011 return( Vec4( m_v[ index ], m_v[ 4 + index ], m_v[ 8 + index ], m_v[ 12 + index ] ) );
02012 }
02013
02014 Vec4 Mat4::getCol( int index ) const {
02015 return( Vec4( m_v[ index * 4 + 0 ], m_v[ index * 4 + 1 ], m_v[ index * 4 + 2 ], m_v[ index * 4 + 3 ] ) );
02016 }
02017
02018 void Mat4::setRow( int index, const Vec4 & row ){
02019 m_v[ index ] = row[0];
02020 m_v[ 4 + index ] = row[1];
02021 m_v[ 8 + index ] = row[2];
02022 m_v[ 12 + index ] = row[3];
02023 }
02024
02025 void Mat4::setCol( int index, const Vec4 & col ){
02026 m_v[ index * 4 + 0 ] = col[0];
02027 m_v[ index * 4 + 1 ] = col[1];
02028 m_v[ index * 4 + 2 ] = col[2];
02029 m_v[ index * 4 + 3 ] = col[3];
02030 }
02031
02032 bool Mat4::equals( const Mat4 & compare, float epsilon ) const {
02033 return( equals( * compare, epsilon ) );
02034 }
02035
02036 bool Mat4::equals( const float * compare, float epsilon ) const {
02037 for( int i = 0; i < 16; i++ ){
02038 if( fabs( compare[i] - m_v[i] ) > epsilon ){
02039 return( false );
02040 }
02041 }
02042 return( true );
02043 }
02044
02045
02046 void Mat4::translate( const Vec3 & b ){
02047 m_v[12] = m_v[0] * b[0] + m_v[4] * b[1] + m_v[8] * b[2] + m_v[12];
02048 m_v[13] = m_v[1] * b[0] + m_v[5] * b[1] + m_v[9] * b[2] + m_v[13];
02049 m_v[14] = m_v[2] * b[0] + m_v[6] * b[1] + m_v[10] * b[2] + m_v[14];
02050 m_v[15] = m_v[3] * b[0] + m_v[7] * b[1] + m_v[11] * b[2] + m_v[15];
02051 }
02052
02053 void Mat4::setTranslation( const Vec3 & b ){
02054 m_v[12] = b[0];
02055 m_v[13] = b[1];
02056 m_v[14] = b[2];
02057 }
02058
02059 Vec3 Mat4::translation( void ) const {
02060 return( Vec3( m_v[12], m_v[13], m_v[14] ) );
02061 }
02062
02063 Mat3 Mat4::rotation( void ) const {
02065 return( Mat3( m_v[0], m_v[1], m_v[2], m_v[4], m_v[5], m_v[6], m_v[8], m_v[9], m_v[10] ) );
02066 }
02067
02068 Mat4 Mat4::transpose( void ) const {
02069
02070 Mat4 a;
02071
02072 a[0] = m_v[0];
02073 a[4] = m_v[1];
02074 a[8] = m_v[2];
02075 a[12] = m_v[3];
02076
02077 a[1] = m_v[4];
02078 a[5] = m_v[5];
02079 a[9] = m_v[6];
02080 a[13] = m_v[7];
02081
02082 a[2] = m_v[8];
02083 a[6] = m_v[9];
02084 a[10] = m_v[10];
02085 a[14] = m_v[11];
02086
02087 a[3] = m_v[12];
02088 a[7] = m_v[13];
02089 a[11] = m_v[14];
02090 a[15] = m_v[15];
02091
02092 return( a );
02093 }
02094
02096 Mat4 Mat4::inverse( void ) const {
02097 Mat4 a;
02098
02099 float wtmp[4][8];
02100 float m0, m1, m2, m3, s;
02101 float *r0, *r1, *r2, *r3;
02102
02103 r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
02104
02105 r0[0] = m_v[0], r0[1] = m_v[4],
02106 r0[2] = m_v[8], r0[3] = m_v[12],
02107 r0[4] = 1.0f, r0[5] = r0[6] = r0[7] = 0.0f,
02108
02109 r1[0] = m_v[1], r1[1] = m_v[5],
02110 r1[2] = m_v[9], r1[3] = m_v[13],
02111 r1[5] = 1.0f, r1[4] = r1[6] = r1[7] = 0.0f,
02112
02113 r2[0] = m_v[2], r2[1] = m_v[6],
02114 r2[2] = m_v[10], r2[3] = m_v[14],
02115 r2[6] = 1.0f, r2[4] = r2[5] = r2[7] = 0.0f,
02116
02117 r3[0] = m_v[3], r3[1] = m_v[7],
02118 r3[2] = m_v[11], r3[3] = m_v[15],
02119 r3[7] = 1.0f, r3[4] = r3[5] = r3[6] = 0.0f;
02120
02121 if( fabs( r3[0] ) > fabs( r2[0] ) ){
02122 swap( r3, r2 );
02123 }
02124 if( fabs( r2[0] ) > fabs( r1[0] ) ){
02125 swap( r2, r1 );
02126 }
02127 if( fabs( r1[0] ) > fabs( r0[0] ) ){
02128 swap( r1, r0 );
02129 }
02130 if( r0[0] == 0.0f ){
02131 Error::warning( Error::INVALID_VALUE, __FILE__, __LINE__, "matrix is singular" );
02132 return( Mat4::fromIdentity() );
02133 }
02134
02135
02136 m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
02137 s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
02138 s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
02139 s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
02140 s = r0[4];
02141 if( s != 0.0 ){ r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
02142 s = r0[5];
02143 if (s != 0.0 ){ r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
02144 s = r0[6];
02145 if (s != 0.0 ){ r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
02146 s = r0[7];
02147 if (s != 0.0 ){ r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
02148
02149
02150 if ( fabs( r3[1] ) > fabs( r2[1] ) ){
02151 swap( r3, r2 );
02152 }
02153 if ( fabs( r2[1] ) > fabs( r1[1] ) ){
02154 swap( r2, r1 );
02155 }
02156 if( r1[1] == 0.0f ){
02157 Error::warning( Error::INVALID_VALUE, __FILE__, __LINE__, "matrix is singular" );
02158 return( Mat4::fromIdentity() );
02159 }
02160
02161
02162 m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1];
02163 r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
02164 r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
02165 s = r1[4]; if( 0.0f != s ){ r2[4] -= m2 * s; r3[4] -= m3 * s; }
02166 s = r1[5]; if( 0.0f != s ){ r2[5] -= m2 * s; r3[5] -= m3 * s; }
02167 s = r1[6]; if( 0.0f != s ){ r2[6] -= m2 * s; r3[6] -= m3 * s; }
02168 s = r1[7]; if( 0.0f != s ){ r2[7] -= m2 * s; r3[7] -= m3 * s; }
02169
02170
02171 if ( fabs( r3[2] ) > fabs( r2[2] ) ){
02172 swap( r3, r2 );
02173 }
02174 if( r2[2] == 0.0f ){
02175 Error::warning( Error::INVALID_VALUE, __FILE__, __LINE__, "matrix is singular" );
02176 return( Mat4::fromIdentity() );
02177 }
02178
02179
02180 m3 = r3[2] / r2[2];
02181 r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
02182 r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
02183 r3[7] -= m3 * r2[7];
02184
02185
02186 if( r3[3] == 0.0f ){
02187 Error::warning( Error::INVALID_VALUE, __FILE__, __LINE__, "matrix is singular" );
02188 return( Mat4::fromIdentity() );
02189 }
02190
02191 s = 1.0f / r3[3];
02192 r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
02193
02194 m2 = r2[3];
02195 s = 1.0f / r2[2];
02196 r2[4] = s * ( r2[4] - r3[4] * m2 ), r2[5] = s * ( r2[5] - r3[5] * m2 ),
02197 r2[6] = s * ( r2[6] - r3[6] * m2 ), r2[7] = s * ( r2[7] - r3[7] * m2 );
02198 m1 = r1[3];
02199 r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
02200 r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
02201 m0 = r0[3];
02202 r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
02203 r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
02204
02205 m1 = r1[2];
02206 s = 1.0f / r1[1];
02207 r1[4] = s * ( r1[4] - r2[4] * m1 ), r1[5] = s * ( r1[5] - r2[5] * m1 ),
02208 r1[6] = s * ( r1[6] - r2[6] * m1 ), r1[7] = s * ( r1[7] - r2[7] * m1 );
02209 m0 = r0[2];
02210 r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
02211 r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
02212
02213 m0 = r0[1];
02214 s = 1.0f / r0[0];
02215 r0[4] = s * ( r0[4] - r1[4] * m0 ), r0[5] = s * ( r0[5] - r1[5] * m0 ),
02216 r0[6] = s * ( r0[6] - r1[6] * m0 ), r0[7] = s * ( r0[7] - r1[7] * m0 );
02217
02218 a[0] = r0[4];
02219 a[1] = r1[4];
02220 a[2] = r2[4];
02221 a[3] = r3[4];
02222
02223 a[4] = r0[5],
02224 a[5] = r1[5],
02225 a[6] = r2[5],
02226 a[7] = r3[5],
02227
02228 a[8] = r0[6];
02229 a[9] = r1[6];
02230 a[10] = r2[6];
02231 a[11] = r3[6];
02232
02233 a[12] = r0[7],
02234 a[13] = r1[7],
02235 a[14] = r2[7],
02236 a[15] = r3[7];
02237
02238 return( a );
02239 }
02240
02241 void Mat4::setIdentity( void ){
02242 m_v[0] = 1.0f;
02243 m_v[1] = 0.0f;
02244 m_v[2] = 0.0f;
02245 m_v[3] = 0.0f;
02246 m_v[4] = 0.0f;
02247 m_v[5] = 1.0f;
02248 m_v[6] = 0.0f;
02249 m_v[7] = 0.0f;
02250 m_v[8] = 0.0f;
02251 m_v[9] = 0.0f;
02252 m_v[10] = 1.0f;
02253 m_v[11] = 0.0f;
02254 m_v[12] = 0.0f;
02255 m_v[13] = 0.0f;
02256 m_v[14] = 0.0f;
02257 m_v[15] = 1.0f;
02258 }
02259
02260 Mat4 Mat4::fromTransformation( const Vec3 & translation, const Mat3 & rotation ){
02261 Mat4 r;
02262 r.m_v[0] = rotation[0];
02263 r.m_v[1] = rotation[1];
02264 r.m_v[2] = rotation[2];
02265 r.m_v[3] = 0.0f;
02266 r.m_v[4] = rotation[3];
02267 r.m_v[5] = rotation[4];
02268 r.m_v[6] = rotation[5];
02269 r.m_v[7] = 0.0f;
02270 r.m_v[8] = rotation[6];
02271 r.m_v[9] = rotation[7];
02272 r.m_v[10] = rotation[8];
02273 r.m_v[11] = 0.0f;
02274 r.m_v[12] = translation[0];
02275 r.m_v[13] = translation[1];
02276 r.m_v[14] = translation[2];
02277 r.m_v[15] = 1.0f;
02278 return( r );
02279 }
02280
02281 Mat4 Mat4::fromAxisAngle( const Vec3 & v, float radians, const Vec3 & t ){
02282 Vec3 u = v.normalized();
02283
02284 float u0u0 = u[0] * u[0];
02285 float u0u1 = u[0] * u[1];
02286 float u0u2 = u[0] * u[2];
02287 float u1u1 = u[1] * u[1];
02288 float u1u2 = u[1] * u[2];
02289 float u2u2 = u[2] * u[2];
02290
02291 float cosa = cos( radians );
02292 float cosa1 = 1.0f - cosa;
02293 float sina = sin( radians );
02294
02295 float u0sina = u[0] * sina;
02296 float u1sina = u[1] * sina;
02297 float u2sina = u[2] * sina;
02298
02299
02300 return( Mat4( u0u0 + cosa * ( 1.0 - u0u0 ), u0u1 * cosa1 - u2sina, u0u2 * cosa1 + u1sina, t[0],
02301 u0u1 * cosa1 + u2sina, u1u1 + cosa * ( 1.0 - u1u1 ), u1u2 * cosa1 - u0sina, t[1],
02302 u0u2 * cosa1 - u1sina, u1u2 * cosa1 + u0sina, u2u2 + cosa * ( 1.0 - u2u2 ), t[2],
02303 0.0f, 0.0f, 0.0f, 1.0f ) );
02304 }
02305
02306
02307 Mat4 Mat4::fromQuaternion( const Quat & q ){
02308 Mat4 r;
02309 Mat3 m3( q.toMat3() );
02310
02311 r.setIdentity();
02312
02313 r.m_v[0] = m3[0];
02314 r.m_v[1] = m3[1];
02315 r.m_v[2] = m3[2];
02316
02317 r.m_v[4] = m3[3];
02318 r.m_v[5] = m3[4];
02319 r.m_v[6] = m3[5];
02320
02321 r.m_v[8] = m3[6];
02322 r.m_v[9] = m3[7];
02323 r.m_v[10] = m3[8];
02324
02325 return( r );
02326 }
02327
02328 Vec4 Mat4::toPolar( void ) const {
02329 Vec2 px = getCol( 0 ).xyz().toPolar();
02330 Vec2 py = getCol( 1 ).xyz().toPolar();
02331 return( Vec4( px[0], px[1], py[0], py[1] ) );
02332 }
02333
02334 Mat4 Mat4::fromPolar( const Vec4 & polar ){
02335 Mat4 m;
02336 m.setCol( 0, Vec4( Vec3( polar.xy() ), 0.0f ) );
02337 m.setCol( 1, Vec4( Vec3( polar.zw() ), 0.0f ) );
02338 m.setCol( 2, Vec4( cross( m.getCol(0).xyz(), m.getCol(1).xyz() ), 0.0f ) );
02339 m.setCol( 3, Vec4( 0, 0, 0, 1 ) );
02340 return( m );
02341 }
02342
02343 Mat4 Mat4::fromPlaneEquation( const Vec4 & equation ){
02344 Mat4 mat;
02345 Vec3 normal = normalize( Vec3( equation[0], equation[1], equation[2] ) );
02346 Mat4 dirMat = fromDirectionalAxis( normal, 'z' );
02347 mat.setCol( 0, dirMat.getCol(0) );
02348 mat.setCol( 1, dirMat.getCol(1) );
02349 mat.setCol( 2, dirMat.getCol(2) );
02350 mat.setCol( 3, Vec4( normal * equation[3], 1.0f ) );
02351 return( mat );
02352 }
02353
02354 Mat4 Mat4::fromDirectionalAxis( const Vec3 & axis, char principalAxis ){
02355 Mat4 mat;
02356 if( length( axis ) < 0.00001f ){
02357
02358 mat.setIdentity();
02359 return( mat );
02360 }
02361
02362 Vec3 x = normalize( axis );
02363
02364 Vec3 y( -x[1], x[0], 0.0f );
02365
02366 Vec3 z = cross( x, y );
02367
02368 if( length( z ) < 0.000001f ){
02369
02370 y = Vec3( 0.0f, 1.0f, 0.0f );
02371
02372 z = cross( x, y );
02373 }
02374
02375
02376 switch( principalAxis ){
02377 case 'x':
02378
02379 mat.setCol( 0, Vec4( normalize( x ), 0.0f ) );
02380 mat.setCol( 1, Vec4( normalize( y ), 0.0f ) );
02381 mat.setCol( 2, Vec4( normalize( z ), 0.0f ) );
02382 break;
02383 case 'y':
02384
02385 mat.setCol( 0, Vec4( -normalize( y ), 0.0f ) );
02386 mat.setCol( 1, Vec4( normalize( x ), 0.0f ) );
02387 mat.setCol( 2, Vec4( normalize( z ), 0.0f ) );
02388 break;
02389 case 'z':
02390
02391 mat.setCol( 0, Vec4( -normalize( z ), 0.0f ) );
02392 mat.setCol( 1, Vec4( normalize( y ), 0.0f ) );
02393 mat.setCol( 2, Vec4( normalize( x ), 0.0f ) );
02394 break;
02395 }
02396 return( mat );
02397 }
02398
02399 Mat4 Mat4::fromIdentity(){
02400 Mat4 m;
02401 m.setIdentity();
02402 return( m );
02403 }
02404
02405 Mat4 Mat4::fromOrtho( float left, float right, float bottom, float top, float zNear, float zFar ){
02406 Mat4 m;
02407 m.ortho( left, right, bottom, top, zNear, zFar );
02408 return( m );
02409 }
02410
02411 Mat4 Mat4::fromFrustum( float left, float right, float bottom, float top, float zNear, float zFar ){
02412 Mat4 m;
02413 m.frustum( left, right, bottom, top, zNear, zFar );
02414 return( m );
02415 }
02416
02417 Mat4 Mat4::fromPerspective( float fovy, float aspect, float zNear, float zFar ){
02418 Mat4 m;
02419 m.perspective( fovy, aspect, zNear, zFar );
02420 return( m );
02421 }
02422
02423 Mat4 Mat4::fromLookAt( const Vec3 & eye, const Vec3 & center, const Vec3 & up ){
02424 Mat4 m;
02425 m.lookAt( eye, center, up );
02426 return( m );
02427 }
02428
02429 void Mat4::ortho( float left, float right, float bottom, float top, float zNear, float zFar ){
02430 m_v[0] = 2.0f / ( right - left );
02431 m_v[1] = 0.0f;
02432 m_v[2] = 0.0f;
02433 m_v[3] = 0.0f;
02434 m_v[4] = 0.0f;
02435 m_v[5] = 2.0f / ( top - bottom );
02436 m_v[6] = 0.0f;
02437 m_v[7] = 0.0f;
02438 m_v[8] = 0.0f;
02439 m_v[9] = 0.0f;
02440 m_v[10] = -2.0f / ( zFar - zNear );
02441 m_v[11] = 0.0f;
02442 m_v[12] = ( -right - left ) / ( right - left );
02443 m_v[13] = ( -top - bottom ) / ( top - bottom );
02444 m_v[14] = ( -zFar - zNear ) / ( zFar - zNear );
02445 m_v[15] = 1.0f;
02446 }
02447
02448 void Mat4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ){
02449 m_v[0] = ( 2.0f * zNear ) / ( right - left );
02450 m_v[1] = 0.0f;
02451 m_v[2] = 0.0f;
02452 m_v[3] = 0.0f;
02453 m_v[4] = 0.0f;
02454 m_v[5] = ( 2.0f * zNear ) / ( top - bottom );
02455 m_v[6] = 0.0f;
02456 m_v[7] = 0.0f;
02457 m_v[8] = ( right + left) / ( right - left );
02458 m_v[9] = ( top + bottom) / ( top - bottom );
02459 m_v[10] = ( -zFar - zNear ) / ( zFar - zNear );
02460 m_v[11] = -1.0f;
02461 m_v[12] = 0.0f;
02462 m_v[13] = 0.0f;
02463 m_v[14] = ( -2.0f * zFar * zNear ) / ( zFar - zNear );
02464 m_v[15] = 0.0f;
02465 }
02466
02467 void Mat4::perspective( float fovy, float aspect, float zNear, float zFar ){
02468 float range = tan( toRadians( fovy / 2.0f ) ) * zNear;
02469 float left = -range * aspect;
02470 float right = range * aspect;
02471 float bottom = -range;
02472 float top = range;
02473
02474 frustum( left, right, bottom, top, zNear, zFar );
02475 }
02476
02477 void Mat4::lookAt( const Vec3 & eye, const Vec3 & center, const Vec3 & up ){
02478 Mat4 m;
02479 Vec3 forward, side;
02480
02481 forward = center - eye;
02482 forward.normalize();
02483
02484 side = cross( forward, up );
02485 side.normalize();
02486
02487 m[0] = side[0];
02488 m[4] = side[1];
02489 m[8] = side[2];
02490
02491 m[1] = up[0];
02492 m[5] = up[1];
02493 m[9] = up[2];
02494
02495 m[2] = -forward[0];
02496 m[6] = -forward[1];
02497 m[10] = -forward[2];
02498
02499 ( * this ) *= m;
02500
02501 translate( -eye );
02502 }
02503
02504 namespace Matrix{
02505
02506 vector< Mat4 > stack[3];
02507
02509 #ifndef RT_AS3
02510 # ifndef RT_GLES1
02511 void _setMatrixUniform( void ){
02512 ProgramPtr program = Program::getCurrent();
02513 PropertyPtr u = PropertyPtr();
02514 if( program ){
02515 program->bind( "modelViewMatrix", toString( get( MODELVIEW ) ) );
02516 program->bind( "projectionMatrix", toString( get( PROJECTION ) ) );
02517 program->bind( "modelViewProjectionMatrix", toString( get( PROJECTION ) * get( MODELVIEW ) ) );
02518 }
02519 }
02520 # else
02521 void _setMatrixUniform( void ){}
02522 # endif
02523
02526 # ifndef RT_GLES2
02527 void _matrixMode( Mode mode ){
02528 switch( mode ){
02529 case MODELVIEW:
02530 glMatrixMode( GL_MODELVIEW );
02531 break;
02532 case PROJECTION:
02533 glMatrixMode( GL_PROJECTION );
02534 break;
02535 case TEXTURE:
02536 glMatrixMode( GL_TEXTURE );
02537 break;
02538 }
02539 }
02540 void _pushMatrix( void ){ glPushMatrix( ); }
02541 void _popMatrix( void ){ glPopMatrix( ); }
02542 void _loadMatrix( const GLfloat * p ){ glLoadMatrixf( p ); }
02543 # else
02544 void _matrixMode( Mode mode ){}
02545 void _pushMatrix( void ){}
02546 void _popMatrix( void ){}
02547 void _loadMatrix( const GLfloat * p ){}
02548 # endif
02549 #else // if RT_AS3 TODO: make connection with Actionscript runtime
02550 void _setMatrixUniform( void ){}
02551 void _matrixMode( Mode mode ){}
02552 void _pushMatrix( void ){}
02553 void _popMatrix( void ){}
02554 void _loadMatrix( const float * p ){}
02555 #endif // RT_AS3
02556
02557 void initialize(){
02559 stack[PROJECTION].clear();
02560 stack[MODELVIEW].clear();
02561 stack[TEXTURE].clear();
02562 stack[PROJECTION].push_back( Mat4::fromIdentity() );
02563 stack[MODELVIEW].push_back( Mat4::fromIdentity() );
02564 stack[TEXTURE].push_back( Mat4::fromIdentity() );
02565 #ifndef RT_AS3
02566 if( RenderTools::isGLInitialized() ){
02567 _matrixMode( PROJECTION );
02568 _pushMatrix();
02569 _loadMatrix( * stack[PROJECTION][0] );
02570 _matrixMode( MODELVIEW );
02571 _pushMatrix();
02572 _loadMatrix( * stack[MODELVIEW][0] );
02573 _matrixMode( TEXTURE );
02574 _pushMatrix();
02575 _loadMatrix( * stack[TEXTURE][0] );
02576 _setMatrixUniform();
02577 }
02578 #endif
02579 }
02580
02581 const Mat4 & get( Mode mode ){
02582 if( stack[ mode ].size() ){
02583 return( stack[ mode ][ stack[ mode ].size() - 1 ] );
02584 }
02585 else{
02586 Error::error( Error::STACK_UNDERFLOW, __FILE__, __LINE__ );
02587 static const Mat4 r = Mat4::fromIdentity();
02588 return( r );
02589 }
02590 }
02591
02592 void set( Mode mode, const Mat4 & m ){
02593 if( stack[ mode ].size() ){
02594 stack[ mode ][ stack[ mode ].size() - 1 ] = m;
02595 #ifndef RT_AS3
02596 if( RenderTools::isGLInitialized() ){
02598 _matrixMode( mode );
02600 _loadMatrix( * m );
02602 _setMatrixUniform();
02603 }
02604 #endif
02605 }
02606 else{
02607 Error::error( Error::STACK_UNDERFLOW, __FILE__, __LINE__ );
02608 }
02609 }
02610
02611 void push( Mode mode, const Mat4 & m ){
02613 stack[ mode ].push_back( m );
02614 #ifndef RT_AS3
02615 if( RenderTools::isGLInitialized() ){
02617 _matrixMode( mode );
02619 _pushMatrix();
02621 _loadMatrix( * m );
02623 _setMatrixUniform();
02624 }
02625 #endif
02626 }
02627
02628 void push( Mode mode ){
02629 if( stack[ mode ].size() ){
02631 stack[ mode ].push_back( stack[ mode ][ stack[ mode ].size() - 1 ] );
02632 }
02633 else{
02635 stack[ mode ].push_back( Mat4::fromIdentity() );
02636 }
02637 #ifndef RT_AS3
02638 if( RenderTools::isGLInitialized() ){
02640 _matrixMode( mode );
02642 _pushMatrix();
02644 _setMatrixUniform();
02645 }
02646 #endif
02647 }
02648
02649 Mat4 pop( Mode mode ){
02650 if( stack[ mode ].size() == 1 ){
02651 Error::warning( Error::INVALID_VALUE, __FILE__, __LINE__, "cannot pop the matrix stack beyond size 1" );
02652 }
02653 else if( stack[ mode ].size() ){
02654 const Mat4 & m = stack[ mode ][ stack[ mode ].size() - 1 ];
02656 stack[ mode ].pop_back();
02657 #ifndef RT_AS3
02658 if( RenderTools::isGLInitialized() ){
02660 _matrixMode( mode );
02662 _popMatrix();
02664 _setMatrixUniform();
02665 }
02666 #endif
02668 return( m );
02669 }
02670 else{
02671 Error::error( Error::STACK_UNDERFLOW, __FILE__, __LINE__ );
02672 }
02673 return( Mat4() );
02674 }
02675
02676 Vec3 project( const Vec3 & object, const Vec4 & viewport ){
02677 Vec4 tmp( object, 1.0f );
02678 tmp = get( MODELVIEW ) * tmp;
02679 tmp = get( PROJECTION ) * tmp;
02680
02681 tmp /= tmp[3];
02682 tmp = tmp * 0.5f + Vec4( 0.5f );
02683 tmp[0] = tmp[0] * viewport[2] + viewport[0];
02684 tmp[1] = tmp[1] * viewport[3] + viewport[1];
02685
02686 return( tmp.xyz() );
02687 }
02688
02689 Vec3 unProject( const Vec3 & window, const Vec4 & viewport ){
02690 Mat4 inverse = ( get( PROJECTION ) * get( MODELVIEW ) ).inverse();
02691
02692 Vec4 tmp( window, 1.0f );
02693 tmp[0] = ( tmp[0] - viewport[0] ) / viewport[2];
02694 tmp[1] = ( tmp[1] - viewport[1] ) / viewport[3];
02695 tmp = tmp * 2.0f - Vec4( 1.0f );
02696
02697 Vec4 obj = inverse * tmp;
02698 obj /= obj[3];
02699
02700 return( obj.xyz() );
02701 }
02702
02703 };
02704
02705 };
02706