matrix3.h

Go to the documentation of this file.
00001 /**********************************************************************
00002  *<
00003    FILE: matrix3.h
00004 
00005    DESCRIPTION: Class definitions for Matrix3
00006 
00007    CREATED BY: Dan Silva
00008 
00009    HISTORY:
00010 
00011  *>   Copyright (c) 1994, All Rights Reserved.
00012  **********************************************************************/
00013 #pragma once
00014 
00015 #include "GeomExport.h"
00016 #include "maxheap.h"
00017 #include "ioapi.h"
00018 #include "point3.h"
00019 #include "point4.h"
00020 
00021 //Flags
00022 #define POS_IDENT  1
00023 #define ROT_IDENT  2
00024 #define SCL_IDENT  4
00025 #define MAT_IDENT (POS_IDENT|ROT_IDENT|SCL_IDENT)
00026 
00027 typedef float MRow[3];
00028 
00029 class Quat;
00030 class AngAxis;
00031 
00032 class Matrix3;
00033 
00063 class Matrix3: public MaxHeapOperators {
00064    friend Matrix3 GEOMEXPORT RotateXMatrix(float angle);   
00065    friend Matrix3 GEOMEXPORT RotateYMatrix(float angle); 
00066    friend Matrix3 GEOMEXPORT RotateZMatrix(float angle); 
00067    friend Matrix3 GEOMEXPORT TransMatrix(const Point3& p);
00068    friend Matrix3 GEOMEXPORT ScaleMatrix(const Point3& s);
00069    friend Matrix3 GEOMEXPORT RotateYPRMatrix(float Yaw, float Pitch, float Roll);
00070    friend Matrix3 GEOMEXPORT RotAngleAxisMatrix(Point3& axis, float angle);
00071    friend Matrix3 GEOMEXPORT Inverse(const Matrix3& M);
00072    friend Point3 GEOMEXPORT operator*(const Matrix3& A, const Point3& V);
00073    friend Point3 GEOMEXPORT operator*(const Point3& V, const Matrix3& A);
00074    friend Point3 GEOMEXPORT VectorTransform(const Matrix3& M, const Point3& V); 
00075    friend Matrix3 GEOMEXPORT XFormMat(const Matrix3& xm, const Matrix3& m);
00076     friend Point3 GEOMEXPORT VectorTransform(const Point3& V, const Matrix3& M);
00077    friend class Quat;
00078    float m[4][3];
00079    // Access i-th row as Point3 for read or assignment:
00080    Point3& operator[](int i) { return((Point3&)(*m[i]));  }
00081    DWORD flags;
00082 
00083 public:
00085    const Point3& operator[](int i) const { return((Point3&)(*m[i])); }
00086    // if change any components directly via GetAddr, must call this
00090    void SetNotIdent() { flags &= ~MAT_IDENT; }
00096    void SetIdentFlags(DWORD f) { flags &= ~MAT_IDENT; flags |= f; }
00098    DWORD GetIdentFlags() const { return flags; }
00104    void ClearIdentFlag(DWORD f) { flags &= ~f; }
00107    BOOL IsIdentity() const { return ((flags&MAT_IDENT)==MAT_IDENT); }
00117    GEOMEXPORT void ValidateFlags(); // recomputes the IDENT flags
00118 
00119    // CAUTION: if you change the matrix via this pointer, you MUST clear the
00120    // proper IDENT flags !!!
00131    MRow* GetAddr() { return (MRow *)(m); }   
00141    const MRow* GetAddr() const { return (MRow *)(m); }
00142 
00143    // Constructors
00146    Matrix3(){ flags = 0; }  // NO INITIALIZATION done in this constructor!!             
00152    Matrix3(BOOL /*init*/) {flags=0; IdentityMatrix();}
00157    GEOMEXPORT Matrix3(float (*fp)[3]);
00169     Matrix3(const Point3& U, const Point3& V, const Point3& N, const Point3& T) {
00170         flags = 0; SetRow(0, U); SetRow(1, V); SetRow(2, N); SetRow(3, T); 
00171         ValidateFlags(); }
00172 
00185     Matrix3& Set(const Point3& U, const Point3& V, const Point3& N, const Point3& T) {
00186         flags = 0; SetRow(0, U); SetRow(1, V); SetRow(2, N); SetRow(3, T);
00187         ValidateFlags(); return *this; }
00188 
00189     // Data member
00190     static const Matrix3 Identity;
00191 
00192     // Comparison operators
00199     GEOMEXPORT int operator==(const Matrix3& M) const;
00209     GEOMEXPORT int Equals(const Matrix3& M, float epsilon = 1E-6f) const;
00210 
00211    // Assignment operators
00213    GEOMEXPORT Matrix3& operator-=( const Matrix3& M);
00215    GEOMEXPORT Matrix3& operator+=( const Matrix3& M); 
00218    GEOMEXPORT Matrix3& operator*=( const Matrix3& M);     // Matrix multiplication
00219    GEOMEXPORT Matrix3& operator*=( float a);
00220 
00221    // Operations on matrix
00223    GEOMEXPORT void IdentityMatrix();       // Make into the Identity Matrix
00225    GEOMEXPORT void Zero();     // set all elements to 0
00226    
00231    Point3 GetRow(int i) const { return (*this)[i]; }  
00238    GEOMEXPORT void SetRow(int i, Point3 p);
00239 
00244    GEOMEXPORT Point4 GetColumn(int i) const;
00251    GEOMEXPORT void SetColumn(int i, Point4 col);
00256    GEOMEXPORT Point3 GetColumn3(int i) const;
00257 
00258    // zero the translation part;
00260    GEOMEXPORT void NoTrans();
00261    // null out the rotation part;
00263    GEOMEXPORT void NoRot();
00264    // null out the scale part;
00275    GEOMEXPORT void NoScale();
00276    
00277    // This is an "unbiased" orthogonalization
00278    // It seems to take a maximum of 4 iterations to converge.
00279    GEOMEXPORT void Orthogonalize();
00280 
00281    // Access the translation row
00287    void SetTrans(const Point3 p) { (*this)[3] = p;  flags &= ~POS_IDENT; }
00295    void SetTrans(int i, float v) { (*this)[3][i] = v; flags &= ~POS_IDENT; }
00298    const Point3& GetTrans() const { return (*this)[3]; }
00299    
00300    // Apply Incremental transformations to this matrix
00301    // Equivalent to multiplying on the RIGHT by transform
00307    GEOMEXPORT void Translate(const Point3& p);
00313    GEOMEXPORT void RotateX(float angle);  
00319    GEOMEXPORT void RotateY(float angle);
00325    GEOMEXPORT void RotateZ(float angle);
00326    // if trans = FALSE the translation component is unaffected:
00346    GEOMEXPORT void Scale(const Point3& s, BOOL trans = FALSE);
00347 
00348    // Apply Incremental transformations to this matrix
00349    // Equivalent to multiplying on the LEFT by transform 
00355    GEOMEXPORT void PreTranslate(const Point3& p);
00361    GEOMEXPORT void PreRotateX(float angle);  
00367    GEOMEXPORT void PreRotateY(float angle);
00373    GEOMEXPORT void PreRotateZ(float angle);
00374    // if trans = FALSE the translation component is unaffected:
00382    GEOMEXPORT void PreScale(const Point3& s, BOOL trans = FALSE);
00383 
00384     // set matrix as described
00390     GEOMEXPORT void SetTranslate(const Point3& p);     // makes translation matrix
00396     GEOMEXPORT void SetRotateX(float angle);           // makes rotation matrix
00402     GEOMEXPORT void SetRotateY(float angle);
00408     GEOMEXPORT void SetRotateZ(float angle);
00414     GEOMEXPORT void SetRotate(const Quat& q);
00420     GEOMEXPORT void SetRotate(const AngAxis& aa);
00439     GEOMEXPORT void SetRotate(float yaw, float pitch, float roll);
00447     GEOMEXPORT void SetAngleAxis(const Point3& axis, float angle);
00453     GEOMEXPORT void SetScale(const Point3& s);          // makes scale matrix
00464     GEOMEXPORT void SetFromToUp(const Point3& from, const Point3& to, const Point3& up);
00467     GEOMEXPORT void Invert();                          // in place
00468       
00469     //binary operators
00471    GEOMEXPORT Matrix3 operator*(const Matrix3&) const;
00473    GEOMEXPORT Matrix3 operator+(const Matrix3&) const;
00475    GEOMEXPORT Matrix3 operator-(const Matrix3&) const;
00476 
00481     GEOMEXPORT Point3 PointTransform(const Point3& p) const;
00486     GEOMEXPORT Point3 VectorTransform(const Point3& p) const;
00499     GEOMEXPORT void TransformPoints(Point3 *array, int n,
00500                 int stride = sizeof(Point3));
00513     GEOMEXPORT void TransformPoints(const Point3 *array, Point3 *to, int n,
00514                 int stride = sizeof(Point3), int strideTo = sizeof(Point3));
00527     GEOMEXPORT void TransformVectors(Point3 *array, int n,
00528                 int stride = sizeof(Point3));
00542     GEOMEXPORT void TransformVectors(const Point3 *array, Point3 *to, int n,
00543                 int stride = sizeof(Point3), int strideTo = sizeof(Point3));
00544 
00545     // Property function
00557     GEOMEXPORT void GetYawPitchRoll(float *yaw, float *pitch, float *roll);
00558 
00559     // I/O
00560    GEOMEXPORT IOResult Save(ISave* isave);
00561    GEOMEXPORT IOResult Load(ILoad* iload);
00562 
00572    GEOMEXPORT BOOL Parity() const;
00573    };
00574 
00575 // Build new matrices for transformations
00581 GEOMEXPORT Matrix3 RotateXMatrix(float angle);   
00587 GEOMEXPORT Matrix3 RotateYMatrix(float angle); 
00593 GEOMEXPORT Matrix3 RotateZMatrix(float angle); 
00599 GEOMEXPORT Matrix3 TransMatrix(const Point3& p);
00605 GEOMEXPORT Matrix3 ScaleMatrix(const Point3& s);
00623 GEOMEXPORT Matrix3 RotateYPRMatrix(float Yaw, float Pitch, float Roll);
00634 GEOMEXPORT Matrix3 RotAngleAxisMatrix(Point3& axis, float angle);
00635  
00640 GEOMEXPORT Matrix3 Inverse(const Matrix3& M);  // return Inverse of matrix
00641 
00642 // These two versions of transforming a point with a matrix do the same thing,
00643 // regardless of the order of operands (linear algebra rules notwithstanding).
00653 GEOMEXPORT Point3 operator*(const Matrix3& A, const Point3& V); // Transform Point with matrix
00663 GEOMEXPORT Point3 operator*(const Point3& V, const Matrix3& A); // Transform Point with matrix
00664 
00665 // ditto
00673 GEOMEXPORT Point3 VectorTransform(const Matrix3& M, const Point3& V); 
00674 GEOMEXPORT Point3 VectorTransform(const Point3& V, const Matrix3& M); 
00675 
00676 // transform a plane: this only works if M is orthogonal
00677 GEOMEXPORT Point4 TransformPlane(const Matrix3& M, const Point4& plin); 
00678 
00679 // transformats matrix m so it is applied in the space of matrix xm:
00680 //  returns xm*m*Inverse(xm)
00695 GEOMEXPORT Matrix3 XFormMat(const Matrix3& xm, const Matrix3& m);
00696