Blender V2.61 - r43446
|
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 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 // first use the normal calculus 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 // on pitch = +/-HalfPI 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; //second solution 00319 //get the pointer to the raw data 00320 00321 // Check that pitch is not at a singularity 00322 if (btFabs(m_el[2].x()) >= 1) 00323 { 00324 euler_out.yaw = 0; 00325 euler_out2.yaw = 0; 00326 00327 // From difference of angles formula 00328 btScalar delta = btAtan2(m_el[0].x(),m_el[0].z()); 00329 if (m_el[2].x() > 0) //gimbal locked up 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 // gimbal locked down 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 // find off-diagonal element [p][q] with largest magnitude 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 // compute Jacobi rotation J which leads to a zero for element [p][q] 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 // approximation for large theta-value, i.e., a nearly diagonal matrix 00473 t = 1 / (theta * (2 + btScalar(0.5) / theta2)); 00474 cos = 1 - btScalar(0.5) * t * t; 00475 sin = cos * t; 00476 } 00477 00478 // apply rotation to matrix (this = J^T * this * J) 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 // apply rotation to rot (rot = rot * J) 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 SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) { 00702 return btMatrix3x3( 00703 m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0], 00704 m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1], 00705 m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2], 00706 m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0], 00707 m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1], 00708 m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2], 00709 m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0], 00710 m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1], 00711 m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); 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