m4math.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 //#include "vmath.h"
00035 #include "v3math.h"
00036 #include "v4math.h"
00037 #include "m4math.h"
00038 #include "m3math.h"
00039 #include "llquaternion.h"
00040 
00041 
00042 
00043 
00044 // LLMatrix4
00045 
00046 // Constructors
00047 
00048 
00049 LLMatrix4::LLMatrix4(const F32 *mat)
00050 {
00051         mMatrix[0][0] = mat[0];
00052         mMatrix[0][1] = mat[1];
00053         mMatrix[0][2] = mat[2];
00054         mMatrix[0][3] = mat[3];
00055 
00056         mMatrix[1][0] = mat[4];
00057         mMatrix[1][1] = mat[5];
00058         mMatrix[1][2] = mat[6];
00059         mMatrix[1][3] = mat[7];
00060 
00061         mMatrix[2][0] = mat[8];
00062         mMatrix[2][1] = mat[9];
00063         mMatrix[2][2] = mat[10];
00064         mMatrix[2][3] = mat[11];
00065 
00066         mMatrix[3][0] = mat[12];
00067         mMatrix[3][1] = mat[13];
00068         mMatrix[3][2] = mat[14];
00069         mMatrix[3][3] = mat[15];
00070 }
00071 
00072 LLMatrix4::LLMatrix4(const LLMatrix3 &mat, const LLVector4 &vec)
00073 {
00074         mMatrix[0][0] = mat.mMatrix[0][0];
00075         mMatrix[0][1] = mat.mMatrix[0][1];
00076         mMatrix[0][2] = mat.mMatrix[0][2];
00077         mMatrix[0][3] = 0.f;
00078 
00079         mMatrix[1][0] = mat.mMatrix[1][0];
00080         mMatrix[1][1] = mat.mMatrix[1][1];
00081         mMatrix[1][2] = mat.mMatrix[1][2];
00082         mMatrix[1][3] = 0.f;
00083 
00084         mMatrix[2][0] = mat.mMatrix[2][0];
00085         mMatrix[2][1] = mat.mMatrix[2][1];
00086         mMatrix[2][2] = mat.mMatrix[2][2];
00087         mMatrix[2][3] = 0.f;
00088 
00089         mMatrix[3][0] = vec.mV[0];
00090         mMatrix[3][1] = vec.mV[1];
00091         mMatrix[3][2] = vec.mV[2];
00092         mMatrix[3][3] = 1.f;
00093 }
00094 
00095 LLMatrix4::LLMatrix4(const LLMatrix3 &mat)
00096 {
00097         mMatrix[0][0] = mat.mMatrix[0][0];
00098         mMatrix[0][1] = mat.mMatrix[0][1];
00099         mMatrix[0][2] = mat.mMatrix[0][2];
00100         mMatrix[0][3] = 0.f;
00101 
00102         mMatrix[1][0] = mat.mMatrix[1][0];
00103         mMatrix[1][1] = mat.mMatrix[1][1];
00104         mMatrix[1][2] = mat.mMatrix[1][2];
00105         mMatrix[1][3] = 0.f;
00106 
00107         mMatrix[2][0] = mat.mMatrix[2][0];
00108         mMatrix[2][1] = mat.mMatrix[2][1];
00109         mMatrix[2][2] = mat.mMatrix[2][2];
00110         mMatrix[2][3] = 0.f;
00111 
00112         mMatrix[3][0] = 0.f;
00113         mMatrix[3][1] = 0.f;
00114         mMatrix[3][2] = 0.f;
00115         mMatrix[3][3] = 1.f;
00116 }
00117 
00118 LLMatrix4::LLMatrix4(const LLQuaternion &q)
00119 {
00120         *this = initRotation(q);
00121 }
00122 
00123 LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos)
00124 {
00125         *this = initRotTrans(q, pos);
00126 }
00127 
00128 LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec, const LLVector4 &pos)
00129 {
00130         initRotTrans(LLQuaternion(angle, vec), pos);
00131 }
00132 
00133 LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec)
00134 {
00135         initRotation(LLQuaternion(angle, vec));
00136 
00137         mMatrix[3][0] = 0.f;
00138         mMatrix[3][1] = 0.f;
00139         mMatrix[3][2] = 0.f;
00140         mMatrix[3][3] = 1.f;
00141 }
00142 
00143 LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos)
00144 {
00145         LLMatrix3       mat(roll, pitch, yaw);
00146         initRotTrans(LLQuaternion(mat), pos);
00147 }
00148 
00149 LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw)
00150 {
00151         LLMatrix3       mat(roll, pitch, yaw);
00152         initRotation(LLQuaternion(mat));
00153 
00154         mMatrix[3][0] = 0.f;
00155         mMatrix[3][1] = 0.f;
00156         mMatrix[3][2] = 0.f;
00157         mMatrix[3][3] = 1.f;
00158 }
00159 
00160 LLMatrix4::~LLMatrix4(void)
00161 {
00162 }
00163 
00164 // Clear and Assignment Functions
00165 
00166 const LLMatrix4& LLMatrix4::zero()
00167 {
00168         mMatrix[0][0] = 0.f;
00169         mMatrix[0][1] = 0.f;
00170         mMatrix[0][2] = 0.f;
00171         mMatrix[0][3] = 0.f;
00172 
00173         mMatrix[1][0] = 0.f;
00174         mMatrix[1][1] = 0.f;
00175         mMatrix[1][2] = 0.f;
00176         mMatrix[1][3] = 0.f;
00177 
00178         mMatrix[2][0] = 0.f;
00179         mMatrix[2][1] = 0.f;
00180         mMatrix[2][2] = 0.f;
00181         mMatrix[2][3] = 0.f;
00182 
00183         mMatrix[3][0] = 0.f;
00184         mMatrix[3][1] = 0.f;
00185         mMatrix[3][2] = 0.f;
00186         mMatrix[3][3] = 0.f;
00187         return *this;
00188 }
00189 
00190 
00191 // various useful mMatrix functions
00192 
00193 const LLMatrix4&        LLMatrix4::transpose()
00194 {
00195         LLMatrix4 mat;
00196         mat.mMatrix[0][0] = mMatrix[0][0];
00197         mat.mMatrix[1][0] = mMatrix[0][1];
00198         mat.mMatrix[2][0] = mMatrix[0][2];
00199         mat.mMatrix[3][0] = mMatrix[0][3];
00200 
00201         mat.mMatrix[0][1] = mMatrix[1][0];
00202         mat.mMatrix[1][1] = mMatrix[1][1];
00203         mat.mMatrix[2][1] = mMatrix[1][2];
00204         mat.mMatrix[3][1] = mMatrix[1][3];
00205 
00206         mat.mMatrix[0][2] = mMatrix[2][0];
00207         mat.mMatrix[1][2] = mMatrix[2][1];
00208         mat.mMatrix[2][2] = mMatrix[2][2];
00209         mat.mMatrix[3][2] = mMatrix[2][3];
00210 
00211         mat.mMatrix[0][3] = mMatrix[3][0];
00212         mat.mMatrix[1][3] = mMatrix[3][1];
00213         mat.mMatrix[2][3] = mMatrix[3][2];
00214         mat.mMatrix[3][3] = mMatrix[3][3];
00215 
00216         *this = mat;
00217         return *this;
00218 }
00219 
00220 
00221 F32 LLMatrix4::determinant() const
00222 {
00223         llerrs << "Not implemented!" << llendl;
00224         return 0.f;
00225 }
00226 
00227 // Only works for pure orthonormal, homogeneous transform matrices.
00228 const LLMatrix4&        LLMatrix4::invert(void) 
00229 {
00230         // transpose the rotation part
00231         F32 temp;
00232         temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
00233         temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
00234         temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
00235 
00236         // rotate the translation part by the new rotation 
00237         // (temporarily store in empty column of matrix)
00238         U32 j;
00239         for (j=0; j<3; j++)
00240         {
00241                 mMatrix[j][VW] =  mMatrix[VW][VX] * mMatrix[VX][j] + 
00242                                                   mMatrix[VW][VY] * mMatrix[VY][j] +
00243                                                   mMatrix[VW][VZ] * mMatrix[VZ][j]; 
00244         }
00245 
00246         // negate and copy the temporary vector back to the tranlation row
00247         mMatrix[VW][VX] = -mMatrix[VX][VW];
00248         mMatrix[VW][VY] = -mMatrix[VY][VW];
00249         mMatrix[VW][VZ] = -mMatrix[VZ][VW];
00250 
00251         // zero the empty column again
00252         mMatrix[VX][VW] = mMatrix[VY][VW] = mMatrix[VZ][VW] = 0.0f;
00253         
00254         return *this;
00255 }
00256 
00257 LLVector4 LLMatrix4::getFwdRow4() const
00258 {
00259         return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]);
00260 }
00261 
00262 LLVector4 LLMatrix4::getLeftRow4() const
00263 {
00264         return LLVector4(mMatrix[VY][VX], mMatrix[VY][VY], mMatrix[VY][VZ], mMatrix[VY][VW]);
00265 }
00266 
00267 LLVector4 LLMatrix4::getUpRow4() const
00268 {
00269         return LLVector4(mMatrix[VZ][VX], mMatrix[VZ][VY], mMatrix[VZ][VZ], mMatrix[VZ][VW]);
00270 }
00271 
00272 // SJB: This code is correct for a logicly stored (non-transposed) matrix;
00273 //              Our matrices are stored transposed, OpenGL style, so this generates the
00274 //              INVERSE quaternion (-x, -y, -z, w)!
00275 //              Because we use similar logic in LLQuaternion::getMatrix3,
00276 //              we are internally consistant so everything works OK :)
00277 LLQuaternion    LLMatrix4::quaternion() const
00278 {
00279         LLQuaternion    quat;
00280         F32             tr, s, q[4];
00281         U32             i, j, k;
00282         U32             nxt[3] = {1, 2, 0};
00283 
00284         tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2];
00285 
00286         // check the diagonal
00287         if (tr > 0.f) 
00288         {
00289                 s = (F32)sqrt (tr + 1.f);
00290                 quat.mQ[VS] = s / 2.f;
00291                 s = 0.5f / s;
00292                 quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s;
00293                 quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s;
00294                 quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s;
00295         } 
00296         else
00297         {               
00298                 // diagonal is negative
00299                 i = 0;
00300                 if (mMatrix[1][1] > mMatrix[0][0]) 
00301                         i = 1;
00302                 if (mMatrix[2][2] > mMatrix[i][i]) 
00303                         i = 2;
00304 
00305                 j = nxt[i];
00306                 k = nxt[j];
00307 
00308 
00309                 s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f);
00310 
00311                 q[i] = s * 0.5f;
00312 
00313                 if (s != 0.f) 
00314                         s = 0.5f / s;
00315 
00316                 q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s;
00317                 q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s;
00318                 q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s;
00319 
00320                 quat.setQuat(q);
00321         }
00322         return quat;
00323 }
00324 
00325 
00326 
00327 void LLMatrix4::initRows(const LLVector4 &row0,
00328                                                  const LLVector4 &row1,
00329                                                  const LLVector4 &row2,
00330                                                  const LLVector4 &row3)
00331 {
00332         mMatrix[0][0] = row0.mV[0];
00333         mMatrix[0][1] = row0.mV[1];
00334         mMatrix[0][2] = row0.mV[2];
00335         mMatrix[0][3] = row0.mV[3];
00336 
00337         mMatrix[1][0] = row1.mV[0];
00338         mMatrix[1][1] = row1.mV[1];
00339         mMatrix[1][2] = row1.mV[2];
00340         mMatrix[1][3] = row1.mV[3];
00341 
00342         mMatrix[2][0] = row2.mV[0];
00343         mMatrix[2][1] = row2.mV[1];
00344         mMatrix[2][2] = row2.mV[2];
00345         mMatrix[2][3] = row2.mV[3];
00346 
00347         mMatrix[3][0] = row3.mV[0];
00348         mMatrix[3][1] = row3.mV[1];
00349         mMatrix[3][2] = row3.mV[2];
00350         mMatrix[3][3] = row3.mV[3];
00351 }
00352 
00353 
00354 const LLMatrix4&        LLMatrix4::initRotation(const F32 angle, const F32 x, const F32 y, const F32 z)
00355 {
00356         LLMatrix3       mat(angle, x, y, z);
00357         return initMatrix(mat);
00358 }
00359 
00360 
00361 const LLMatrix4&        LLMatrix4::initRotation(F32 angle, const LLVector4 &vec)
00362 {
00363         LLMatrix3       mat(angle, vec);
00364         return initMatrix(mat);
00365 }
00366 
00367 
00368 const LLMatrix4&        LLMatrix4::initRotation(const F32 roll, const F32 pitch, const F32 yaw)
00369 {
00370         LLMatrix3       mat(roll, pitch, yaw);
00371         return initMatrix(mat);
00372 }
00373 
00374 
00375 const LLMatrix4&        LLMatrix4::initRotation(const LLQuaternion &q)
00376 {
00377         LLMatrix3       mat(q);
00378         return initMatrix(mat);
00379 }
00380 
00381 
00382 // Position and Rotation
00383 const LLMatrix4&        LLMatrix4::initRotTrans(const F32 angle, const F32 rx, const F32 ry, const F32 rz,
00384                                                                                         const F32 tx, const F32 ty, const F32 tz)
00385 {
00386         LLMatrix3       mat(angle, rx, ry, rz);
00387         LLVector3       translation(tx, ty, tz);
00388         initMatrix(mat);
00389         setTranslation(translation);
00390         return (*this);
00391 }
00392 
00393 const LLMatrix4&        LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation)
00394 {
00395         LLMatrix3       mat(angle, axis);
00396         initMatrix(mat);
00397         setTranslation(translation);
00398         return (*this);
00399 }
00400 
00401 const LLMatrix4&        LLMatrix4::initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &translation)
00402 {
00403         LLMatrix3       mat(roll, pitch, yaw);
00404         initMatrix(mat);
00405         setTranslation(translation);
00406         return (*this);
00407 }
00408 
00409 /*
00410 const LLMatrix4&        LLMatrix4::initRotTrans(const LLVector4 &fwd, 
00411                                                                                         const LLVector4 &left, 
00412                                                                                         const LLVector4 &up, 
00413                                                                                         const LLVector4 &translation)
00414 {
00415         LLMatrix3 mat(fwd, left, up);
00416         initMatrix(mat);
00417         setTranslation(translation);
00418         return (*this);
00419 }
00420 */
00421 
00422 const LLMatrix4&        LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector4 &translation)
00423 {
00424         LLMatrix3       mat(q);
00425         initMatrix(mat);
00426         setTranslation(translation);
00427         return (*this);
00428 }
00429 
00430 const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos)
00431 {
00432         F32             sx, sy, sz;
00433         F32             xx, xy, xz, xw, yy, yz, yw, zz, zw;
00434 
00435         sx      = scale.mV[0];
00436         sy      = scale.mV[1];
00437         sz      = scale.mV[2];
00438 
00439     xx      = q.mQ[VX] * q.mQ[VX];
00440     xy      = q.mQ[VX] * q.mQ[VY];
00441     xz      = q.mQ[VX] * q.mQ[VZ];
00442     xw      = q.mQ[VX] * q.mQ[VW];
00443 
00444     yy      = q.mQ[VY] * q.mQ[VY];
00445     yz      = q.mQ[VY] * q.mQ[VZ];
00446     yw      = q.mQ[VY] * q.mQ[VW];
00447 
00448     zz      = q.mQ[VZ] * q.mQ[VZ];
00449     zw      = q.mQ[VZ] * q.mQ[VW];
00450 
00451     mMatrix[0][0]  = (1.f - 2.f * ( yy + zz )) *sx;
00452     mMatrix[0][1]  = (      2.f * ( xy + zw )) *sx;
00453     mMatrix[0][2]  = (      2.f * ( xz - yw )) *sx;
00454 
00455     mMatrix[1][0]  = (      2.f * ( xy - zw )) *sy;
00456     mMatrix[1][1]  = (1.f - 2.f * ( xx + zz )) *sy;
00457     mMatrix[1][2]  = (      2.f * ( yz + xw )) *sy;
00458 
00459     mMatrix[2][0]  = (      2.f * ( xz + yw )) *sz;
00460     mMatrix[2][1]  = (      2.f * ( yz - xw )) *sz;
00461     mMatrix[2][2]  = (1.f - 2.f * ( xx + yy )) *sz;
00462 
00463         mMatrix[3][0]  = pos.mV[0];
00464         mMatrix[3][1]  = pos.mV[1];
00465         mMatrix[3][2]  = pos.mV[2];
00466         mMatrix[3][3]  = 1.0;
00467 
00468         // TODO -- should we set the translation portion to zero?
00469         return (*this);
00470 }
00471 
00472 // Rotate exisitng mMatrix
00473 const LLMatrix4&        LLMatrix4::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
00474 {
00475         LLVector4       vec4(x, y, z);
00476         LLMatrix4       mat(angle, vec4);
00477         *this *= mat;
00478         return *this;
00479 }
00480 
00481 const LLMatrix4&        LLMatrix4::rotate(const F32 angle, const LLVector4 &vec)
00482 {
00483         LLMatrix4       mat(angle, vec);
00484         *this *= mat;
00485         return *this;
00486 }
00487 
00488 const LLMatrix4&        LLMatrix4::rotate(const F32 roll, const F32 pitch, const F32 yaw)
00489 {
00490         LLMatrix4       mat(roll, pitch, yaw);
00491         *this *= mat;
00492         return *this;
00493 }
00494 
00495 const LLMatrix4&        LLMatrix4::rotate(const LLQuaternion &q)
00496 {
00497         LLMatrix4       mat(q);
00498         *this *= mat;
00499         return *this;
00500 }
00501 
00502 
00503 const LLMatrix4&        LLMatrix4::translate(const LLVector3 &vec)
00504 {
00505         mMatrix[3][0] += vec.mV[0];
00506         mMatrix[3][1] += vec.mV[1];
00507         mMatrix[3][2] += vec.mV[2];
00508         return (*this);
00509 }
00510 
00511 
00512 void LLMatrix4::setFwdRow(const LLVector3 &row)
00513 {
00514         mMatrix[VX][VX] = row.mV[VX];
00515         mMatrix[VX][VY] = row.mV[VY];
00516         mMatrix[VX][VZ] = row.mV[VZ];
00517 }
00518 
00519 void LLMatrix4::setLeftRow(const LLVector3 &row)
00520 {
00521         mMatrix[VY][VX] = row.mV[VX];
00522         mMatrix[VY][VY] = row.mV[VY];
00523         mMatrix[VY][VZ] = row.mV[VZ];
00524 }
00525 
00526 void LLMatrix4::setUpRow(const LLVector3 &row)
00527 {
00528         mMatrix[VZ][VX] = row.mV[VX];
00529         mMatrix[VZ][VY] = row.mV[VY];
00530         mMatrix[VZ][VZ] = row.mV[VZ];
00531 }
00532 
00533 
00534 void LLMatrix4::setFwdCol(const LLVector3 &col)
00535 {
00536         mMatrix[VX][VX] = col.mV[VX];
00537         mMatrix[VY][VX] = col.mV[VY];
00538         mMatrix[VZ][VX] = col.mV[VZ];
00539 }
00540 
00541 void LLMatrix4::setLeftCol(const LLVector3 &col)
00542 {
00543         mMatrix[VX][VY] = col.mV[VX];
00544         mMatrix[VY][VY] = col.mV[VY];
00545         mMatrix[VZ][VY] = col.mV[VZ];
00546 }
00547 
00548 void LLMatrix4::setUpCol(const LLVector3 &col)
00549 {
00550         mMatrix[VX][VZ] = col.mV[VX];
00551         mMatrix[VY][VZ] = col.mV[VY];
00552         mMatrix[VZ][VZ] = col.mV[VZ];
00553 }
00554 
00555 
00556 const LLMatrix4&        LLMatrix4::setTranslation(const F32 tx, const F32 ty, const F32 tz)
00557 {
00558         mMatrix[VW][VX] = tx;
00559         mMatrix[VW][VY] = ty;
00560         mMatrix[VW][VZ] = tz;
00561         return (*this);
00562 }
00563 
00564 const LLMatrix4&        LLMatrix4::setTranslation(const LLVector3 &translation)
00565 {
00566         mMatrix[VW][VX] = translation.mV[VX];
00567         mMatrix[VW][VY] = translation.mV[VY];
00568         mMatrix[VW][VZ] = translation.mV[VZ];
00569         return (*this);
00570 }
00571 
00572 const LLMatrix4&        LLMatrix4::setTranslation(const LLVector4 &translation)
00573 {
00574         mMatrix[VW][VX] = translation.mV[VX];
00575         mMatrix[VW][VY] = translation.mV[VY];
00576         mMatrix[VW][VZ] = translation.mV[VZ];
00577         return (*this);
00578 }
00579 
00580 // LLMatrix3 Extraction and Setting
00581 LLMatrix3       LLMatrix4::getMat3() const
00582 {
00583         LLMatrix3 retmat;
00584 
00585         retmat.mMatrix[0][0] = mMatrix[0][0];
00586         retmat.mMatrix[0][1] = mMatrix[0][1];
00587         retmat.mMatrix[0][2] = mMatrix[0][2];
00588 
00589         retmat.mMatrix[1][0] = mMatrix[1][0];
00590         retmat.mMatrix[1][1] = mMatrix[1][1];
00591         retmat.mMatrix[1][2] = mMatrix[1][2];
00592 
00593         retmat.mMatrix[2][0] = mMatrix[2][0];
00594         retmat.mMatrix[2][1] = mMatrix[2][1];
00595         retmat.mMatrix[2][2] = mMatrix[2][2];
00596 
00597         return retmat;
00598 }
00599 
00600 const LLMatrix4&        LLMatrix4::initMatrix(const LLMatrix3 &mat)
00601 {
00602         mMatrix[0][0] = mat.mMatrix[0][0];
00603         mMatrix[0][1] = mat.mMatrix[0][1];
00604         mMatrix[0][2] = mat.mMatrix[0][2];
00605         mMatrix[0][3] = 0.f;
00606 
00607         mMatrix[1][0] = mat.mMatrix[1][0];
00608         mMatrix[1][1] = mat.mMatrix[1][1];
00609         mMatrix[1][2] = mat.mMatrix[1][2];
00610         mMatrix[1][3] = 0.f;
00611 
00612         mMatrix[2][0] = mat.mMatrix[2][0];
00613         mMatrix[2][1] = mat.mMatrix[2][1];
00614         mMatrix[2][2] = mat.mMatrix[2][2];
00615         mMatrix[2][3] = 0.f;
00616 
00617         mMatrix[3][0] = 0.f;
00618         mMatrix[3][1] = 0.f;
00619         mMatrix[3][2] = 0.f;
00620         mMatrix[3][3] = 1.f;
00621         return (*this);
00622 }
00623 
00624 const LLMatrix4&        LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 &translation)
00625 {
00626         mMatrix[0][0] = mat.mMatrix[0][0];
00627         mMatrix[0][1] = mat.mMatrix[0][1];
00628         mMatrix[0][2] = mat.mMatrix[0][2];
00629         mMatrix[0][3] = 0.f;
00630 
00631         mMatrix[1][0] = mat.mMatrix[1][0];
00632         mMatrix[1][1] = mat.mMatrix[1][1];
00633         mMatrix[1][2] = mat.mMatrix[1][2];
00634         mMatrix[1][3] = 0.f;
00635 
00636         mMatrix[2][0] = mat.mMatrix[2][0];
00637         mMatrix[2][1] = mat.mMatrix[2][1];
00638         mMatrix[2][2] = mat.mMatrix[2][2];
00639         mMatrix[2][3] = 0.f;
00640 
00641         mMatrix[3][0] = translation.mV[0];
00642         mMatrix[3][1] = translation.mV[1];
00643         mMatrix[3][2] = translation.mV[2];
00644         mMatrix[3][3] = 1.f;
00645         return (*this);
00646 }
00647 
00648 // LLMatrix4 Operators
00649 
00650 
00651 /* Not implemented to help enforce code consistency with the syntax of
00652    row-major notation.  This is a Good Thing.
00653 LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b)
00654 {
00655         // Operate "to the right" on column-vector b
00656         LLVector4       vec;
00657         vec.mV[VX] = a.mMatrix[VX][VX] * b.mV[VX] + 
00658                                  a.mMatrix[VY][VX] * b.mV[VY] + 
00659                                  a.mMatrix[VZ][VX] * b.mV[VZ] +
00660                                  a.mMatrix[VW][VX] * b.mV[VW];
00661 
00662         vec.mV[VY] = a.mMatrix[VX][VY] * b.mV[VX] + 
00663                                  a.mMatrix[VY][VY] * b.mV[VY] + 
00664                                  a.mMatrix[VZ][VY] * b.mV[VZ] +
00665                                  a.mMatrix[VW][VY] * b.mV[VW];
00666 
00667         vec.mV[VZ] = a.mMatrix[VX][VZ] * b.mV[VX] + 
00668                                  a.mMatrix[VY][VZ] * b.mV[VY] + 
00669                                  a.mMatrix[VZ][VZ] * b.mV[VZ] +
00670                                  a.mMatrix[VW][VZ] * b.mV[VW];
00671 
00672         vec.mV[VW] = a.mMatrix[VX][VW] * b.mV[VX] + 
00673                                  a.mMatrix[VY][VW] * b.mV[VY] + 
00674                                  a.mMatrix[VZ][VW] * b.mV[VZ] +
00675                                  a.mMatrix[VW][VW] * b.mV[VW];
00676         return vec;
00677 }
00678 */
00679 
00680 // Operates "to the left" on row-vector a
00681 //
00682 // This used to be in the header file but was not actually inlined in practice.
00683 // When avatar vertex programs are off, this function is a hot spot in profiles
00684 // due to software skinning in LLViewerJointMesh::updateGeometry().  JC
00685 LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b)
00686 {
00687         // This is better than making a temporary LLVector3.  This eliminates an
00688         // unnecessary LLVector3() constructor and also helps the compiler to
00689         // realize that the output floats do not alias the input floats, hence
00690         // eliminating redundant loads of a.mV[0], etc.  JC
00691         return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + 
00692                                          a.mV[VY] * b.mMatrix[VY][VX] + 
00693                                          a.mV[VZ] * b.mMatrix[VZ][VX] +
00694                                          b.mMatrix[VW][VX],
00695                                          
00696                                          a.mV[VX] * b.mMatrix[VX][VY] + 
00697                                          a.mV[VY] * b.mMatrix[VY][VY] + 
00698                                          a.mV[VZ] * b.mMatrix[VZ][VY] +
00699                                          b.mMatrix[VW][VY],
00700                                          
00701                                          a.mV[VX] * b.mMatrix[VX][VZ] + 
00702                                          a.mV[VY] * b.mMatrix[VY][VZ] + 
00703                                          a.mV[VZ] * b.mMatrix[VZ][VZ] +
00704                                          b.mMatrix[VW][VZ]);
00705 }
00706 
00707 LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b)
00708 {
00709         // Operate "to the left" on row-vector a
00710         return LLVector4(a.mV[VX] * b.mMatrix[VX][VX] + 
00711                                          a.mV[VY] * b.mMatrix[VY][VX] + 
00712                                          a.mV[VZ] * b.mMatrix[VZ][VX] +
00713                                          a.mV[VW] * b.mMatrix[VW][VX],
00714 
00715                                          a.mV[VX] * b.mMatrix[VX][VY] + 
00716                                          a.mV[VY] * b.mMatrix[VY][VY] + 
00717                                          a.mV[VZ] * b.mMatrix[VZ][VY] +
00718                                          a.mV[VW] * b.mMatrix[VW][VY],
00719 
00720                                          a.mV[VX] * b.mMatrix[VX][VZ] + 
00721                                          a.mV[VY] * b.mMatrix[VY][VZ] + 
00722                                          a.mV[VZ] * b.mMatrix[VZ][VZ] +
00723                                          a.mV[VW] * b.mMatrix[VW][VZ],
00724 
00725                                          a.mV[VX] * b.mMatrix[VX][VW] + 
00726                                          a.mV[VY] * b.mMatrix[VY][VW] + 
00727                                          a.mV[VZ] * b.mMatrix[VZ][VW] +
00728                                          a.mV[VW] * b.mMatrix[VW][VW]);
00729 }
00730 
00731 LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b)
00732 {
00733         // Rotates but does not translate
00734         // Operate "to the left" on row-vector a
00735         LLVector4       vec;
00736         vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] + 
00737                                  a.mV[VY] * b.mMatrix[VY][VX] + 
00738                                  a.mV[VZ] * b.mMatrix[VZ][VX];
00739 
00740         vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] + 
00741                                  a.mV[VY] * b.mMatrix[VY][VY] + 
00742                                  a.mV[VZ] * b.mMatrix[VZ][VY];
00743 
00744         vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] + 
00745                                  a.mV[VY] * b.mMatrix[VY][VZ] + 
00746                                  a.mV[VZ] * b.mMatrix[VZ][VZ];
00747 
00748 //      vec.mV[VW] = a.mV[VX] * b.mMatrix[VX][VW] + 
00749 //                               a.mV[VY] * b.mMatrix[VY][VW] + 
00750 //                               a.mV[VZ] * b.mMatrix[VZ][VW] +
00751         vec.mV[VW] = a.mV[VW];
00752         return vec;
00753 }
00754 
00755 LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b)
00756 {
00757         // Rotates but does not translate
00758         // Operate "to the left" on row-vector a
00759         LLVector3       vec;
00760         vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] + 
00761                                  a.mV[VY] * b.mMatrix[VY][VX] + 
00762                                  a.mV[VZ] * b.mMatrix[VZ][VX];
00763 
00764         vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] + 
00765                                  a.mV[VY] * b.mMatrix[VY][VY] + 
00766                                  a.mV[VZ] * b.mMatrix[VZ][VY];
00767 
00768         vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] + 
00769                                  a.mV[VY] * b.mMatrix[VY][VZ] + 
00770                                  a.mV[VZ] * b.mMatrix[VZ][VZ];
00771         return vec;
00772 }
00773 
00774 bool operator==(const LLMatrix4 &a, const LLMatrix4 &b)
00775 {
00776         U32             i, j;
00777         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00778         {
00779                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00780                 {
00781                         if (a.mMatrix[j][i] != b.mMatrix[j][i])
00782                                 return FALSE;
00783                 }
00784         }
00785         return TRUE;
00786 }
00787 
00788 bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b)
00789 {
00790         U32             i, j;
00791         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00792         {
00793                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00794                 {
00795                         if (a.mMatrix[j][i] != b.mMatrix[j][i])
00796                                 return TRUE;
00797                 }
00798         }
00799         return FALSE;
00800 }
00801 
00802 const LLMatrix4& operator*=(LLMatrix4 &a, F32 k)
00803 {
00804         U32             i, j;
00805         for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
00806         {
00807                 for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
00808                 {
00809                         a.mMatrix[j][i] *= k;
00810                 }
00811         }
00812         return a;
00813 }
00814 
00815 std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a) 
00816 {
00817         s << "{ " 
00818                 << a.mMatrix[VX][VX] << ", " 
00819                 << a.mMatrix[VX][VY] << ", " 
00820                 << a.mMatrix[VX][VZ] << ", " 
00821                 << a.mMatrix[VX][VW] 
00822                 << "; "
00823                 << a.mMatrix[VY][VX] << ", " 
00824                 << a.mMatrix[VY][VY] << ", " 
00825                 << a.mMatrix[VY][VZ] << ", " 
00826                 << a.mMatrix[VY][VW] 
00827                 << "; "
00828                 << a.mMatrix[VZ][VX] << ", " 
00829                 << a.mMatrix[VZ][VY] << ", " 
00830                 << a.mMatrix[VZ][VZ] << ", " 
00831                 << a.mMatrix[VZ][VW] 
00832                 << "; "
00833                 << a.mMatrix[VW][VX] << ", " 
00834                 << a.mMatrix[VW][VY] << ", " 
00835                 << a.mMatrix[VW][VZ] << ", " 
00836                 << a.mMatrix[VW][VW] 
00837           << " }";
00838         return s;
00839 }
00840 
00841 

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