00001
00032 #include "linden_common.h"
00033
00034
00035 #include "v3math.h"
00036 #include "v3dmath.h"
00037 #include "v4math.h"
00038 #include "m4math.h"
00039 #include "m3math.h"
00040 #include "llquaternion.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 LLMatrix3::LLMatrix3(const LLQuaternion &q)
00058 {
00059 setRot(q);
00060 }
00061
00062
00063 LLMatrix3::LLMatrix3(const F32 angle, const LLVector3 &vec)
00064 {
00065 LLQuaternion quat(angle, vec);
00066 setRot(quat);
00067 }
00068
00069 LLMatrix3::LLMatrix3(const F32 angle, const LLVector3d &vec)
00070 {
00071 LLVector3 vec_f;
00072 vec_f.setVec(vec);
00073 LLQuaternion quat(angle, vec_f);
00074 setRot(quat);
00075 }
00076
00077 LLMatrix3::LLMatrix3(const F32 angle, const LLVector4 &vec)
00078 {
00079 LLQuaternion quat(angle, vec);
00080 setRot(quat);
00081 }
00082
00083 LLMatrix3::LLMatrix3(const F32 angle, const F32 x, const F32 y, const F32 z)
00084 {
00085 LLVector3 vec(x, y, z);
00086 LLQuaternion quat(angle, vec);
00087 setRot(quat);
00088 }
00089
00090 LLMatrix3::LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw)
00091 {
00092 setRot(roll,pitch,yaw);
00093 }
00094
00095
00096 void LLMatrix3::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
00097 {
00098 F64 angle_x, angle_y, angle_z;
00099 F64 cx, cy, cz;
00100 F64 sx, sz;
00101
00102 angle_y = asin(llclamp(mMatrix[2][0], -1.f, 1.f));
00103 cy = cos(angle_y);
00104
00105 if (fabs(cy) > 0.005)
00106 {
00107
00108 cx = mMatrix[2][2] / cy;
00109 sx = - mMatrix[2][1] / cy;
00110
00111 angle_x = (F32) atan2(sx, cx);
00112
00113 cz = mMatrix[0][0] / cy;
00114 sz = - mMatrix[1][0] / cy;
00115
00116 angle_z = (F32) atan2(sz, cz);
00117 }
00118 else
00119 {
00120
00121 angle_x = 0;
00122
00123
00124
00125 cz = mMatrix[1][1];
00126 sz = mMatrix[0][1];
00127
00128 angle_z = atan2(sz, cz);
00129 }
00130
00131 *roll = (F32)angle_x;
00132 *pitch = (F32)angle_y;
00133 *yaw = (F32)angle_z;
00134 }
00135
00136
00137
00138
00139 const LLMatrix3& LLMatrix3::setIdentity()
00140 {
00141 mMatrix[0][0] = 1.f;
00142 mMatrix[0][1] = 0.f;
00143 mMatrix[0][2] = 0.f;
00144
00145 mMatrix[1][0] = 0.f;
00146 mMatrix[1][1] = 1.f;
00147 mMatrix[1][2] = 0.f;
00148
00149 mMatrix[2][0] = 0.f;
00150 mMatrix[2][1] = 0.f;
00151 mMatrix[2][2] = 1.f;
00152 return (*this);
00153 }
00154
00155 const LLMatrix3& LLMatrix3::clear()
00156 {
00157 mMatrix[0][0] = 0.f;
00158 mMatrix[0][1] = 0.f;
00159 mMatrix[0][2] = 0.f;
00160
00161 mMatrix[1][0] = 0.f;
00162 mMatrix[1][1] = 0.f;
00163 mMatrix[1][2] = 0.f;
00164
00165 mMatrix[2][0] = 0.f;
00166 mMatrix[2][1] = 0.f;
00167 mMatrix[2][2] = 0.f;
00168 return (*this);
00169 }
00170
00171 const LLMatrix3& LLMatrix3::setZero()
00172 {
00173 mMatrix[0][0] = 0.f;
00174 mMatrix[0][1] = 0.f;
00175 mMatrix[0][2] = 0.f;
00176
00177 mMatrix[1][0] = 0.f;
00178 mMatrix[1][1] = 0.f;
00179 mMatrix[1][2] = 0.f;
00180
00181 mMatrix[2][0] = 0.f;
00182 mMatrix[2][1] = 0.f;
00183 mMatrix[2][2] = 0.f;
00184 return (*this);
00185 }
00186
00187
00188
00189 const LLMatrix3& LLMatrix3::transpose()
00190 {
00191
00192 F32 temp;
00193 temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
00194 temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
00195 temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
00196 return *this;
00197 }
00198
00199
00200 F32 LLMatrix3::determinant() const
00201 {
00202
00203
00204 return mMatrix[0][0] * (mMatrix[1][1] * mMatrix[2][2] - mMatrix[1][2] * mMatrix[2][1]) +
00205 mMatrix[0][1] * (mMatrix[1][2] * mMatrix[2][0] - mMatrix[1][0] * mMatrix[2][2]) +
00206 mMatrix[0][2] * (mMatrix[1][0] * mMatrix[2][1] - mMatrix[1][1] * mMatrix[2][0]);
00207 }
00208
00209
00210 void LLMatrix3::invert()
00211 {
00212
00213 F32 det = determinant();
00214 const F32 VERY_SMALL_DETERMINANT = 0.000001f;
00215 if (fabs(det) > VERY_SMALL_DETERMINANT)
00216 {
00217
00218 LLMatrix3 t(*this);
00219 mMatrix[VX][VX] = ( t.mMatrix[VY][VY] * t.mMatrix[VZ][VZ] - t.mMatrix[VY][VZ] * t.mMatrix[VZ][VY] ) / det;
00220 mMatrix[VY][VX] = ( t.mMatrix[VY][VZ] * t.mMatrix[VZ][VX] - t.mMatrix[VY][VX] * t.mMatrix[VZ][VZ] ) / det;
00221 mMatrix[VZ][VX] = ( t.mMatrix[VY][VX] * t.mMatrix[VZ][VY] - t.mMatrix[VY][VY] * t.mMatrix[VZ][VX] ) / det;
00222 mMatrix[VX][VY] = ( t.mMatrix[VZ][VY] * t.mMatrix[VX][VZ] - t.mMatrix[VZ][VZ] * t.mMatrix[VX][VY] ) / det;
00223 mMatrix[VY][VY] = ( t.mMatrix[VZ][VZ] * t.mMatrix[VX][VX] - t.mMatrix[VZ][VX] * t.mMatrix[VX][VZ] ) / det;
00224 mMatrix[VZ][VY] = ( t.mMatrix[VZ][VX] * t.mMatrix[VX][VY] - t.mMatrix[VZ][VY] * t.mMatrix[VX][VX] ) / det;
00225 mMatrix[VX][VZ] = ( t.mMatrix[VX][VY] * t.mMatrix[VY][VZ] - t.mMatrix[VX][VZ] * t.mMatrix[VY][VY] ) / det;
00226 mMatrix[VY][VZ] = ( t.mMatrix[VX][VZ] * t.mMatrix[VY][VX] - t.mMatrix[VX][VX] * t.mMatrix[VY][VZ] ) / det;
00227 mMatrix[VZ][VZ] = ( t.mMatrix[VX][VX] * t.mMatrix[VY][VY] - t.mMatrix[VX][VY] * t.mMatrix[VY][VX] ) / det;
00228 }
00229 }
00230
00231
00232 const LLMatrix3& LLMatrix3::adjointTranspose()
00233 {
00234 LLMatrix3 adjoint_transpose;
00235 adjoint_transpose.mMatrix[VX][VX] = mMatrix[VY][VY] * mMatrix[VZ][VZ] - mMatrix[VY][VZ] * mMatrix[VZ][VY] ;
00236 adjoint_transpose.mMatrix[VY][VX] = mMatrix[VY][VZ] * mMatrix[VZ][VX] - mMatrix[VY][VX] * mMatrix[VZ][VZ] ;
00237 adjoint_transpose.mMatrix[VZ][VX] = mMatrix[VY][VX] * mMatrix[VZ][VY] - mMatrix[VY][VY] * mMatrix[VZ][VX] ;
00238 adjoint_transpose.mMatrix[VX][VY] = mMatrix[VZ][VY] * mMatrix[VX][VZ] - mMatrix[VZ][VZ] * mMatrix[VX][VY] ;
00239 adjoint_transpose.mMatrix[VY][VY] = mMatrix[VZ][VZ] * mMatrix[VX][VX] - mMatrix[VZ][VX] * mMatrix[VX][VZ] ;
00240 adjoint_transpose.mMatrix[VZ][VY] = mMatrix[VZ][VX] * mMatrix[VX][VY] - mMatrix[VZ][VY] * mMatrix[VX][VX] ;
00241 adjoint_transpose.mMatrix[VX][VZ] = mMatrix[VX][VY] * mMatrix[VY][VZ] - mMatrix[VX][VZ] * mMatrix[VY][VY] ;
00242 adjoint_transpose.mMatrix[VY][VZ] = mMatrix[VX][VZ] * mMatrix[VY][VX] - mMatrix[VX][VX] * mMatrix[VY][VZ] ;
00243 adjoint_transpose.mMatrix[VZ][VZ] = mMatrix[VX][VX] * mMatrix[VY][VY] - mMatrix[VX][VY] * mMatrix[VY][VX] ;
00244
00245 *this = adjoint_transpose;
00246 return *this;
00247 }
00248
00249
00250
00251
00252
00253
00254 LLQuaternion LLMatrix3::quaternion() const
00255 {
00256 LLQuaternion quat;
00257 F32 tr, s, q[4];
00258 U32 i, j, k;
00259 U32 nxt[3] = {1, 2, 0};
00260
00261 tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2];
00262
00263
00264 if (tr > 0.f)
00265 {
00266 s = (F32)sqrt (tr + 1.f);
00267 quat.mQ[VS] = s / 2.f;
00268 s = 0.5f / s;
00269 quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s;
00270 quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s;
00271 quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s;
00272 }
00273 else
00274 {
00275
00276 i = 0;
00277 if (mMatrix[1][1] > mMatrix[0][0])
00278 i = 1;
00279 if (mMatrix[2][2] > mMatrix[i][i])
00280 i = 2;
00281
00282 j = nxt[i];
00283 k = nxt[j];
00284
00285
00286 s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f);
00287
00288 q[i] = s * 0.5f;
00289
00290 if (s != 0.f)
00291 s = 0.5f / s;
00292
00293 q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s;
00294 q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s;
00295 q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s;
00296
00297 quat.setQuat(q);
00298 }
00299 return quat;
00300 }
00301
00302
00303
00304 const LLMatrix3& LLMatrix3::setRot(const F32 angle, const F32 x, const F32 y, const F32 z)
00305 {
00306 setRot(LLQuaternion(angle,x,y,z));
00307 return *this;
00308 }
00309
00310 const LLMatrix3& LLMatrix3::setRot(const F32 angle, const LLVector3 &vec)
00311 {
00312 setRot(LLQuaternion(angle, vec));
00313 return *this;
00314 }
00315
00316 const LLMatrix3& LLMatrix3::setRot(const F32 roll, const F32 pitch, const F32 yaw)
00317 {
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 F32 cx, sx, cy, sy, cz, sz;
00333 F32 cxsy, sxsy;
00334
00335 cx = (F32)cos(roll);
00336 sx = (F32)sin(roll);
00337 cy = (F32)cos(pitch);
00338 sy = (F32)sin(pitch);
00339 cz = (F32)cos(yaw);
00340 sz = (F32)sin(yaw);
00341
00342 cxsy = cx * sy;
00343 sxsy = sx * sy;
00344
00345 mMatrix[0][0] = cy * cz;
00346 mMatrix[1][0] = -cy * sz;
00347 mMatrix[2][0] = sy;
00348 mMatrix[0][1] = sxsy * cz + cx * sz;
00349 mMatrix[1][1] = -sxsy * sz + cx * cz;
00350 mMatrix[2][1] = -sx * cy;
00351 mMatrix[0][2] = -cxsy * cz + sx * sz;
00352 mMatrix[1][2] = cxsy * sz + sx * cz;
00353 mMatrix[2][2] = cx * cy;
00354 return *this;
00355 }
00356
00357
00358 const LLMatrix3& LLMatrix3::setRot(const LLQuaternion &q)
00359 {
00360 *this = q.getMatrix3();
00361 return *this;
00362 }
00363
00364 const LLMatrix3& LLMatrix3::setRows(const LLVector3 &fwd, const LLVector3 &left, const LLVector3 &up)
00365 {
00366 mMatrix[0][0] = fwd.mV[0];
00367 mMatrix[0][1] = fwd.mV[1];
00368 mMatrix[0][2] = fwd.mV[2];
00369
00370 mMatrix[1][0] = left.mV[0];
00371 mMatrix[1][1] = left.mV[1];
00372 mMatrix[1][2] = left.mV[2];
00373
00374 mMatrix[2][0] = up.mV[0];
00375 mMatrix[2][1] = up.mV[1];
00376 mMatrix[2][2] = up.mV[2];
00377
00378 return *this;
00379 }
00380
00381 const LLMatrix3& LLMatrix3::setRow( U32 rowIndex, const LLVector3& row )
00382 {
00383 llassert( rowIndex >= 0 && rowIndex < NUM_VALUES_IN_MAT3 );
00384
00385 mMatrix[rowIndex][0] = row[0];
00386 mMatrix[rowIndex][1] = row[1];
00387 mMatrix[rowIndex][2] = row[2];
00388
00389 return *this;
00390 }
00391
00392 const LLMatrix3& LLMatrix3::setCol( U32 colIndex, const LLVector3& col )
00393 {
00394 llassert( colIndex >= 0 && colIndex < NUM_VALUES_IN_MAT3 );
00395
00396 mMatrix[0][colIndex] = col[0];
00397 mMatrix[1][colIndex] = col[1];
00398 mMatrix[2][colIndex] = col[2];
00399
00400 return *this;
00401 }
00402
00403
00404 const LLMatrix3& LLMatrix3::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
00405 {
00406 LLMatrix3 mat(angle, x, y, z);
00407 *this *= mat;
00408 return *this;
00409 }
00410
00411
00412 const LLMatrix3& LLMatrix3::rotate(const F32 angle, const LLVector3 &vec)
00413 {
00414 LLMatrix3 mat(angle, vec);
00415 *this *= mat;
00416 return *this;
00417 }
00418
00419
00420 const LLMatrix3& LLMatrix3::rotate(const F32 roll, const F32 pitch, const F32 yaw)
00421 {
00422 LLMatrix3 mat(roll, pitch, yaw);
00423 *this *= mat;
00424 return *this;
00425 }
00426
00427
00428 const LLMatrix3& LLMatrix3::rotate(const LLQuaternion &q)
00429 {
00430 LLMatrix3 mat(q);
00431 *this *= mat;
00432 return *this;
00433 }
00434
00435 void LLMatrix3::add(const LLMatrix3& other_matrix)
00436 {
00437 for (S32 i = 0; i < 3; ++i)
00438 {
00439 for (S32 j = 0; j < 3; ++j)
00440 {
00441 mMatrix[i][j] += other_matrix.mMatrix[i][j];
00442 }
00443 }
00444 }
00445
00446 LLVector3 LLMatrix3::getFwdRow() const
00447 {
00448 return LLVector3(mMatrix[VX]);
00449 }
00450
00451 LLVector3 LLMatrix3::getLeftRow() const
00452 {
00453 return LLVector3(mMatrix[VY]);
00454 }
00455
00456 LLVector3 LLMatrix3::getUpRow() const
00457 {
00458 return LLVector3(mMatrix[VZ]);
00459 }
00460
00461
00462
00463 const LLMatrix3& LLMatrix3::orthogonalize()
00464 {
00465 LLVector3 x_axis(mMatrix[VX]);
00466 LLVector3 y_axis(mMatrix[VY]);
00467 LLVector3 z_axis(mMatrix[VZ]);
00468
00469 x_axis.normVec();
00470 y_axis -= x_axis * (x_axis * y_axis);
00471 y_axis.normVec();
00472 z_axis = x_axis % y_axis;
00473 setRows(x_axis, y_axis, z_axis);
00474 return (*this);
00475 }
00476
00477
00478
00479
00480 LLMatrix3 operator*(const LLMatrix3 &a, const LLMatrix3 &b)
00481 {
00482 U32 i, j;
00483 LLMatrix3 mat;
00484 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00485 {
00486 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00487 {
00488 mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +
00489 a.mMatrix[j][1] * b.mMatrix[1][i] +
00490 a.mMatrix[j][2] * b.mMatrix[2][i];
00491 }
00492 }
00493 return mat;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 LLVector3 operator*(const LLVector3 &a, const LLMatrix3 &b)
00519 {
00520
00521 return LLVector3(
00522 a.mV[VX] * b.mMatrix[VX][VX] +
00523 a.mV[VY] * b.mMatrix[VY][VX] +
00524 a.mV[VZ] * b.mMatrix[VZ][VX],
00525
00526 a.mV[VX] * b.mMatrix[VX][VY] +
00527 a.mV[VY] * b.mMatrix[VY][VY] +
00528 a.mV[VZ] * b.mMatrix[VZ][VY],
00529
00530 a.mV[VX] * b.mMatrix[VX][VZ] +
00531 a.mV[VY] * b.mMatrix[VY][VZ] +
00532 a.mV[VZ] * b.mMatrix[VZ][VZ] );
00533 }
00534
00535 LLVector3d operator*(const LLVector3d &a, const LLMatrix3 &b)
00536 {
00537
00538 return LLVector3d(
00539 a.mdV[VX] * b.mMatrix[VX][VX] +
00540 a.mdV[VY] * b.mMatrix[VY][VX] +
00541 a.mdV[VZ] * b.mMatrix[VZ][VX],
00542
00543 a.mdV[VX] * b.mMatrix[VX][VY] +
00544 a.mdV[VY] * b.mMatrix[VY][VY] +
00545 a.mdV[VZ] * b.mMatrix[VZ][VY],
00546
00547 a.mdV[VX] * b.mMatrix[VX][VZ] +
00548 a.mdV[VY] * b.mMatrix[VY][VZ] +
00549 a.mdV[VZ] * b.mMatrix[VZ][VZ] );
00550 }
00551
00552 bool operator==(const LLMatrix3 &a, const LLMatrix3 &b)
00553 {
00554 U32 i, j;
00555 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00556 {
00557 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00558 {
00559 if (a.mMatrix[j][i] != b.mMatrix[j][i])
00560 return FALSE;
00561 }
00562 }
00563 return TRUE;
00564 }
00565
00566 bool operator!=(const LLMatrix3 &a, const LLMatrix3 &b)
00567 {
00568 U32 i, j;
00569 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00570 {
00571 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00572 {
00573 if (a.mMatrix[j][i] != b.mMatrix[j][i])
00574 return TRUE;
00575 }
00576 }
00577 return FALSE;
00578 }
00579
00580 const LLMatrix3& operator*=(LLMatrix3 &a, const LLMatrix3 &b)
00581 {
00582 U32 i, j;
00583 LLMatrix3 mat;
00584 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00585 {
00586 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00587 {
00588 mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +
00589 a.mMatrix[j][1] * b.mMatrix[1][i] +
00590 a.mMatrix[j][2] * b.mMatrix[2][i];
00591 }
00592 }
00593 a = mat;
00594 return a;
00595 }
00596
00597 const LLMatrix3& operator*=(LLMatrix3 &a, F32 scalar )
00598 {
00599 for( U32 i = 0; i < NUM_VALUES_IN_MAT3; ++i )
00600 {
00601 for( U32 j = 0; j < NUM_VALUES_IN_MAT3; ++j )
00602 {
00603 a.mMatrix[i][j] *= scalar;
00604 }
00605 }
00606
00607 return a;
00608 }
00609
00610 std::ostream& operator<<(std::ostream& s, const LLMatrix3 &a)
00611 {
00612 s << "{ "
00613 << a.mMatrix[VX][VX] << ", " << a.mMatrix[VX][VY] << ", " << a.mMatrix[VX][VZ] << "; "
00614 << a.mMatrix[VY][VX] << ", " << a.mMatrix[VY][VY] << ", " << a.mMatrix[VY][VZ] << "; "
00615 << a.mMatrix[VZ][VX] << ", " << a.mMatrix[VZ][VY] << ", " << a.mMatrix[VZ][VZ]
00616 << " }";
00617 return s;
00618 }
00619