00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef BT_MATRIX3x3_H
00017 #define BT_MATRIX3x3_H
00018
00019 #include "btVector3.h"
00020 #include "btQuaternion.h"
00021
00022 #ifdef BT_USE_DOUBLE_PRECISION
00023 #define btMatrix3x3Data btMatrix3x3DoubleData
00024 #else
00025 #define btMatrix3x3Data btMatrix3x3FloatData
00026 #endif //BT_USE_DOUBLE_PRECISION
00027
00028
00031 class btMatrix3x3 {
00032
00034 btVector3 m_el[3];
00035
00036 public:
00038 btMatrix3x3 () {}
00039
00040
00041
00043 explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); }
00044
00045
00046
00047
00048
00049
00050
00052 btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz,
00053 const btScalar& yx, const btScalar& yy, const btScalar& yz,
00054 const btScalar& zx, const btScalar& zy, const btScalar& zz)
00055 {
00056 setValue(xx, xy, xz,
00057 yx, yy, yz,
00058 zx, zy, zz);
00059 }
00061 SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
00062 {
00063 m_el[0] = other.m_el[0];
00064 m_el[1] = other.m_el[1];
00065 m_el[2] = other.m_el[2];
00066 }
00068 SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
00069 {
00070 m_el[0] = other.m_el[0];
00071 m_el[1] = other.m_el[1];
00072 m_el[2] = other.m_el[2];
00073 return *this;
00074 }
00075
00078 SIMD_FORCE_INLINE btVector3 getColumn(int i) const
00079 {
00080 return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
00081 }
00082
00083
00086 SIMD_FORCE_INLINE const btVector3& getRow(int i) const
00087 {
00088 btFullAssert(0 <= i && i < 3);
00089 return m_el[i];
00090 }
00091
00094 SIMD_FORCE_INLINE btVector3& operator[](int i)
00095 {
00096 btFullAssert(0 <= i && i < 3);
00097 return m_el[i];
00098 }
00099
00102 SIMD_FORCE_INLINE const btVector3& operator[](int i) const
00103 {
00104 btFullAssert(0 <= i && i < 3);
00105 return m_el[i];
00106 }
00107
00111 btMatrix3x3& operator*=(const btMatrix3x3& m);
00112
00115 void setFromOpenGLSubMatrix(const btScalar *m)
00116 {
00117 m_el[0].setValue(m[0],m[4],m[8]);
00118 m_el[1].setValue(m[1],m[5],m[9]);
00119 m_el[2].setValue(m[2],m[6],m[10]);
00120
00121 }
00132 void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz,
00133 const btScalar& yx, const btScalar& yy, const btScalar& yz,
00134 const btScalar& zx, const btScalar& zy, const btScalar& zz)
00135 {
00136 m_el[0].setValue(xx,xy,xz);
00137 m_el[1].setValue(yx,yy,yz);
00138 m_el[2].setValue(zx,zy,zz);
00139 }
00140
00143 void setRotation(const btQuaternion& q)
00144 {
00145 btScalar d = q.length2();
00146 btFullAssert(d != btScalar(0.0));
00147 btScalar s = btScalar(2.0) / d;
00148 btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s;
00149 btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs;
00150 btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs;
00151 btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs;
00152 setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy,
00153 xy + wz, btScalar(1.0) - (xx + zz), yz - wx,
00154 xz - wy, yz + wx, btScalar(1.0) - (xx + yy));
00155 }
00156
00157
00163 void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) __attribute__((deprecated))
00164 {
00165 setEulerYPR(yaw, pitch, roll);
00166 }
00167
00177 void setEulerYPR(btScalar eulerZ, btScalar eulerY,btScalar eulerX) {
00178 btScalar ci ( btCos(eulerX));
00179 btScalar cj ( btCos(eulerY));
00180 btScalar ch ( btCos(eulerZ));
00181 btScalar si ( btSin(eulerX));
00182 btScalar sj ( btSin(eulerY));
00183 btScalar sh ( btSin(eulerZ));
00184 btScalar cc = ci * ch;
00185 btScalar cs = ci * sh;
00186 btScalar sc = si * ch;
00187 btScalar ss = si * sh;
00188
00189 setValue(cj * ch, sj * sc - cs, sj * cc + ss,
00190 cj * sh, sj * ss + cc, sj * cs - sc,
00191 -sj, cj * si, cj * ci);
00192 }
00193
00200 void setRPY(btScalar roll, btScalar pitch,btScalar yaw) {
00201 setEulerYPR(yaw, pitch, roll);
00202 }
00203
00205 void setIdentity()
00206 {
00207 setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0),
00208 btScalar(0.0), btScalar(1.0), btScalar(0.0),
00209 btScalar(0.0), btScalar(0.0), btScalar(1.0));
00210 }
00211
00212 static const btMatrix3x3& getIdentity()
00213 {
00214 static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0),
00215 btScalar(0.0), btScalar(1.0), btScalar(0.0),
00216 btScalar(0.0), btScalar(0.0), btScalar(1.0));
00217 return identityMatrix;
00218 }
00219
00222 void getOpenGLSubMatrix(btScalar *m) const
00223 {
00224 m[0] = btScalar(m_el[0].x());
00225 m[1] = btScalar(m_el[1].x());
00226 m[2] = btScalar(m_el[2].x());
00227 m[3] = btScalar(0.0);
00228 m[4] = btScalar(m_el[0].y());
00229 m[5] = btScalar(m_el[1].y());
00230 m[6] = btScalar(m_el[2].y());
00231 m[7] = btScalar(0.0);
00232 m[8] = btScalar(m_el[0].z());
00233 m[9] = btScalar(m_el[1].z());
00234 m[10] = btScalar(m_el[2].z());
00235 m[11] = btScalar(0.0);
00236 }
00237
00240 void getRotation(btQuaternion& q) const
00241 {
00242 btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
00243 btScalar temp[4];
00244
00245 if (trace > btScalar(0.0))
00246 {
00247 btScalar s = btSqrt(trace + btScalar(1.0));
00248 temp[3]=(s * btScalar(0.5));
00249 s = btScalar(0.5) / s;
00250
00251 temp[0]=((m_el[2].y() - m_el[1].z()) * s);
00252 temp[1]=((m_el[0].z() - m_el[2].x()) * s);
00253 temp[2]=((m_el[1].x() - m_el[0].y()) * s);
00254 }
00255 else
00256 {
00257 int i = m_el[0].x() < m_el[1].y() ?
00258 (m_el[1].y() < m_el[2].z() ? 2 : 1) :
00259 (m_el[0].x() < m_el[2].z() ? 2 : 0);
00260 int j = (i + 1) % 3;
00261 int k = (i + 2) % 3;
00262
00263 btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0));
00264 temp[i] = s * btScalar(0.5);
00265 s = btScalar(0.5) / s;
00266
00267 temp[3] = (m_el[k][j] - m_el[j][k]) * s;
00268 temp[j] = (m_el[j][i] + m_el[i][j]) * s;
00269 temp[k] = (m_el[k][i] + m_el[i][k]) * s;
00270 }
00271 q.setValue(temp[0],temp[1],temp[2],temp[3]);
00272 }
00273
00279 __attribute__((deprecated)) void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
00280 {
00281 getEulerYPR(yaw, pitch, roll, solution_number);
00282 };
00283
00284
00289 void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
00290 {
00291 struct Euler
00292 {
00293 btScalar yaw;
00294 btScalar pitch;
00295 btScalar roll;
00296 };
00297
00298 Euler euler_out;
00299 Euler euler_out2;
00300
00301
00302
00303
00304 if (btFabs(m_el[2].x()) >= 1)
00305 {
00306 euler_out.yaw = 0;
00307 euler_out2.yaw = 0;
00308
00309
00310 btScalar delta = btAtan2(m_el[2].y(),m_el[2].z());
00311 if (m_el[2].x() < 0)
00312 {
00313 euler_out.pitch = SIMD_PI / btScalar(2.0);
00314 euler_out2.pitch = SIMD_PI / btScalar(2.0);
00315 euler_out.roll = delta;
00316 euler_out2.roll = delta;
00317 }
00318 else
00319 {
00320 euler_out.pitch = -SIMD_PI / btScalar(2.0);
00321 euler_out2.pitch = -SIMD_PI / btScalar(2.0);
00322 euler_out.roll = delta;
00323 euler_out2.roll = delta;
00324 }
00325 }
00326 else
00327 {
00328 euler_out.pitch = - btAsin(m_el[2].x());
00329 euler_out2.pitch = SIMD_PI - euler_out.pitch;
00330
00331 euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch),
00332 m_el[2].z()/btCos(euler_out.pitch));
00333 euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch),
00334 m_el[2].z()/btCos(euler_out2.pitch));
00335
00336 euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch),
00337 m_el[0].x()/btCos(euler_out.pitch));
00338 euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch),
00339 m_el[0].x()/btCos(euler_out2.pitch));
00340 }
00341
00342 if (solution_number == 1)
00343 {
00344 yaw = euler_out.yaw;
00345 pitch = euler_out.pitch;
00346 roll = euler_out.roll;
00347 }
00348 else
00349 {
00350 yaw = euler_out2.yaw;
00351 pitch = euler_out2.pitch;
00352 roll = euler_out2.roll;
00353 }
00354 }
00355
00361 void getRPY(btScalar& roll, btScalar& pitch, btScalar& yaw, unsigned int solution_number = 1) const
00362 {
00363 getEulerYPR(yaw, pitch, roll, solution_number);
00364 }
00365
00369 btMatrix3x3 scaled(const btVector3& s) const
00370 {
00371 return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
00372 m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(),
00373 m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
00374 }
00375
00377 btScalar determinant() const;
00379 btMatrix3x3 adjoint() const;
00381 btMatrix3x3 absolute() const;
00383 btMatrix3x3 transpose() const;
00385 btMatrix3x3 inverse() const;
00386
00387 btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
00388 btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
00389
00390 SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const
00391 {
00392 return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z();
00393 }
00394 SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const
00395 {
00396 return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z();
00397 }
00398 SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const
00399 {
00400 return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z();
00401 }
00402
00403
00413 void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
00414 {
00415 rot.setIdentity();
00416 for (int step = maxSteps; step > 0; step--)
00417 {
00418
00419 int p = 0;
00420 int q = 1;
00421 int r = 2;
00422 btScalar max = btFabs(m_el[0][1]);
00423 btScalar v = btFabs(m_el[0][2]);
00424 if (v > max)
00425 {
00426 q = 2;
00427 r = 1;
00428 max = v;
00429 }
00430 v = btFabs(m_el[1][2]);
00431 if (v > max)
00432 {
00433 p = 1;
00434 q = 2;
00435 r = 0;
00436 max = v;
00437 }
00438
00439 btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2]));
00440 if (max <= t)
00441 {
00442 if (max <= SIMD_EPSILON * t)
00443 {
00444 return;
00445 }
00446 step = 1;
00447 }
00448
00449
00450 btScalar mpq = m_el[p][q];
00451 btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq);
00452 btScalar theta2 = theta * theta;
00453 btScalar cos;
00454 btScalar sin;
00455 if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON))
00456 {
00457 t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))
00458 : 1 / (theta - btSqrt(1 + theta2));
00459 cos = 1 / btSqrt(1 + t * t);
00460 sin = cos * t;
00461 }
00462 else
00463 {
00464
00465 t = 1 / (theta * (2 + btScalar(0.5) / theta2));
00466 cos = 1 - btScalar(0.5) * t * t;
00467 sin = cos * t;
00468 }
00469
00470
00471 m_el[p][q] = m_el[q][p] = 0;
00472 m_el[p][p] -= t * mpq;
00473 m_el[q][q] += t * mpq;
00474 btScalar mrp = m_el[r][p];
00475 btScalar mrq = m_el[r][q];
00476 m_el[r][p] = m_el[p][r] = cos * mrp - sin * mrq;
00477 m_el[r][q] = m_el[q][r] = cos * mrq + sin * mrp;
00478
00479
00480 for (int i = 0; i < 3; i++)
00481 {
00482 btVector3& row = rot[i];
00483 mrp = row[p];
00484 mrq = row[q];
00485 row[p] = cos * mrp - sin * mrq;
00486 row[q] = cos * mrq + sin * mrp;
00487 }
00488 }
00489 }
00490
00491
00492
00493
00501 btScalar cofac(int r1, int c1, int r2, int c2) const
00502 {
00503 return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
00504 }
00505
00506 void serialize(struct btMatrix3x3Data& dataOut) const;
00507
00508 void serializeFloat(struct btMatrix3x3FloatData& dataOut) const;
00509
00510 void deSerialize(const struct btMatrix3x3Data& dataIn);
00511
00512 void deSerializeFloat(const struct btMatrix3x3FloatData& dataIn);
00513
00514 void deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn);
00515
00516 };
00517
00518
00519 SIMD_FORCE_INLINE btMatrix3x3&
00520 btMatrix3x3::operator*=(const btMatrix3x3& m)
00521 {
00522 setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
00523 m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),
00524 m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]));
00525 return *this;
00526 }
00527
00528 SIMD_FORCE_INLINE btScalar
00529 btMatrix3x3::determinant() const
00530 {
00531 return btTriple((*this)[0], (*this)[1], (*this)[2]);
00532 }
00533
00534
00535 SIMD_FORCE_INLINE btMatrix3x3
00536 btMatrix3x3::absolute() const
00537 {
00538 return btMatrix3x3(
00539 btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()),
00540 btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()),
00541 btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z()));
00542 }
00543
00544 SIMD_FORCE_INLINE btMatrix3x3
00545 btMatrix3x3::transpose() const
00546 {
00547 return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(),
00548 m_el[0].y(), m_el[1].y(), m_el[2].y(),
00549 m_el[0].z(), m_el[1].z(), m_el[2].z());
00550 }
00551
00552 SIMD_FORCE_INLINE btMatrix3x3
00553 btMatrix3x3::adjoint() const
00554 {
00555 return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
00556 cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
00557 cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
00558 }
00559
00560 SIMD_FORCE_INLINE btMatrix3x3
00561 btMatrix3x3::inverse() const
00562 {
00563 btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
00564 btScalar det = (*this)[0].dot(co);
00565 btFullAssert(det != btScalar(0.0));
00566 btScalar s = btScalar(1.0) / det;
00567 return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
00568 co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
00569 co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
00570 }
00571
00572 SIMD_FORCE_INLINE btMatrix3x3
00573 btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
00574 {
00575 return btMatrix3x3(
00576 m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
00577 m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
00578 m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
00579 m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
00580 m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
00581 m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
00582 m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
00583 m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
00584 m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z());
00585 }
00586
00587 SIMD_FORCE_INLINE btMatrix3x3
00588 btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
00589 {
00590 return btMatrix3x3(
00591 m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
00592 m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
00593 m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
00594
00595 }
00596
00597 SIMD_FORCE_INLINE btVector3
00598 operator*(const btMatrix3x3& m, const btVector3& v)
00599 {
00600 return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
00601 }
00602
00603
00604 SIMD_FORCE_INLINE btVector3
00605 operator*(const btVector3& v, const btMatrix3x3& m)
00606 {
00607 return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
00608 }
00609
00610 SIMD_FORCE_INLINE btMatrix3x3
00611 operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
00612 {
00613 return btMatrix3x3(
00614 m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]),
00615 m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]),
00616 m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2]));
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00636 SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
00637 {
00638 return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
00639 m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] &&
00640 m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
00641 }
00642
00644 struct btMatrix3x3FloatData
00645 {
00646 btVector3FloatData m_el[3];
00647 };
00648
00650 struct btMatrix3x3DoubleData
00651 {
00652 btVector3DoubleData m_el[3];
00653 };
00654
00655
00656
00657
00658 SIMD_FORCE_INLINE void btMatrix3x3::serialize(struct btMatrix3x3Data& dataOut) const
00659 {
00660 for (int i=0;i<3;i++)
00661 m_el[i].serialize(dataOut.m_el[i]);
00662 }
00663
00664 SIMD_FORCE_INLINE void btMatrix3x3::serializeFloat(struct btMatrix3x3FloatData& dataOut) const
00665 {
00666 for (int i=0;i<3;i++)
00667 m_el[i].serializeFloat(dataOut.m_el[i]);
00668 }
00669
00670
00671 SIMD_FORCE_INLINE void btMatrix3x3::deSerialize(const struct btMatrix3x3Data& dataIn)
00672 {
00673 for (int i=0;i<3;i++)
00674 m_el[i].deSerialize(dataIn.m_el[i]);
00675 }
00676
00677 SIMD_FORCE_INLINE void btMatrix3x3::deSerializeFloat(const struct btMatrix3x3FloatData& dataIn)
00678 {
00679 for (int i=0;i<3;i++)
00680 m_el[i].deSerializeFloat(dataIn.m_el[i]);
00681 }
00682
00683 SIMD_FORCE_INLINE void btMatrix3x3::deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn)
00684 {
00685 for (int i=0;i<3;i++)
00686 m_el[i].deSerializeDouble(dataIn.m_el[i]);
00687 }
00688
00689 #endif //BT_MATRIX3x3_H
00690