Matrix34.h

Go to the documentation of this file.
00001 // BC  12/24/2003  \Bob110\Include\Matrix34.h
00002 
00003 #ifndef __MATRIX34_H
00004 #define __MATRIX34_H
00005 
00006 #ifndef __MATRIX44_H
00007 #include "Matrix44.h"
00008 #endif
00009 #ifndef __MATRIX33_H
00010 #include "Matrix33.h"
00011 #endif
00012 #ifndef __ROTATE_H
00013 #include "Rotate.h"
00014 #endif
00015 
00016 #ifdef _SIMD
00017 #include "smlmath.h"
00018 #include "smlMatrix34.h"
00019 #endif
00020 
00021 class MATRIXEXPORT Matrix34 {
00022 protected:
00023 #ifdef _SIMD
00024    union {
00025       struct { SMLMatrix34f m_smlmatrix34f; };
00026       struct { Vector4 v[3]; };
00027    };
00028 #else
00029    Vector4 v[3];
00030 #endif
00031 
00032 public:
00033    Matrix34( void ) { SetIdentity(FALSE); }
00034    Matrix34( const Vector4 &, const Vector4 &, const Vector4 & );
00035    Matrix34( const Matrix34 &m );
00036    Matrix34( float fillvalue );
00037    Matrix34( const RotateVector &rotate );
00038    Matrix34( const Quaternion & );
00039    Matrix34( const RotateEuler &re );
00040    Matrix34( const TSQ &tsq );
00041    
00042 #ifdef _SIMD
00043    const SMLMatrix34f &GetSMLMatrix34f() const { return m_smlmatrix34f; }
00044    void  SetIdentity(BOOL state) { m_smlmatrix34f.SetIdentity( state!=FALSE ); }
00045    void InitBottomRow() {
00046       m_smlmatrix34f.Set( 3,0,0 );
00047       m_smlmatrix34f.Set( 3,1,0 );
00048       m_smlmatrix34f.Set( 3,2,0 );
00049       m_smlmatrix34f.Set( 3,3,1 );
00050    }
00051 #else
00052    void  SetIdentity(BOOL state) {}
00053    void InitBottomRow() {}
00054 #endif
00055    Matrix34 &operator *= ( const Matrix34 &other ) { return (*this = *this * other); }
00056 
00057    const Vector4 &operator[]( int row ) const { return v[row]; }
00058    Vector4 &operator[]( int row ) { return v[row]; }
00059    void Set( const Vector4 &a, const Vector4 &b, const Vector4 &c );
00060    void SetIdentity()
00061    {
00062       v[0].Set(1.0f,0.0f,0.0f,0.0f);
00063       v[1].Set(0.0f,1.0f,0.0f,0.0f);
00064       v[2].Set(0.0f,0.0f,1.0f,0.0f);
00065       SetIdentity( TRUE );      
00066    }
00067    Matrix34 Transpose( void ) const;
00068    Matrix34 Inverse( void ) const;
00069    void SetTranslate( const Vector &t );
00070    Vector GetTranslate( void ) const;
00071    Matrix34 NoTranslate( void ) const;
00072    Matrix34 GetScaleMatrix( void ) const;
00073    Vector   GetScaleVector( void ) const;
00074    int operator == ( const Matrix34 &a ) const { return v[0]==a[0] && v[1]==a[1] && v[2]==a[2]; }
00075    int operator != ( const Matrix34 &a ) const { return !(*this == a); }   
00076    Vector GetXAxis() const { return Vector( v[0][0], v[1][0], v[2][0] ); }
00077    Vector GetYAxis() const { return Vector( v[0][1], v[1][1], v[2][1] ); }
00078    Vector GetZAxis() const { return Vector( v[0][2], v[1][2], v[2][2] ); }
00079    Matrix34 operator * ( const Matrix34 & ) const;
00080    Vector operator * ( const Vector & ) const;
00081 
00082    Matrix34 InvertRotateTranslate() const  // THE MATRIX MUST HAVE NO SCALE
00083    {
00084       Matrix34 rotate = Transpose();
00085       rotate.SetTranslate( rotate * -GetTranslate());
00086       return rotate;
00087    }
00088    friend /* inline */ Vector operator * ( const Vector &v, const Matrix34 &m );
00089    friend MATRIXEXPORT Matrix34 Identity34( void );
00090 
00091    // GL MATRIX CREATION FUNCTIONS
00092    friend MATRIXEXPORT Matrix34 Translatef( float x, float y, float z );
00093    friend MATRIXEXPORT Matrix34 TranslateV( const Vector &v );
00094    friend MATRIXEXPORT Matrix34 Scalef( float x, float y, float z );
00095    friend MATRIXEXPORT Matrix34 ScaleV( const Vector &v );
00096    friend MATRIXEXPORT Matrix34 RotateVRadians( float angle, const Vector &axis );
00097    friend MATRIXEXPORT Matrix34 Rotatef( float angle, float x, float y, float z );
00098    friend MATRIXEXPORT Matrix34 Rotate2V( const Vector &from, const Vector &to );
00099    friend MATRIXEXPORT Matrix34 XRotateRadians( float anglerad );
00100    friend MATRIXEXPORT Matrix34 YRotateRadians( float anglerad );
00101    friend MATRIXEXPORT Matrix34 ZRotateRadians( float anglerad );
00102    friend MATRIXEXPORT Matrix34 YXRotateRadians( float yangle, float xangle );
00103    friend MATRIXEXPORT Matrix34 YXZRotateRadians( float yangle, float xangle, float zangle );
00104    friend /* inline */ Matrix34 YXZRotate( float yangle, float xangle, float zangle );
00105    friend MATRIXEXPORT Matrix34 XZYRotate( float xangle, float zangle, float yangle );
00106    friend MATRIXEXPORT Matrix34 VectorsToStandard( const Vector &becomezdir, const Vector &becomeydir );
00107    friend MATRIXEXPORT Matrix34 StandardToVectors( const Vector &newzdir, const Vector &newydir );
00108 
00109    friend /* inline */ Matrix34 RotateV( float angle, const Vector &axis );
00110    friend /* inline */ Matrix34 XRotate( float angle );
00111    friend /* inline */ Matrix34 YRotate( float angle );
00112    friend /* inline */ Matrix34 ZRotate( float angle );
00113    
00114    // CONVERSION FUNCTIONS
00115    friend MATRIXEXPORT Matrix44 ToMatrix44( const Matrix33 &m );
00116    friend MATRIXEXPORT Matrix44 ToMatrix44( const Matrix34 &m );
00117    friend MATRIXEXPORT Matrix33 ToMatrix33( const Matrix34 &m );
00118    friend MATRIXEXPORT Matrix33 ToMatrix33( const Matrix44 &m );
00119    friend MATRIXEXPORT Matrix34 ToMatrix34( const Matrix44 &m );
00120    friend MATRIXEXPORT Matrix34 ToMatrix34( const Matrix33 &m );
00121 
00122    friend MATRIXEXPORT void MatrixTimesScale( Matrix34 &a, const Vector &s );
00123    friend MATRIXEXPORT void ScaleTimesMatrix( const Vector &s, Matrix34 &a );
00124    friend MATRIXEXPORT void TwoVectorsToAxisAngle( const Vector &from, const Vector &to, Vector &axis, float &radangle );
00125    friend MATRIXEXPORT void TransformVectorNoTranslate( const Matrix34 &matrix, Vector &p );
00126    friend /* inline */ Matrix34 CreateEulerMatrix( const Rotate &rotate );
00127    friend /* inline */ void TransformVector( const Matrix34 &matrix, Vector &p );
00128 };
00129 
00130 // inline friend functions
00131 inline Vector operator * ( const Vector &v, const Matrix34 &m )
00132 {
00133     return m * v;
00134 }
00135 inline Matrix34 YXZRotate( float yangle, float xangle, float zangle ) 
00136 {
00137    return YXZRotateRadians( yangle/RADIANS, xangle/RADIANS, zangle/RADIANS ); 
00138 }
00139 inline Matrix34 RotateV( float angle, const Vector &axis )
00140 {
00141    return RotateVRadians( angle / RADIANS, axis ); 
00142 }
00143 inline Matrix34 XRotate( float angle )
00144 {
00145    return XRotateRadians( angle / RADIANS ); 
00146 }
00147 inline Matrix34 YRotate( float angle )
00148 {
00149    return YRotateRadians( angle / RADIANS ); 
00150 }
00151 inline Matrix34 ZRotate( float angle )
00152 {
00153    return ZRotateRadians( angle / RADIANS ); 
00154 }
00155 inline Matrix34 CreateEulerMatrix( const Rotate &rotate )
00156 {
00157    return YXZRotate( -rotate.roll, -rotate.swivel, -rotate.tilt ).Transpose(); 
00158 }
00159 inline void TransformVector( const Matrix34 &matrix, Vector &p ) 
00160 {
00161    p = matrix * p; 
00162 }
00163 
00164 
00165 // regular inlined functions
00166 inline void Matrix34::Set( const Vector4 &v0, const Vector4 &v1, const Vector4 &v2 )
00167 {
00168    v[0] = v0;
00169    v[1] = v1;
00170    v[2] = v2;
00171    InitBottomRow();
00172    SetIdentity(FALSE);
00173 }
00174 
00175 inline Matrix34::Matrix34( const Vector4 &v0, const Vector4 &v1, const Vector4 &v2 )
00176 {
00177    Set( v0, v1, v2 );
00178 }
00179 
00180 inline Matrix34::Matrix34( float fillvalue )
00181 {
00182    v[0] = Vector4( fillvalue );
00183    v[1] = Vector4( fillvalue );
00184    v[2] = Vector4( fillvalue );
00185    SetIdentity( FALSE );
00186 }
00187 
00188 inline Matrix34::Matrix34( const RotateVector &rv )
00189 {
00190    float y = (float)atan2( rv.end.x, rv.end.z );
00191    float x = (float)atan2( -rv.end.y, (float)sqrt(rv.end.x*rv.end.x + rv.end.z*rv.end.z));
00192    if ( rv.roll )
00193       *this = YXZRotateRadians( y, x, rv.roll / RADIANS );
00194    else
00195       *this = YXRotateRadians( y, x );
00196    SetIdentity( FALSE );
00197 }
00198 
00199 inline Matrix34::Matrix34( const RotateEuler &re )
00200 {
00201    *this = YXZRotate( re.y, re.x, re.z );
00202    SetIdentity( FALSE );
00203 }
00204 
00205 inline Matrix34 Identity34( void )
00206 {
00207    static Matrix34 identity34(
00208                     Vector4( 1.f, 0.f, 0.f, 0.f ),
00209                     Vector4( 0.f, 1.f, 0.f, 0.f ),
00210                     Vector4( 0.f, 0.f, 1.f, 0.f ));
00211    identity34.SetIdentity( TRUE );
00212    identity34.InitBottomRow();
00213    return identity34;
00214 }                    
00215 
00216 inline void Matrix34::SetTranslate( const Vector &t )
00217 {
00218    v[0][3] = t.x;
00219    v[1][3] = t.y;
00220    v[2][3] = t.z;
00221    SetIdentity( FALSE );
00222 }
00223 
00224 inline Vector Matrix34::GetTranslate( void ) const
00225 {
00226    return Vector( v[0][3], v[1][3], v[2][3] );
00227 }
00228 
00229 inline Matrix34 Matrix34::NoTranslate( void ) const
00230 {
00231    return Matrix34( Vector4( v[0][0], v[0][1], v[0][2], 0.f ),
00232                     Vector4( v[1][0], v[1][1], v[1][2], 0.f ),
00233                     Vector4( v[2][0], v[2][1], v[2][2], 0.f ));
00234 }
00235 
00236 inline Matrix34 Matrix34::GetScaleMatrix( void ) const
00237 {
00238    return Matrix34((Quaternion(*this).Inverse())) * NoTranslate();
00239 }
00240 
00241 inline Vector Matrix34::GetScaleVector( void ) const
00242 {
00243    Matrix34 scalem = GetScaleMatrix();
00244    return Vector(scalem[0][0], scalem[1][1], scalem[2][2]);
00245 }
00246 
00247 inline Vector &Vector::operator *= ( const Matrix34 &m )
00248 {
00249    *this =  m * *this;
00250    return *this;
00251 }
00252 
00253 // ------------ CONVERSION TO AND FROM OTHER TYPES -------------------
00254 
00255 inline Matrix44 ToMatrix44( const Matrix34 &m )
00256 {
00257    return Matrix44( m[0],
00258                     m[1],
00259                     m[2],
00260            Vector4( 0.f, 0.f, 0.f, 1.f ));
00261 }
00262 
00263 inline Matrix44 ToMatrix44( const Matrix33 &m )
00264 {
00265    return Matrix44(
00266     Vector4( m[0][0], m[0][1], m[0][2], 0.f ),
00267     Vector4( m[1][0], m[1][1], m[1][2], 0.f ),
00268     Vector4( m[2][0], m[2][1], m[2][2], 0.f ),
00269     Vector4( 0.f,     0.f,     0.f,     1.f ));
00270 }
00271 
00272 inline Matrix33 ToMatrix33( const Matrix34 &m )
00273 {
00274    return Matrix33( Vector( m[0][0], m[0][1], m[0][2] ),
00275                     Vector( m[1][0], m[1][1], m[1][2] ),
00276                     Vector( m[2][0], m[2][1], m[2][2] ));
00277 }
00278 
00279 inline Matrix33 ToMatrix33( const Matrix44 &m )
00280 {
00281    return Matrix33( Vector( m[0][0], m[0][1], m[0][2] ),
00282                     Vector( m[1][0], m[1][1], m[1][2] ),
00283                     Vector( m[2][0], m[2][1], m[2][2] ));
00284 }
00285 
00286 inline Matrix34 ToMatrix34( const Matrix44 &m )
00287 {
00288    return Matrix34( m[0],
00289                     m[1],
00290                     m[2] );
00291 }
00292 
00293 inline Matrix34 ToMatrix34( const Matrix33 &m )
00294 {
00295    return Matrix34( Vector4( m[0][0], m[0][1], m[0][2], 0.f ),
00296                     Vector4( m[1][0], m[1][1], m[1][2], 0.f ),
00297                     Vector4( m[2][0], m[2][1], m[2][2], 0.f ));
00298 }
00299 
00300 inline Matrix34 VectorsToStandard( const Vector &becomezdir, const Vector &becomeydir )
00301 {
00302    Matrix34 vectostandard = Rotate2V( becomezdir, Vector( 0.0f, 0.0f, 1.0f ));
00303    Vector   rollvec = vectostandard * becomeydir;
00304    float    roll = (float)atan2( -rollvec.x, rollvec.y );
00305    if ( roll )
00306       vectostandard = ZRotateRadians( -roll ) * vectostandard;
00307    return vectostandard;  // may be faster to just compute like below, but the transpose
00308 }
00309 
00310 inline Matrix34 StandardToVectors( const Vector &newzdir, const Vector &newydir )
00311 {
00312    Vector xdir, ydir, zdir;
00313    ydir = newydir;
00314    ydir.Normalize();
00315    zdir = newzdir;
00316    zdir.Normalize();
00317    xdir = Cross( ydir, zdir );
00318    float xlength = xdir.Norm();
00319    if (xlength!=1.0f) {
00320       xdir /= xlength;
00321       ydir = Cross( zdir, xdir );
00322    }
00323    return Matrix34( Vector4(xdir[0], ydir[0], zdir[0], 0),
00324                     Vector4(xdir[0], ydir[0], zdir[0], 0),
00325                     Vector4(xdir[0], ydir[0], zdir[0], 0));
00326 }
00327 
00328 // -------------------- GL STYLE CREATION FUNCTIONS ----------------------
00329 
00330 inline Matrix34 Translatef( float x, float y, float z )
00331 {
00332    return Matrix34( Vector4( 1.f, 0.f, 0.f, x ),
00333                     Vector4( 0.f, 1.f, 0.f, y ),
00334                     Vector4( 0.f, 0.f, 1.f, z ));
00335 }
00336 
00337 inline Matrix34 TranslateV( const Vector &v )
00338 {
00339    return Translatef( v[0], v[1], v[2] );
00340 }
00341 
00342 inline Matrix34 Scalef( float x, float y, float z )
00343 {
00344    return Matrix34( Vector4(   x, 0.f, 0.f, 0.f ),
00345                     Vector4( 0.f,   y, 0.f, 0.f ),
00346                     Vector4( 0.f, 0.f,   z, 0.f ));
00347 }
00348 
00349 inline Matrix34 ScaleV( const Vector &v )
00350 {
00351    return Scalef( v[0], v[1], v[2] );
00352 }
00353 
00354 inline Matrix34 Rotatef( float angle, float x, float y, float z )
00355 {
00356    return RotateV( angle, Vector( x, y, z ));
00357 }
00358 
00359 inline void TransformVectorNoTranslate( const Matrix34 &m, Vector &v )  // CANDIDATE FOR SML
00360 {
00361    v.Set( m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z, 
00362           m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
00363           m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z );
00364 }
00365 
00366 inline Matrix34 XRotateRadians( float anglerad )
00367 {
00368    float ca = (float)cos( anglerad ),
00369          sa = (float)sin( anglerad );
00370    return Matrix34( Vector4( 1.f, 0.f, 0.f, 0.f ),
00371                     Vector4( 0.f,  ca, -sa, 0.f ),
00372                     Vector4( 0.f,  sa,  ca, 0.f ));
00373 }
00374 
00375 inline Matrix34 YRotateRadians( float anglerad )
00376 {
00377    float ca = (float)cos( anglerad ),
00378          sa = (float)sin( anglerad );
00379    return Matrix34( Vector4(  ca, 0.f,  sa, 0.f ),
00380                     Vector4( 0.f, 1.f, 0.f, 0.f ),
00381                     Vector4( -sa, 0.f,  ca, 0.f ));
00382 }
00383 
00384 inline Matrix34 ZRotateRadians( float anglerad )
00385 {
00386    float ca = (float)cos( anglerad ),
00387          sa = (float)sin( anglerad );
00388    return Matrix34( Vector4(  ca, -sa, 0.f, 0.f ),
00389                     Vector4(  sa,  ca, 0.f, 0.f ),
00390                     Vector4( 0.f, 0.f, 1.f, 0.f ));
00391 }
00392 
00393 // ROTATION CONVERSIONS THAT REQUIRE MATRIX34
00394 
00395 inline RotateVector::RotateVector( const Matrix34 &matrix )
00396 {
00397    end = matrix.GetZAxis();
00398    float y = (float)atan2( end.x, end.z );
00399    float x = (float)atan2( -end.y, (float)sqrt(end.x*end.x + end.z*end.z));
00400    Vector rolldir = matrix.GetYAxis();
00401    rolldir *= YXRotateRadians( y, x ).Transpose();
00402    roll = (float)atan2( -rolldir.x, rolldir.y ) * RADIANS;
00403 }
00404 
00405 inline RotateEuler::RotateEuler( const Matrix34 &matrix )
00406 {
00407    Vector end = matrix.GetZAxis();
00408    y = (float)atan2( end.x, end.z );
00409    x = (float)atan2( -end.y, (float)sqrt(end.x*end.x + end.z*end.z));
00410    Vector rolldir = matrix.GetYAxis();
00411    rolldir *= YXRotateRadians( y, x ).Transpose();
00412    z = (float)atan2( -rolldir.x, rolldir.y ) * RADIANS;
00413    x *= RADIANS;
00414    y *= RADIANS;
00415 }
00416 
00417 #ifdef _SIMD
00418 
00419 inline Matrix34::Matrix34( const Matrix34 &m ) : m_smlmatrix34f( m.m_smlmatrix34f )
00420 {
00421 }
00422 
00423 inline Matrix34 Matrix34::operator * ( const Matrix34 &b ) const 
00424 {
00425    Matrix34 result;
00426    result.m_smlmatrix34f.Multiply(m_smlmatrix34f, b.m_smlmatrix34f);
00427    return result;
00428 }
00429 
00430 inline Vector Matrix34::operator * ( const Vector &v ) const
00431 {
00432    Vector result;
00433    m_smlmatrix34f.TransformPoint( v.m_smlvec3f, result.m_smlvec3f );
00434    return result;
00435 }
00436 
00437 inline Matrix34 Matrix34::Transpose( void ) const
00438 {
00439    Matrix34 temp( *this );
00440    temp.m_smlmatrix34f.Transpose();
00441    temp.InitBottomRow();
00442    return temp;
00443 }
00444 
00445 inline Matrix34 Matrix34::Inverse( void ) const
00446 {
00447    Matrix34 result, source=*this;
00448    result.m_smlmatrix34f.Invert(source.m_smlmatrix34f);  // BUG IN SML, SOURCE SHOULD BE DECLARED CONST
00449    result.InitBottomRow();
00450    return result;
00451 }      
00452 
00453 #else   // not SIMD
00454 
00455 inline Matrix34::Matrix34( const Matrix34 &m )
00456 {
00457    *this = m;
00458 }
00459 
00460 inline Vector Matrix34::operator * ( const Vector &vec ) const
00461 {
00462    return Vector( v[0]|vec, v[1]|vec, v[2]|vec );
00463 }
00464 
00465 inline Matrix34 Matrix34::Transpose( void ) const
00466 {
00467    return Matrix34( Vector4( v[0][0], v[1][0], v[2][0], 0.f ),
00468                     Vector4( v[0][1], v[1][1], v[2][1], 0.f ),
00469                     Vector4( v[0][2], v[1][2], v[2][2], 0.f ));
00470 }
00471 
00472 inline Matrix34 Matrix34::Inverse( void ) const
00473 {
00474    Matrix44 a = ToMatrix44( *this );
00475    return ToMatrix34( a.Inverse() );
00476 }      
00477 
00478 #endif  // not SIMD
00479 
00480 #endif  // __MATRIX34_H

This A:M SDK v12.0 documentation is maintained by Hash Inc. Please address any comments concerning this documentation to AMReports. If you have any information, knowledge, or documentation to share with the A:M developer community, please post them on the Hash SDK forum.

Generated on Thu Oct 27 11:46:44 2005 with doxygen 1.4.5 written by Dimitri van Heesch, © 1997-2001