btMatrix3x3.h

Go to the documentation of this file.
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 setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 
00164         {
00165                 setEulerZYX(roll, pitch, yaw);
00166         }
00167 
00177         void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { 
00179                 btScalar ci ( btCos(eulerX)); 
00180                 btScalar cj ( btCos(eulerY)); 
00181                 btScalar ch ( btCos(eulerZ)); 
00182                 btScalar si ( btSin(eulerX)); 
00183                 btScalar sj ( btSin(eulerY)); 
00184                 btScalar sh ( btSin(eulerZ)); 
00185                 btScalar cc = ci * ch; 
00186                 btScalar cs = ci * sh; 
00187                 btScalar sc = si * ch; 
00188                 btScalar ss = si * sh;
00189 
00190                 setValue(cj * ch, sj * sc - cs, sj * cc + ss,
00191                         cj * sh, sj * ss + cc, sj * cs - sc, 
00192                         -sj,      cj * si,      cj * ci);
00193         }
00194 
00196         void setIdentity()
00197         { 
00198                 setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), 
00199                         btScalar(0.0), btScalar(1.0), btScalar(0.0), 
00200                         btScalar(0.0), btScalar(0.0), btScalar(1.0)); 
00201         }
00202 
00203         static const btMatrix3x3&       getIdentity()
00204         {
00205                 static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0), 
00206                         btScalar(0.0), btScalar(1.0), btScalar(0.0), 
00207                         btScalar(0.0), btScalar(0.0), btScalar(1.0));
00208                 return identityMatrix;
00209         }
00210 
00213         void getOpenGLSubMatrix(btScalar *m) const 
00214         {
00215                 m[0]  = btScalar(m_el[0].x()); 
00216                 m[1]  = btScalar(m_el[1].x());
00217                 m[2]  = btScalar(m_el[2].x());
00218                 m[3]  = btScalar(0.0); 
00219                 m[4]  = btScalar(m_el[0].y());
00220                 m[5]  = btScalar(m_el[1].y());
00221                 m[6]  = btScalar(m_el[2].y());
00222                 m[7]  = btScalar(0.0); 
00223                 m[8]  = btScalar(m_el[0].z()); 
00224                 m[9]  = btScalar(m_el[1].z());
00225                 m[10] = btScalar(m_el[2].z());
00226                 m[11] = btScalar(0.0); 
00227         }
00228 
00231         void getRotation(btQuaternion& q) const
00232         {
00233                 btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
00234                 btScalar temp[4];
00235 
00236                 if (trace > btScalar(0.0)) 
00237                 {
00238                         btScalar s = btSqrt(trace + btScalar(1.0));
00239                         temp[3]=(s * btScalar(0.5));
00240                         s = btScalar(0.5) / s;
00241 
00242                         temp[0]=((m_el[2].y() - m_el[1].z()) * s);
00243                         temp[1]=((m_el[0].z() - m_el[2].x()) * s);
00244                         temp[2]=((m_el[1].x() - m_el[0].y()) * s);
00245                 } 
00246                 else 
00247                 {
00248                         int i = m_el[0].x() < m_el[1].y() ? 
00249                                 (m_el[1].y() < m_el[2].z() ? 2 : 1) :
00250                                 (m_el[0].x() < m_el[2].z() ? 2 : 0); 
00251                         int j = (i + 1) % 3;  
00252                         int k = (i + 2) % 3;
00253 
00254                         btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0));
00255                         temp[i] = s * btScalar(0.5);
00256                         s = btScalar(0.5) / s;
00257 
00258                         temp[3] = (m_el[k][j] - m_el[j][k]) * s;
00259                         temp[j] = (m_el[j][i] + m_el[i][j]) * s;
00260                         temp[k] = (m_el[k][i] + m_el[i][k]) * s;
00261                 }
00262                 q.setValue(temp[0],temp[1],temp[2],temp[3]);
00263         }
00264 
00269         void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
00270         {
00271 
00272                 // first use the normal calculus
00273                 yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
00274                 pitch = btScalar(btAsin(-m_el[2].x()));
00275                 roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
00276 
00277                 // on pitch = +/-HalfPI
00278                 if (btFabs(pitch)==SIMD_HALF_PI)
00279                 {
00280                         if (yaw>0)
00281                                 yaw-=SIMD_PI;
00282                         else
00283                                 yaw+=SIMD_PI;
00284 
00285                         if (roll>0)
00286                                 roll-=SIMD_PI;
00287                         else
00288                                 roll+=SIMD_PI;
00289                 }
00290         };
00291 
00292 
00298         void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
00299         {
00300                 struct Euler
00301                 {
00302                         btScalar yaw;
00303                         btScalar pitch;
00304                         btScalar roll;
00305                 };
00306 
00307                 Euler euler_out;
00308                 Euler euler_out2; //second solution
00309                 //get the pointer to the raw data
00310 
00311                 // Check that pitch is not at a singularity
00312                 if (btFabs(m_el[2].x()) >= 1)
00313                 {
00314                         euler_out.yaw = 0;
00315                         euler_out2.yaw = 0;
00316 
00317                         // From difference of angles formula
00318                         btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
00319                         if (m_el[2].x() > 0)  //gimbal locked up
00320                         {
00321                                 euler_out.pitch = SIMD_PI / btScalar(2.0);
00322                                 euler_out2.pitch = SIMD_PI / btScalar(2.0);
00323                                 euler_out.roll = euler_out.pitch + delta;
00324                                 euler_out2.roll = euler_out.pitch + delta;
00325                         }
00326                         else // gimbal locked down
00327                         {
00328                                 euler_out.pitch = -SIMD_PI / btScalar(2.0);
00329                                 euler_out2.pitch = -SIMD_PI / btScalar(2.0);
00330                                 euler_out.roll = -euler_out.pitch + delta;
00331                                 euler_out2.roll = -euler_out.pitch + delta;
00332                         }
00333                 }
00334                 else
00335                 {
00336                         euler_out.pitch = - btAsin(m_el[2].x());
00337                         euler_out2.pitch = SIMD_PI - euler_out.pitch;
00338 
00339                         euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch), 
00340                                 m_el[2].z()/btCos(euler_out.pitch));
00341                         euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch), 
00342                                 m_el[2].z()/btCos(euler_out2.pitch));
00343 
00344                         euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch), 
00345                                 m_el[0].x()/btCos(euler_out.pitch));
00346                         euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch), 
00347                                 m_el[0].x()/btCos(euler_out2.pitch));
00348                 }
00349 
00350                 if (solution_number == 1)
00351                 { 
00352                         yaw = euler_out.yaw; 
00353                         pitch = euler_out.pitch;
00354                         roll = euler_out.roll;
00355                 }
00356                 else
00357                 { 
00358                         yaw = euler_out2.yaw; 
00359                         pitch = euler_out2.pitch;
00360                         roll = euler_out2.roll;
00361                 }
00362         }
00363 
00367         btMatrix3x3 scaled(const btVector3& s) const
00368         {
00369                 return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
00370                         m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(),
00371                         m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
00372         }
00373 
00375         btScalar            determinant() const;
00377         btMatrix3x3 adjoint() const;
00379         btMatrix3x3 absolute() const;
00381         btMatrix3x3 transpose() const;
00383         btMatrix3x3 inverse() const; 
00384 
00385         btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
00386         btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
00387 
00388         SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const 
00389         {
00390                 return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z();
00391         }
00392         SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const 
00393         {
00394                 return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z();
00395         }
00396         SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const 
00397         {
00398                 return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z();
00399         }
00400 
00401 
00411         void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
00412         {
00413                 rot.setIdentity();
00414                 for (int step = maxSteps; step > 0; step--)
00415                 {
00416                         // find off-diagonal element [p][q] with largest magnitude
00417                         int p = 0;
00418                         int q = 1;
00419                         int r = 2;
00420                         btScalar max = btFabs(m_el[0][1]);
00421                         btScalar v = btFabs(m_el[0][2]);
00422                         if (v > max)
00423                         {
00424                                 q = 2;
00425                                 r = 1;
00426                                 max = v;
00427                         }
00428                         v = btFabs(m_el[1][2]);
00429                         if (v > max)
00430                         {
00431                                 p = 1;
00432                                 q = 2;
00433                                 r = 0;
00434                                 max = v;
00435                         }
00436 
00437                         btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2]));
00438                         if (max <= t)
00439                         {
00440                                 if (max <= SIMD_EPSILON * t)
00441                                 {
00442                                         return;
00443                                 }
00444                                 step = 1;
00445                         }
00446 
00447                         // compute Jacobi rotation J which leads to a zero for element [p][q] 
00448                         btScalar mpq = m_el[p][q];
00449                         btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq);
00450                         btScalar theta2 = theta * theta;
00451                         btScalar cos;
00452                         btScalar sin;
00453                         if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON))
00454                         {
00455                                 t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))
00456                                         : 1 / (theta - btSqrt(1 + theta2));
00457                                 cos = 1 / btSqrt(1 + t * t);
00458                                 sin = cos * t;
00459                         }
00460                         else
00461                         {
00462                                 // approximation for large theta-value, i.e., a nearly diagonal matrix
00463                                 t = 1 / (theta * (2 + btScalar(0.5) / theta2));
00464                                 cos = 1 - btScalar(0.5) * t * t;
00465                                 sin = cos * t;
00466                         }
00467 
00468                         // apply rotation to matrix (this = J^T * this * J)
00469                         m_el[p][q] = m_el[q][p] = 0;
00470                         m_el[p][p] -= t * mpq;
00471                         m_el[q][q] += t * mpq;
00472                         btScalar mrp = m_el[r][p];
00473                         btScalar mrq = m_el[r][q];
00474                         m_el[r][p] = m_el[p][r] = cos * mrp - sin * mrq;
00475                         m_el[r][q] = m_el[q][r] = cos * mrq + sin * mrp;
00476 
00477                         // apply rotation to rot (rot = rot * J)
00478                         for (int i = 0; i < 3; i++)
00479                         {
00480                                 btVector3& row = rot[i];
00481                                 mrp = row[p];
00482                                 mrq = row[q];
00483                                 row[p] = cos * mrp - sin * mrq;
00484                                 row[q] = cos * mrq + sin * mrp;
00485                         }
00486                 }
00487         }
00488 
00489 
00490 
00491 
00499         btScalar cofac(int r1, int c1, int r2, int c2) const 
00500         {
00501                 return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
00502         }
00503 
00504         void    serialize(struct        btMatrix3x3Data& dataOut) const;
00505 
00506         void    serializeFloat(struct   btMatrix3x3FloatData& dataOut) const;
00507 
00508         void    deSerialize(const struct        btMatrix3x3Data& dataIn);
00509 
00510         void    deSerializeFloat(const struct   btMatrix3x3FloatData& dataIn);
00511 
00512         void    deSerializeDouble(const struct  btMatrix3x3DoubleData& dataIn);
00513 
00514 };
00515 
00516 
00517 SIMD_FORCE_INLINE btMatrix3x3& 
00518 btMatrix3x3::operator*=(const btMatrix3x3& m)
00519 {
00520         setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
00521                 m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),
00522                 m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]));
00523         return *this;
00524 }
00525 
00526 SIMD_FORCE_INLINE btScalar 
00527 btMatrix3x3::determinant() const
00528 { 
00529         return btTriple((*this)[0], (*this)[1], (*this)[2]);
00530 }
00531 
00532 
00533 SIMD_FORCE_INLINE btMatrix3x3 
00534 btMatrix3x3::absolute() const
00535 {
00536         return btMatrix3x3(
00537                 btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()),
00538                 btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()),
00539                 btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z()));
00540 }
00541 
00542 SIMD_FORCE_INLINE btMatrix3x3 
00543 btMatrix3x3::transpose() const 
00544 {
00545         return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(),
00546                 m_el[0].y(), m_el[1].y(), m_el[2].y(),
00547                 m_el[0].z(), m_el[1].z(), m_el[2].z());
00548 }
00549 
00550 SIMD_FORCE_INLINE btMatrix3x3 
00551 btMatrix3x3::adjoint() const 
00552 {
00553         return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
00554                 cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
00555                 cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
00556 }
00557 
00558 SIMD_FORCE_INLINE btMatrix3x3 
00559 btMatrix3x3::inverse() const
00560 {
00561         btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
00562         btScalar det = (*this)[0].dot(co);
00563         btFullAssert(det != btScalar(0.0));
00564         btScalar s = btScalar(1.0) / det;
00565         return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
00566                 co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
00567                 co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
00568 }
00569 
00570 SIMD_FORCE_INLINE btMatrix3x3 
00571 btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
00572 {
00573         return btMatrix3x3(
00574                 m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
00575                 m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
00576                 m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
00577                 m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
00578                 m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
00579                 m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
00580                 m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
00581                 m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
00582                 m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z());
00583 }
00584 
00585 SIMD_FORCE_INLINE btMatrix3x3 
00586 btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
00587 {
00588         return btMatrix3x3(
00589                 m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
00590                 m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
00591                 m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
00592 
00593 }
00594 
00595 SIMD_FORCE_INLINE btVector3 
00596 operator*(const btMatrix3x3& m, const btVector3& v) 
00597 {
00598         return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
00599 }
00600 
00601 
00602 SIMD_FORCE_INLINE btVector3
00603 operator*(const btVector3& v, const btMatrix3x3& m)
00604 {
00605         return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
00606 }
00607 
00608 SIMD_FORCE_INLINE btMatrix3x3 
00609 operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
00610 {
00611         return btMatrix3x3(
00612                 m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]),
00613                 m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]),
00614                 m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2]));
00615 }
00616 
00617 /*
00618 SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) {
00619 return btMatrix3x3(
00620 m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0],
00621 m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1],
00622 m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2],
00623 m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0],
00624 m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1],
00625 m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2],
00626 m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0],
00627 m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1],
00628 m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]);
00629 }
00630 */
00631 
00634 SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
00635 {
00636         return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
00637                 m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] &&
00638                 m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
00639 }
00640 
00642 struct  btMatrix3x3FloatData
00643 {
00644         btVector3FloatData m_el[3];
00645 };
00646 
00648 struct  btMatrix3x3DoubleData
00649 {
00650         btVector3DoubleData m_el[3];
00651 };
00652 
00653 
00654         
00655 
00656 SIMD_FORCE_INLINE       void    btMatrix3x3::serialize(struct   btMatrix3x3Data& dataOut) const
00657 {
00658         for (int i=0;i<3;i++)
00659                 m_el[i].serialize(dataOut.m_el[i]);
00660 }
00661 
00662 SIMD_FORCE_INLINE       void    btMatrix3x3::serializeFloat(struct      btMatrix3x3FloatData& dataOut) const
00663 {
00664         for (int i=0;i<3;i++)
00665                 m_el[i].serializeFloat(dataOut.m_el[i]);
00666 }
00667 
00668 
00669 SIMD_FORCE_INLINE       void    btMatrix3x3::deSerialize(const struct   btMatrix3x3Data& dataIn)
00670 {
00671         for (int i=0;i<3;i++)
00672                 m_el[i].deSerialize(dataIn.m_el[i]);
00673 }
00674 
00675 SIMD_FORCE_INLINE       void    btMatrix3x3::deSerializeFloat(const struct      btMatrix3x3FloatData& dataIn)
00676 {
00677         for (int i=0;i<3;i++)
00678                 m_el[i].deSerializeFloat(dataIn.m_el[i]);
00679 }
00680 
00681 SIMD_FORCE_INLINE       void    btMatrix3x3::deSerializeDouble(const struct     btMatrix3x3DoubleData& dataIn)
00682 {
00683         for (int i=0;i<3;i++)
00684                 m_el[i].deSerializeDouble(dataIn.m_el[i]);
00685 }
00686 
00687 #endif //BT_MATRIX3x3_H
00688 

Generated on Mon Feb 15 22:17:05 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1