m4math.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_M4MATH_H
00033 #define LL_M4MATH_H
00034 
00035 #include "v3math.h"
00036 
00037 class LLVector4;
00038 class LLMatrix3;
00039 class LLQuaternion;
00040 
00041 // NOTA BENE: Currently assuming a right-handed, x-forward, y-left, z-up universe
00042 
00043 // Us versus OpenGL:
00044 
00045 // Even though OpenGL uses column vectors and we use row vectors, we can plug our matrices
00046 // directly into OpenGL.  This is because OpenGL numbers its matrices going columnwise:
00047 //
00048 // OpenGL indexing:          Our indexing:
00049 // 0  4  8 12                [0][0] [0][1] [0][2] [0][3]
00050 // 1  5  9 13                [1][0] [1][1] [1][2] [1][3]
00051 // 2  6 10 14                [2][0] [2][1] [2][2] [2][3]
00052 // 3  7 11 15                [3][0] [3][1] [3][2] [3][3]
00053 //
00054 // So when you're looking at OpenGL related matrices online, our matrices will be
00055 // "transposed".  But our matrices can be plugged directly into OpenGL and work fine!
00056 //
00057 
00058 // We're using row vectors - [vx, vy, vz, vw]
00059 //
00060 // There are several different ways of thinking of matrices, if you mix them up, you'll get very confused.
00061 //
00062 // One way to think about it is a matrix that takes the origin frame A
00063 // and rotates it into B': i.e. A*M = B
00064 //
00065 //              Vectors:
00066 //              f - forward axis of B expressed in A
00067 //              l - left axis of B expressed in A
00068 //              u - up axis of B expressed in A
00069 //
00070 //              |  0: fx  1: fy  2: fz  3:0 |
00071 //  M = |  4: lx  5: ly  6: lz  7:0 |
00072 //      |  8: ux  9: uy 10: uz 11:0 |
00073 //      | 12: 0  13: 0  14:  0 15:1 |
00074 //              
00075 //
00076 //
00077 //
00078 // Another way to think of matrices is matrix that takes a point p in frame A, and puts it into frame B:
00079 // This is used most commonly for the modelview matrix.
00080 //
00081 // so p*M = p'
00082 //
00083 //              Vectors:
00084 //      f - forward of frame B in frame A
00085 //      l - left of frame B in frame A
00086 //      u - up of frame B in frame A
00087 //      o - origin of frame frame B in frame A
00088 //
00089 //              |  0: fx  1: lx  2: ux  3:0 |
00090 //  M = |  4: fy  5: ly  6: uy  7:0 |
00091 //      |  8: fz  9: lz 10: uz 11:0 |
00092 //      | 12:-of 13:-ol 14:-ou 15:1 |
00093 //
00094 //              of, ol, and ou mean the component of the "global" origin o in the f axis, l axis, and u axis.
00095 //
00096 
00097 static const U32 NUM_VALUES_IN_MAT4 = 4;
00098 
00099 class LLMatrix4
00100 {
00101 public:
00102         F32     mMatrix[NUM_VALUES_IN_MAT4][NUM_VALUES_IN_MAT4];
00103 
00104         // Initializes Matrix to identity matrix
00105         LLMatrix4()
00106         {
00107                 setIdentity();
00108         }
00109         explicit LLMatrix4(const F32 *mat);                                                             // Initializes Matrix to values in mat
00110         explicit LLMatrix4(const LLMatrix3 &mat);                                               // Initializes Matrix to values in mat and sets position to (0,0,0)
00111         explicit LLMatrix4(const LLQuaternion &q);                                              // Initializes Matrix with rotation q and sets position to (0,0,0)
00112 
00113         LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos);  // Initializes Matrix to values in mat and pos
00114 
00115         // These are really, really, inefficient as implemented! - djs
00116         LLMatrix4(const LLQuaternion &q, const LLVector4 &pos); // Initializes Matrix with rotation q and position pos
00117         LLMatrix4(F32 angle,
00118                           const LLVector4 &vec, 
00119                           const LLVector4 &pos);                                                // Initializes Matrix with axis-angle and position
00120         LLMatrix4(F32 angle, const LLVector4 &vec);                             // Initializes Matrix with axis-angle and sets position to (0,0,0)
00121         LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, 
00122                           const LLVector4 &pos);                                                // Initializes Matrix with Euler angles
00123         LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw);                              // Initializes Matrix with Euler angles
00124 
00125         ~LLMatrix4(void);                                                                               // Destructor
00126 
00127 
00129         //
00130         // Matrix initializers - these replace any existing values in the matrix
00131         //
00132 
00133         void initRows(const LLVector4 &row0,
00134                                   const LLVector4 &row1,
00135                                   const LLVector4 &row2,
00136                                   const LLVector4 &row3);
00137 
00138         // various useful matrix functions
00139         const LLMatrix4& setIdentity();                                 // Load identity matrix
00140         const LLMatrix4& setZero();                                             // Clears matrix to all zeros.
00141 
00142         const LLMatrix4& initRotation(const F32 angle, const F32 x, const F32 y, const F32 z);  // Calculate rotation matrix by rotating angle radians about (x, y, z)
00143         const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis);  // Calculate rotation matrix for rotating angle radians about vec
00144         const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw);          // Calculate rotation matrix from Euler angles
00145         const LLMatrix4& initRotation(const LLQuaternion &q);                   // Set with Quaternion and position
00146         
00147         // Position Only
00148         const LLMatrix4& initMatrix(const LLMatrix3 &mat); //
00149         const LLMatrix4& initMatrix(const LLMatrix3 &mat, const LLVector4 &translation);
00150 
00151         // These operation create a matrix that will rotate and translate by the
00152         // specified amounts.
00153         const LLMatrix4& initRotTrans(const F32 angle,
00154                                                                   const F32 rx, const F32 ry, const F32 rz,
00155                                                                   const F32 px, const F32 py, const F32 pz);
00156 
00157         const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation);     // Rotation from axis angle + translation
00158         const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation
00159         const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos);     // Set with Quaternion and position
00160 
00161 
00162         // Set all
00163         const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos);  
00164 
00165 
00167         //
00168         // Matrix setters - set some properties without modifying others
00169         //
00170 
00171         const LLMatrix4& setTranslation(const F32 x, const F32 y, const F32 z); // Sets matrix to translate by (x,y,z)
00172 
00173         void setFwdRow(const LLVector3 &row);
00174         void setLeftRow(const LLVector3 &row);
00175         void setUpRow(const LLVector3 &row);
00176 
00177         void setFwdCol(const LLVector3 &col);
00178         void setLeftCol(const LLVector3 &col);
00179         void setUpCol(const LLVector3 &col);
00180 
00181         const LLMatrix4& setTranslation(const LLVector4 &translation);
00182         const LLMatrix4& setTranslation(const LLVector3 &translation);
00183 
00185         //
00186         // Get properties of a matrix
00187         //
00188 
00189         F32                      determinant(void) const;                                               // Return determinant
00190         LLQuaternion quaternion(void) const;                    // Returns quaternion
00191 
00192         LLVector4 getFwdRow4() const;
00193         LLVector4 getLeftRow4() const;
00194         LLVector4 getUpRow4() const;
00195 
00196         LLMatrix3 getMat3() const;
00197 
00198         const LLVector3& getTranslation() const { return *(LLVector3*)&mMatrix[3][0]; }
00199 
00201         //
00202         // Operations on an existing matrix
00203         //
00204 
00205         const LLMatrix4& transpose();                                           // Transpose LLMatrix4
00206         const LLMatrix4& invert();                                              // Invert LLMatrix4
00207 
00208         // Rotate existing matrix
00209         // These are really, really, inefficient as implemented! - djs
00210         const LLMatrix4& rotate(const F32 angle, const F32 x, const F32 y, const F32 z);                // Rotate matrix by rotating angle radians about (x, y, z)
00211         const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec);         // Rotate matrix by rotating angle radians about vec
00212         const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw);                // Rotate matrix by Euler angles
00213         const LLMatrix4& rotate(const LLQuaternion &q);                         // Rotate matrix by Quaternion
00214 
00215         
00216         // Translate existing matrix
00217         const LLMatrix4& translate(const LLVector3 &vec);                               // Translate matrix by (vec[VX], vec[VY], vec[VZ])
00218         
00219 
00220 
00221 
00223         //
00224         // Operators
00225         //
00226 
00227 // Not implemented to enforce code that agrees with symbolic syntax
00228 //              friend LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b);             // Apply rotation a to vector b
00229 
00230 //      friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b);              // Return a * b
00231         friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b);             // Return transform of vector a by matrix b
00232         friend LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b);             // Return full transform of a by matrix b
00233         friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate
00234         friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b); // Rotates a but does not translate
00235 
00236         friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b);                 // Return a == b
00237         friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b);                 // Return a != b
00238 
00239         friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a + b
00240         friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a - b
00241         friend const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a * b
00242         friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b);                 // Return a * b
00243 
00244         friend std::ostream&     operator<<(std::ostream& s, const LLMatrix4 &a);       // Stream a
00245 };
00246 
00247 inline const LLMatrix4& LLMatrix4::setIdentity()
00248 {
00249         mMatrix[0][0] = 1.f;
00250         mMatrix[0][1] = 0.f;
00251         mMatrix[0][2] = 0.f;
00252         mMatrix[0][3] = 0.f;
00253 
00254         mMatrix[1][0] = 0.f;
00255         mMatrix[1][1] = 1.f;
00256         mMatrix[1][2] = 0.f;
00257         mMatrix[1][3] = 0.f;
00258 
00259         mMatrix[2][0] = 0.f;
00260         mMatrix[2][1] = 0.f;
00261         mMatrix[2][2] = 1.f;
00262         mMatrix[2][3] = 0.f;
00263 
00264         mMatrix[3][0] = 0.f;
00265         mMatrix[3][1] = 0.f;
00266         mMatrix[3][2] = 0.f;
00267         mMatrix[3][3] = 1.f;
00268         return (*this);
00269 }
00270 
00271 
00272 /*
00273 inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b)
00274 {
00275         U32             i, j;
00276         LLMatrix4       mat;
00277         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00278         {
00279                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00280                 {
00281                         mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + 
00282                                                             a.mMatrix[j][1] * b.mMatrix[1][i] + 
00283                                                             a.mMatrix[j][2] * b.mMatrix[2][i] +
00284                                                                 a.mMatrix[j][3] * b.mMatrix[3][i];
00285                 }
00286         }
00287         return mat;
00288 }
00289 */
00290 
00291 
00292 inline const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b)
00293 {
00294         U32             i, j;
00295         LLMatrix4       mat;
00296         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00297         {
00298                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00299                 {
00300                         mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + 
00301                                                             a.mMatrix[j][1] * b.mMatrix[1][i] + 
00302                                                             a.mMatrix[j][2] * b.mMatrix[2][i] +
00303                                                                 a.mMatrix[j][3] * b.mMatrix[3][i];
00304                 }
00305         }
00306         a = mat;
00307         return a;
00308 }
00309 
00310 inline const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b)
00311 {
00312         U32             i, j;
00313         LLMatrix4       mat;
00314         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00315         {
00316                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00317                 {
00318                         mat.mMatrix[j][i] = a.mMatrix[j][i] * b;
00319                 }
00320         }
00321         a = mat;
00322         return a;
00323 }
00324 
00325 inline const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b)
00326 {
00327         LLMatrix4 mat;
00328         U32             i, j;
00329         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00330         {
00331                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00332                 {
00333                         mat.mMatrix[j][i] = a.mMatrix[j][i] + b.mMatrix[j][i];
00334                 }
00335         }
00336         a = mat;
00337         return a;
00338 }
00339 
00340 inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b)
00341 {
00342         LLMatrix4 mat;
00343         U32             i, j;
00344         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00345         {
00346                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00347                 {
00348                         mat.mMatrix[j][i] = a.mMatrix[j][i] - b.mMatrix[j][i];
00349                 }
00350         }
00351         a = mat;
00352         return a;
00353 }
00354 
00355 #endif
00356 
00357 
00358 

Generated on Fri May 16 08:32:18 2008 for SecondLife by  doxygen 1.5.5