Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Matrix.h

Go to the documentation of this file.
00001 
00002 /*
00003     TEDDY - General graphics application library
00004     Copyright (C) 1999-2002  Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007         Adapted from
00008 
00009         The Universe Development Kit
00010         Copyright (C) 2000  Sean O'Neil
00011         s_p_oneil@hotmail.com
00012 
00013     This library is free software; you can redistribute it and/or
00014     modify it under the terms of the GNU Lesser General Public
00015     License as published by the Free Software Foundation; either
00016     version 2.1 of the License, or (at your option) any later version.
00017 
00018     This library is distributed in the hope that it will be useful,
00019     but WITHOUT ANY WARRANTY; without even the implied warranty of
00020     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021     Lesser General Public License for more details.
00022 
00023     You should have received a copy of the GNU Lesser General Public
00024     License along with this library; if not, write to the Free Software
00025     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 
00027     $Id: Matrix.h,v 1.7 2002/02/16 12:41:39 tksuoran Exp $
00028 */
00029 
00030 
00031 #ifndef TEDDY__MATHS__MATRIX_H
00032 #define TEDDY__MATHS__MATRIX_H
00033 
00034 
00035 #if defined(_MSC_VER)
00036 # pragma warning(disable:4786)
00037 #endif
00038 
00039 
00040 #include "Teddy/Maths/Vector.h"
00041 #include "Teddy/Maths/Vector4.h"
00042 #include "Teddy/Maths/CrossVector4.h"
00043 #include "Teddy/SysSupport/StdMaths.h"
00044 using namespace Teddy::SysSupport;
00045 
00046 
00047 namespace Teddy {
00048 namespace Maths {
00049 
00050 
00051 class Quaternion;
00052 
00053 
00069 class Matrix {
00070 public:
00071     static const Matrix IDENTITY;
00072     static const Matrix SWAP_XY;
00073     static const Matrix SWAP_XZ;
00074     static const Matrix SWAP_YZ;
00075     static const Matrix MIRROR_X;
00076     static const Matrix MIRROR_Y;
00077     static const Matrix MIRROR_Z;
00078 public:
00079     // This class uses column-major order, as used by OpenGL
00080     // | m[0][0] m[1][0] m[2][0] m[3][0] |
00081     // | m[0][1] m[1][1] m[2][1] m[3][1] | 
00082     // | m[0][2] m[1][2] m[2][2] m[3][2] | 
00083     // | m[0][3] m[1][3] m[2][3] m[3][3] | 
00084     float m[4][4];
00085 
00086     Matrix(){}
00087     Matrix( const float       f  ){ *this = f;  }
00088     Matrix( const float      *pf ){ *this = pf; }
00089     Matrix( const Quaternion &q  ){ *this = q;  }
00090 
00091     // Init functions
00092     void zeroMatrix(){
00093         m[0][0] = m[0][1] = m[0][2] = m[0][3] =
00094         m[1][0] = m[1][1] = m[1][2] = m[1][3] =
00095         m[2][0] = m[2][1] = m[2][2] = m[2][3] =
00096         m[3][0] = m[3][1] = m[3][2] = m[3][3] = 0;
00097     }
00098 
00099            operator     float* ()                                    { return &m[0][0]; }
00100     float &operator            () ( const int i, const int j )       { return m[i][j]; }
00101            operator const float*  ()                           const { return &m[0][0]; }
00102     float  operator            () ( const int i, const int j ) const { return m[i][j]; }
00103 
00104     void operator=( const float k ){
00105         float *f;
00106 
00107         for( f = &m[0][0]; f != (float *)m+16; f++ ){
00108             *f = k;
00109         }
00110     }
00111 
00112     void operator=( const float *pf ){
00113         float *to = &m[0][0];
00114 
00115         for( register int i=0; i<16; i++ ){
00116             to[i] = pf[i];
00117         }
00118     }
00119 
00120     void   operator=( const Quaternion &q );
00121 
00122     Matrix operator-() const {
00123         Matrix       mat;
00124         const float *from = &    m[0][0];
00125         float       *to   = &mat.m[0][0];
00126 
00127         for( register int i=0; i<16; i++ ){
00128             to[i] = -from[i];
00129         }
00130         return mat;
00131     }
00132 
00133           Matrix   operator* ( const Matrix  &mat ) const;
00134     const Matrix  &operator*=( const Matrix  &mat ){ *this = *this * mat; return *this; }
00135           Vector   operator* ( const Vector  &vec ) const { return transformVector (vec); }
00136           Vector4  operator* ( const Vector4 &vec ) const { return transformVector4(vec); }
00137 
00138     Vector transformVector( const Vector &vec ) const {
00139         // 9 muls, 9 adds
00140         // | m[0][0] m[1][0] m[2][0] m[3][0] |   | v.v[0] |   | m[0][0]*v.v[0]+m[1][0]*v.v[1]+m[2][0]*v.v[2]+m[3][0] |
00141         // | m[0][1] m[1][1] m[2][1] m[3][1] |   | v.v[1] |   | m[0][1]*v.v[0]+m[1][1]*v.v[1]+m[2][1]*v.v[2]+m[3][1] |
00142         // | m[0][2] m[1][2] m[2][2] m[3][2] | * | v.v[2] | = | m[0][2]*v.v[0]+m[1][2]*v.v[1]+m[2][2]*v.v[2]+m[3][2] |
00143         // | 0   0   0   1   |   | 1   |   | 1                           |
00144         return Vector(
00145             (m[0][0]*vec.v[0] + m[1][0]*vec.v[1] + m[2][0]*vec.v[2] + m[3][0]),
00146             (m[0][1]*vec.v[0] + m[1][1]*vec.v[1] + m[2][1]*vec.v[2] + m[3][1]),
00147             (m[0][2]*vec.v[0] + m[1][2]*vec.v[1] + m[2][2]*vec.v[2] + m[3][2])
00148         );
00149     }
00150     Vector4 transformVector4( const Vector4 &vec ) const {
00151         return Vector4(
00152             (m[0][0]*vec.v[0] + m[1][0]*vec.v[1] + m[2][0]*vec.v[2] + m[3][0]*vec.v[3]),
00153             (m[0][1]*vec.v[0] + m[1][1]*vec.v[1] + m[2][1]*vec.v[2] + m[3][1]*vec.v[3]),
00154             (m[0][2]*vec.v[0] + m[1][2]*vec.v[1] + m[2][2]*vec.v[2] + m[3][2]*vec.v[3]),
00155             (m[0][3]*vec.v[0] + m[1][3]*vec.v[1] + m[2][3]*vec.v[2] + m[3][3]*vec.v[3])
00156         );
00157     }
00158 
00159     Vector4 getRow    ( const int i                   ) const { return Vector4( m[i][0], m[i][1], m[i][2], m[i][3] ); }
00160     Vector4 getColumn ( const int i                   ) const { return Vector4( m[0][i], m[1][i], m[2][i], m[3][i] ); }
00161     void    setRow    ( const int i, const Vector4 &v )       { m[i][0] = (float)v[0]; m[i][1] = (float)v[1]; m[i][2] = (float)v[2]; m[i][3] = (float)v[3]; }
00162     void    setColumn ( const int i, const Vector4 &v )       { m[0][i] = (float)v[0]; m[1][i] = (float)v[1]; m[2][i] = (float)v[2]; m[3][i] = (float)v[3]; }
00163     Vector  get3Row   ( const int i                   ) const { return Vector ( m[i][0], m[i][1], m[i][2] ); }
00164     Vector  get3Column( const int i                   ) const { return Vector ( m[0][i], m[1][i], m[2][i] ); }
00165     void    set3Row   ( const int i, const Vector  &v )       { m[i][0] = (float)v[0]; m[i][1] = (float)v[1]; m[i][2] = (float)v[2]; }
00166     void    set3Column( const int i, const Vector  &v )       { m[0][i] = (float)v[0]; m[1][i] = (float)v[1]; m[2][i] = (float)v[2]; }
00167 
00169     Vector uniformTransformNormal( const Vector &vec ) const {
00170         // 9 muls, 6 adds
00171         // | m[0][0] m[1][0] m[2][0] m[3][0] |   | v.v[0] |   | m[0][0]*v.v[0]+m[1][0]*v.v[1]+m[2][0]*v.v[2] |
00172         // | m[0][1] m[1][1] m[2][1] m[3][1] |   | v.v[1] |   | m[0][1]*v.v[0]+m[1][1]*v.v[1]+m[2][1]*v.v[2] |
00173         // | m[0][2] m[1][2] m[2][2] m[3][2] | * | v.v[2] | = | m[0][2]*v.v[0]+m[1][2]*v.v[1]+m[2][2]*v.v[2] |
00174         // | 0   0   0   1   |   | 1   |   | 1                       |
00175         return Vector(
00176             (m[0][0]*vec.v[0] + m[1][0]*vec.v[1] + m[2][0]*vec.v[2] ),
00177             (m[0][1]*vec.v[0] + m[1][1]*vec.v[1] + m[2][1]*vec.v[2] ),
00178             (m[0][2]*vec.v[0] + m[1][2]*vec.v[1] + m[2][2]*vec.v[2] )
00179         );
00180     }
00181 
00182     void modelMatrix( const Quaternion &q, const Vector &vFrom ){
00183         *this = q;
00184         m[3][0] = (float)vFrom.v[0];
00185         m[3][1] = (float)vFrom.v[1];
00186         m[3][2] = (float)vFrom.v[2];
00187     }
00188 
00189     void translateMatrix( const TVector<double> &v ){
00190         // | 1  0  0  x |
00191         // | 0  1  0  y |
00192         // | 0  0  1  z |
00193         // | 0  0  0  1 |
00194         m[0][1] = m[0][2] = m[0][3] =
00195         m[1][0] = m[1][2] = m[1][3] =
00196         m[2][0] = m[2][1] = m[2][3] = 0;
00197         m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
00198         m[3][0] = (float)v[0]; 
00199         m[3][1] = (float)v[1]; 
00200         m[3][2] = (float)v[2]; 
00201     }
00202 
00203     void translateMatrix( const Vector &v ){
00204         // | 1  0  0  x |
00205         // | 0  1  0  y |
00206         // | 0  0  1  z |
00207         // | 0  0  0  1 |
00208         m[0][1] = m[0][2] = m[0][3] =
00209         m[1][0] = m[1][2] = m[1][3] =
00210         m[2][0] = m[2][1] = m[2][3] = 0;
00211         m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
00212         m[3][0] = (float)v[0]; 
00213         m[3][1] = (float)v[1]; 
00214         m[3][2] = (float)v[2]; 
00215     }
00216 
00217     // Translate functions
00218     void translateMatrix( const float x, const float y, const float z ){
00219         // | 1  0  0  x |
00220         // | 0  1  0  y |
00221         // | 0  0  1  z |
00222         // | 0  0  0  1 |
00223         m[0][1] = m[0][2] = m[0][3] =
00224         m[1][0] = m[1][2] = m[1][3] =
00225         m[2][0] = m[2][1] = m[2][3] = 0;
00226         m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
00227         m[3][0] = x; 
00228         m[3][1] = y; 
00229         m[3][2] = z;
00230     }
00231 
00232     //void translateMatrix( const float *pf ){ translateMatrix( pf[0], pf[1], pf[2] ); }
00233 
00234     void translate( const float x, const float y, const float z ){
00235         // 9 muls, 9 adds
00236         // | m[0][0] m[1][0] m[2][0] m[3][0] |   | 1  0  0  x |   | m[0][0] m[1][0] m[2][0] m[0][0]*x+m[1][0]*y+m[2][0]*z+m[3][0] |
00237         // | m[0][1] m[1][1] m[2][1] m[3][1] |   | 0  1  0  y |   | m[0][1] m[1][1] m[2][1] m[0][1]*x+m[1][1]*y+m[2][1]*z+m[3][1] |
00238         // | m[0][2] m[1][2] m[2][2] m[3][2] | * | 0  0  1  z | = | m[0][2] m[1][2] m[2][2] m[0][2]*x+m[1][2]*y+m[2][2]*z+m[3][2] |
00239         // | 0   0   0   1   |   | 0  0  0  1 |   | 0   0   0   1                     |
00240         m[3][0] = m[0][0]*x + m[1][0]*y + m[2][0]*z + m[3][0];
00241         m[3][1] = m[0][1]*x + m[1][1]*y + m[2][1]*z + m[3][1];
00242         m[3][2] = m[0][2]*x + m[1][2]*y + m[2][2]*z + m[3][2];
00243     }
00244 
00245     void translate( const float *pf ){
00246         translate( pf[0], pf[1], pf[2] );
00247     }
00248 
00249     // Scale functions
00250     void scaleMatrix( const float x, const float y, const float z ){
00251         // | x  0  0  0 |
00252         // | 0  y  0  0 |
00253         // | 0  0  z  0 |
00254         // | 0  0  0  1 |
00255         m[0][1] = m[0][2] = m[0][3] =
00256         m[1][0] = m[1][2] = m[1][3] =
00257         m[2][0] = m[2][1] = m[2][3] =
00258         m[3][0] = m[3][1] = m[3][2] = 0;
00259         m[0][0] = x;
00260         m[1][1] = y;
00261         m[2][2] = z;
00262         m[3][3] = 1;
00263     }
00264 
00265     void scaleMatrix( const float *pf ){
00266         scaleMatrix( pf[0], pf[1], pf[2] );
00267     }
00268 
00269     void scale( const float x, const float y, const float z ){
00270         // 9 muls
00271         // | m[0][0] m[1][0] m[2][0] m[3][0] |   | x  0  0  0 |   | m[0][0]*x m[1][0]*y m[2][0]*z m[3][0] |
00272         // | m[0][1] m[1][1] m[2][1] m[3][1] |   | 0  y  0  0 |   | m[0][1]*x m[1][1]*y m[2][1]*z m[3][1] |
00273         // | m[0][2] m[1][2] m[2][2] m[3][2] | * | 0  0  z  0 | = | m[0][2]*x m[1][2]*y m[2][2]*z m[3][2] |
00274         // | 0   0   0   1   |   | 0  0  0  1 |   | 0     0     0     1   |
00275         m[0][0] *= x; m[1][0] *= y; m[2][0] *= z;
00276         m[0][1] *= x; m[1][1] *= y; m[2][1] *= z;
00277         m[0][2] *= x; m[1][2] *= y; m[2][2] *= z;
00278     }
00279 
00280     void scale( const float *pf ){
00281         scale( pf[0], pf[1], pf[2] );
00282     }
00283 
00284     // Rotate functions
00285     void rotateXMatrix( const float radians ){
00286         // | 1 0    0     0 |
00287         // | 0 fCos -fSin 0 |
00288         // | 0 fSin fCos  0 |
00289         // | 0 0    0     1 |
00290         m[0][1] = m[0][2] = m[0][3] = 
00291         m[1][0] = m[1][3] =
00292         m[2][0] = m[2][3] =
00293         m[3][0] = m[3][1] = m[3][2] = 0;
00294         m[0][0] = m[3][3] = 1;
00295 
00296         float fCos = cosf( radians );
00297         float fSin = sinf( radians );
00298         m[1][1] = m[2][2] = fCos;
00299         m[1][2] =  fSin;
00300         m[2][1] = -fSin;
00301     }
00302 
00303     void rotateX( const float radians ){
00304         // 12 muls, 6 adds, 2 trig function calls
00305         // | m[0][0] m[1][0] m[2][0] m[3][0] |   | 1 0    0     0 |   | m[0][0] m[1][0]*fCos+m[2][0]*fSin m[2][0]*fCos-m[1][0]*fSin m[3][0] |
00306         // | m[0][1] m[1][1] m[2][1] m[3][1] |   | 0 fCos -fSin 0 |   | m[0][1] m[1][1]*fCos+m[2][1]*fSin m[2][1]*fCos-m[1][1]*fSin m[3][1] |
00307         // | m[0][2] m[1][2] m[2][2] m[3][2] | * | 0 fSin fCos  0 | = | m[0][2] m[1][2]*fCos+m[2][2]*fSin m[2][2]*fCos-m[1][2]*fSin m[3][2] |
00308         // | 0   0   0   1   |   | 0 0    0     1 |   | 0   0                 0                 1   |
00309         float fTemp;
00310         float fCos = cosf( radians );
00311         float fSin = sinf( radians );
00312 
00313         fTemp   = m[1][0]*fCos + m[2][0]*fSin;
00314         m[2][0] = m[2][0]*fCos - m[1][0]*fSin;
00315         m[1][0] = fTemp;
00316         fTemp   = m[1][1]*fCos + m[2][1]*fSin;
00317         m[2][1] = m[2][1]*fCos - m[1][1]*fSin;
00318         m[1][1] = fTemp;
00319         fTemp   = m[1][2]*fCos + m[2][2]*fSin;
00320         m[2][2] = m[2][2]*fCos - m[1][2]*fSin;
00321         m[1][2] = fTemp;
00322     }
00323 
00324     void rotateYMatrix( const float radians ){
00325         // | fCos  0 fSin  0 |
00326         // | 0     1 0     0 |
00327         // | -fSin 0 fCos  0 |
00328         // | 0     0 0     1 |
00329         m[0][1] = m[0][3] = 
00330         m[1][0] = m[1][2] = m[1][3] = 
00331         m[2][1] = m[2][3] = 
00332         m[3][0] = m[3][1] = m[3][2] = 0;
00333         m[1][1] = m[3][3] = 1;
00334 
00335         float fCos = cosf( radians );
00336         float fSin = sinf( radians );
00337         m[0][0] = m[2][2] = fCos;
00338         m[0][2] = -fSin;
00339         m[2][0] =  fSin;
00340     }
00341     void rotateY( const float radians ){
00342         // 12 muls, 6 adds, 2 trig function calls
00343         // | m[0][0] m[1][0] m[2][0] m[3][0] |   | fCos  0 fSin  0 |   | m[0][0]*fCos-m[2][0]*fSin m[1][0] m[0][0]*fSin+m[2][0]*fCos m[3][0] |
00344         // | m[0][1] m[1][1] m[2][1] m[3][1] |   | 0     1 0     0 |   | m[0][1]*fCos-m[2][1]*fSin m[1][1] m[0][1]*fSin+m[2][1]*fCos m[3][1] |
00345         // | m[0][2] m[1][2] m[2][2] m[3][2] | * | -fSin 0 fCos  0 | = | m[0][2]*fCos-m[2][2]*fSin m[1][2] m[0][2]*fSin+m[2][2]*fCos m[3][2] |
00346         // | 0   0   0   1   |   | 0     0 0     1 |   | 0                 0   0                 1   |
00347         float fTemp;
00348         float fCos = cosf( radians );
00349         float fSin = sinf( radians );
00350         fTemp   = m[0][0]*fCos - m[2][0]*fSin;
00351         m[2][0] = m[0][0]*fSin + m[2][0]*fCos;
00352         m[0][0] = fTemp;
00353         fTemp   = m[0][1]*fCos - m[2][1]*fSin;
00354         m[2][1] = m[0][1]*fSin + m[2][1]*fCos;
00355         m[0][1] = fTemp;
00356         fTemp   = m[0][2]*fCos - m[2][2]*fSin;
00357         m[2][2] = m[0][2]*fSin + m[2][2]*fCos;
00358         m[0][2] = fTemp;
00359     }
00360     void rotateZMatrix( const float radians ){
00361         // | fCos -fSin 0 0 |
00362         // | fSin fCos  0 0 |
00363         // | 0    0     1 0 |
00364         // | 0    0     0 1 |
00365         m[0][2] = m[0][3] =
00366         m[1][2] = m[1][3] =
00367         m[2][0] = m[2][1] = m[2][3] =
00368         m[3][0] = m[3][1] = m[3][2] = 0;
00369         m[2][2] = m[3][3] = 1;
00370 
00371         float fCos = cosf( radians );
00372         float fSin = sinf( radians );
00373         m[0][0] = m[1][1] = fCos;
00374         m[0][1] =  fSin;
00375         m[1][0] = -fSin;
00376     }
00377 
00378     void rotateZ( const float radians ){
00379         // 12 muls, 6 adds, 2 trig function calls
00380         // | m[0][0] m[1][0] m[2][0] m[3][0] |   | fCos -fSin 0 0 |   | m[0][0]*fCos+m[1][0]*fSin m[1][0]*fCos-m[0][0]*fSin m[2][0] m[3][0] |
00381         // | m[0][1] m[1][1] m[2][1] m[3][1] |   | fSin fCos  0 0 |   | m[0][1]*fCos+m[1][1]*fSin m[1][1]*fCos-m[0][1]*fSin m[2][1] m[3][1] |
00382         // | m[0][2] m[1][2] m[2][2] m[3][2] | * | 0    0     1 0 | = | m[0][2]*fCos+m[1][2]*fSin m[1][2]*fCos-m[0][2]*fSin m[2][2] m[3][2] |
00383         // | 0   0   0   1   |   | 0    0     0 1 |   | 0                 0                 0   1   |
00384         float fTemp;
00385         float fCos = cosf( radians );
00386         float fSin = sinf( radians );
00387         fTemp   = m[0][0]*fCos + m[1][0]*fSin;
00388         m[1][0] = m[1][0]*fCos - m[0][0]*fSin;
00389         m[0][0] = fTemp;
00390         fTemp   = m[0][1]*fCos + m[1][1]*fSin;
00391         m[1][1] = m[1][1]*fCos - m[0][1]*fSin;
00392         m[0][1] = fTemp;
00393         fTemp   = m[0][2]*fCos + m[1][2]*fSin;
00394         m[1][2] = m[1][2]*fCos - m[0][2]*fSin;
00395         m[0][2] = fTemp;
00396     }
00397 
00398     void rotateMatrix( const Vector &vec, const double radians ){
00399         // 15 muls, 10 adds, 2 trig function calls
00400         float  fCos = (float)cos( radians );
00401         Vector vCos = vec * (1 - fCos);
00402         Vector vSin = vec * (float)sin( radians );
00403 
00404         m[0][3] = 
00405         m[1][3] = 
00406         m[2][3] = 
00407         m[3][0] = m[3][1] = m[3][2] = 0;
00408         m[3][3] = 1;
00409 
00410         m[0][0] = (float)((vec.v[0] * vCos.v[0]) + fCos);
00411         m[1][0] = (float)((vec.v[0] * vCos.v[1]) - (vSin.v[2]));
00412         m[2][0] = (float)((vec.v[0] * vCos.v[2]) + (vSin.v[1]));
00413         m[0][1] = (float)((vec.v[1] * vCos.v[0]) + (vSin.v[2]));
00414         m[1][1] = (float)((vec.v[1] * vCos.v[1]) + fCos);
00415         m[2][1] = (float)((vec.v[1] * vCos.v[2]) - (vSin.v[0]));
00416         m[0][2] = (float)((vec.v[2] * vCos.v[0]) - (vSin.v[1]));
00417         m[2][1] = (float)((vec.v[2] * vCos.v[1]) + (vSin.v[0]));
00418         m[2][2] = (float)((vec.v[2] * vCos.v[2]) + fCos);
00419     }
00420 
00421     void rotate( const Vector &vec, const double f ){
00422         // 51 muls, 37 adds, 2 trig function calls
00423         Matrix mat;
00424         mat.rotateMatrix( vec, f );
00425         *this *= mat;
00426     }
00427 
00428     void direction( const Vector &vec ){
00429         Vector z = vec;
00430         Vector h;
00431         z.normalize();
00432         if( z[0]< (sqrt(2.0)/2.0) ){
00433             h = Vector(1,0,0);
00434         }else{
00435             h = Vector(0,1,0);
00436         }
00437         Vector x = z ^ h;
00438         Vector y = z ^ x;
00439         x        = z ^ y;
00440         //x.normalize();
00441         //y.normalize();
00442         //z.normalize();
00443         setRow( 0, Vector4(x,0)     );
00444         setRow( 1, Vector4(y,0)     );
00445         setRow( 2, Vector4(z,0)     );
00446         setRow( 3, Vector4(0,0,0,1) );
00447     }
00448 
00449     bool invert(){
00450         Vector4 x  = getColumn( 0 );
00451         Vector4 y  = getColumn( 1 );
00452         Vector4 z  = getColumn( 2 );
00453         Vector4 w  = getColumn( 3 );
00454         Vector4 x1 = CrossVector4( y, z, w );
00455         Vector4 y1 = CrossVector4( z, w, x );
00456         Vector4 z1 = CrossVector4( w, x, y );
00457         Vector4 w1 = CrossVector4( x, y, z );
00458         float   lx = x | x1;
00459         float   ly = y | y1;
00460         float   lz = z | z1;
00461         float   lw = w | w1;
00462 
00463         if( !lx || !ly || !lz || !lw ){
00464             return false;
00465         }
00466 
00467         x1 *= 1.0f/lx;
00468         y1 *= 1.0f/ly;
00469         z1 *= 1.0f/lz;
00470         w1 *= 1.0f/lw;
00471 
00472         setRow( 0, x1 );
00473         setRow( 1, y1 );
00474         setRow( 2, z1 );
00475         setRow( 3, w1 );
00476         return true;
00477     }
00478 
00479     // For orthogonal matrices, I belive this also gives you the inverse.
00480     void transpose(){
00481 #       define SWAP(a,b,c) c=a; a=b; b=c
00482         float f;
00483         SWAP(m[0][1], m[1][0], f);
00484         SWAP(m[0][2], m[2][0], f);
00485         SWAP(m[0][3], m[3][0], f);
00486         SWAP(m[1][2], m[2][1], f);
00487         SWAP(m[1][3], m[3][1], f);
00488         SWAP(m[2][3], m[3][2], f);
00489 #       undef SWAP
00490     }
00491 
00492 };
00493 
00494 
00495 };  //  namespace Maths;
00496 };  //  namespace Teddy;
00497 
00498 
00499 #endif  //  TEDDY__MATHS__MATRIX_H
00500