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::identity()
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::zero()
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
00172
00173 const LLMatrix3& LLMatrix3::transpose()
00174 {
00175
00176 F32 temp;
00177 temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
00178 temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
00179 temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
00180 return *this;
00181 }
00182
00183
00184 F32 LLMatrix3::determinant() const
00185 {
00186
00187
00188 return mMatrix[0][0] * (mMatrix[1][1] * mMatrix[2][2] - mMatrix[1][2] * mMatrix[2][1]) +
00189 mMatrix[0][1] * (mMatrix[1][2] * mMatrix[2][0] - mMatrix[1][0] * mMatrix[2][2]) +
00190 mMatrix[0][2] * (mMatrix[1][0] * mMatrix[2][1] - mMatrix[1][1] * mMatrix[2][0]);
00191 }
00192
00193
00194 const LLMatrix3& LLMatrix3::invert()
00195 {
00196
00197 F32 temp;
00198 temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
00199 temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
00200 temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
00201 return *this;
00202 }
00203
00204
00205 const LLMatrix3& LLMatrix3::adjointTranspose()
00206 {
00207 LLMatrix3 adjoint_transpose;
00208 adjoint_transpose.mMatrix[VX][VX] = mMatrix[VY][VY] * mMatrix[VZ][VZ] - mMatrix[VY][VZ] * mMatrix[VZ][VY] ;
00209 adjoint_transpose.mMatrix[VY][VX] = mMatrix[VY][VZ] * mMatrix[VZ][VX] - mMatrix[VY][VX] * mMatrix[VZ][VZ] ;
00210 adjoint_transpose.mMatrix[VZ][VX] = mMatrix[VY][VX] * mMatrix[VZ][VY] - mMatrix[VY][VY] * mMatrix[VZ][VX] ;
00211 adjoint_transpose.mMatrix[VX][VY] = mMatrix[VZ][VY] * mMatrix[VX][VZ] - mMatrix[VZ][VZ] * mMatrix[VX][VY] ;
00212 adjoint_transpose.mMatrix[VY][VY] = mMatrix[VZ][VZ] * mMatrix[VX][VX] - mMatrix[VZ][VX] * mMatrix[VX][VZ] ;
00213 adjoint_transpose.mMatrix[VZ][VY] = mMatrix[VZ][VX] * mMatrix[VX][VY] - mMatrix[VZ][VY] * mMatrix[VX][VX] ;
00214 adjoint_transpose.mMatrix[VX][VZ] = mMatrix[VX][VY] * mMatrix[VY][VZ] - mMatrix[VX][VZ] * mMatrix[VY][VY] ;
00215 adjoint_transpose.mMatrix[VY][VZ] = mMatrix[VX][VZ] * mMatrix[VY][VX] - mMatrix[VX][VX] * mMatrix[VY][VZ] ;
00216 adjoint_transpose.mMatrix[VZ][VZ] = mMatrix[VX][VX] * mMatrix[VY][VY] - mMatrix[VX][VY] * mMatrix[VY][VX] ;
00217
00218 *this = adjoint_transpose;
00219 return *this;
00220 }
00221
00222
00223
00224
00225
00226
00227 LLQuaternion LLMatrix3::quaternion() const
00228 {
00229 LLQuaternion quat;
00230 F32 tr, s, q[4];
00231 U32 i, j, k;
00232 U32 nxt[3] = {1, 2, 0};
00233
00234 tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2];
00235
00236
00237 if (tr > 0.f)
00238 {
00239 s = (F32)sqrt (tr + 1.f);
00240 quat.mQ[VS] = s / 2.f;
00241 s = 0.5f / s;
00242 quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s;
00243 quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s;
00244 quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s;
00245 }
00246 else
00247 {
00248
00249 i = 0;
00250 if (mMatrix[1][1] > mMatrix[0][0])
00251 i = 1;
00252 if (mMatrix[2][2] > mMatrix[i][i])
00253 i = 2;
00254
00255 j = nxt[i];
00256 k = nxt[j];
00257
00258
00259 s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f);
00260
00261 q[i] = s * 0.5f;
00262
00263 if (s != 0.f)
00264 s = 0.5f / s;
00265
00266 q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s;
00267 q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s;
00268 q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s;
00269
00270 quat.setQuat(q);
00271 }
00272 return quat;
00273 }
00274
00275
00276
00277 const LLMatrix3& LLMatrix3::setRot(const F32 angle, const F32 x, const F32 y, const F32 z)
00278 {
00279 setRot(LLQuaternion(angle,x,y,z));
00280 return *this;
00281 }
00282
00283 const LLMatrix3& LLMatrix3::setRot(const F32 angle, const LLVector3 &vec)
00284 {
00285 setRot(LLQuaternion(angle, vec));
00286 return *this;
00287 }
00288
00289 const LLMatrix3& LLMatrix3::setRot(const F32 roll, const F32 pitch, const F32 yaw)
00290 {
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 F32 cx, sx, cy, sy, cz, sz;
00306 F32 cxsy, sxsy;
00307
00308 cx = (F32)cos(roll);
00309 sx = (F32)sin(roll);
00310 cy = (F32)cos(pitch);
00311 sy = (F32)sin(pitch);
00312 cz = (F32)cos(yaw);
00313 sz = (F32)sin(yaw);
00314
00315 cxsy = cx * sy;
00316 sxsy = sx * sy;
00317
00318 mMatrix[0][0] = cy * cz;
00319 mMatrix[1][0] = -cy * sz;
00320 mMatrix[2][0] = sy;
00321 mMatrix[0][1] = sxsy * cz + cx * sz;
00322 mMatrix[1][1] = -sxsy * sz + cx * cz;
00323 mMatrix[2][1] = -sx * cy;
00324 mMatrix[0][2] = -cxsy * cz + sx * sz;
00325 mMatrix[1][2] = cxsy * sz + sx * cz;
00326 mMatrix[2][2] = cx * cy;
00327 return *this;
00328 }
00329
00330
00331 const LLMatrix3& LLMatrix3::setRot(const LLQuaternion &q)
00332 {
00333 *this = q.getMatrix3();
00334 return *this;
00335 }
00336
00337 const LLMatrix3& LLMatrix3::setRows(const LLVector3 &fwd, const LLVector3 &left, const LLVector3 &up)
00338 {
00339 mMatrix[0][0] = fwd.mV[0];
00340 mMatrix[0][1] = fwd.mV[1];
00341 mMatrix[0][2] = fwd.mV[2];
00342
00343 mMatrix[1][0] = left.mV[0];
00344 mMatrix[1][1] = left.mV[1];
00345 mMatrix[1][2] = left.mV[2];
00346
00347 mMatrix[2][0] = up.mV[0];
00348 mMatrix[2][1] = up.mV[1];
00349 mMatrix[2][2] = up.mV[2];
00350
00351 return *this;
00352 }
00353
00354
00355
00356 const LLMatrix3& LLMatrix3::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
00357 {
00358 LLMatrix3 mat(angle, x, y, z);
00359 *this *= mat;
00360 return *this;
00361 }
00362
00363
00364 const LLMatrix3& LLMatrix3::rotate(const F32 angle, const LLVector3 &vec)
00365 {
00366 LLMatrix3 mat(angle, vec);
00367 *this *= mat;
00368 return *this;
00369 }
00370
00371
00372 const LLMatrix3& LLMatrix3::rotate(const F32 roll, const F32 pitch, const F32 yaw)
00373 {
00374 LLMatrix3 mat(roll, pitch, yaw);
00375 *this *= mat;
00376 return *this;
00377 }
00378
00379
00380 const LLMatrix3& LLMatrix3::rotate(const LLQuaternion &q)
00381 {
00382 LLMatrix3 mat(q);
00383 *this *= mat;
00384 return *this;
00385 }
00386
00387
00388 LLVector3 LLMatrix3::getFwdRow() const
00389 {
00390 return LLVector3(mMatrix[VX]);
00391 }
00392
00393 LLVector3 LLMatrix3::getLeftRow() const
00394 {
00395 return LLVector3(mMatrix[VY]);
00396 }
00397
00398 LLVector3 LLMatrix3::getUpRow() const
00399 {
00400 return LLVector3(mMatrix[VZ]);
00401 }
00402
00403
00404
00405 const LLMatrix3& LLMatrix3::orthogonalize()
00406 {
00407 LLVector3 x_axis(mMatrix[VX]);
00408 LLVector3 y_axis(mMatrix[VY]);
00409 LLVector3 z_axis(mMatrix[VZ]);
00410
00411 x_axis.normVec();
00412 y_axis -= x_axis * (x_axis * y_axis);
00413 y_axis.normVec();
00414 z_axis = x_axis % y_axis;
00415 setRows(x_axis, y_axis, z_axis);
00416 return (*this);
00417 }
00418
00419
00420
00421
00422 LLMatrix3 operator*(const LLMatrix3 &a, const LLMatrix3 &b)
00423 {
00424 U32 i, j;
00425 LLMatrix3 mat;
00426 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00427 {
00428 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00429 {
00430 mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +
00431 a.mMatrix[j][1] * b.mMatrix[1][i] +
00432 a.mMatrix[j][2] * b.mMatrix[2][i];
00433 }
00434 }
00435 return mat;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 LLVector3 operator*(const LLVector3 &a, const LLMatrix3 &b)
00461 {
00462
00463 return LLVector3(
00464 a.mV[VX] * b.mMatrix[VX][VX] +
00465 a.mV[VY] * b.mMatrix[VY][VX] +
00466 a.mV[VZ] * b.mMatrix[VZ][VX],
00467
00468 a.mV[VX] * b.mMatrix[VX][VY] +
00469 a.mV[VY] * b.mMatrix[VY][VY] +
00470 a.mV[VZ] * b.mMatrix[VZ][VY],
00471
00472 a.mV[VX] * b.mMatrix[VX][VZ] +
00473 a.mV[VY] * b.mMatrix[VY][VZ] +
00474 a.mV[VZ] * b.mMatrix[VZ][VZ] );
00475 }
00476
00477 LLVector3d operator*(const LLVector3d &a, const LLMatrix3 &b)
00478 {
00479
00480 return LLVector3d(
00481 a.mdV[VX] * b.mMatrix[VX][VX] +
00482 a.mdV[VY] * b.mMatrix[VY][VX] +
00483 a.mdV[VZ] * b.mMatrix[VZ][VX],
00484
00485 a.mdV[VX] * b.mMatrix[VX][VY] +
00486 a.mdV[VY] * b.mMatrix[VY][VY] +
00487 a.mdV[VZ] * b.mMatrix[VZ][VY],
00488
00489 a.mdV[VX] * b.mMatrix[VX][VZ] +
00490 a.mdV[VY] * b.mMatrix[VY][VZ] +
00491 a.mdV[VZ] * b.mMatrix[VZ][VZ] );
00492 }
00493
00494 bool operator==(const LLMatrix3 &a, const LLMatrix3 &b)
00495 {
00496 U32 i, j;
00497 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00498 {
00499 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00500 {
00501 if (a.mMatrix[j][i] != b.mMatrix[j][i])
00502 return FALSE;
00503 }
00504 }
00505 return TRUE;
00506 }
00507
00508 bool operator!=(const LLMatrix3 &a, const LLMatrix3 &b)
00509 {
00510 U32 i, j;
00511 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00512 {
00513 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00514 {
00515 if (a.mMatrix[j][i] != b.mMatrix[j][i])
00516 return TRUE;
00517 }
00518 }
00519 return FALSE;
00520 }
00521
00522 const LLMatrix3& operator*=(LLMatrix3 &a, const LLMatrix3 &b)
00523 {
00524 U32 i, j;
00525 LLMatrix3 mat;
00526 for (i = 0; i < NUM_VALUES_IN_MAT3; i++)
00527 {
00528 for (j = 0; j < NUM_VALUES_IN_MAT3; j++)
00529 {
00530 mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] +
00531 a.mMatrix[j][1] * b.mMatrix[1][i] +
00532 a.mMatrix[j][2] * b.mMatrix[2][i];
00533 }
00534 }
00535 a = mat;
00536 return a;
00537 }
00538
00539 std::ostream& operator<<(std::ostream& s, const LLMatrix3 &a)
00540 {
00541 s << "{ "
00542 << a.mMatrix[VX][VX] << ", " << a.mMatrix[VX][VY] << ", " << a.mMatrix[VX][VZ] << "; "
00543 << a.mMatrix[VY][VX] << ", " << a.mMatrix[VY][VY] << ", " << a.mMatrix[VY][VZ] << "; "
00544 << a.mMatrix[VZ][VX] << ", " << a.mMatrix[VZ][VY] << ", " << a.mMatrix[VZ][VZ]
00545 << " }";
00546 return s;
00547 }
00548