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
00116 btMatrix3x3& operator+=(const btMatrix3x3& m);
00117
00121 btMatrix3x3& operator-=(const btMatrix3x3& m);
00122
00125 void setFromOpenGLSubMatrix(const btScalar *m)
00126 {
00127 m_el[0].setValue(m[0],m[4],m[8]);
00128 m_el[1].setValue(m[1],m[5],m[9]);
00129 m_el[2].setValue(m[2],m[6],m[10]);
00130
00131 }
00142 void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz,
00143 const btScalar& yx, const btScalar& yy, const btScalar& yz,
00144 const btScalar& zx, const btScalar& zy, const btScalar& zz)
00145 {
00146 m_el[0].setValue(xx,xy,xz);
00147 m_el[1].setValue(yx,yy,yz);
00148 m_el[2].setValue(zx,zy,zz);
00149 }
00150
00153 void setRotation(const btQuaternion& q)
00154 {
00155 btScalar d = q.length2();
00156 btFullAssert(d != btScalar(0.0));
00157 btScalar s = btScalar(2.0) / d;
00158 btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s;
00159 btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs;
00160 btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs;
00161 btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs;
00162 setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy,
00163 xy + wz, btScalar(1.0) - (xx + zz), yz - wx,
00164 xz - wy, yz + wx, btScalar(1.0) - (xx + yy));
00165 }
00166
00167
00173 void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
00174 {
00175 setEulerZYX(roll, pitch, yaw);
00176 }
00177
00187 void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) {
00189 btScalar ci ( btCos(eulerX));
00190 btScalar cj ( btCos(eulerY));
00191 btScalar ch ( btCos(eulerZ));
00192 btScalar si ( btSin(eulerX));
00193 btScalar sj ( btSin(eulerY));
00194 btScalar sh ( btSin(eulerZ));
00195 btScalar cc = ci * ch;
00196 btScalar cs = ci * sh;
00197 btScalar sc = si * ch;
00198 btScalar ss = si * sh;
00199
00200 setValue(cj * ch, sj * sc - cs, sj * cc + ss,
00201 cj * sh, sj * ss + cc, sj * cs - sc,
00202 -sj, cj * si, cj * ci);
00203 }
00204
00206 void setIdentity()
00207 {
00208 setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0),
00209 btScalar(0.0), btScalar(1.0), btScalar(0.0),
00210 btScalar(0.0), btScalar(0.0), btScalar(1.0));
00211 }
00212
00213 static const btMatrix3x3& getIdentity()
00214 {
00215 static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0),
00216 btScalar(0.0), btScalar(1.0), btScalar(0.0),
00217 btScalar(0.0), btScalar(0.0), btScalar(1.0));
00218 return identityMatrix;
00219 }
00220
00223 void getOpenGLSubMatrix(btScalar *m) const
00224 {
00225 m[0] = btScalar(m_el[0].x());
00226 m[1] = btScalar(m_el[1].x());
00227 m[2] = btScalar(m_el[2].x());
00228 m[3] = btScalar(0.0);
00229 m[4] = btScalar(m_el[0].y());
00230 m[5] = btScalar(m_el[1].y());
00231 m[6] = btScalar(m_el[2].y());
00232 m[7] = btScalar(0.0);
00233 m[8] = btScalar(m_el[0].z());
00234 m[9] = btScalar(m_el[1].z());
00235 m[10] = btScalar(m_el[2].z());
00236 m[11] = btScalar(0.0);
00237 }
00238
00241 void getRotation(btQuaternion& q) const
00242 {
00243 btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
00244 btScalar temp[4];
00245
00246 if (trace > btScalar(0.0))
00247 {
00248 btScalar s = btSqrt(trace + btScalar(1.0));
00249 temp[3]=(s * btScalar(0.5));
00250 s = btScalar(0.5) / s;
00251
00252 temp[0]=((m_el[2].y() - m_el[1].z()) * s);
00253 temp[1]=((m_el[0].z() - m_el[2].x()) * s);
00254 temp[2]=((m_el[1].x() - m_el[0].y()) * s);
00255 }
00256 else
00257 {
00258 int i = m_el[0].x() < m_el[1].y() ?
00259 (m_el[1].y() < m_el[2].z() ? 2 : 1) :
00260 (m_el[0].x() < m_el[2].z() ? 2 : 0);
00261 int j = (i + 1) % 3;
00262 int k = (i + 2) % 3;
00263
00264 btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0));
00265 temp[i] = s * btScalar(0.5);
00266 s = btScalar(0.5) / s;
00267
00268 temp[3] = (m_el[k][j] - m_el[j][k]) * s;
00269 temp[j] = (m_el[j][i] + m_el[i][j]) * s;
00270 temp[k] = (m_el[k][i] + m_el[i][k]) * s;
00271 }
00272 q.setValue(temp[0],temp[1],temp[2],temp[3]);
00273 }
00274
00279 void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
00280 {
00281
00282
00283 yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
00284 pitch = btScalar(btAsin(-m_el[2].x()));
00285 roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
00286
00287
00288 if (btFabs(pitch)==SIMD_HALF_PI)
00289 {
00290 if (yaw>0)
00291 yaw-=SIMD_PI;
00292 else
00293 yaw+=SIMD_PI;
00294
00295 if (roll>0)
00296 roll-=SIMD_PI;
00297 else
00298 roll+=SIMD_PI;
00299 }
00300 };
00301
00302
00308 void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
00309 {
00310 struct Euler
00311 {
00312 btScalar yaw;
00313 btScalar pitch;
00314 btScalar roll;
00315 };
00316
00317 Euler euler_out;
00318 Euler euler_out2;
00319
00320
00321
00322 if (btFabs(m_el[2].x()) >= 1)
00323 {
00324 euler_out.yaw = 0;
00325 euler_out2.yaw = 0;
00326
00327
00328 btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
00329 if (m_el[2].x() > 0)
00330 {
00331 euler_out.pitch = SIMD_PI / btScalar(2.0);
00332 euler_out2.pitch = SIMD_PI / btScalar(2.0);
00333 euler_out.roll = euler_out.pitch + delta;
00334 euler_out2.roll = euler_out.pitch + delta;
00335 }
00336 else
00337 {
00338 euler_out.pitch = -SIMD_PI / btScalar(2.0);
00339 euler_out2.pitch = -SIMD_PI / btScalar(2.0);
00340 euler_out.roll = -euler_out.pitch + delta;
00341 euler_out2.roll = -euler_out.pitch + delta;
00342 }
00343 }
00344 else
00345 {
00346 euler_out.pitch = - btAsin(m_el[2].x());
00347 euler_out2.pitch = SIMD_PI - euler_out.pitch;
00348
00349 euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch),
00350 m_el[2].z()/btCos(euler_out.pitch));
00351 euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch),
00352 m_el[2].z()/btCos(euler_out2.pitch));
00353
00354 euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch),
00355 m_el[0].x()/btCos(euler_out.pitch));
00356 euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch),
00357 m_el[0].x()/btCos(euler_out2.pitch));
00358 }
00359
00360 if (solution_number == 1)
00361 {
00362 yaw = euler_out.yaw;
00363 pitch = euler_out.pitch;
00364 roll = euler_out.roll;
00365 }
00366 else
00367 {
00368 yaw = euler_out2.yaw;
00369 pitch = euler_out2.pitch;
00370 roll = euler_out2.roll;
00371 }
00372 }
00373
00377 btMatrix3x3 scaled(const btVector3& s) const
00378 {
00379 return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
00380 m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(),
00381 m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
00382 }
00383
00385 btScalar determinant() const;
00387 btMatrix3x3 adjoint() const;
00389 btMatrix3x3 absolute() const;
00391 btMatrix3x3 transpose() const;
00393 btMatrix3x3 inverse() const;
00394
00395 btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
00396 btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
00397
00398 SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const
00399 {
00400 return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z();
00401 }
00402 SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const
00403 {
00404 return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z();
00405 }
00406 SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const
00407 {
00408 return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z();
00409 }
00410
00411
00421 void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
00422 {
00423 rot.setIdentity();
00424 for (int step = maxSteps; step > 0; step--)
00425 {
00426
00427 int p = 0;
00428 int q = 1;
00429 int r = 2;
00430 btScalar max = btFabs(m_el[0][1]);
00431 btScalar v = btFabs(m_el[0][2]);
00432 if (v > max)
00433 {
00434 q = 2;
00435 r = 1;
00436 max = v;
00437 }
00438 v = btFabs(m_el[1][2]);
00439 if (v > max)
00440 {
00441 p = 1;
00442 q = 2;
00443 r = 0;
00444 max = v;
00445 }
00446
00447 btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2]));
00448 if (max <= t)
00449 {
00450 if (max <= SIMD_EPSILON * t)
00451 {
00452 return;
00453 }
00454 step = 1;
00455 }
00456
00457
00458 btScalar mpq = m_el[p][q];
00459 btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq);
00460 btScalar theta2 = theta * theta;
00461 btScalar cos;
00462 btScalar sin;
00463 if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON))
00464 {
00465 t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))
00466 : 1 / (theta - btSqrt(1 + theta2));
00467 cos = 1 / btSqrt(1 + t * t);
00468 sin = cos * t;
00469 }
00470 else
00471 {
00472
00473 t = 1 / (theta * (2 + btScalar(0.5) / theta2));
00474 cos = 1 - btScalar(0.5) * t * t;
00475 sin = cos * t;
00476 }
00477
00478
00479 m_el[p][q] = m_el[q][p] = 0;
00480 m_el[p][p] -= t * mpq;
00481 m_el[q][q] += t * mpq;
00482 btScalar mrp = m_el[r][p];
00483 btScalar mrq = m_el[r][q];
00484 m_el[r][p] = m_el[p][r] = cos * mrp - sin * mrq;
00485 m_el[r][q] = m_el[q][r] = cos * mrq + sin * mrp;
00486
00487
00488 for (int i = 0; i < 3; i++)
00489 {
00490 btVector3& row = rot[i];
00491 mrp = row[p];
00492 mrq = row[q];
00493 row[p] = cos * mrp - sin * mrq;
00494 row[q] = cos * mrq + sin * mrp;
00495 }
00496 }
00497 }
00498
00499
00500
00501
00509 btScalar cofac(int r1, int c1, int r2, int c2) const
00510 {
00511 return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
00512 }
00513
00514 void serialize(struct btMatrix3x3Data& dataOut) const;
00515
00516 void serializeFloat(struct btMatrix3x3FloatData& dataOut) const;
00517
00518 void deSerialize(const struct btMatrix3x3Data& dataIn);
00519
00520 void deSerializeFloat(const struct btMatrix3x3FloatData& dataIn);
00521
00522 void deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn);
00523
00524 };
00525
00526
00527 SIMD_FORCE_INLINE btMatrix3x3&
00528 btMatrix3x3::operator*=(const btMatrix3x3& m)
00529 {
00530 setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
00531 m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),
00532 m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]));
00533 return *this;
00534 }
00535
00536 SIMD_FORCE_INLINE btMatrix3x3&
00537 btMatrix3x3::operator+=(const btMatrix3x3& m)
00538 {
00539 setValue(
00540 m_el[0][0]+m.m_el[0][0],
00541 m_el[0][1]+m.m_el[0][1],
00542 m_el[0][2]+m.m_el[0][2],
00543 m_el[1][0]+m.m_el[1][0],
00544 m_el[1][1]+m.m_el[1][1],
00545 m_el[1][2]+m.m_el[1][2],
00546 m_el[2][0]+m.m_el[2][0],
00547 m_el[2][1]+m.m_el[2][1],
00548 m_el[2][2]+m.m_el[2][2]);
00549 return *this;
00550 }
00551
00552 SIMD_FORCE_INLINE btMatrix3x3
00553 operator*(const btMatrix3x3& m, const btScalar & k)
00554 {
00555 return btMatrix3x3(
00556 m[0].x()*k,m[0].y()*k,m[0].z()*k,
00557 m[1].x()*k,m[1].y()*k,m[1].z()*k,
00558 m[2].x()*k,m[2].y()*k,m[2].z()*k);
00559 }
00560
00561 SIMD_FORCE_INLINE btMatrix3x3
00562 operator+(const btMatrix3x3& m1, const btMatrix3x3& m2)
00563 {
00564 return btMatrix3x3(
00565 m1[0][0]+m2[0][0],
00566 m1[0][1]+m2[0][1],
00567 m1[0][2]+m2[0][2],
00568 m1[1][0]+m2[1][0],
00569 m1[1][1]+m2[1][1],
00570 m1[1][2]+m2[1][2],
00571 m1[2][0]+m2[2][0],
00572 m1[2][1]+m2[2][1],
00573 m1[2][2]+m2[2][2]);
00574 }
00575
00576 SIMD_FORCE_INLINE btMatrix3x3
00577 operator-(const btMatrix3x3& m1, const btMatrix3x3& m2)
00578 {
00579 return btMatrix3x3(
00580 m1[0][0]-m2[0][0],
00581 m1[0][1]-m2[0][1],
00582 m1[0][2]-m2[0][2],
00583 m1[1][0]-m2[1][0],
00584 m1[1][1]-m2[1][1],
00585 m1[1][2]-m2[1][2],
00586 m1[2][0]-m2[2][0],
00587 m1[2][1]-m2[2][1],
00588 m1[2][2]-m2[2][2]);
00589 }
00590
00591
00592 SIMD_FORCE_INLINE btMatrix3x3&
00593 btMatrix3x3::operator-=(const btMatrix3x3& m)
00594 {
00595 setValue(
00596 m_el[0][0]-m.m_el[0][0],
00597 m_el[0][1]-m.m_el[0][1],
00598 m_el[0][2]-m.m_el[0][2],
00599 m_el[1][0]-m.m_el[1][0],
00600 m_el[1][1]-m.m_el[1][1],
00601 m_el[1][2]-m.m_el[1][2],
00602 m_el[2][0]-m.m_el[2][0],
00603 m_el[2][1]-m.m_el[2][1],
00604 m_el[2][2]-m.m_el[2][2]);
00605 return *this;
00606 }
00607
00608
00609 SIMD_FORCE_INLINE btScalar
00610 btMatrix3x3::determinant() const
00611 {
00612 return btTriple((*this)[0], (*this)[1], (*this)[2]);
00613 }
00614
00615
00616 SIMD_FORCE_INLINE btMatrix3x3
00617 btMatrix3x3::absolute() const
00618 {
00619 return btMatrix3x3(
00620 btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()),
00621 btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()),
00622 btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z()));
00623 }
00624
00625 SIMD_FORCE_INLINE btMatrix3x3
00626 btMatrix3x3::transpose() const
00627 {
00628 return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(),
00629 m_el[0].y(), m_el[1].y(), m_el[2].y(),
00630 m_el[0].z(), m_el[1].z(), m_el[2].z());
00631 }
00632
00633 SIMD_FORCE_INLINE btMatrix3x3
00634 btMatrix3x3::adjoint() const
00635 {
00636 return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
00637 cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
00638 cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
00639 }
00640
00641 SIMD_FORCE_INLINE btMatrix3x3
00642 btMatrix3x3::inverse() const
00643 {
00644 btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
00645 btScalar det = (*this)[0].dot(co);
00646 btFullAssert(det != btScalar(0.0));
00647 btScalar s = btScalar(1.0) / det;
00648 return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
00649 co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
00650 co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
00651 }
00652
00653 SIMD_FORCE_INLINE btMatrix3x3
00654 btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
00655 {
00656 return btMatrix3x3(
00657 m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
00658 m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
00659 m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
00660 m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
00661 m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
00662 m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
00663 m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
00664 m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
00665 m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z());
00666 }
00667
00668 SIMD_FORCE_INLINE btMatrix3x3
00669 btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
00670 {
00671 return btMatrix3x3(
00672 m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
00673 m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
00674 m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
00675
00676 }
00677
00678 SIMD_FORCE_INLINE btVector3
00679 operator*(const btMatrix3x3& m, const btVector3& v)
00680 {
00681 return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
00682 }
00683
00684
00685 SIMD_FORCE_INLINE btVector3
00686 operator*(const btVector3& v, const btMatrix3x3& m)
00687 {
00688 return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
00689 }
00690
00691 SIMD_FORCE_INLINE btMatrix3x3
00692 operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
00693 {
00694 return btMatrix3x3(
00695 m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]),
00696 m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]),
00697 m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2]));
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00717 SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
00718 {
00719 return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
00720 m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] &&
00721 m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
00722 }
00723
00725 struct btMatrix3x3FloatData
00726 {
00727 btVector3FloatData m_el[3];
00728 };
00729
00731 struct btMatrix3x3DoubleData
00732 {
00733 btVector3DoubleData m_el[3];
00734 };
00735
00736
00737
00738
00739 SIMD_FORCE_INLINE void btMatrix3x3::serialize(struct btMatrix3x3Data& dataOut) const
00740 {
00741 for (int i=0;i<3;i++)
00742 m_el[i].serialize(dataOut.m_el[i]);
00743 }
00744
00745 SIMD_FORCE_INLINE void btMatrix3x3::serializeFloat(struct btMatrix3x3FloatData& dataOut) const
00746 {
00747 for (int i=0;i<3;i++)
00748 m_el[i].serializeFloat(dataOut.m_el[i]);
00749 }
00750
00751
00752 SIMD_FORCE_INLINE void btMatrix3x3::deSerialize(const struct btMatrix3x3Data& dataIn)
00753 {
00754 for (int i=0;i<3;i++)
00755 m_el[i].deSerialize(dataIn.m_el[i]);
00756 }
00757
00758 SIMD_FORCE_INLINE void btMatrix3x3::deSerializeFloat(const struct btMatrix3x3FloatData& dataIn)
00759 {
00760 for (int i=0;i<3;i++)
00761 m_el[i].deSerializeFloat(dataIn.m_el[i]);
00762 }
00763
00764 SIMD_FORCE_INLINE void btMatrix3x3::deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn)
00765 {
00766 for (int i=0;i<3;i++)
00767 m_el[i].deSerializeDouble(dataIn.m_el[i]);
00768 }
00769
00770 #endif //BT_MATRIX3x3_H
00771