$search
00001 /* 00002 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ 00003 00004 This software is provided 'as-is', without any express or implied warranty. 00005 In no event will the authors be held liable for any damages arising from the use of this software. 00006 Permission is granted to anyone to use this software for any purpose, 00007 including commercial applications, and to alter it and redistribute it freely, 00008 subject to the following restrictions: 00009 00010 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 00011 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00012 3. This notice may not be removed or altered from any source distribution. 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 // explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); } 00041 00043 explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); } 00044 /* 00045 template <typename btScalar> 00046 Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 00047 { 00048 setEulerYPR(yaw, pitch, roll); 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; //second solution 00300 //get the pointer to the raw data 00301 00302 // Check that pitch is not at a singularity 00303 // Check that pitch is not at a singularity 00304 if (btFabs(m_el[2].x()) >= 1) 00305 { 00306 euler_out.yaw = 0; 00307 euler_out2.yaw = 0; 00308 00309 // From difference of angles formula 00310 btScalar delta = btAtan2(m_el[2].y(),m_el[2].z()); 00311 if (m_el[2].x() < 0) //gimbal locked down 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 // gimbal locked up 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 // find off-diagonal element [p][q] with largest magnitude 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 // compute Jacobi rotation J which leads to a zero for element [p][q] 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 // approximation for large theta-value, i.e., a nearly diagonal matrix 00465 t = 1 / (theta * (2 + btScalar(0.5) / theta2)); 00466 cos = 1 - btScalar(0.5) * t * t; 00467 sin = cos * t; 00468 } 00469 00470 // apply rotation to matrix (this = J^T * this * J) 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 // apply rotation to rot (rot = rot * J) 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 SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) { 00621 return btMatrix3x3( 00622 m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0], 00623 m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1], 00624 m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2], 00625 m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0], 00626 m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1], 00627 m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2], 00628 m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0], 00629 m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1], 00630 m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); 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