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         LLMatrix4();                                                                            // Initializes Matrix to identity matrix
00105         explicit LLMatrix4(const F32 *mat);                                                             // Initializes Matrix to values in mat
00106         explicit LLMatrix4(const LLMatrix3 &mat);                                               // Initializes Matrix to valuee in mat and sets position to (0,0,0)
00107         explicit LLMatrix4(const LLQuaternion &q);                                              // Initializes Matrix with rotation q and sets position to (0,0,0)
00108 
00109         LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos);  // Initializes Matrix to values in mat and pos
00110 
00111         // These are really, really, inefficient as implemented! - djs
00112         LLMatrix4(const LLQuaternion &q, const LLVector4 &pos); // Initializes Matrix with rotation q and position pos
00113         LLMatrix4(F32 angle,
00114                           const LLVector4 &vec, 
00115                           const LLVector4 &pos);                                                // Initializes Matrix with axis-angle and position
00116         LLMatrix4(F32 angle, const LLVector4 &vec);                             // Initializes Matrix with axis-angle and sets position to (0,0,0)
00117         LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, 
00118                           const LLVector4 &pos);                                                // Initializes Matrix with Euler angles
00119         LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw);                              // Initializes Matrix with Euler angles
00120 
00121         ~LLMatrix4(void);                                                                               // Destructor
00122 
00123 
00125         //
00126         // Matrix initializers - these replace any existing values in the matrix
00127         //
00128 
00129         void initRows(const LLVector4 &row0,
00130                                   const LLVector4 &row1,
00131                                   const LLVector4 &row2,
00132                                   const LLVector4 &row3);
00133 
00134         // various useful matrix functions
00135         const LLMatrix4& identity();                                    // Load identity matrix
00136         const LLMatrix4& zero();                                                // Clears matrix to all zeros.
00137 
00138         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)
00139         const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis);  // Calculate rotation matrix for rotating angle radians about vec
00140         const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw);          // Calculate rotation matrix from Euler angles
00141         const LLMatrix4& initRotation(const LLQuaternion &q);                   // Set with Quaternion and position
00142         
00143         // Position Only
00144         const LLMatrix4& initMatrix(const LLMatrix3 &mat); //
00145         const LLMatrix4& initMatrix(const LLMatrix3 &mat, const LLVector4 &translation);
00146 
00147         // These operation create a matrix that will rotate and translate by the
00148         // specified amounts.
00149         const LLMatrix4& initRotTrans(const F32 angle,
00150                                                                   const F32 rx, const F32 ry, const F32 rz,
00151                                                                   const F32 px, const F32 py, const F32 pz);
00152 
00153         const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation);     // Rotation from axis angle + translation
00154         const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation
00155         const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos);     // Set with Quaternion and position
00156 
00157 
00158         // Set all
00159         const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos);  
00160 
00161 
00163         //
00164         // Matrix setters - set some properties without modifying others
00165         //
00166 
00167         const LLMatrix4& setTranslation(const F32 x, const F32 y, const F32 z); // Sets matrix to translate by (x,y,z)
00168 
00169         void setFwdRow(const LLVector3 &row);
00170         void setLeftRow(const LLVector3 &row);
00171         void setUpRow(const LLVector3 &row);
00172 
00173         void setFwdCol(const LLVector3 &col);
00174         void setLeftCol(const LLVector3 &col);
00175         void setUpCol(const LLVector3 &col);
00176 
00177         const LLMatrix4& setTranslation(const LLVector4 &translation);
00178         const LLMatrix4& setTranslation(const LLVector3 &translation);
00179 
00181         //
00182         // Get properties of a matrix
00183         //
00184 
00185         F32                      determinant(void) const;                                               // Return determinant
00186         LLQuaternion quaternion(void) const;                    // Returns quaternion
00187 
00188         LLVector4 getFwdRow4() const;
00189         LLVector4 getLeftRow4() const;
00190         LLVector4 getUpRow4() const;
00191 
00192         LLMatrix3 getMat3() const;
00193 
00194         const LLVector3& getTranslation() const { return *(LLVector3*)&mMatrix[3][0]; }
00195 
00197         //
00198         // Operations on an existing matrix
00199         //
00200 
00201         const LLMatrix4& transpose();                                           // Transpose LLMatrix4
00202         const LLMatrix4& invert();                                              // Invert LLMatrix4
00203 
00204         // Rotate existing matrix
00205         // These are really, really, inefficient as implemented! - djs
00206         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)
00207         const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec);         // Rotate matrix by rotating angle radians about vec
00208         const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw);                // Rotate matrix by Euler angles
00209         const LLMatrix4& rotate(const LLQuaternion &q);                         // Rotate matrix by Quaternion
00210 
00211         
00212         // Translate existing matrix
00213         const LLMatrix4& translate(const LLVector3 &vec);                               // Translate matrix by (vec[VX], vec[VY], vec[VZ])
00214         
00215 
00216 
00217 
00219         //
00220         // Operators
00221         //
00222 
00223 // Not implemented to enforce code that agrees with symbolic syntax
00224 //              friend LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b);             // Apply rotation a to vector b
00225 
00226 //      friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b);              // Return a * b
00227         friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b);             // Return transform of vector a by matrix b
00228         friend LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b);             // Return full transform of a by matrix b
00229         friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate
00230         friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b); // Rotates a but does not translate
00231 
00232         friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b);                 // Return a == b
00233         friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b);                 // Return a != b
00234 
00235         friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a + b
00236         friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a - b
00237         friend const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b);   // Return a * b
00238         friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b);                 // Return a * b
00239 
00240         friend std::ostream&     operator<<(std::ostream& s, const LLMatrix4 &a);       // Stream a
00241 };
00242 
00243 
00244 inline LLMatrix4::LLMatrix4()
00245 {
00246         identity();
00247 }
00248 
00249 inline const LLMatrix4& LLMatrix4::identity()
00250 {
00251         mMatrix[0][0] = 1.f;
00252         mMatrix[0][1] = 0.f;
00253         mMatrix[0][2] = 0.f;
00254         mMatrix[0][3] = 0.f;
00255 
00256         mMatrix[1][0] = 0.f;
00257         mMatrix[1][1] = 1.f;
00258         mMatrix[1][2] = 0.f;
00259         mMatrix[1][3] = 0.f;
00260 
00261         mMatrix[2][0] = 0.f;
00262         mMatrix[2][1] = 0.f;
00263         mMatrix[2][2] = 1.f;
00264         mMatrix[2][3] = 0.f;
00265 
00266         mMatrix[3][0] = 0.f;
00267         mMatrix[3][1] = 0.f;
00268         mMatrix[3][2] = 0.f;
00269         mMatrix[3][3] = 1.f;
00270         return (*this);
00271 }
00272 
00273 
00274 /*
00275 inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b)
00276 {
00277         U32             i, j;
00278         LLMatrix4       mat;
00279         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00280         {
00281                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00282                 {
00283                         mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + 
00284                                                             a.mMatrix[j][1] * b.mMatrix[1][i] + 
00285                                                             a.mMatrix[j][2] * b.mMatrix[2][i] +
00286                                                                 a.mMatrix[j][3] * b.mMatrix[3][i];
00287                 }
00288         }
00289         return mat;
00290 }
00291 */
00292 
00293 
00294 inline const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b)
00295 {
00296         U32             i, j;
00297         LLMatrix4       mat;
00298         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00299         {
00300                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00301                 {
00302                         mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + 
00303                                                             a.mMatrix[j][1] * b.mMatrix[1][i] + 
00304                                                             a.mMatrix[j][2] * b.mMatrix[2][i] +
00305                                                                 a.mMatrix[j][3] * b.mMatrix[3][i];
00306                 }
00307         }
00308         a = mat;
00309         return a;
00310 }
00311 
00312 inline const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b)
00313 {
00314         U32             i, j;
00315         LLMatrix4       mat;
00316         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00317         {
00318                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00319                 {
00320                         mat.mMatrix[j][i] = a.mMatrix[j][i] * b;
00321                 }
00322         }
00323         a = mat;
00324         return a;
00325 }
00326 
00327 inline const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b)
00328 {
00329         LLMatrix4 mat;
00330         U32             i, j;
00331         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00332         {
00333                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00334                 {
00335                         mat.mMatrix[j][i] = a.mMatrix[j][i] + b.mMatrix[j][i];
00336                 }
00337         }
00338         a = mat;
00339         return a;
00340 }
00341 
00342 inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b)
00343 {
00344         LLMatrix4 mat;
00345         U32             i, j;
00346         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00347         {
00348                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00349                 {
00350                         mat.mMatrix[j][i] = a.mMatrix[j][i] - b.mMatrix[j][i];
00351                 }
00352         }
00353         a = mat;
00354         return a;
00355 }
00356 
00357 #endif
00358 
00359 
00360 

Generated on Thu Jul 1 06:09:54 2010 for Second Life Viewer by  doxygen 1.4.7