00001 
00032 #include "linden_common.h"
00033 
00034 
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 
00045 
00046 
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 
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 
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 
00228 const LLMatrix4&        LLMatrix4::invert(void) 
00229 {
00230         
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         
00237         
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         
00247         mMatrix[VW][VX] = -mMatrix[VX][VW];
00248         mMatrix[VW][VY] = -mMatrix[VY][VW];
00249         mMatrix[VW][VZ] = -mMatrix[VZ][VW];
00250 
00251         
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 
00273 
00274 
00275 
00276 
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         
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                 
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 
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 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
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         
00469         return (*this);
00470 }
00471 
00472 
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 
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 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
00685 LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b)
00686 {
00687         
00688         
00689         
00690         
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         
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         
00734         
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 
00749 
00750 
00751         vec.mV[VW] = a.mV[VW];
00752         return vec;
00753 }
00754 
00755 LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b)
00756 {
00757         
00758         
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