gee_lwo.hpp

Go to the documentation of this file.
00001 #ifndef __VECTORMATRIX_HPP
00002 #define __VECTORMATRIX_HPP
00003 
00004 //changes history
00005 //[021027 jussi] added vector comparisons with epsilon (uses radius, not component-wise threshold)
00006 //[021004 jussi] added const return values to all functions returning objects
00007 //[030128 jussi] added Matrix2x3 and Matrix3x2 classes
00008 //[030218 jussi] fixed a bug in Matrix2 invert
00009 
00010 // Review History:
00011 // 020726 jan
00012 // 020729 jan
00013 // 020730 jan
00014 // 020731 jan
00015 // \todo [020726 jan] doxygen comments
00016 // \todo [020726 jan] separate .inl file for inline functions
00017 //       -jussi: no, because we want to have as few files as possible for easy ripping
00018 
00019 // \todo [020726 jan] in general, write operator@(a,b) as { return T(a) @= b; }
00020 //                                              - preferred by Stroustrup and Meyers
00021 // jussi: NOT DONE: produces identical code at least on msvc (with optimizations),
00022 //                  + proposed way is unintuitive + forces all member functions to return reference
00023 //                    to *this (for example invert couldn't return a bool anymore)
00024 // jan:                         I will check this out. It's most likely MSVC inliner doing the optimization
00025 //
00026 // \todo [020726 jan] consider private with public accessors for Vectors. Annoying, yes, but you can
00027 //                                              always use operator[]
00028 //                                              - allows data validity checks in debug build
00029 // jussi: NOT DONE: VERY annoying to use, access to Vector.x/y/z is very intuitive and used all the time.
00030 //                  what would be the data validity checks to be performed? check for NAN/INF?
00031 //                                      what is the use of these tests? aren't they dependent on application and thus
00032 //                                      couldn't be generic?
00033 //      jan:                    NAN/DENORMAL/INF should be checked in (paranoid) debug build. Can be asserted in math functions as well.
00034 
00035 //TODO check the code produced by m[][] access (they are used heavily internally)
00036 
00037 //TODO is there a better name for vector::project that indicates which vector is projected on which?
00038 
00039 //TODO should we have defaultMultiplicationOrder and defaultHandedness global variables to cut down
00040 //     the number of parameters the user needs to give?
00041 //  jan: no. #define DEFAULT_HANDEDNESS etc. could be defined prior header #include directive,
00042 //                      but may cause grey hair. if not defined, then define it as you like
00043 
00044 
00045 //TODO add Matrix::skewX,skewY and skewZ?
00046 
00047 //TODO initialize Vectors in debug build to NaN
00048 
00049 
00050 
00051 
00052 
00053 
00054 //MatrixRxC, R = number of rows, C = number of columns
00055 //indexing: matrix[row][column]
00056 
00057 // left multiply : M * columnVector
00058 // right multiply: rowVector * N
00059 // the matrices are related by M = N^T <=> M^T = N              (^T = transpose)
00060 // for left multiply, the columns of the matrix are the basis vectors of the coordinate system
00061 // for right multiply, the rows of the matrix are the basis vectors of the coordinate system
00062 
00063 //matrices formed by RIGHT_MULTIPLY correspond to OpenGL input format (column major order)
00064 //matrices formed by LEFT_MULTIPLY must be transposed before passing them to OpenGL
00065 //in addition to this, OpenGL uses right-handed matrices (z-axis points towards the viewer)
00066 // and our matrices are left-handed (z-axis points away from the viewer). this can be confusing when
00067 // mixing OpenGL matrix operations with ours.
00068 // calculating everything using our matrices (including the projection matrix)
00069 // and passing the result (which is a left handed matrix) directly to OpenGL works.
00070 
00071 //to convert between left and right handed coordinate systems, negate the z-axis (for left multiply
00072 // it is the third column, for right multiply the third row)
00073 
00074 #include <math.h>               //for sqrt, sin and cos
00075 #include <stdlib.h>             //for rand
00076 #include <assert.h>
00077 
00078 namespace VECTORMATRIX  //TODO is this a proper name?
00079 {
00080 
00081 typedef float T;        //TODO is this enough, or do we need to use templates?
00082 
00083 #ifndef ASSERT
00084 #define ASSERT assert
00085 #endif
00086 
00087 inline T                                                RAND()                          { return T(rand()) * T(2) / T(RAND_MAX) - T(1); }       //random number [-1,1], used by VectorFactories
00088 template<class TT> inline TT    OOSQRT( TT a )          { return TT(1) / TT(sqrt(a)); } //used by Vector::normalize
00089 template<class TT> inline TT    SQRT( TT a )            { return TT(sqrt(a)); }                 //used by Vector::length
00090 template<class TT> inline TT    SQR( TT a )                     { return a*a; }                                 //used by vector isEqual
00091 template<class TT> inline TT    ABS( TT a )                     { return (a < TT(0)) ? -a : a; }//used by VectorFactory::perpendicular
00092 template<class TT> inline TT    SIN( TT a )                     { return TT(sin(double(a))); }  //used by Matrix::rotate
00093 template<class TT> inline TT    COS( TT a )                     { return TT(cos(double(a))); }  //used by Matrix::rotate
00094 template<class TT> inline TT    TAN( TT a )                     { return TT(tan(double(a))); }  //used by MatrixFactory::frustum, frustum01
00095 template<class TT> inline void  SWAP( TT &a, TT &b ){ TT tmp = a; a = b; b = tmp; }     //used by Matrix::transpose
00096 
00097 enum MultiplicationOrder
00098 {
00099         LEFT_MULTIPLY,          //for column vectors to be multiplied from the left
00100         RIGHT_MULTIPLY          //for row vectors to be multiplied from the right
00101 };
00102 
00103 class Matrix2;
00104 class Matrix3;
00105 class Matrix4;
00106 class Matrix2x3;        //2 rows, 3 columns, for column vector transformations with implied 3rd row [0,0,1]
00107 class Matrix3x2;        //3 rows, 2 columns, for row vector transformations with implied 3rd column [0,0,1]
00108 class Matrix3x4;        //3 rows, 4 columns, for column vector transformations with implied 4th row [0,0,0,1]
00109 class Matrix4x3;        //4 rows, 3 columns, for row vector transformations with implied 4th column [0,0,0,1]
00110 
00111 class Vector2;
00112 class Vector3;
00113 class Vector4;
00114 
00115 /*
00116 design principles:
00117 --------------------------------------------------------------------------
00118 -orthogonal set of functions
00119  *except not all combinations of vector * matrix and matrix * matrix are present since these are mostly
00120    useless
00121  *except Matrix3x4 does not have right multiply since in practice it is used for left multiply matrices
00122    only. the same applies for Matrix4x3
00123  *different types of matrices can be multiplied through the use of constructors and explicit conversion
00124    functions
00125 
00126 -follows mathematical notation
00127  *the order of multiplications was considered important. for example Matrix3x4, which has only left
00128    multiply, does not have operator*=
00129 
00130 -allows row vectors with matrix multiplication from right, and column vectors with multiplication
00131   from left
00132 
00133 -not dependent on proprietary code
00134  *only a few operations need to be defined
00135  *all of these are defined above, so replacing them with faster variants is easy
00136 
00137 -usability was considered more important than speed
00138  *with less usable functions some temporaries could be avoided
00139    for example void cross(Vector& dest, const Vector& v1, const Vector& v2) instead of
00140              Vector cross( const Vector& v1, const Vector& v2 )
00141    but then it wouldn't be possible to write Vector a( normalize( cross( b, c ) ) );
00142 
00143 -avoids redundancy
00144  *except some functions are both globals and members. there are no strict rules for this though.
00145 
00146 -does not return references because Vector3 a; a.normalize().negate(); is bad style compared to
00147  Vector3 a; a = -normalize( a ); even though the former avoids the use of temporaries.
00148  note that it is still possible to write Vector3 a; a.normalize(); a.negate(); to avoid temporaries
00149  it would also be impossible to return a boolean telling if normalize and invert succeeded
00150 
00151 -single header + cpp
00152  *easy to copy to other projects
00153    TODO for readability and ease of checking the available functions a separate .inl file could be handy.
00154         functions from the .cpp could be moved there?
00155 
00156 -handling of mathematical singularities
00157  *no assertions, the user is expected to do the checks when necessary
00158  *different behaviour for members and globals (members return a boolean indicating success or failure)
00159  *if an operation fails, the operand is not changed
00160  *zero vector normalization returns a zero vector
00161    TODO should there be two versions of normalize, one that quietly outputs a zero vector if the input
00162         is a zero vector, and another that asserts that the input is non-zero?
00163  *projection on a zero vector returns a zero vector
00164    TODO vector::project: what the behaviour should be if the second vector is zero? (assertion or return 0?)
00165  *global inversion of a singular matrix returns the original matrix
00166    TODO should we assert that the input is not singular?
00167 
00168 example of multiplication from right:
00169 Matrix4x3 objectToWorld,cameraToWorld;
00170 Matrix4x3 worldToCamera = invert(cameraToWorld);
00171 Matrix4x3 objectToCamera = objectToWorld * worldToCamera;
00172 Vector3 vertexPosition(1,2,3);
00173 Vector4 result = Vector4(vertexPosition,1) * objectToCamera; //implicit conversion to Matrix4
00174 
00175 example of multiplication from left:
00176 Matrix3x4 objectToWorld,cameraToWorld;
00177 Matrix3x4 worldToCamera = invert(cameraToWorld);
00178 Matrix3x4 objectToCamera = worldToCamera * objectToWorld;
00179 Vector3 vertexPosition(1,2,3);
00180 Vector4 result = objectToCamera * Vector4(vertexPosition,1); //implicit conversion to Matrix4
00181 
00182 transformations:
00183 point p (Vector3) by Matrix4 m:                Vector4 r = Vector4(p,1) * m;
00184 normal n (Vector3) by Matrix4 m:               Vector3 r = n * transpose(invert(m.getRotation()));
00185 tangent or direction t (Vector3) by Matrix4 m: Vector3 r = t * m.getRotation();
00186 */
00187 
00188 //==============================================================================================
00189 //==============================================================================================
00190 
00191 class Matrix2
00192 {
00193 public:
00194         inline                                  Matrix2                 ();                                             //initialize to identity
00195         inline                                  Matrix2                 ( const Matrix2& m );   //copy
00196         //construction from other types is explicit for safer use (see makeMatrix2 functions below)
00197         inline                                  Matrix2                 ( T m00, T m01, T m10, T m11 );
00198         inline                                  ~Matrix2                ();
00199         inline Matrix2&                 operator=               ( const Matrix2& m );
00200         inline Vector2&                 operator[]              ( int i );                              //returns a row vector
00201         inline const Vector2&   operator[]              ( int i ) const;
00202         inline void                             set                             ( T m00, T m01, T m10, T m11 );
00203         inline const Vector2    getRow                  ( int i ) const;
00204         inline const Vector2    getColumn               ( int i ) const;
00205         inline void                             setRow                  ( int i, const Vector2& v );
00206         inline void                             setColumn               ( int i, const Vector2& v );
00207         inline void                             operator*=              ( const Matrix2& m );
00208         inline void                             multiply                ( const Matrix2& m, MultiplicationOrder o );
00209         inline void                             operator*=              ( T f );
00210         inline void                             operator+=              ( const Matrix2& m );
00211         inline void                             operator-=              ( const Matrix2& m );
00212         inline const Matrix2    operator-               () const;
00213         inline void                             identity                ();
00214         inline void                             transpose               ();
00215         bool                                    invert                  ();     //if the matrix is singular, returns false and leaves it unmodified
00216         inline T                                det                             () const;
00217         void                                    rotate                  ( T radians, MultiplicationOrder o );   //counterclockwise
00218         inline void                             scale                   ( const Vector2& v, MultiplicationOrder o );
00219 
00220 private:
00221         T                                               matrix[2][2];
00222 };
00223 
00224 //==============================================================================================
00225 //==============================================================================================
00226 
00227 class Matrix3
00228 {
00229 public:
00230         inline                                  Matrix3                 ();                                             //initialize to identity
00231         inline                                  Matrix3                 ( const Matrix2& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00232         inline                                  Matrix3                 ( const Matrix2x3& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00233         inline                                  Matrix3                 ( const Matrix3x2& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00234         inline                                  Matrix3                 ( const Matrix3& m );   //copy
00235         //construction from other types is explicit for safer use (see makeMatrix3 functions below)
00236         inline                                  Matrix3                 ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22 );
00237         inline                                  ~Matrix3                ();
00238         inline Matrix3&                 operator=               ( const Matrix3& m );
00239         inline Vector3&                 operator[]              ( int i );                              //returns a row vector
00240         inline const Vector3&   operator[]              ( int i ) const;
00241         inline void                             set                             ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22 );
00242         inline const Vector3    getRow                  ( int i ) const;
00243         inline const Vector3    getColumn               ( int i ) const;
00244         inline void                             setRow                  ( int i, const Vector3& v );
00245         inline void                             setColumn               ( int i, const Vector3& v );
00246         inline void                             operator*=              ( const Matrix3& m );
00247         inline void                             multiply                ( const Matrix3& m, MultiplicationOrder o );
00248         inline void                             operator*=              ( T f );
00249         inline void                             operator+=              ( const Matrix3& m );
00250         inline void                             operator-=              ( const Matrix3& m );
00251         inline const Matrix3    operator-               () const;
00252         inline void                             identity                ();
00253         inline void                             transpose               ();
00254         bool                                    invert                  ();     //if the matrix is singular, returns false and leaves it unmodified
00255         inline T                                det                             () const;
00256         void                                    rotate                  ( T radians, const Vector3& aboutThis, MultiplicationOrder o );
00257         inline void                             scale                   ( const Vector3& v, MultiplicationOrder o );
00258 
00259 private:
00260         T                                               matrix[3][3];
00261 };
00262 
00263 //==============================================================================================
00264 //==============================================================================================
00265 
00266 class Matrix4
00267 {
00268 public:
00269         inline                                  Matrix4                 ();                                             //initialize to identity
00270         inline                                  Matrix4                 ( const Matrix2& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00271         inline                                  Matrix4                 ( const Matrix2x3& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00272         inline                                  Matrix4                 ( const Matrix3x2& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00273         inline                                  Matrix4                 ( const Matrix3& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00274         inline                                  Matrix4                 ( const Matrix3x4& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00275         inline                                  Matrix4                 ( const Matrix4x3& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00276         inline                                  Matrix4                 ( const Matrix4& m );   //copy
00277         inline                                  Matrix4                 ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33 );
00278         inline                                  ~Matrix4                ();
00279         inline Matrix4&                 operator=               ( const Matrix4& m );
00280         inline Vector4&                 operator[]              ( int i );                              //returns a row vector
00281         inline const Vector4&   operator[]              ( int i ) const;
00282         inline void                             set                             ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33 );
00283         inline const Vector4    getRow                  ( int i ) const;
00284         inline const Vector4    getColumn               ( int i ) const;
00285         inline void                             setRow                  ( int i, const Vector4& v );
00286         inline void                             setColumn               ( int i, const Vector4& v );
00287         inline const Matrix3    getRotation             () const;       //upper-left submatrix
00288         inline const Vector3    getTranslation  ( MultiplicationOrder o ) const;        //third row or column depending on the multiplication order
00289         inline void                             setRotation             ( const Matrix3& m );   //upper-left submatrix
00290         inline void                             setTranslation  ( const Vector3& v, MultiplicationOrder o );    //third row or column depending on the multiplication order
00291         inline void                             operator*=              ( const Matrix4& m );
00292         inline void                             multiply                ( const Matrix4& m, MultiplicationOrder o );
00293         inline void                             operator*=              ( T f );
00294         inline void                             operator+=              ( const Matrix4& m );
00295         inline void                             operator-=              ( const Matrix4& m );
00296         inline const Matrix4    operator-               () const;
00297         inline void                             identity                ();
00298         inline void                             transpose               ();
00299         bool                                    invert                  ();     //if the matrix is singular, returns false and leaves it unmodified
00300         T                                               det                             () const;
00301         void                                    rotate                  ( T radians, const Vector3& aboutThis, MultiplicationOrder o );
00302         inline void                             translate               ( const Vector3& v, MultiplicationOrder o );
00303         inline void                             scale                   ( const Vector3& v, MultiplicationOrder o );
00304 
00305 private:
00306         T                                               matrix[4][4];
00307 };
00308 
00309 //==============================================================================================
00310 //==============================================================================================
00311 
00312 //2 rows, 3 columns, for column vector transformations with implied 3rd row [0,0,1]
00313 //uses always left multiply
00314 class Matrix2x3
00315 {
00316 public:
00317         inline                                  Matrix2x3               ();                                             //initialize to identity
00318         inline                                  Matrix2x3               ( const Matrix2& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00319         inline                                  Matrix2x3               ( const Matrix2x3& m ); //copy
00320         //construction from other types is explicit for safer use (see makeMatrix2x3 functions below)
00321         inline                                  Matrix2x3               ( T m00, T m01, T m02, T m10, T m11, T m12 );
00322         inline                                  ~Matrix2x3              ();
00323         inline Matrix2x3&               operator=               ( const Matrix2x3& m );
00324         inline Vector3&                 operator[]              ( int i );                              //returns a row vector
00325         inline const Vector3&   operator[]              ( int i ) const;
00326         inline void                             set                             ( T m00, T m01, T m02, T m10, T m11, T m12 );
00327         inline const Vector3    getRow                  ( int i ) const;
00328         inline const Vector2    getColumn               ( int i ) const;
00329         inline void                             setRow                  ( int i, const Vector3& v );
00330         inline void                             setColumn               ( int i, const Vector2& v );
00331         inline const Matrix2    getRotation             () const;
00332         inline const Vector2    getTranslation  () const;
00333         inline void                             setRotation             ( const Matrix2& m );
00334         inline void                             setTranslation  ( const Vector2& v );
00335         inline void                             multiply                ( const Matrix2x3& m ); // this = m * this (left multiply)
00336         inline void                             operator*=              ( T f );
00337         inline void                             operator+=              ( const Matrix2x3& m );
00338         inline void                             operator-=              ( const Matrix2x3& m );
00339         inline const Matrix2x3  operator-               () const;
00340         inline void                             identity                ();
00341         inline void                             transpose               ();
00342         bool                                    invert                  ();     //if the matrix is singular, returns false and leaves it unmodified
00343         T                                               det                             () const;
00344         void                                    rotate                  ( T radians );
00345         inline void                             translate               ( const Vector2& v );
00346         inline void                             scale                   ( const Vector2& v );
00347 
00348 private:
00349         T                                               matrix[2][3];
00350 };
00351 
00352 //==============================================================================================
00353 //==============================================================================================
00354 
00355 //3 rows, 2 columns, for row vector transformations with implied 3rd column [0,0,1]
00356 //uses always right multiply
00357 class Matrix3x2
00358 {
00359 public:
00360         inline                                  Matrix3x2               ();                                             //initialize to identity
00361         inline                                  Matrix3x2               ( const Matrix2& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00362         inline                                  Matrix3x2               ( const Matrix3x2& m ); //copy
00363         //construction from other types is explicit for safer use (see makeMatrix3x2 functions below)
00364         inline                                  Matrix3x2               ( T m00, T m01, T m10, T m11, T m20, T m21 );
00365         inline                                  ~Matrix3x2              ();
00366         inline Matrix3x2&               operator=               ( const Matrix3x2& m );
00367         inline Vector2&                 operator[]              ( int i );                              //returns a row vector
00368         inline const Vector2&   operator[]              ( int i ) const;
00369         inline void                             set                             ( T m00, T m01, T m10, T m11, T m20, T m21 );
00370         inline const Vector2    getRow                  ( int i ) const;
00371         inline const Vector3    getColumn               ( int i ) const;
00372         inline void                             setRow                  ( int i, const Vector2& v );
00373         inline void                             setColumn               ( int i, const Vector3& v );
00374         inline const Matrix2    getRotation             () const;
00375         inline const Vector2    getTranslation  () const;
00376         inline void                             setRotation             ( const Matrix2& m );
00377         inline void                             setTranslation  ( const Vector2& v );
00378         inline void                             operator*=              ( const Matrix3x2& m ); // this = this * m (right multiply)
00379         inline void                             multiply                ( const Matrix3x2& m ); // this = this * m (right multiply)
00380         inline void                             operator*=              ( T f );
00381         inline void                             operator+=              ( const Matrix3x2& m );
00382         inline void                             operator-=              ( const Matrix3x2& m );
00383         inline const Matrix3x2  operator-               () const;
00384         inline void                             identity                ();
00385         inline void                             transpose               ();
00386         bool                                    invert                  ();     //if the matrix is singular, returns false and leaves it unmodified
00387         inline T                                det                             () const;
00388         void                                    rotate                  ( T radians );
00389         inline void                             translate               ( const Vector2& v );
00390         inline void                             scale                   ( const Vector2& v );
00391 
00392 private:
00393         T                                               matrix[3][2];
00394 };
00395 
00396 //==============================================================================================
00397 //==============================================================================================
00398 
00399 //3 rows, 4 columns, for column vector transformations with implied 4th row [0,0,0,1]
00400 //uses always left multiply
00401 class Matrix3x4
00402 {
00403 public:
00404         inline                                  Matrix3x4               ();                                             //initialize to identity
00405         inline                                  Matrix3x4               ( const Matrix2& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00406         inline                                  Matrix3x4               ( const Matrix2x3& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00407         inline                                  Matrix3x4               ( const Matrix3x2& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00408         inline                                  Matrix3x4               ( const Matrix3& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00409         inline                                  Matrix3x4               ( const Matrix3x4& m ); //copy
00410         //construction from other types is explicit for safer use (see makeMatrix3x4 functions below)
00411         inline                                  Matrix3x4               ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23 );
00412         inline                                  ~Matrix3x4              ();
00413         inline Matrix3x4&               operator=               ( const Matrix3x4& m );
00414         inline Vector4&                 operator[]              ( int i );                              //returns a row vector
00415         inline const Vector4&   operator[]              ( int i ) const;
00416         inline void                             set                             ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23 );
00417         inline const Vector4    getRow                  ( int i ) const;
00418         inline const Vector3    getColumn               ( int i ) const;
00419         inline void                             setRow                  ( int i, const Vector4& v );
00420         inline void                             setColumn               ( int i, const Vector3& v );
00421         inline const Matrix3    getRotation             () const;
00422         inline const Vector3    getTranslation  () const;
00423         inline void                             setRotation             ( const Matrix3& m );
00424         inline void                             setTranslation  ( const Vector3& v );
00425         inline void                             multiply                ( const Matrix3x4& m ); // this = m * this (left multiply)
00426         inline void                             operator*=              ( T f );
00427         inline void                             operator+=              ( const Matrix3x4& m );
00428         inline void                             operator-=              ( const Matrix3x4& m );
00429         inline const Matrix3x4  operator-               () const;
00430         inline void                             identity                ();
00431         inline void                             transpose               ();
00432         bool                                    invert                  ();     //if the matrix is singular, returns false and leaves it unmodified
00433         T                                               det                             () const;
00434         void                                    rotate                  ( T radians, const Vector3& aboutThis );
00435         inline void                             translate               ( const Vector3& v );
00436         inline void                             scale                   ( const Vector3& v );
00437 
00438 private:
00439         T                                               matrix[3][4];
00440 };
00441 
00442 //==============================================================================================
00443 //==============================================================================================
00444 
00445 //4 rows, 3 columns, for row vector transformations with implied 4th column [0,0,0,1]
00446 //uses always right multiply
00447 class Matrix4x3
00448 {
00449 public:
00450         inline                                  Matrix4x3               ();                                             //initialize to identity
00451         inline                                  Matrix4x3               ( const Matrix2& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00452         inline                                  Matrix4x3               ( const Matrix2x3& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00453         inline                                  Matrix4x3               ( const Matrix3x2& m ); //extend: 1 to the diagonal and 0 to off-diagonal
00454         inline                                  Matrix4x3               ( const Matrix3& m );   //extend: 1 to the diagonal and 0 to off-diagonal
00455         inline                                  Matrix4x3               ( const Matrix4x3& m ); //copy
00456         //construction from other types is explicit for safer use (see makeMatrix4x3 functions below)
00457         inline                                  Matrix4x3               ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22, T m30, T m31, T m32 );
00458         inline                                  ~Matrix4x3              ();
00459         inline Matrix4x3&               operator=               ( const Matrix4x3& m );
00460         inline Vector3&                 operator[]              ( int i );                              //returns a row vector
00461         inline const Vector3&   operator[]              ( int i ) const;
00462         inline void                             set                             ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22, T m30, T m31, T m32 );
00463         inline const Vector3    getRow                  ( int i ) const;
00464         inline const Vector4    getColumn               ( int i ) const;
00465         inline void                             setRow                  ( int i, const Vector3& v );
00466         inline void                             setColumn               ( int i, const Vector4& v );
00467         inline const Matrix3    getRotation             () const;
00468         inline const Vector3    getTranslation  () const;
00469         inline void                             setRotation             ( const Matrix3& m );
00470         inline void                             setTranslation  ( const Vector3& v );
00471         inline void                             operator*=              ( const Matrix4x3& m ); // this = this * m (right multiply)
00472         inline void                             multiply                ( const Matrix4x3& m ); // this = this * m (right multiply)
00473         inline void                             operator*=              ( T f );
00474         inline void                             operator+=              ( const Matrix4x3& m );
00475         inline void                             operator-=              ( const Matrix4x3& m );
00476         inline const Matrix4x3  operator-               () const;
00477         inline void                             identity                ();
00478         inline void                             transpose               ();
00479         bool                                    invert                  ();     //if the matrix is singular, returns false and leaves it unmodified
00480         inline T                                det                             () const;
00481         void                                    rotate                  ( T radians, const Vector3& aboutThis );
00482         inline void                             translate               ( const Vector3& v );
00483         inline void                             scale                   ( const Vector3& v );
00484 
00485 private:
00486         T                                               matrix[4][3];
00487 };
00488 
00489 //==============================================================================================
00490 //==============================================================================================
00491 
00492 class Vector2
00493 {
00494 public:
00495         //not initialized (avoids some of the cost of temporary vectors)
00496         inline                                  Vector2                 ()                                                              {}
00497         inline                                  Vector2                 ( const Vector2& v )                    { x = v.x; y = v.y; }
00498         inline                                  Vector2                 ( T fx, T fy )                                  { x = fx; y = fy; }
00499         inline                                  ~Vector2                ()                                                              {}
00500         inline Vector2&                 operator=               ( const Vector2& v )                    { x = v.x; y = v.y; return *this; }
00501         inline T&                               operator[]              ( int i )                                               { ASSERT(i>=0&&i<2); return (&x)[i]; }
00502         inline const T&                 operator[]              ( int i ) const                                 { ASSERT(i>=0&&i<2); return (&x)[i]; }
00503         inline void                             set                             ( T fx, T fy )                                  { x = fx; y = fy; }
00504         inline void                             operator*=              ( T f )                                                 { x *= f; y *= f; }
00505         //row vector * matrix (= RIGHT_MULTIPLY)
00506         inline void                             operator*=              ( const Matrix2& m )                    { T tx = x,ty = y; x = tx*m[0][0]+ty*m[1][0]; y = tx*m[0][1]+ty*m[1][1]; }
00507         //right multiply with implicit 1 in the third component
00508         inline void                             operator*=              ( const Matrix3x2& m )                  { T tx = x,ty = y; x = tx*m[0][0]+ty*m[1][0]+m[2][0]; y = tx*m[0][1]+ty*m[1][1]+m[2][1]; }
00509         //no default parameter for safer use
00510         inline void                             multiply                ( const Matrix2& m, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) { T tx = x,ty = y; x = tx*m[0][0]+ty*m[0][1]; y = tx*m[1][0]+ty*m[1][1]; } else { *this *= m; } }
00511         //right multiply with implicit 1 in the third component
00512         inline void                             multiply                ( const Matrix3x2& m )                  { T tx = x,ty = y; x = tx*m[0][0]+ty*m[1][0]+m[2][0]; y = tx*m[0][1]+ty*m[1][1]+m[2][1]; }
00513         //left multiply with implicit 1 in the third component
00514         inline void                             multiply                ( const Matrix2x3& m );
00515         inline void                             operator+=              ( const Vector2& v )                    { x += v.x; y += v.y; }
00516         inline void                             operator-=              ( const Vector2& v )                    { x -= v.x; y -= v.y; }
00517         inline const Vector2    operator-               () const                                                { return Vector2(-x,-y); }
00518         //if the vector is zero, returns false and leaves it unmodified
00519         inline bool                             normalize               ()                                                              { T l = x*x+y*y; if( l == T(0) ) return false; l = OOSQRT(l); x *= l; y *= l; return true; }
00520         inline T                                length                  () const                                                { return SQRT(x*x+y*y); }
00521         inline void                             scale                   ( const Vector2& v )                    { x *= v.x; y *= v.y; } //component-wise scale
00522         inline void                             negate                  ()                                                              { x = -x; y = -y; }
00523 
00524         T                                               x,y;
00525 };
00526 
00527 //==============================================================================================
00528 //==============================================================================================
00529 
00530 class Vector3
00531 {
00532 public:
00533         //not initialized (avoids some of the cost of temporary vectors)
00534         inline                                  Vector3                 ()                                                              {}
00535         inline                                  Vector3                 ( const Vector2& v, T fz )              { x = v.x; y = v.y; z = fz; }
00536         inline                                  Vector3                 ( const Vector3& v )                    { x = v.x; y = v.y; z = v.z; }
00537         inline                                  Vector3                 ( T fx, T fy, T fz )                    { x = fx; y = fy; z = fz; }
00538         inline                                  ~Vector3                ()                                                              {}
00539         inline Vector3&                 operator=               ( const Vector3& v )                    { x = v.x; y = v.y; z = v.z; return *this; }
00540         inline T&                               operator[]              ( int i )                                               { ASSERT(i>=0&&i<3); return (&x)[i]; }
00541         inline const T&                 operator[]              ( int i ) const                                 { ASSERT(i>=0&&i<3); return (&x)[i]; }
00542         inline void                             set                             ( T fx, T fy, T fz )                    { x = fx; y = fy; z = fz; }
00543         inline void                             operator*=              ( T f )                                                 { x *= f; y *= f; z *= f; }
00544         //row vector * matrix (= RIGHT_MULTIPLY)
00545         inline void                             operator*=              ( const Matrix3& m )                    { T tx = x,ty = y,tz = z; x = tx*m[0][0]+ty*m[1][0]+tz*m[2][0]; y = tx*m[0][1]+ty*m[1][1]+tz*m[2][1]; z = tx*m[0][2]+ty*m[1][2]+tz*m[2][2]; }
00546         //right multiply with implicit 1 in the fourth component
00547         inline void                             operator*=              ( const Matrix4x3& m )                  { T tx = x,ty = y,tz = z; x = tx*m[0][0]+ty*m[1][0]+tz*m[2][0]+m[3][0]; y = tx*m[0][1]+ty*m[1][1]+tz*m[2][1]+m[3][1]; z = tx*m[0][2]+ty*m[1][2]+tz*m[2][2]+m[3][2]; }
00548         //no default parameter for safer use
00549         inline void                             multiply                ( const Matrix3& m, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) { T tx = x,ty = y,tz = z; x = tx*m[0][0]+ty*m[0][1]+tz*m[0][2]; y = tx*m[1][0]+ty*m[1][1]+tz*m[1][2]; z = tx*m[2][0]+ty*m[2][1]+tz*m[2][2]; } else { *this *= m; } }
00550         //right multiply with implicit 1 in the fourth component
00551         inline void                             multiply                ( const Matrix4x3& m )                  { T tx = x,ty = y,tz = z; x = tx*m[0][0]+ty*m[1][0]+tz*m[2][0]+m[3][0]; y = tx*m[0][1]+ty*m[1][1]+tz*m[2][1]+m[3][1]; z = tx*m[0][2]+ty*m[1][2]+tz*m[2][2]+m[3][2]; }
00552         //left multiply with implicit 1 in the fourth component
00553         inline void                             multiply                ( const Matrix3x4& m );
00554         inline void                             operator+=              ( const Vector3& v )                    { x += v.x; y += v.y; z += v.z; }
00555         inline void                             operator-=              ( const Vector3& v )                    { x -= v.x; y -= v.y; z -= v.z; }
00556         inline const Vector3    operator-               () const                                                { return Vector3(-x,-y,-z); }
00557         //if the vector is zero, returns false and leaves it unmodified
00558         inline bool                             normalize               ()                                                              { T l = x*x+y*y+z*z; if( l == T(0) ) return false; l = OOSQRT(l); x *= l; y *= l; z *= l; return true; }
00559         inline T                                length                  () const                                                { return SQRT(x*x+y*y+z*z); }
00560         inline void                             scale                   ( const Vector3& v )                    { x *= v.x; y *= v.y; z *= v.z; }       //component-wise scale
00561         inline void                             negate                  ()                                                              { x = -x; y = -y; z = -z; }
00562 
00563         T                                               x,y,z;
00564 };
00565 
00566 //==============================================================================================
00567 //==============================================================================================
00568 
00569 class Vector4
00570 {
00571 public:
00572         //not initialized (avoids some of the cost of temporary vectors)
00573         inline                                  Vector4                 ()                                                              {}
00574         inline                                  Vector4                 ( const Vector2& v, T fz, T fw ){ x = v.x; y = v.y; z = fz; w = fw; }
00575         inline                                  Vector4                 ( const Vector3& v, T fw )              { x = v.x; y = v.y; z = v.z; w = fw; }
00576         inline                                  Vector4                 ( const Vector4& v )                    { x = v.x; y = v.y; z = v.z; w = v.w; }
00577         inline                                  Vector4                 ( T fx, T fy, T fz, T fw )              { x = fx; y = fy; z = fz; w = fw; }
00578         inline                                  ~Vector4                ()                                                              {}
00579         inline Vector4&                 operator=               ( const Vector4& v )                    { x = v.x; y = v.y; z = v.z; w = v.w; return *this; }
00580         inline T&                               operator[]              ( int i )                                               { ASSERT(i>=0&&i<4); return (&x)[i]; }
00581         inline const T&                 operator[]              ( int i ) const                                 { ASSERT(i>=0&&i<4); return (&x)[i]; }
00582         inline void                             set                             ( T fx, T fy, T fz, T fw )              { x = fx; y = fy; z = fz; w = fw; }
00583         inline void                             operator*=              ( T f )                                                 { x *= f; y *= f; z *= f; w *= f; }
00584         //row vector * matrix (= RIGHT_MULTIPLY)
00585         inline void                             operator*=              ( const Matrix4& m )                    { T tx = x,ty = y,tz = z,tw = w; x = tx*m[0][0]+ty*m[1][0]+tz*m[2][0]+tw*m[3][0]; y = tx*m[0][1]+ty*m[1][1]+tz*m[2][1]+tw*m[3][1]; z = tx*m[0][2]+ty*m[1][2]+tz*m[2][2]+tw*m[3][2]; w = tx*m[0][3]+ty*m[1][3]+tz*m[2][3]+tw*m[3][3]; }
00586         //no default parameter for safer use
00587         inline void                             multiply                ( const Matrix4& m, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) { T tx = x,ty = y,tz = z,tw = w; x = tx*m[0][0]+ty*m[0][1]+tz*m[0][2]+tw*m[0][3]; y = tx*m[1][0]+ty*m[1][1]+tz*m[1][2]+tw*m[1][3]; z = tx*m[2][0]+ty*m[2][1]+tz*m[2][2]+tw*m[2][3]; w = tx*m[3][0]+ty*m[3][1]+tz*m[3][2]+tw*m[3][3]; } else { *this *= m; } }
00588         inline void                             operator+=              ( const Vector4& v )                    { x += v.x; y += v.y; z += v.z; w += v.w; }
00589         inline void                             operator-=              ( const Vector4& v )                    { x -= v.x; y -= v.y; z -= v.z; w -= v.w; }
00590         inline const Vector4    operator-               () const                                                { return Vector4(-x,-y,-z,-w); }
00591         //if the vector is zero, returns false and leaves it unmodified
00592         inline bool                             normalize               ()                                                              { T l = x*x+y*y+z*z+w*w; if( l == T(0) ) return false; l = OOSQRT(l); x *= l; y *= l; z *= l; w *= l; return true; }
00593         inline T                                length                  () const                                                { return SQRT(x*x+y*y+z*z+w*w); }
00594         inline void                             scale                   ( const Vector4& v )                    { x *= v.x; y *= v.y; z *= v.z; w *= v.w; }     //component-wise scale
00595         inline void                             negate                  ()                                                              { x = -x; y = -y; z = -z; w = -w; }
00596 
00597         T                                               x,y,z,w;
00598 };
00599 
00600 //==============================================================================================
00601 //==============================================================================================
00602 
00603 //Vector2 global functions
00604 inline bool                             operator==      ( const Vector2& v1, const Vector2& v2 )        { return (v1.x == v2.x) && (v1.y == v2.y); }
00605 inline bool                             operator!=      ( const Vector2& v1, const Vector2& v2 )        { return (v1.x != v2.x) || (v1.y != v2.y); }
00606 inline bool                             isEqual         ( const Vector2& v1, const Vector2& v2, T epsilon )     { return SQR(v2.x-v1.x) + SQR(v2.y-v1.y) <= epsilon*epsilon; }
00607 inline const Vector2    operator*       ( T f, const Vector2& v )                                       { return Vector2(v.x*f,v.y*f); }
00608 inline const Vector2    operator*       ( const Vector2& v, T f )                                       { return Vector2(v.x*f,v.y*f); }
00609 inline const Vector2    operator+       ( const Vector2& v1, const Vector2& v2 )        { return Vector2(v1.x+v2.x, v1.y+v2.y); }
00610 inline const Vector2    operator-       ( const Vector2& v1, const Vector2& v2 )        { return Vector2(v1.x-v2.x, v1.y-v2.y); }
00611 inline T                                dot                     ( const Vector2& v1, const Vector2& v2 )        { return v1.x*v2.x+v1.y*v2.y; }
00612 //if v is a zero vector, returns a zero vector
00613 inline const Vector2    normalize       ( const Vector2& v )                                            { T l = dot(v,v); if( l != T(0) ) l = OOSQRT(l); return v * l; }
00614 //if onThis is a zero vector, returns a zero vector
00615 inline const Vector2    project         ( const Vector2& v, const Vector2& onThis ) { T l = dot(onThis,onThis); if( l != T(0) ) l = dot(v, onThis)/l; return onThis * l; }
00616 inline const Vector2    lerp            ( const Vector2& v1, const Vector2& v2, T ratio )       { return v1 + ratio * (v2 - v1); }
00617 inline const Vector2    scale           ( const Vector2& v1, const Vector2& v2 )        { return Vector2(v1.x*v2.x, v1.y*v2.y); }
00618 
00619 //==============================================================================================
00620 //==============================================================================================
00621 
00622 //Vector3 global functions
00623 inline bool                             operator==      ( const Vector3& v1, const Vector3& v2 )        { return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z); }
00624 inline bool                             operator!=      ( const Vector3& v1, const Vector3& v2 )        { return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z); }
00625 inline bool                             isEqual         ( const Vector3& v1, const Vector3& v2, T epsilon )     { return SQR(v2.x-v1.x) + SQR(v2.y-v1.y) + SQR(v2.z-v1.z) <= epsilon*epsilon; }
00626 inline const Vector3    operator*       ( T f, const Vector3& v )                                       { return Vector3(v.x*f,v.y*f,v.z*f); }
00627 inline const Vector3    operator*       ( const Vector3& v, T f )                                       { return Vector3(v.x*f,v.y*f,v.z*f); }
00628 inline const Vector3    operator+       ( const Vector3& v1, const Vector3& v2 )        { return Vector3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); }
00629 inline const Vector3    operator-       ( const Vector3& v1, const Vector3& v2 )        { return Vector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); }
00630 inline T                                dot                     ( const Vector3& v1, const Vector3& v2 )        { return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z; }
00631 inline const Vector3    cross           ( const Vector3& v1, const Vector3& v2 )        { return Vector3( v1.y*v2.z-v1.z*v2.y, v1.z*v2.x-v1.x*v2.z, v1.x*v2.y-v1.y*v2.x ); }
00632 //if v is a zero vector, returns a zero vector
00633 inline const Vector3    normalize       ( const Vector3& v )                                            { T l = dot(v,v); if( l != T(0) ) l = OOSQRT(l); return v * l; }
00634 //if onThis is a zero vector, returns a zero vector
00635 inline const Vector3    project         ( const Vector3& v, const Vector3& onThis ) { T l = dot(onThis,onThis); if( l != T(0) ) l = dot(v, onThis)/l; return onThis * l; }
00636 inline const Vector3    lerp            ( const Vector3& v1, const Vector3& v2, T ratio )       { return v1 + ratio * (v2 - v1); }
00637 inline const Vector3    scale           ( const Vector3& v1, const Vector3& v2 )        { return Vector3(v1.x*v2.x, v1.y*v2.y, v1.z*v2.z); }
00638 
00639 //==============================================================================================
00640 //==============================================================================================
00641 
00642 //Vector4 global functions
00643 inline bool                             operator==      ( const Vector4& v1, const Vector4& v2 )        { return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z) && (v1.w == v2.w); }
00644 inline bool                             operator!=      ( const Vector4& v1, const Vector4& v2 )        { return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z) || (v1.w != v2.w); }
00645 inline bool                             isEqual         ( const Vector4& v1, const Vector4& v2, T epsilon )     { return SQR(v2.x-v1.x) + SQR(v2.y-v1.y) + SQR(v2.z-v1.z) + SQR(v2.w-v1.w) <= epsilon*epsilon; }
00646 inline const Vector4    operator*       ( T f, const Vector4& v )                                       { return Vector4(v.x*f,v.y*f,v.z*f,v.w*f); }
00647 inline const Vector4    operator*       ( const Vector4& v, T f )                                       { return Vector4(v.x*f,v.y*f,v.z*f,v.w*f); }
00648 inline const Vector4    operator+       ( const Vector4& v1, const Vector4& v2 )        { return Vector4(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z, v1.w+v2.w); }
00649 inline const Vector4    operator-       ( const Vector4& v1, const Vector4& v2 )        { return Vector4(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z, v1.w-v2.w); }
00650 inline T                                dot                     ( const Vector4& v1, const Vector4& v2 )        { return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z+v1.w*v2.w; }
00651 //if v is a zero vector, returns a zero vector
00652 inline const Vector4    normalize       ( const Vector4& v )                                            { T l = dot(v,v); if( l != T(0) ) l = OOSQRT(l); return v * l; }
00653 //if onThis is a zero vector, returns a zero vector
00654 inline const Vector4    project         ( const Vector4& v, const Vector4& onThis ) { T l = dot(onThis,onThis); if( l != T(0) ) l = dot(v, onThis)/l; return onThis * l; }
00655 inline const Vector4    lerp            ( const Vector4& v1, const Vector4& v2, T ratio )       { return v1 + ratio * (v2 - v1); }
00656 inline const Vector4    scale           ( const Vector4& v1, const Vector4& v2 )        { return Vector4(v1.x*v2.x, v1.y*v2.y, v1.z*v2.z, v1.w*v2.w); }
00657 
00658 //==============================================================================================
00659 //==============================================================================================
00660 
00661 //Vector2 inline functions (cannot be defined in the class because of dependency issues)
00662 inline void                             Vector2::multiply               ( const Matrix2x3& m )                  { T tx = x,ty = y; x = tx*m[0][0]+ty*m[0][1]+m[0][2]; y = tx*m[1][0]+ty*m[1][1]+m[1][2]; }
00663 
00664 //global Vector2-Matrix2 multiplications
00665 //row vector * matrix
00666 inline const Vector2    operator*       ( const Vector2& v, const Matrix2& m)           { return Vector2( v.x*m[0][0]+v.y*m[1][0], v.x*m[0][1]+v.y*m[1][1] ); }
00667 //row vector * matrix with implied 1 in the third component of the vector
00668 inline const Vector2    operator*       ( const Vector2& v, const Matrix3x2& m)         { return Vector2( v.x*m[0][0]+v.y*m[1][0]+m[2][0], v.x*m[0][1]+v.y*m[1][1]+m[2][1] ); }
00669 //matrix * column vector
00670 inline const Vector2    operator*       ( const Matrix2& m, const Vector2& v)           { return Vector2( v.x*m[0][0]+v.y*m[0][1], v.x*m[1][0]+v.y*m[1][1] ); }
00671 //matrix * column vector with implied 1 in the third component of the vector
00672 inline const Vector2    operator*       ( const Matrix2x3& m, const Vector2& v)         { return Vector2( v.x*m[0][0]+v.y*m[0][1]+m[0][2], v.x*m[1][0]+v.y*m[1][1]+m[1][2] ); }
00673 
00674 //==============================================================================================
00675 //==============================================================================================
00676 
00677 //Vector3 inline functions (cannot be defined in the class because of dependency issues)
00678 inline void                             Vector3::multiply               ( const Matrix3x4& m )                  { T tx = x,ty = y,tz = z; x = tx*m[0][0]+ty*m[0][1]+tz*m[0][2]+m[0][3]; y = tx*m[1][0]+ty*m[1][1]+tz*m[1][2]+m[1][3]; z = tx*m[2][0]+ty*m[2][1]+tz*m[2][2]+m[2][3]; }
00679 
00680 //global Vector3-Matrix3 multiplications
00681 //row vector * matrix
00682 inline const Vector3    operator*       ( const Vector3& v, const Matrix3& m)           { return Vector3( v.x*m[0][0]+v.y*m[1][0]+v.z*m[2][0], v.x*m[0][1]+v.y*m[1][1]+v.z*m[2][1], v.x*m[0][2]+v.y*m[1][2]+v.z*m[2][2] ); }
00683 //row vector * matrix with implied 1 in the fourth component of the vector
00684 inline const Vector3    operator*       ( const Vector3& v, const Matrix4x3& m)         { return Vector3( v.x*m[0][0]+v.y*m[1][0]+v.z*m[2][0]+m[3][0], v.x*m[0][1]+v.y*m[1][1]+v.z*m[2][1]+m[3][1], v.x*m[0][2]+v.y*m[1][2]+v.z*m[2][2]+m[3][2] ); }
00685 //matrix * column vector
00686 inline const Vector3    operator*       ( const Matrix3& m, const Vector3& v)           { return Vector3( v.x*m[0][0]+v.y*m[0][1]+v.z*m[0][2], v.x*m[1][0]+v.y*m[1][1]+v.z*m[1][2], v.x*m[2][0]+v.y*m[2][1]+v.z*m[2][2] ); }
00687 //matrix * column vector with implied 1 in the fourth component of the vector
00688 inline const Vector3    operator*       ( const Matrix3x4& m, const Vector3& v)         { return Vector3( v.x*m[0][0]+v.y*m[0][1]+v.z*m[0][2]+m[0][3], v.x*m[1][0]+v.y*m[1][1]+v.z*m[1][2]+m[1][3], v.x*m[2][0]+v.y*m[2][1]+v.z*m[2][2]+m[2][3] ); }
00689 
00690 //==============================================================================================
00691 //==============================================================================================
00692 
00693 //global Vector4-Matrix4 multiplications
00694 //row vector * matrix
00695 inline const Vector4    operator*       ( const Vector4& v, const Matrix4& m)           { return Vector4( v.x*m[0][0]+v.y*m[1][0]+v.z*m[2][0]+v.w*m[3][0], v.x*m[0][1]+v.y*m[1][1]+v.z*m[2][1]+v.w*m[3][1], v.x*m[0][2]+v.y*m[1][2]+v.z*m[2][2]+v.w*m[3][2], v.x*m[0][3]+v.y*m[1][3]+v.z*m[2][3]+v.w*m[3][3] ); }
00696 //matrix * column vector
00697 inline const Vector4    operator*       ( const Matrix4& m, const Vector4& v)           { return Vector4( v.x*m[0][0]+v.y*m[0][1]+v.z*m[0][2]+v.w*m[0][3], v.x*m[1][0]+v.y*m[1][1]+v.z*m[1][2]+v.w*m[1][3], v.x*m[2][0]+v.y*m[2][1]+v.z*m[2][2]+v.w*m[2][3], v.x*m[3][0]+v.y*m[3][1]+v.z*m[3][2]+v.w*m[3][3] ); }
00698 
00699 //==============================================================================================
00700 //==============================================================================================
00701 
00702 //Matrix2 global functions
00703 inline bool                             operator==      ( const Matrix2& m1, const Matrix2& m2 )        { for(int i=0;i<2;i++) for(int j=0;j<2;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
00704 inline bool                             operator!=      ( const Matrix2& m1, const Matrix2& m2 )        { return !(m1 == m2); }
00705 inline const Matrix2    operator*       ( const Matrix2& m1, const Matrix2& m2 )        { Matrix2 t; for(int i=0;i<2;i++) for(int j=0;j<2;j++) t[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j]; return t; }
00706 inline const Matrix2    operator*       ( T f, const Matrix2& m )                                       { Matrix2 t(m); t *= f; return t; }
00707 inline const Matrix2    operator*       ( const Matrix2& m, T f )                                       { Matrix2 t(m); t *= f; return t; }
00708 inline const Matrix2    operator+       ( const Matrix2& m1, const Matrix2& m2 )        { Matrix2 t(m1); t += m2; return t; }
00709 inline const Matrix2    operator-       ( const Matrix2& m1, const Matrix2& m2 )        { Matrix2 t(m1); t -= m2; return t; }
00710 inline const Matrix2    transpose       ( const Matrix2& m )                                            { Matrix2 t(m); t.transpose(); return t; }
00711 // if the matrix is singular, returns it unmodified
00712 inline const Matrix2    invert          ( const Matrix2& m )                                            { Matrix2 t(m); t.invert(); return t; }
00713 
00714 //==============================================================================================
00715 //==============================================================================================
00716 
00717 //Matrix2 inline functions (cannot be inside the class because Vector2 is not defined yet when Matrix2 is defined)
00718 inline                                  Matrix2::Matrix2        ()                                                                      { identity(); }
00719 inline                                  Matrix2::Matrix2        ( const Matrix2& m )                            { *this = m; }
00720 inline                                  Matrix2::Matrix2        ( T m00, T m01, T m10, T m11 )          { set(m00,m01,m10,m11); }
00721 inline                                  Matrix2::~Matrix2       ()                                                                      {}
00722 inline Matrix2&                 Matrix2::operator=      ( const Matrix2& m )                            { for(int i=0;i<2;i++) for(int j=0;j<2;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
00723 inline Vector2&                 Matrix2::operator[]     ( int i )                                                       { ASSERT(i>=0&&i<2); return (Vector2&)matrix[i][0]; }
00724 inline const Vector2&   Matrix2::operator[]     ( int i ) const                                         { ASSERT(i>=0&&i<2); return (const Vector2&)matrix[i][0]; }
00725 inline void                             Matrix2::set            ( T m00, T m01, T m10, T m11 )          { matrix[0][0] = m00; matrix[0][1] = m01; matrix[1][0] = m10; matrix[1][1] = m11; }
00726 inline const Vector2    Matrix2::getRow         ( int i ) const                                         { ASSERT(i>=0&&i<2); return Vector2(matrix[i][0],matrix[i][1]); }
00727 inline const Vector2    Matrix2::getColumn      ( int i ) const                                         { ASSERT(i>=0&&i<2); return Vector2(matrix[0][i],matrix[1][i]); }
00728 inline void                             Matrix2::setRow         ( int i, const Vector2& v )                     { ASSERT(i>=0&&i<2); matrix[i][0] = v.x; matrix[i][1] = v.y; }
00729 inline void                             Matrix2::setColumn      ( int i, const Vector2& v )                     { ASSERT(i>=0&&i<2); matrix[0][i] = v.x; matrix[1][i] = v.y; }
00730 inline void                             Matrix2::operator*=     ( const Matrix2& m )                            { *this = *this * m; }
00731 inline void                             Matrix2::multiply       ( const Matrix2& m, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) *this = m * (*this); else *this *= m; }
00732 inline void                             Matrix2::operator*=     ( T f )                                                         { for(int i=0;i<2;i++) for(int j=0;j<2;j++) matrix[i][j] *= f; }
00733 inline void                             Matrix2::operator+=     ( const Matrix2& m )                            { for(int i=0;i<2;i++) for(int j=0;j<2;j++) matrix[i][j] += m.matrix[i][j]; }
00734 inline void                             Matrix2::operator-=     ( const Matrix2& m )                            { for(int i=0;i<2;i++) for(int j=0;j<2;j++) matrix[i][j] -= m.matrix[i][j]; }
00735 inline const Matrix2    Matrix2::operator-      () const                                                        { return Matrix2( -matrix[0][0],-matrix[0][1],-matrix[1][0],-matrix[1][1]); }
00736 inline void                             Matrix2::identity       ()                                                                      { for(int i=0;i<2;i++) for(int j=0;j<2;j++) matrix[i][j] = (i == j) ? T(1) : T(0); }
00737 inline void                             Matrix2::transpose      ()                                                                      { SWAP(matrix[1][0], matrix[0][1]); }
00738 inline T                                Matrix2::det            () const                                                        { return matrix[0][0] * matrix[1][1] - matrix[1][0]*matrix[0][1]; }
00739 inline void                             Matrix2::scale          ( const Vector2& v, MultiplicationOrder o ) { multiply( Matrix2( v.x, T(0), T(0),  v.y ), o ); }
00740 
00741 //==============================================================================================
00742 //==============================================================================================
00743 
00744 //Matrix3 global functions
00745 inline bool                             operator==      ( const Matrix3& m1, const Matrix3& m2 )        { for(int i=0;i<3;i++) for(int j=0;j<3;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
00746 inline bool                             operator!=      ( const Matrix3& m1, const Matrix3& m2 )        { return !(m1 == m2); }
00747 inline const Matrix3    operator*       ( const Matrix3& m1, const Matrix3& m2 )        { Matrix3 t; for(int i=0;i<3;i++) for(int j=0;j<3;j++) t[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j]; return t; }
00748 inline const Matrix3    operator*       ( T f, const Matrix3& m )                                       { Matrix3 t(m); t *= f; return t; }
00749 inline const Matrix3    operator*       ( const Matrix3& m, T f )                                       { Matrix3 t(m); t *= f; return t; }
00750 inline const Matrix3    operator+       ( const Matrix3& m1, const Matrix3& m2 )        { Matrix3 t(m1); t += m2; return t; }
00751 inline const Matrix3    operator-       ( const Matrix3& m1, const Matrix3& m2 )        { Matrix3 t(m1); t -= m2; return t; }
00752 inline const Matrix3    transpose       ( const Matrix3& m )                                            { Matrix3 t(m); t.transpose(); return t; }
00753 // if the matrix is singular, returns it unmodified
00754 inline const Matrix3    invert          ( const Matrix3& m )                                            { Matrix3 t(m); t.invert(); return t; }
00755 
00756 //==============================================================================================
00757 //==============================================================================================
00758 
00759 //Matrix3 inline functions (cannot be inside the class because Vector3 is not defined yet when Matrix3 is defined)
00760 inline                                  Matrix3::Matrix3        ()                                                                      { identity(); }
00761 inline                                  Matrix3::Matrix3        ( const Matrix2& m )                            { set( m[0][0], m[0][1], T(0), m[1][0], m[1][1], T(0), T(0), T(0), T(1) ); }
00762 inline                                  Matrix3::Matrix3        ( const Matrix2x3& m )                          { set( m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], T(0), T(0), T(1) ); }
00763 inline                                  Matrix3::Matrix3        ( const Matrix3x2& m )                          { set( m[0][0], m[0][1], T(0), m[1][0], m[1][1], T(0), m[2][0], m[2][1], T(1) ); }
00764 inline                                  Matrix3::Matrix3        ( const Matrix3& m )                            { *this = m; }
00765 inline                                  Matrix3::Matrix3        ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22 )       { set(m00,m01,m02,m10,m11,m12,m20,m21,m22); }
00766 inline                                  Matrix3::~Matrix3       ()                                                                      {}
00767 inline Matrix3&                 Matrix3::operator=      ( const Matrix3& m )                            { for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
00768 inline Vector3&                 Matrix3::operator[]     ( int i )                                                       { ASSERT(i>=0&&i<3); return (Vector3&)matrix[i][0]; }
00769 inline const Vector3&   Matrix3::operator[]     ( int i ) const                                         { ASSERT(i>=0&&i<3); return (const Vector3&)matrix[i][0]; }
00770 inline void                             Matrix3::set            ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22 ) {     matrix[0][0] = m00; matrix[0][1] = m01; matrix[0][2] = m02; matrix[1][0] = m10; matrix[1][1] = m11; matrix[1][2] = m12; matrix[2][0] = m20; matrix[2][1] = m21; matrix[2][2] = m22; }
00771 inline const Vector3    Matrix3::getRow         ( int i ) const                                         { ASSERT(i>=0&&i<3); return Vector3(matrix[i][0],matrix[i][1],matrix[i][2]); }
00772 inline const Vector3    Matrix3::getColumn      ( int i ) const                                         { ASSERT(i>=0&&i<3); return Vector3(matrix[0][i],matrix[1][i],matrix[2][i]); }
00773 inline void                             Matrix3::setRow         ( int i, const Vector3& v )                     { ASSERT(i>=0&&i<3); matrix[i][0] = v.x; matrix[i][1] = v.y; matrix[i][2] = v.z; }
00774 inline void                             Matrix3::setColumn      ( int i, const Vector3& v )                     { ASSERT(i>=0&&i<3); matrix[0][i] = v.x; matrix[1][i] = v.y; matrix[2][i] = v.z; }
00775 inline void                             Matrix3::operator*=     ( const Matrix3& m )                            { *this = *this * m; }
00776 inline void                             Matrix3::multiply       ( const Matrix3& m, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) *this = m * (*this); else *this *= m; }
00777 inline void                             Matrix3::operator*=     ( T f )                                                         { for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] *= f; }
00778 inline void                             Matrix3::operator+=     ( const Matrix3& m )                            { for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] += m.matrix[i][j]; }
00779 inline void                             Matrix3::operator-=     ( const Matrix3& m )                            { for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] -= m.matrix[i][j]; }
00780 inline const Matrix3    Matrix3::operator-      () const                                                        { return Matrix3( -matrix[0][0],-matrix[0][1],-matrix[0][2], -matrix[1][0],-matrix[1][1],-matrix[1][2], -matrix[2][0],-matrix[2][1],-matrix[2][2]); }
00781 inline void                             Matrix3::identity       ()                                                                      { for(int i=0;i<3;i++) for(int j=0;j<3;j++) matrix[i][j] = (i == j) ? T(1) : T(0); }
00782 inline void                             Matrix3::transpose      ()                                                                      { SWAP(matrix[1][0], matrix[0][1]); SWAP(matrix[2][0], matrix[0][2]); SWAP(matrix[2][1], matrix[1][2]); }
00783 inline T                                Matrix3::det            () const                                                        { return matrix[0][0] * (matrix[1][1]*matrix[2][2] - matrix[2][1]*matrix[1][2]) + matrix[0][1] * (matrix[2][0]*matrix[1][2] - matrix[1][0]*matrix[2][2]) + matrix[0][2] * (matrix[1][0]*matrix[2][1] - matrix[2][0]*matrix[1][1]); }
00784 inline void                             Matrix3::scale          ( const Vector3& v, MultiplicationOrder o )     { multiply( Matrix3( v.x, T(0), T(0), T(0), v.y, T(0), T(0), T(0), v.z ), o ); }
00785 
00786 //==============================================================================================
00787 //==============================================================================================
00788 
00789 //Matrix4 global functions
00790 inline bool                             operator==      ( const Matrix4& m1, const Matrix4& m2 )        { for(int i=0;i<4;i++) for(int j=0;j<4;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
00791 inline bool                             operator!=      ( const Matrix4& m1, const Matrix4& m2 )        { return !(m1 == m2); }
00792 inline const Matrix4    operator*       ( const Matrix4& m1, const Matrix4& m2 )        { Matrix4 t; for(int i=0;i<4;i++) for(int j=0;j<4;j++) t[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j] + m1[i][3] * m2[3][j]; return t; }
00793 inline const Matrix4    operator*       ( T f, const Matrix4& m )                                       { Matrix4 t(m); t *= f; return t; }
00794 inline const Matrix4    operator*       ( const Matrix4& m, T f )                                       { Matrix4 t(m); t *= f; return t; }
00795 inline const Matrix4    operator+       ( const Matrix4& m1, const Matrix4& m2 )        { Matrix4 t(m1); t += m2; return t; }
00796 inline const Matrix4    operator-       ( const Matrix4& m1, const Matrix4& m2 )        { Matrix4 t(m1); t -= m2; return t; }
00797 inline const Matrix4    transpose       ( const Matrix4& m )                                            { Matrix4 t(m); t.transpose(); return t; }
00798 // if the matrix is singular, returns it unmodified
00799 inline const Matrix4    invert          ( const Matrix4& m )                                            { Matrix4 t(m); t.invert(); return t; }
00800 
00801 //==============================================================================================
00802 //==============================================================================================
00803 
00804 //Matrix4 inline functions (cannot be inside the class because Vector4 is not defined yet when Matrix4 is defined)
00805 inline                                  Matrix4::Matrix4                ()                                                                      { identity(); }
00806 inline                                  Matrix4::Matrix4                ( const Matrix2& m )                            { set(m[0][0],m[0][1],T(0),T(0),m[1][0],m[1][1],T(0),T(0),T(0),T(0),T(1),T(0),T(0),T(0),T(0),T(1)); }
00807 inline                                  Matrix4::Matrix4                ( const Matrix2x3& m )                          { set(m[0][0],m[0][1],m[0][2],T(0),m[1][0],m[1][1],m[1][2],T(0),T(0),T(0),T(1),T(0),T(0),T(0),T(0),T(1)); }
00808 inline                                  Matrix4::Matrix4                ( const Matrix3x2& m )                          { set(m[0][0],m[0][1],T(0),T(0),m[1][0],m[1][1],T(0),T(0),m[2][0],m[2][1],T(1),T(0),T(0),T(0),T(0),T(1)); }
00809 inline                                  Matrix4::Matrix4                ( const Matrix3& m )                            { set(m[0][0],m[0][1],m[0][2],T(0),m[1][0],m[1][1],m[1][2],T(0),m[2][0],m[2][1],m[2][2],T(0),T(0),T(0),T(0),T(1)); }
00810 inline                                  Matrix4::Matrix4                ( const Matrix3x4& m )                          { set(m[0][0],m[0][1],m[0][2],m[0][3],m[1][0],m[1][1],m[1][2],m[1][3],m[2][0],m[2][1],m[2][2],m[2][3],T(0),T(0),T(0),T(1)); }
00811 inline                                  Matrix4::Matrix4                ( const Matrix4x3& m )                          { set(m[0][0],m[0][1],m[0][2],T(0),m[1][0],m[1][1],m[1][2],T(0),m[2][0],m[2][1],m[2][2],T(0),m[3][0],m[3][1],m[3][2],T(1)); }
00812 inline                                  Matrix4::Matrix4                ( const Matrix4& m )                            { *this = m; }
00813 inline                                  Matrix4::Matrix4                ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33 )      { set(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33); }
00814 inline                                  Matrix4::~Matrix4               ()                                                                      {}
00815 inline Matrix4&                 Matrix4::operator=              ( const Matrix4& m )                            { for(int i=0;i<4;i++) for(int j=0;j<4;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
00816 inline Vector4&                 Matrix4::operator[]             ( int i )                                                       { ASSERT(i>=0&&i<4); return (Vector4&)matrix[i][0]; }
00817 inline const Vector4&   Matrix4::operator[]             ( int i ) const                                         { ASSERT(i>=0&&i<4); return (const Vector4&)matrix[i][0]; }
00818 inline void                             Matrix4::set                    ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33  ) { matrix[0][0] = m00; matrix[0][1] = m01; matrix[0][2] = m02; matrix[0][3] = m03; matrix[1][0] = m10; matrix[1][1] = m11; matrix[1][2] = m12;  matrix[1][3] = m13; matrix[2][0] = m20; matrix[2][1] = m21; matrix[2][2] = m22; matrix[2][3] = m23; matrix[3][0] = m30; matrix[3][1] = m31; matrix[3][2] = m32; matrix[3][3] = m33; }
00819 inline const Vector4    Matrix4::getRow                 ( int i ) const                                         { ASSERT(i>=0&&i<4); return Vector4(matrix[i][0],matrix[i][1],matrix[i][2],matrix[i][3]); }
00820 inline const Vector4    Matrix4::getColumn              ( int i ) const                                         { ASSERT(i>=0&&i<4); return Vector4(matrix[0][i],matrix[1][i],matrix[2][i],matrix[3][i]); }
00821 inline void                             Matrix4::setRow                 ( int i, const Vector4& v )                     { ASSERT(i>=0&&i<4); matrix[i][0] = v.x; matrix[i][1] = v.y; matrix[i][2] = v.z; matrix[i][3] = v.w; }
00822 inline void                             Matrix4::setColumn              ( int i, const Vector4& v )                     { ASSERT(i>=0&&i<4); matrix[0][i] = v.x; matrix[1][i] = v.y; matrix[2][i] = v.z; matrix[3][i] = v.w; }
00823 inline const Matrix3    Matrix4::getRotation    () const                                                        { return Matrix3(matrix[0][0],matrix[0][1],matrix[0][2],matrix[1][0],matrix[1][1],matrix[1][2],matrix[2][0],matrix[2][1],matrix[2][2]); }
00824 inline const Vector3    Matrix4::getTranslation ( MultiplicationOrder o ) const         { if( o == LEFT_MULTIPLY ) return Vector3(matrix[0][3],matrix[1][3],matrix[2][3]); else return Vector3(matrix[3][0],matrix[3][1],matrix[3][2]); }
00825 inline void                             Matrix4::setRotation    ( const Matrix3& m )                            { matrix[0][0] = m[0][0]; matrix[0][1] = m[0][1]; matrix[0][2] = m[0][2]; matrix[1][0] = m[1][0]; matrix[1][1] = m[1][1]; matrix[1][2] = m[1][2]; matrix[2][0] = m[2][0]; matrix[2][1] = m[2][1]; matrix[2][2] = m[2][2]; }
00826 inline void                             Matrix4::setTranslation ( const Vector3& v, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) { matrix[0][3] = v.x; matrix[1][3] = v.y; matrix[2][3] = v.z; } else { matrix[3][0] = v.x; matrix[3][1] = v.y; matrix[3][2] = v.z; } }
00827 inline void                             Matrix4::operator*=             ( const Matrix4& m )                            { *this = *this * m; }
00828 inline void                             Matrix4::multiply               ( const Matrix4& m, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) *this = m * (*this); else *this *= m; }
00829 inline void                             Matrix4::operator*=             ( T f )                                                         { for(int i=0;i<4;i++) for(int j=0;j<4;j++) matrix[i][j] *= f; }
00830 inline void                             Matrix4::operator+=             ( const Matrix4& m )                            { for(int i=0;i<4;i++) for(int j=0;j<4;j++) matrix[i][j] += m.matrix[i][j]; }
00831 inline void                             Matrix4::operator-=             ( const Matrix4& m )                            { for(int i=0;i<4;i++) for(int j=0;j<4;j++) matrix[i][j] -= m.matrix[i][j]; }
00832 inline const Matrix4    Matrix4::operator-              () const                                                        { return Matrix4( -matrix[0][0],-matrix[0][1],-matrix[0][2],-matrix[0][3], -matrix[1][0],-matrix[1][1],-matrix[1][2],-matrix[1][3], -matrix[2][0],-matrix[2][1],-matrix[2][2],-matrix[2][3],-matrix[3][0],-matrix[3][1],-matrix[3][2],-matrix[3][3]); }
00833 inline void                             Matrix4::identity               ()                                                                      { for(int i=0;i<4;i++) for(int j=0;j<4;j++) matrix[i][j] = (i == j) ? T(1) : T(0); }
00834 inline void                             Matrix4::transpose              ()                                                                      { SWAP(matrix[1][0], matrix[0][1]); SWAP(matrix[2][0], matrix[0][2]); SWAP(matrix[3][0], matrix[0][3]); SWAP(matrix[2][1], matrix[1][2]); SWAP(matrix[3][1], matrix[1][3]); SWAP(matrix[3][2], matrix[2][3]); }
00835 inline void                             Matrix4::translate              ( const Vector3& v, MultiplicationOrder o )     { if( o == LEFT_MULTIPLY ) { matrix[0][3] += v.x; matrix[1][3] += v.y; matrix[2][3] += v.z; } else { matrix[3][0] += v.x; matrix[3][1] += v.y; matrix[3][2] += v.z; } }
00836 inline void                             Matrix4::scale                  ( const Vector3& v, MultiplicationOrder o )     { multiply( Matrix4( v.x, T(0), T(0), T(0), T(0), v.y, T(0), T(0), T(0), T(0), v.z, T(0), T(0), T(0), T(0), T(1) ), o ); }
00837 
00838 //==============================================================================================
00839 //==============================================================================================
00840 
00841 //Matrix2x3 global functions
00842 inline bool                             operator==      ( const Matrix2x3& m1, const Matrix2x3& m2 )    { for(int i=0;i<2;i++) for(int j=0;j<3;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
00843 inline bool                             operator!=      ( const Matrix2x3& m1, const Matrix2x3& m2 )    { return !(m1 == m2); }
00844 const Matrix2x3                 operator*       ( const Matrix2x3& m1, const Matrix2x3& m2 );   //in .cpp
00845 inline const Matrix2x3  operator*       ( T f, const Matrix2x3& m )                                             { Matrix2x3 t(m); t *= f; return t; }
00846 inline const Matrix2x3  operator*       ( const Matrix2x3& m, T f )                                             { Matrix2x3 t(m); t *= f; return t; }
00847 inline const Matrix2x3  operator+       ( const Matrix2x3& m1, const Matrix2x3& m2 )    { Matrix2x3 t(m1); t += m2; return t; }
00848 inline const Matrix2x3  operator-       ( const Matrix2x3& m1, const Matrix2x3& m2 )    { Matrix2x3 t(m1); t -= m2; return t; }
00849 inline const Matrix2x3  transpose       ( const Matrix2x3& m )                                                  { Matrix2x3 t(m); t.transpose(); return t; }
00850 // if the matrix is singular, returns it unmodified
00851 inline const Matrix2x3  invert          ( const Matrix2x3& m )                                                  { Matrix2x3 t(m); t.invert(); return t; }
00852 
00853 //==============================================================================================
00854 //==============================================================================================
00855 
00856 //Matrix2x3 inline functions
00857 inline                                  Matrix2x3::Matrix2x3            ()                                                              { identity(); }
00858 inline                                  Matrix2x3::Matrix2x3            ( const Matrix2& m )                    { set(m[0][0],m[0][1],T(0),m[1][0],m[1][1],T(0)); }
00859 inline                                  Matrix2x3::Matrix2x3            ( const Matrix2x3& m )                  { *this = m; }
00860 inline                                  Matrix2x3::Matrix2x3            ( T m00, T m01, T m02, T m10, T m11, T m12 )    { set(m00,m01,m02,m10,m11,m12); }
00861 inline                                  Matrix2x3::~Matrix2x3           ()                                                              {}
00862 inline Matrix2x3&               Matrix2x3::operator=            ( const Matrix2x3& m )                  { for(int i=0;i<2;i++) for(int j=0;j<3;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
00863 inline Vector3&                 Matrix2x3::operator[]           ( int i )                                               { ASSERT(i>=0&&i<2); return (Vector3&)matrix[i][0]; }
00864 inline const Vector3&   Matrix2x3::operator[]           ( int i ) const                                 { ASSERT(i>=0&&i<2); return (const Vector3&)matrix[i][0]; }
00865 inline void                             Matrix2x3::set                          ( T m00, T m01, T m02, T m10, T m11, T m12 ) { matrix[0][0] = m00; matrix[0][1] = m01; matrix[0][2] = m02; matrix[1][0] = m10; matrix[1][1] = m11; matrix[1][2] = m12;  }
00866 inline const Vector3    Matrix2x3::getRow                       ( int i ) const                                 { ASSERT(i>=0&&i<2); return Vector3(matrix[i][0],matrix[i][1],matrix[i][2]); }
00867 inline const Vector2    Matrix2x3::getColumn            ( int i ) const                                 { ASSERT(i>=0&&i<3); return Vector2(matrix[0][i],matrix[1][i]); }
00868 inline void                             Matrix2x3::setRow                       ( int i, const Vector3& v )             { ASSERT(i>=0&&i<2); matrix[i][0] = v.x; matrix[i][1] = v.y; matrix[i][2] = v.z; }
00869 inline void                             Matrix2x3::setColumn            ( int i, const Vector2& v )             { ASSERT(i>=0&&i<3); matrix[0][i] = v.x; matrix[1][i] = v.y; }
00870 inline const Matrix2    Matrix2x3::getRotation          () const                                                { return Matrix2(matrix[0][0],matrix[0][1],matrix[1][0],matrix[1][1]); }
00871 inline const Vector2    Matrix2x3::getTranslation       () const                                                { return Vector2(matrix[0][2],matrix[1][2]); }
00872 inline void                             Matrix2x3::setRotation          ( const Matrix2& m )                    { matrix[0][0] = m[0][0]; matrix[0][1] = m[0][1]; matrix[1][0] = m[1][0]; matrix[1][1] = m[1][1]; }
00873 inline void                             Matrix2x3::setTranslation       ( const Vector2& v )                    { matrix[0][2] = v[0]; matrix[1][2] = v[1]; }
00874 inline void                             Matrix2x3::multiply                     ( const Matrix2x3& m )                  { *this = m * (*this); }
00875 inline void                             Matrix2x3::operator*=           ( T f )                                                 { for(int i=0;i<2;i++) for(int j=0;j<3;j++) matrix[i][j] *= f; }
00876 inline void                             Matrix2x3::operator+=           ( const Matrix2x3& m )                  { for(int i=0;i<2;i++) for(int j=0;j<3;j++) matrix[i][j] += m.matrix[i][j]; }
00877 inline void                             Matrix2x3::operator-=           ( const Matrix2x3& m )                  { for(int i=0;i<2;i++) for(int j=0;j<3;j++) matrix[i][j] -= m.matrix[i][j]; }
00878 inline const Matrix2x3  Matrix2x3::operator-            () const                                                { return Matrix2x3( -matrix[0][0],-matrix[0][1],-matrix[0][2], -matrix[1][0],-matrix[1][1],-matrix[1][2]); }
00879 inline void                             Matrix2x3::identity                     ()                                                              { for(int i=0;i<2;i++) for(int j=0;j<3;j++) matrix[i][j] = (i == j) ? T(1) : T(0); }
00880 inline void                             Matrix2x3::transpose            ()                                                              { SWAP(matrix[1][0], matrix[0][1]); }
00881 inline T                                Matrix2x3::det                          () const                                                { return getRotation().det( ); }
00882 inline void                             Matrix2x3::translate            ( const Vector2& v )                    { matrix[0][2] += v.x; matrix[1][2] += v.y; }
00883 inline void                             Matrix2x3::scale                        ( const Vector2& v )                    { multiply( Matrix2x3( v.x, T(0), T(0), T(0), v.y, T(0) ) ); }
00884 
00885 //==============================================================================================
00886 //==============================================================================================
00887 
00888 //Matrix3x2 global functions
00889 inline bool                             operator==      ( const Matrix3x2& m1, const Matrix3x2& m2 )    { for(int i=0;i<3;i++) for(int j=0;j<2;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
00890 inline bool                             operator!=      ( const Matrix3x2& m1, const Matrix3x2& m2 )    { return !(m1 == m2); }
00891 const Matrix3x2                 operator*       ( const Matrix3x2& m1, const Matrix3x2& m2 );   //in .cpp
00892 inline const Matrix3x2  operator*       ( T f, const Matrix3x2& m )                                             { Matrix3x2 t(m); t *= f; return t; }
00893 inline const Matrix3x2  operator*       ( const Matrix3x2& m, T f )                                             { Matrix3x2 t(m); t *= f; return t; }
00894 inline const Matrix3x2  operator+       ( const Matrix3x2& m1, const Matrix3x2& m2 )    { Matrix3x2 t(m1); t += m2; return t; }
00895 inline const Matrix3x2  operator-       ( const Matrix3x2& m1, const Matrix3x2& m2 )    { Matrix3x2 t(m1); t -= m2; return t; }
00896 inline const Matrix3x2  transpose       ( const Matrix3x2& m )                                                  { Matrix3x2 t(m); t.transpose(); return t; }
00897 // if the matrix is singular, returns it unmodified
00898 inline const Matrix3x2  invert          ( const Matrix3x2& m )                                                  { Matrix3x2 t(m); t.invert(); return t; }
00899 
00900 //==============================================================================================
00901 //==============================================================================================
00902 
00903 //Matrix3x2 inline functions
00904 inline                                  Matrix3x2::Matrix3x2            ()                                                              { identity(); }
00905 inline                                  Matrix3x2::Matrix3x2            ( const Matrix2& m )                    { set(m[0][0],m[0][1], m[1][0],m[1][1], T(0),T(0)); }
00906 inline                                  Matrix3x2::Matrix3x2            ( const Matrix3x2& m )                  { *this = m; }
00907 inline                                  Matrix3x2::Matrix3x2            ( T m00, T m01, T m10, T m11, T m20, T m21 )    { set(m00,m01,m10,m11,m20,m21); }
00908 inline                                  Matrix3x2::~Matrix3x2           ()                                                              {}
00909 inline Matrix3x2&               Matrix3x2::operator=            ( const Matrix3x2& m )                  { for(int i=0;i<3;i++) for(int j=0;j<2;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
00910 inline Vector2&                 Matrix3x2::operator[]           ( int i )                                               { ASSERT(i>=0&&i<3); return (Vector2&)matrix[i][0]; }
00911 inline const Vector2&   Matrix3x2::operator[]           ( int i ) const                                 { ASSERT(i>=0&&i<3); return (const Vector2&)matrix[i][0]; }
00912 inline void                             Matrix3x2::set                          ( T m00, T m01, T m10, T m11, T m20, T m21 ) { matrix[0][0] = m00; matrix[0][1] = m01; matrix[1][0] = m10; matrix[1][1] = m11; matrix[2][0] = m20; matrix[2][1] = m21; }
00913 inline const Vector2    Matrix3x2::getRow                       ( int i ) const                                 { ASSERT(i>=0&&i<3); return Vector2(matrix[i][0],matrix[i][1]); }
00914 inline const Vector3    Matrix3x2::getColumn            ( int i ) const                                 { ASSERT(i>=0&&i<2); return Vector3(matrix[0][i],matrix[1][i],matrix[2][i]); }
00915 inline void                             Matrix3x2::setRow                       ( int i, const Vector2& v )             { ASSERT(i>=0&&i<3); matrix[i][0] = v.x; matrix[i][1] = v.y; }
00916 inline void                             Matrix3x2::setColumn            ( int i, const Vector3& v )             { ASSERT(i>=0&&i<2); matrix[0][i] = v.x; matrix[1][i] = v.y; matrix[2][i] = v.z; }
00917 inline const Matrix2    Matrix3x2::getRotation          () const                                                { return Matrix2(matrix[0][0],matrix[0][1],matrix[1][0],matrix[1][1]); }
00918 inline const Vector2    Matrix3x2::getTranslation       () const                                                { return (*this)[2]; }
00919 inline void                             Matrix3x2::setRotation          ( const Matrix2& m )                    { matrix[0][0] = m[0][0]; matrix[0][1] = m[0][1]; matrix[1][0] = m[1][0]; matrix[1][1] = m[1][1]; }
00920 inline void                             Matrix3x2::setTranslation       ( const Vector2& v )                    { (*this)[2] = v; }
00921 inline void                             Matrix3x2::operator*=           ( const Matrix3x2& m )                  { *this = *this * m; }
00922 inline void                             Matrix3x2::multiply                     ( const Matrix3x2& m )                  { *this *= m; }
00923 inline void                             Matrix3x2::operator*=           ( T f )                                                 { for(int i=0;i<3;i++) for(int j=0;j<2;j++) matrix[i][j] *= f; }
00924 inline void                             Matrix3x2::operator+=           ( const Matrix3x2& m )                  { for(int i=0;i<3;i++) for(int j=0;j<2;j++) matrix[i][j] += m.matrix[i][j]; }
00925 inline void                             Matrix3x2::operator-=           ( const Matrix3x2& m )                  { for(int i=0;i<3;i++) for(int j=0;j<2;j++) matrix[i][j] -= m.matrix[i][j]; }
00926 inline const Matrix3x2  Matrix3x2::operator-            () const                                                { return Matrix3x2( -matrix[0][0],-matrix[0][1], -matrix[1][0],-matrix[1][1], -matrix[2][0],-matrix[2][1]); }
00927 inline void                             Matrix3x2::identity                     ()                                                              { for(int i=0;i<3;i++) for(int j=0;j<2;j++) matrix[i][j] = (i == j) ? T(1) : T(0); }
00928 inline void                             Matrix3x2::transpose            ()                                                              { SWAP(matrix[1][0], matrix[0][1]); }
00929 inline T                                Matrix3x2::det                          () const                                                { return ((Matrix2&)(*this)).det( ); }  //works because upperleft corner of Matrix3x2 is Matrix2x2
00930 inline void                             Matrix3x2::translate            ( const Vector2& v )                    { matrix[2][0] += v.x; matrix[2][1] += v.y; }
00931 inline void                             Matrix3x2::scale                        ( const Vector2& v )                    { multiply( Matrix3x2( v.x, T(0), T(0), v.y, T(0), T(0) ) ); }
00932 
00933 //==============================================================================================
00934 //==============================================================================================
00935 
00936 //Matrix3x4 global functions
00937 inline bool                             operator==      ( const Matrix3x4& m1, const Matrix3x4& m2 )    { for(int i=0;i<3;i++) for(int j=0;j<4;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
00938 inline bool                             operator!=      ( const Matrix3x4& m1, const Matrix3x4& m2 )    { return !(m1 == m2); }
00939 const Matrix3x4                 operator*       ( const Matrix3x4& m1, const Matrix3x4& m2 );   //in .cpp
00940 inline const Matrix3x4  operator*       ( T f, const Matrix3x4& m )                                             { Matrix3x4 t(m); t *= f; return t; }
00941 inline const Matrix3x4  operator*       ( const Matrix3x4& m, T f )                                             { Matrix3x4 t(m); t *= f; return t; }
00942 inline const Matrix3x4  operator+       ( const Matrix3x4& m1, const Matrix3x4& m2 )    { Matrix3x4 t(m1); t += m2; return t; }
00943 inline const Matrix3x4  operator-       ( const Matrix3x4& m1, const Matrix3x4& m2 )    { Matrix3x4 t(m1); t -= m2; return t; }
00944 inline const Matrix3x4  transpose       ( const Matrix3x4& m )                                                  { Matrix3x4 t(m); t.transpose(); return t; }
00945 // if the matrix is singular, returns it unmodified
00946 inline const Matrix3x4  invert          ( const Matrix3x4& m )                                                  { Matrix3x4 t(m); t.invert(); return t; }
00947 
00948 //==============================================================================================
00949 //==============================================================================================
00950 
00951 //Matrix3x4 inline functions
00952 inline                                  Matrix3x4::Matrix3x4            ()                                                              { identity(); }
00953 inline                                  Matrix3x4::Matrix3x4            ( const Matrix2& m )                    { set(m[0][0],m[0][1],T(0),T(0),m[1][0],m[1][1],T(0),T(0),T(0),T(0),T(1),T(0)); }
00954 inline                                  Matrix3x4::Matrix3x4            ( const Matrix2x3& m )                  { set(m[0][0],m[0][1],m[0][2],T(0),m[1][0],m[1][1],m[1][2],T(0),T(0),T(0),T(1),T(0)); }
00955 inline                                  Matrix3x4::Matrix3x4            ( const Matrix3x2& m )                  { set(m[0][0],m[0][1],T(0),T(0),m[1][0],m[1][1],T(0),T(0),m[2][0],m[2][1],T(1),T(0)); }
00956 inline                                  Matrix3x4::Matrix3x4            ( const Matrix3& m )                    { set(m[0][0],m[0][1],m[0][2],T(0),m[1][0],m[1][1],m[1][2],T(0),m[2][0],m[2][1],m[2][2],T(0)); }
00957 inline                                  Matrix3x4::Matrix3x4            ( const Matrix3x4& m )                  { *this = m; }
00958 inline                                  Matrix3x4::Matrix3x4            ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23 )  { set(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23); }
00959 inline                                  Matrix3x4::~Matrix3x4           ()                                                              {}
00960 inline Matrix3x4&               Matrix3x4::operator=            ( const Matrix3x4& m )                  { for(int i=0;i<3;i++) for(int j=0;j<4;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
00961 inline Vector4&                 Matrix3x4::operator[]           ( int i )                                               { ASSERT(i>=0&&i<3); return (Vector4&)matrix[i][0]; }
00962 inline const Vector4&   Matrix3x4::operator[]           ( int i ) const                                 { ASSERT(i>=0&&i<3); return (const Vector4&)matrix[i][0]; }
00963 inline void                             Matrix3x4::set                          ( T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23 ) { matrix[0][0] = m00; matrix[0][1] = m01; matrix[0][2] = m02; matrix[0][3] = m03; matrix[1][0] = m10; matrix[1][1] = m11; matrix[1][2] = m12;  matrix[1][3] = m13; matrix[2][0] = m20; matrix[2][1] = m21; matrix[2][2] = m22; matrix[2][3] = m23; }
00964 inline const Vector4    Matrix3x4::getRow                       ( int i ) const                                 { ASSERT(i>=0&&i<3); return Vector4(matrix[i][0],matrix[i][1],matrix[i][2],matrix[i][3]); }
00965 inline const Vector3    Matrix3x4::getColumn            ( int i ) const                                 { ASSERT(i>=0&&i<4); return Vector3(matrix[0][i],matrix[1][i],matrix[2][i]); }
00966 inline void                             Matrix3x4::setRow                       ( int i, const Vector4& v )             { ASSERT(i>=0&&i<3); matrix[i][0] = v.x; matrix[i][1] = v.y; matrix[i][2] = v.z; matrix[i][3] = v.w; }
00967 inline void                             Matrix3x4::setColumn            ( int i, const Vector3& v )             { ASSERT(i>=0&&i<4); matrix[0][i] = v.x; matrix[1][i] = v.y; matrix[2][i] = v.z; }
00968 inline const Matrix3    Matrix3x4::getRotation          () const                                                { return Matrix3(matrix[0][0],matrix[0][1],matrix[0][2],matrix[1][0],matrix[1][1],matrix[1][2],matrix[2][0],matrix[2][1],matrix[2][2]); }
00969 inline const Vector3    Matrix3x4::getTranslation       () const                                                { return Vector3(matrix[0][3],matrix[1][3],matrix[2][3]); }
00970 inline void                             Matrix3x4::setRotation          ( const Matrix3& m )                    { matrix[0][0] = m[0][0]; matrix[0][1] = m[0][1]; matrix[0][2] = m[0][2]; matrix[1][0] = m[1][0]; matrix[1][1] = m[1][1]; matrix[1][2] = m[1][2]; matrix[2][0] = m[2][0]; matrix[2][1] = m[2][1]; matrix[2][2] = m[2][2]; }
00971 inline void                             Matrix3x4::setTranslation       ( const Vector3& v )                    { matrix[0][3] = v[0]; matrix[1][3] = v[1]; matrix[2][3] = v[2]; }
00972 inline void                             Matrix3x4::multiply                     ( const Matrix3x4& m )                  { *this = m * (*this); }
00973 inline void                             Matrix3x4::operator*=           ( T f )                                                 { for(int i=0;i<3;i++) for(int j=0;j<4;j++) matrix[i][j] *= f; }
00974 inline void                             Matrix3x4::operator+=           ( const Matrix3x4& m )                  { for(int i=0;i<3;i++) for(int j=0;j<4;j++) matrix[i][j] += m.matrix[i][j]; }
00975 inline void                             Matrix3x4::operator-=           ( const Matrix3x4& m )                  { for(int i=0;i<3;i++) for(int j=0;j<4;j++) matrix[i][j] -= m.matrix[i][j]; }
00976 inline const Matrix3x4  Matrix3x4::operator-            () const                                                { return Matrix3x4( -matrix[0][0],-matrix[0][1],-matrix[0][2],-matrix[0][3], -matrix[1][0],-matrix[1][1],-matrix[1][2],-matrix[1][3], -matrix[2][0],-matrix[2][1],-matrix[2][2],-matrix[2][3]); }
00977 inline void                             Matrix3x4::identity                     ()                                                              { for(int i=0;i<3;i++) for(int j=0;j<4;j++) matrix[i][j] = (i == j) ? T(1) : T(0); }
00978 inline void                             Matrix3x4::transpose            ()                                                              { SWAP(matrix[1][0], matrix[0][1]); SWAP(matrix[2][0], matrix[0][2]); SWAP(matrix[2][1], matrix[1][2]); }
00979 inline T                                Matrix3x4::det                          () const                                                { return getRotation().det( ); }
00980 inline void                             Matrix3x4::translate            ( const Vector3& v )                    { matrix[0][3] += v.x; matrix[1][3] += v.y; matrix[2][3] += v.z; }
00981 inline void                             Matrix3x4::scale                        ( const Vector3& v )                    { multiply( Matrix3x4( v.x, T(0), T(0), T(0), T(0), v.y, T(0), T(0), T(0), T(0), v.z, T(0)) ); }
00982 
00983 //==============================================================================================
00984 //==============================================================================================
00985 
00986 //Matrix4x3 global functions
00987 inline bool                             operator==      ( const Matrix4x3& m1, const Matrix4x3& m2 )    { for(int i=0;i<4;i++) for(int j=0;j<3;j++) if( m1[i][j] != m2[i][j] ) return false; return true; }
00988 inline bool                             operator!=      ( const Matrix4x3& m1, const Matrix4x3& m2 )    { return !(m1 == m2); }
00989 const Matrix4x3                 operator*       ( const Matrix4x3& m1, const Matrix4x3& m2 );   //in .cpp
00990 inline const Matrix4x3  operator*       ( T f, const Matrix4x3& m )                                             { Matrix4x3 t(m); t *= f; return t; }
00991 inline const Matrix4x3  operator*       ( const Matrix4x3& m, T f )                                             { Matrix4x3 t(m); t *= f; return t; }
00992 inline const Matrix4x3  operator+       ( const Matrix4x3& m1, const Matrix4x3& m2 )    { Matrix4x3 t(m1); t += m2; return t; }
00993 inline const Matrix4x3  operator-       ( const Matrix4x3& m1, const Matrix4x3& m2 )    { Matrix4x3 t(m1); t -= m2; return t; }
00994 inline const Matrix4x3  transpose       ( const Matrix4x3& m )                                                  { Matrix4x3 t(m); t.transpose(); return t; }
00995 // if the matrix is singular, returns it unmodified
00996 inline const Matrix4x3  invert          ( const Matrix4x3& m )                                                  { Matrix4x3 t(m); t.invert(); return t; }
00997 
00998 //==============================================================================================
00999 //==============================================================================================
01000 
01001 //Matrix4x3 inline functions
01002 inline                                  Matrix4x3::Matrix4x3            ()                                                              { identity(); }
01003 inline                                  Matrix4x3::Matrix4x3            ( const Matrix2& m )                    { set(m[0][0],m[0][1],T(0),m[1][0],m[1][1],T(0),T(0),T(0),T(1),T(0),T(0),T(0)); }
01004 inline                                  Matrix4x3::Matrix4x3            ( const Matrix2x3& m )                  { set(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],T(0),T(0),T(1),T(0),T(0),T(0)); }
01005 inline                                  Matrix4x3::Matrix4x3            ( const Matrix3x2& m )                  { set(m[0][0],m[0][1],T(0),m[1][0],m[1][1],T(0),m[2][0],m[2][1],T(1),T(0),T(0),T(0)); }
01006 inline                                  Matrix4x3::Matrix4x3            ( const Matrix3& m )                    { set(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],m[2][0],m[2][1],m[2][2],T(0),T(0),T(0)); }
01007 inline                                  Matrix4x3::Matrix4x3            ( const Matrix4x3& m )                  { *this = m; }
01008 inline                                  Matrix4x3::Matrix4x3            ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22, T m30, T m31, T m32 )  { set(m00,m01,m02,m10,m11,m12,m20,m21,m22,m30,m31,m32); }
01009 inline                                  Matrix4x3::~Matrix4x3           ()                                                              {}
01010 inline Matrix4x3&               Matrix4x3::operator=            ( const Matrix4x3& m )                  { for(int i=0;i<4;i++) for(int j=0;j<3;j++) matrix[i][j] = m.matrix[i][j]; return *this; }
01011 inline Vector3&                 Matrix4x3::operator[]           ( int i )                                               { ASSERT(i>=0&&i<4); return (Vector3&)matrix[i][0]; }
01012 inline const Vector3&   Matrix4x3::operator[]           ( int i ) const                                 { ASSERT(i>=0&&i<4); return (const Vector3&)matrix[i][0]; }
01013 inline void                             Matrix4x3::set                          ( T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22, T m30, T m31, T m32 ) { matrix[0][0] = m00; matrix[0][1] = m01; matrix[0][2] = m02; matrix[1][0] = m10; matrix[1][1] = m11; matrix[1][2] = m12; matrix[2][0] = m20; matrix[2][1] = m21; matrix[2][2] = m22; matrix[3][0] = m30; matrix[3][1] = m31; matrix[3][2] = m32; }
01014 inline const Vector3    Matrix4x3::getRow                       ( int i ) const                                 { ASSERT(i>=0&&i<4); return Vector3(matrix[i][0],matrix[i][1],matrix[i][2]); }
01015 inline const Vector4    Matrix4x3::getColumn            ( int i ) const                                 { ASSERT(i>=0&&i<3); return Vector4(matrix[0][i],matrix[1][i],matrix[2][i],matrix[3][i]); }
01016 inline void                             Matrix4x3::setRow                       ( int i, const Vector3& v )             { ASSERT(i>=0&&i<4); matrix[i][0] = v.x; matrix[i][1] = v.y; matrix[i][2] = v.z; }
01017 inline void                             Matrix4x3::setColumn            ( int i, const Vector4& v )             { ASSERT(i>=0&&i<3); matrix[0][i] = v.x; matrix[1][i] = v.y; matrix[2][i] = v.z; matrix[3][i] = v.w; }
01018 inline const Matrix3    Matrix4x3::getRotation          () const                                                { return Matrix3(matrix[0][0],matrix[0][1],matrix[0][2],matrix[1][0],matrix[1][1],matrix[1][2],matrix[2][0],matrix[2][1],matrix[2][2]); }
01019 inline const Vector3    Matrix4x3::getTranslation       () const                                                { return (*this)[3]; }
01020 inline void                             Matrix4x3::setRotation          ( const Matrix3& m )                    { matrix[0][0] = m[0][0]; matrix[0][1] = m[0][1]; matrix[0][2] = m[0][2]; matrix[1][0] = m[1][0]; matrix[1][1] = m[1][1]; matrix[1][2] = m[1][2]; matrix[2][0] = m[2][0]; matrix[2][1] = m[2][1]; matrix[2][2] = m[2][2]; }
01021 inline void                             Matrix4x3::setTranslation       ( const Vector3& v )                    { (*this)[3] = v; }
01022 inline void                             Matrix4x3::operator*=           ( const Matrix4x3& m )                  { *this = *this * m; }
01023 inline void                             Matrix4x3::multiply                     ( const Matrix4x3& m )                  { *this *= m; }
01024 inline void                             Matrix4x3::operator*=           ( T f )                                                 { for(int i=0;i<4;i++) for(int j=0;j<3;j++) matrix[i][j] *= f; }
01025 inline void                             Matrix4x3::operator+=           ( const Matrix4x3& m )                  { for(int i=0;i<4;i++) for(int j=0;j<3;j++) matrix[i][j] += m.matrix[i][j]; }
01026 inline void                             Matrix4x3::operator-=           ( const Matrix4x3& m )                  { for(int i=0;i<4;i++) for(int j=0;j<3;j++) matrix[i][j] -= m.matrix[i][j]; }
01027 inline const Matrix4x3  Matrix4x3::operator-            () const                                                { return Matrix4x3( -matrix[0][0],-matrix[0][1],-matrix[0][2], -matrix[1][0],-matrix[1][1],-matrix[1][2], -matrix[2][0],-matrix[2][1],-matrix[2][2],-matrix[3][0],-matrix[3][1],-matrix[3][2]); }
01028 inline void                             Matrix4x3::identity                     ()                                                              { for(int i=0;i<4;i++) for(int j=0;j<3;j++) matrix[i][j] = (i == j) ? T(1) : T(0); }
01029 inline void                             Matrix4x3::transpose            ()                                                              { SWAP(matrix[1][0], matrix[0][1]); SWAP(matrix[2][0], matrix[0][2]); SWAP(matrix[2][1], matrix[1][2]); }
01030 inline T                                Matrix4x3::det                          () const                                                { return ((Matrix3&)(*this)).det( ); }  //works because upperleft corner of Matrix4x3 is Matrix3x3
01031 inline void                             Matrix4x3::translate            ( const Vector3& v )                    { matrix[3][0] += v.x; matrix[3][1] += v.y; matrix[3][2] += v.z; }
01032 inline void                             Matrix4x3::scale                        ( const Vector3& v )                    { multiply( Matrix4x3( v.x, T(0), T(0), T(0), v.y, T(0), T(0), T(0), v.z, T(0), T(0), T(0)) ); }
01033 
01034 //==============================================================================================
01035 //==============================================================================================
01036 
01037 //global matrix conversions
01038 //NOTE: these could be constructors of respective classes, but as the compiler would use constructors
01039 // in unexpected places, it was considered safer to make the conversion explicit.
01040 // the safe conversions (from smaller to larger) are written as constructors
01041 
01042 //there are no conversion for vectors, as these are easy enough to write with constructors:
01043 // Vector3 a(1,2,3); Vector2 b(a.x, a.y);
01044 
01045 //these transpose the matrix
01046 inline const Matrix2x3  makeMatrix2x3   ( const Matrix3x2& m )                                          { Matrix2x3 t; for(int i=0;i<3;i++) for(int j=0;j<2;j++) t[j][i] = m[i][j]; return t; }
01047 inline const Matrix3x2  makeMatrix3x2   ( const Matrix2x3& m )                                          { Matrix3x2 t; for(int i=0;i<3;i++) for(int j=0;j<2;j++) t[i][j] = m[j][i]; return t; }
01048 
01049 inline const Matrix3x4  makeMatrix3x4   ( const Matrix4x3& m )                                          { Matrix3x4 t; for(int i=0;i<4;i++) for(int j=0;j<3;j++) t[j][i] = m[i][j]; return t; }
01050 inline const Matrix4x3  makeMatrix4x3   ( const Matrix3x4& m )                                          { Matrix4x3 t; for(int i=0;i<4;i++) for(int j=0;j<3;j++) t[i][j] = m[j][i]; return t; }
01051 
01052 //these take the upper-left submatrix of the larger matrix
01053 inline const Matrix2    makeMatrix2             ( const Matrix2x3& m )                                          { return Matrix2(m[0][0],m[0][1],m[1][0],m[1][1]); }
01054 inline const Matrix2    makeMatrix2             ( const Matrix3x2& m )                                          { return Matrix2(m[0][0],m[0][1],m[1][0],m[1][1]); }
01055 inline const Matrix2    makeMatrix2             ( const Matrix3& m )                                            { return Matrix2(m[0][0],m[0][1],m[1][0],m[1][1]); }
01056 inline const Matrix2    makeMatrix2             ( const Matrix3x4& m )                                          { return Matrix2(m[0][0],m[0][1],m[1][0],m[1][1]); }
01057 inline const Matrix2    makeMatrix2             ( const Matrix4x3& m )                                          { return Matrix2(m[0][0],m[0][1],m[1][0],m[1][1]); }
01058 inline const Matrix2    makeMatrix2             ( const Matrix4& m )                                            { return Matrix2(m[0][0],m[0][1],m[1][0],m[1][1]); }
01059 
01060 inline const Matrix3x2  makeMatrix3x2   ( const Matrix3& m )                                            { return Matrix3x2(m[0][0],m[0][1],m[1][0],m[1][1],m[2][0],m[2][1]); }
01061 inline const Matrix2x3  makeMatrix2x3   ( const Matrix3& m )                                            { return Matrix2x3(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2]); }
01062 
01063 inline const Matrix3    makeMatrix3             ( const Matrix3x4& m )                                          { return Matrix3(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],m[2][0],m[2][1],m[2][2]); }
01064 inline const Matrix3    makeMatrix3             ( const Matrix4x3& m )                                          { return Matrix3(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],m[2][0],m[2][1],m[2][2]); }
01065 inline const Matrix3    makeMatrix3             ( const Matrix4& m )                                            { return Matrix3(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],m[2][0],m[2][1],m[2][2]); }
01066 
01067 inline const Matrix3x2  makeMatrix3x2   ( const Matrix4& m )                                            { return Matrix3x2(m[0][0],m[0][1],m[1][0],m[1][1],m[2][0],m[2][1]); }
01068 inline const Matrix2x3  makeMatrix2x3   ( const Matrix4& m )                                            { return Matrix2x3(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2]); }
01069 
01070 inline const Matrix4x3  makeMatrix4x3   ( const Matrix4& m )                                            { return Matrix4x3(m[0][0],m[0][1],m[0][2],m[1][0],m[1][1],m[1][2],m[2][0],m[2][1],m[2][2],m[3][0],m[3][1],m[3][2]); }
01071 inline const Matrix3x4  makeMatrix3x4   ( const Matrix4& m )                                            { return Matrix3x4(m[0][0],m[0][1],m[0][2],m[0][3],m[1][0],m[1][1],m[1][2],m[1][3],m[2][0],m[2][1],m[2][2],m[2][3]); }
01072 
01073 //==============================================================================================
01074 //==============================================================================================
01075 
01076 
01077 
01078 
01079 
01080 //==============================================================================================
01081 //==============================================================================================
01082 
01083 class Vector2Factory
01084 {
01085 public:
01086         static const Vector2    randInSquare    ( T edgeLength = T(2) );
01087         static const Vector2    randInCircle    ( T radius = T(1) );
01088         static const Vector2    randOnCircle    ( T radius = T(1) );
01089         //returns a vector perpendicular to v in the counterclockwise direction
01090         static const Vector2    perpendicular   ( const Vector2& v );
01091 };
01092 
01093 //==============================================================================================
01094 //==============================================================================================
01095 
01096 class Vector3Factory
01097 {
01098 public:
01099         static const Vector3    randInCube              ( T edgeLength = T(2) );
01100         static const Vector3    randInSphere    ( T radius = T(1) );
01101         static const Vector3    randOnSphere    ( T radius = T(1) );
01102         //returns a "random" vector perpendicular to v
01103         //for more randomness, rotate the result by a random amount about v
01104         static const Vector3    perpendicular   ( const Vector3& v );
01105 };
01106 
01107 //==============================================================================================
01108 //==============================================================================================
01109 
01110 class Vector4Factory
01111 {
01112 public:
01113         static const Vector4    randInCube              ( T edgeLength = T(2) );
01114         static const Vector4    randInSphere    ( T radius = T(1) );
01115         static const Vector4    randOnSphere    ( T radius = T(1) );
01116 };
01117 
01118 //==============================================================================================
01119 //==============================================================================================
01120 
01121 //constructs left-handed coordinate systems
01122 //TODO add support for right-handed coordinate systems
01123 //TODO add random rotation matrix?
01124 
01125 // \todo [020731 jan] I'd prefer complete set of functionality for both D3D and OpenGL.
01126 //                                              - enum ProjectionModel { OPENGL, DIRECT3D, WHATNOT };
01127 //                                              - need frustum, ortho, frustumFOV
01128 
01129 class MatrixFactory
01130 {
01131 public:
01132         //given the position of the viewer and the target, and the up-vector, makes an orthonormal rotation
01133         //matrix where z-axis points towards the target
01134         static const Matrix3    target          ( const Vector3& pos, const Vector3& tgt, const Vector3& up, MultiplicationOrder o );
01135 
01136         //The (left, bottom, znear) and (right, top, znear) parameters specify the points on the
01137         //near clipping plane that are mapped to the lower-left and upper-right corners of the window,
01138         //respectively, assuming that the eye is located at (0, 0, 0)
01139         //this maps the view frustum to a box with dimensions [-1,1]
01140         //this corresponds to OpenGL projection matrix format
01141         static const Matrix4    frustum         ( T left, T right, T bottom, T top, T zNear, T zFar, MultiplicationOrder o );
01142 
01143         //this maps the view frustum to a box with dimensions [-1,1]
01144         //this corresponds to OpenGL projection matrix format
01145         //FOV is given in radians
01146         static const Matrix4    frustum         ( T horizontalFOV, T verticalFOV, T zNear, T zFar, MultiplicationOrder o );
01147 
01148         //The (left, bottom, near) and (right, top, near) parameters specify the points on the
01149         //near clipping plane that are mapped to the lower-left and upper-right corners of the window,
01150         //respectively, assuming that the eye is located at (0, 0, 0)
01151         //this maps the view frustum to a box with dimensions [-1,1]
01152         //this corresponds to OpenGL projection matrix format
01153         static const Matrix4    ortho           ( T left, T right, T bottom, T top, T zNear, T zFar, MultiplicationOrder o );
01154 
01155         //this maps the view frustum to a box with dimensions [-1,1] for x- and y-axis, and [0,1] for z-axis
01156         //this corresponds to Direct3D projection matrix format
01157         //FOV is given in radians
01158         static const Matrix4    frustum01       ( T horizontalFOV, T verticalFOV, T zNear, T zFar, MultiplicationOrder o );
01159 
01160 };
01161 
01162 //==============================================================================================
01163 //==============================================================================================
01164 
01165 }      //namespace VECTORMATRIX
01166 
01167 #endif //__VECTORMATRIX_HPP
01168 
01171 
01172 // NEW FILE
01173 
01174 #ifndef SBDEF_H
01175 #define SBDEF_H
01176 
01177 //=======================================================================
01178 //=======================================================================
01179 
01180 //#include <float.h>            //for FLT_MAX
01181 #include <math.h>               //for sqrt, sin and cos
01182 #include <stdlib.h>             //for rand
01183 #include <assert.h>
01184 #include <string.h>
01185 
01186 //TODO add Timer class?
01187 
01188 //=======================================================================
01189 //=======================================================================
01190 
01191 #define PI                                              3.141592654f
01192 template<class TT> inline TT    RAD( TT x )                                                             { return x * TT(PI) / TT(180); }
01193 template<class TT> inline TT    DEG( TT x )                                                             { return x * TT(180) / TT(PI); }
01194 template<class TT> inline TT    MAX( TT a, TT b )                                               { return ( a > b ) ? a : b; }
01195 template<class TT> inline TT    MIN( TT a, TT b )                                               { return ( a < b ) ? a : b; }
01196 template<class TT> inline TT    CLAMP( TT x, TT min, TT max )                   { ASSERT( min <= max ); return (x >= max) ? max : (x <= min) ? min : x; }
01197 template<class TT> inline TT    STEP( TT x, TT edge )                                   { if( x < edge ) return TT(0); return TT(1); }
01198 template<class TT> inline TT    SMOOTHSTEP( TT x, TT edge0, TT edge1 )  { ASSERT( edge0 <= edge1 ); if(x <= edge0) return TT(0); if(x >= edge1) return TT(1); TT t = (x - edge0) / (edge1 - edge0); return t * t * (TT(3) - TT(2) * t); }
01199 template<class TT> inline int   SIGN( TT x )                                                    { unsigned int a = *reinterpret_cast<const unsigned int*>(&x); if( !(a & 0x7fffffff) ) return 0; if( a & 0x80000000 ) return -1; return 1; }
01200 template<class TT> inline TT    LERP( TT x, TT y, TT r )                                { return x + r * (y - x); }
01201 inline float                                    RAND01()                                                                { return float(rand()) / float(RAND_MAX); }     //random number [0,1]
01202 inline int                                              FLOOR( const float& f )
01203 { 
01204         int a                   = *reinterpret_cast<const int*>(&f);                                                                    // take bit pattern of float into a register
01205         int sign                = (a>>31);                                                                                                                              // sign = 0xFFFFFFFF if original value is negative, 0 if positive
01206         a&=0x7fffffff;                                                                                                                                                  // we don't need the sign any more
01207         int exponent    = (a>>23)-127;                                                                                                                  // extract the exponent
01208         int expsign             = ~(exponent>>31);                                                                                                              // 0xFFFFFFFF if exponent is positive, 0 otherwise
01209         int imask               = ( (1<<(31-(exponent))))-1;                                                                                    // mask for true integer values
01210         int mantissa    = (a&((1<<23)-1));                                                                                                              // extract mantissa (without the hidden bit)
01211         int r                   = ((unsigned int)(mantissa|(1<<23))<<8)>>(31-exponent);                                 // ((1<<exponent)*(mantissa|hidden bit))>>24 -- (we know that mantissa > (1<<24))
01212         r = ((r & expsign) ^ (sign)) + ((!((mantissa<<8)&imask)&(expsign^((a-1)>>31)))&sign);   // if (fabs(value)<1.0) value = 0; copy sign; if (value < 0 && value==(int)(value)) value++; 
01213         return r;
01214 }
01215 inline int                                              CEIL( const float& f )
01216 { 
01217         int a                   = *reinterpret_cast<const int*>(&f) ^ 0x80000000;                                               // take bit pattern of float into a register
01218         int sign                = (a>>31);                                                                                                                              // sign = 0xFFFFFFFF if original value is negative, 0 if positive
01219         a&=0x7fffffff;                                                                                                                                                  // we don't need the sign any more
01220         int exponent    = (a>>23)-127;                                                                                                                  // extract the exponent
01221         int expsign             = ~(exponent>>31);                                                                                                              // 0xFFFFFFFF if exponent is positive, 0 otherwise
01222         int imask               = ( (1<<(31-(exponent))))-1;                                                                                    // mask for true integer values
01223         int mantissa    = (a&((1<<23)-1));                                                                                                              // extract mantissa (without the hidden bit)
01224         int r                   = ((unsigned int)(mantissa|(1<<23))<<8)>>(31-exponent);                                 // ((1<<exponent)*(mantissa|hidden bit))>>24 -- (we know that mantissa > (1<<24))
01225         r = ((r & expsign) ^ (sign)) + ((!((mantissa<<8)&imask)&(expsign^((a-1)>>31)))&sign);   // if (fabs(value)<1.0) value = 0; copy sign; if (value < 0 && value==(int)(value)) value++; 
01226         return -r;
01227 }
01228 inline float                                    FRACT( float x )                                                { return x - float(FLOOR(x)); }
01229 inline unsigned int                             CEILPOW2( unsigned int x )
01230 {
01231         x--;
01232         x |= (x >>  1);
01233         x |= (x >>  2);
01234         x |= (x >>  4);
01235         x |= (x >>  8);
01236         x |= (x >> 16);
01237         return x + 1;
01238 }
01239 
01240 //=======================================================================
01241 //=======================================================================
01242 
01243 class Surface
01244 {
01245 public:
01246         Surface( int w, int h )
01247         {
01248                 m_data = NULL;
01249                 m_width = 0;
01250                 m_height = 0;
01251                 resize(w,h);
01252         }
01253         ~Surface()
01254         {
01255                 delete[] m_data;
01256         }
01257 
01258         void            resize( int w, int h )
01259         {
01260                 assert(w>0 && h>0);
01261                 if( w == m_width && h == m_height )
01262                         return;
01263                 delete[] m_data;
01264                 m_width = w;
01265                 m_height = h;
01266                 m_data = new unsigned int[w*h];
01267         }
01268 
01269         void            clear()
01270         {
01271                 memset(m_data,0,sizeof(unsigned int)*m_width*m_height);
01272         }
01273 
01274         int                             getWidth() const                { return m_width; }
01275         int                             getHeight() const               { return m_height; }
01276         unsigned int*   getSurfaceData() const  { return m_data; }
01277 private:
01278         unsigned int*   m_data;
01279         int                             m_width;
01280         int                             m_height;
01281 };
01282 
01283 //=======================================================================
01284 //=======================================================================
01285 
01286 //#ifdef DETECT_MEMORY_LEAKS ???
01287 // memory leak detection
01288 /*void* operator new            (size_t s);
01289 void*   operator new[]          (size_t s);
01290 void    operator delete         (void* p);
01291 void    operator delete[]       (void* p);
01292 */
01293 //#endif
01294 /*      //put these in main.cpp
01295 static int s_allocations = 0, s_allocationsDone = 0;
01296 void*   operator new            (size_t s)      { ++s_allocations; ++s_allocationsDone; return malloc(s);       }
01297 void*   operator new[]          (size_t s)      { ++s_allocations; ++s_allocationsDone; return malloc(s);       }
01298 void    operator delete         (void* p)       { if (p) { free(p); --s_allocations;}   }
01299 void    operator delete[]       (void* p)       { if (p) { free(p); --s_allocations;}   }
01300 */
01301 
01302 //=======================================================================
01303 //=======================================================================
01304 
01305 // #include "VectorMatrix.hpp"
01306 using namespace VECTORMATRIX;
01307 
01308 //=======================================================================
01309 //=======================================================================
01310 
01311 //=======================================================================
01312 //=======================================================================
01313 
01314 #endif //SBDEF_H
01315 
01316 
01317 #ifndef __FILE_H
01318 #define __FILE_H
01319 
01320 bool                    fileExists( const char *name );
01321 char*                   fileLoad( const char *name );
01322 void                    fileSave( const char *name, const void *s, unsigned int l );
01323 unsigned int    fileSize( const char *name );
01324 void                    fileFree( char *data );
01325 
01326 #endif //__FILE_H
01327 #ifndef MESH_H
01328 #define MESH_H
01329 
01330 // #include "def.h"
01331 
01332 #ifdef _MSC_VER         //ms visual studio
01333 #pragma warning(disable:4786)   //debug info was truncated to 255 characters
01334 #endif
01335 
01336 #include <string>
01337 #include <vector>
01338 
01339 //TODO test discontinuos vertex maps (VMAD) with more than one point chunk
01340 
01341 //=============================================================================
01342 //=============================================================================
01343 
01344 //fast next and prev functions with mod 3
01345 //the input must be 0,1 or 2
01346 inline int nextMod3( int i )    { assert(i>=0&&i<3); return (1 << i) & 3; }     // (i+1) % 3
01347 inline int prevMod3( int i )    { assert(i>=0&&i<3); return (0x102 >> (i<<2)) & 0xf; }  // (i-1+3) % 3
01348 
01349 //=============================================================================
01350 //=============================================================================
01351 
01352 class Mesh
01353 {
01354 public:
01355 #pragma pack( push, 4 )
01356         struct Vertex
01357         {
01358                 void                    null()
01359                 {
01360                         m_position.set(0,0,0);
01361                         m_normal.set(0,0,0);
01362                         m_t1.set(0,0,0);
01363                         m_t2.set(0,0,0);
01364                         m_uv.set(0,0);
01365                         m_diffuse.set(0,0,0,0);
01366                 }
01367                 void                    add( const Vertex& v )
01368                 {
01369                         m_position += v.m_position;
01370                         m_normal += v.m_normal;
01371                         m_t1 += v.m_t1;
01372                         m_t2 += v.m_t2;
01373                         m_uv += v.m_uv;
01374                         m_diffuse += v.m_diffuse;
01375                 }
01376                 void                    mad( const Vertex& v, float c )
01377                 {
01378                         m_position += v.m_position * c;
01379                         m_normal += v.m_normal * c;
01380                         m_t1 += v.m_t1 * c;
01381                         m_t2 += v.m_t2 * c;
01382                         m_uv += v.m_uv * c;
01383                         m_diffuse += v.m_diffuse * c;
01384                 }
01385                 void                    normalize()
01386                 {
01387                         m_normal.normalize();
01388                         m_t1.normalize();
01389                         m_t2.normalize();
01390                 }
01391                 Vector3                 m_position;
01392                 Vector3                 m_normal;
01393                 Vector3                 m_t1;                           //tangent 1
01394                 Vector3                 m_t2;                           //tangent 2
01395                 int                             m_triangleUsing;        //30msb polyindex 2lsb edgeindex
01396                 Vector2                 m_uv;
01397                 Vector4                 m_diffuse;
01398                 bool                    m_reliable;                     //true if it was possible to calculate the tangent field reliably using curvature
01399         };
01400 
01401         struct Triangle
01402         {
01403                 Vector3                 m_normal;
01404                 float                   m_area;
01405                 int                             m_surface;                      //index into the surface array
01406                 int                             m_v[3];                         //vertex indices into the vertex array
01407                 int                             m_n[3];                         //neighbour indices into the triangle array
01408                 char                    m_nedge[3];                     //corresponding neighbours' edge numbers
01409                 char                    m_dummy;                        //for alignment
01410                 Vector2                 m_uv[3];
01411                 int                             m_baseTriangle;         //original triangle index before subdivision
01412         };
01413 
01414         struct Edge
01415         {
01416                 bool operator<( const Edge& e ) const   { if( m_v[0] < e.m_v[0] ) return true; else if( m_v[0] > e.m_v[0] ) return false; else return (m_v[1] < e.m_v[1]) ? true : false; }
01417                 bool operator==( const Edge& e ) const  { if( m_v[0] == e.m_v[0] && m_v[1] == e.m_v[1] ) return true; return false; }
01418                 int                             m_v[2];
01419                 int                             m_t[2];
01420         };
01421 
01422         struct Surface
01423         {
01424                 Vector4                 m_color;
01425                 int                             m_polygons;                     //polygons using this surface material
01426                 std::string             m_name;
01427         };
01428 #pragma pack( pop )
01429 
01430         Mesh();
01431         Mesh( int vertices, int triangles );
01432         Mesh( const char* fileName );
01433         Mesh( const Mesh& m );
01434         ~Mesh();
01435 
01436         void                                    load( const char* fileName );
01437         void                                    save( const char* fileName );
01438         void                                    copy( const Mesh& m );
01439         void                                    clear( int newVertices, int newTriangles );
01440 
01441         Vertex&                                 getVertex( int i )                              { assert(i>=0&&i<(int)m_vertices.size()); return m_vertices[i]; }
01442         Triangle&                               getTriangle( int i )                    { assert(i>=0&&i<(int)m_triangles.size()); return m_triangles[i]; }
01443         Edge&                                   getEdge( int i )                                { assert(i>=0&&i<(int)m_edges.size()); return m_edges[i]; }
01444         Surface&                                getSurface( int i )                             { assert(i>=0&&i<(int)m_surfaces.size()); return m_surfaces[i]; }
01445 
01446         int                                             getVertexCount() const                  { return m_vertices.size(); }
01447         int                                             getTriangleCount() const                { return m_triangles.size(); }
01448         int                                             getEdgeCount() const                    { return m_edges.size(); }
01449         int                                             getSurfaceCount() const                 { return m_surfaces.size(); }
01450 
01451         std::vector<Vertex>&    getVertices()                                   { return m_vertices; }
01452         std::vector<Triangle>&  getTriangles()                                  { return m_triangles; }
01453         std::vector<Edge>&              getEdges()                                              { return m_edges; }
01454         std::vector<Surface>&   getSurfaces()                                   { return m_surfaces; }
01455 
01456         const Vector3&                  getBoundingBoxMin() const               { return m_boundingBoxMin; }
01457         const Vector3&                  getBoundingBoxMax() const               { return m_boundingBoxMax; }
01458         float                                   getBoundingRadius() const               { return m_boundingRadius; }
01459 
01460         void                                    calculateAdjacency();   //calculates also edges and sets triangleUsing
01461         void                                    recalculateAdjacency(); //forces recalculation of adjacency
01462         void                                    calculateCurvature();
01463         void                                    calculateNormals();
01464         void                                    setParametrization();
01465         void                                    interpolateTangents( float stddev );
01466         void                                    singleSurfaceVertices();        //duplicates vertices which have more than 1 surface
01467         void                                    silhouette( std::vector<int>& lines, const Matrix4x3& objectToWorldMatrix, const Vector3& cameraInWorld );
01468         void                                    calculateBoundingBox();
01469         void                                    duplicateVertices();    //makes each triangle to have its own vertices
01470 
01471         //vertices, triangles and edges at the current subdivision level will be passed in the
01472         // displacement function. if original vertices etc. are needed, they can be requested
01473         // as normally through mesh->getVertices() etc.
01474         typedef void DisplacementFunc( Mesh* mesh, std::vector<Vertex>& vertices, const std::vector<Triangle>& triangles, const std::vector<Edge>& edges, int level );
01475         void                                    subdivide( int n, DisplacementFunc* displacement = NULL );
01476 
01477         struct ventry
01478         {
01479                 int             m_vertex;
01480                 int             m_i;
01481         };
01482         const std::vector<ventry>&      get1Neighbourhood( int ver, int& valence, bool& boundary, int& left, int& right ) const;
01483         const std::vector<int>&         get1NeighbourhoodPolygons( int ver ) const;
01484 protected:
01485         std::vector<Vertex>             m_vertices;
01486         std::vector<Triangle>   m_triangles;
01487         std::vector<Edge>               m_edges;
01488         std::vector<Surface>    m_surfaces;
01489         std::string                             m_filename;
01490 
01491         Vector3                                 m_boundingBoxMin;
01492         Vector3                                 m_boundingBoxMax;
01493         float                                   m_boundingRadius;
01494         int                                             m_ambiguousNeighbours;
01495         bool                                    m_adjacencyCalculated;
01496 
01497         static unsigned char*   m_fileptr;
01498         static unsigned char*   m_nextchunkptr;
01499         static unsigned char*   m_nextsubchunkptr;
01500         static unsigned char*   m_fileend;
01501         static unsigned char*   m_readptr;
01502         static unsigned char*   m_writeptr;
01503 
01504         unsigned int                    readID4();
01505         int                                             readI1();
01506         int                                             readI2();
01507         int                                             readI4();
01508         unsigned char                   readU1();
01509         unsigned short                  readU2();
01510         unsigned int                    readU4();
01511         float                                   readF4();
01512         const char*                             readS0();
01513         unsigned int                    readVX();
01514         Vector3                                 readCOL12();
01515         Vector3                                 readVEC12();
01516 
01517         void                                    writeID4( unsigned int i );
01518         void                                    writeI1( signed char i );
01519         void                                    writeI2( signed short i );
01520         void                                    writeI4( int i );
01521         void                                    writeU1( unsigned char i );
01522         void                                    writeU2( unsigned short i );
01523         void                                    writeU4( unsigned int i );
01524         void                                    writeF4( float f );
01525         void                                    writeS0( const char* s );
01526         void                                    writeVX( unsigned int v );
01527         void                                    writeCOL12( const Vector3& c );
01528         void                                    writeVEC12( const Vector3& v );
01529 
01530         void                                    loadLW5();
01531         void                                    loadLW6();
01532         void                                    saveLW6();
01533 };
01534 
01535 //=============================================================================
01536 //=============================================================================
01537 
01538 #endif

Generated on Mon Mar 12 21:09:00 2007 for VEE - The Visual Effects Engine by  doxygen 1.4.6