00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2012 Torus Knot Software Ltd 00008 00009 Permission is hereby granted, free of charge, to any person obtaining a copy 00010 of this software and associated documentation files (the "Software"), to deal 00011 in the Software without restriction, including without limitation the rights 00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 copies of the Software, and to permit persons to whom the Software is 00014 furnished to do so, subject to the following conditions: 00015 00016 The above copyright notice and this permission notice shall be included in 00017 all copies or substantial portions of the Software. 00018 00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 THE SOFTWARE. 00026 ----------------------------------------------------------------------------- 00027 */ 00028 #ifndef __Matrix3_H__ 00029 #define __Matrix3_H__ 00030 00031 #include "OgrePrerequisites.h" 00032 00033 #include "OgreVector3.h" 00034 00035 // NB All code adapted from Wild Magic 0.2 Matrix math (free source code) 00036 // http://www.geometrictools.com/ 00037 00038 // NOTE. The (x,y,z) coordinate system is assumed to be right-handed. 00039 // Coordinate axis rotation matrices are of the form 00040 // RX = 1 0 0 00041 // 0 cos(t) -sin(t) 00042 // 0 sin(t) cos(t) 00043 // where t > 0 indicates a counterclockwise rotation in the yz-plane 00044 // RY = cos(t) 0 sin(t) 00045 // 0 1 0 00046 // -sin(t) 0 cos(t) 00047 // where t > 0 indicates a counterclockwise rotation in the zx-plane 00048 // RZ = cos(t) -sin(t) 0 00049 // sin(t) cos(t) 0 00050 // 0 0 1 00051 // where t > 0 indicates a counterclockwise rotation in the xy-plane. 00052 00053 namespace Ogre 00054 { 00068 class _OgreExport Matrix3 00069 { 00070 public: 00075 inline Matrix3 () {} 00076 inline explicit Matrix3 (const Real arr[3][3]) 00077 { 00078 memcpy(m,arr,9*sizeof(Real)); 00079 } 00080 inline Matrix3 (const Matrix3& rkMatrix) 00081 { 00082 memcpy(m,rkMatrix.m,9*sizeof(Real)); 00083 } 00084 Matrix3 (Real fEntry00, Real fEntry01, Real fEntry02, 00085 Real fEntry10, Real fEntry11, Real fEntry12, 00086 Real fEntry20, Real fEntry21, Real fEntry22) 00087 { 00088 m[0][0] = fEntry00; 00089 m[0][1] = fEntry01; 00090 m[0][2] = fEntry02; 00091 m[1][0] = fEntry10; 00092 m[1][1] = fEntry11; 00093 m[1][2] = fEntry12; 00094 m[2][0] = fEntry20; 00095 m[2][1] = fEntry21; 00096 m[2][2] = fEntry22; 00097 } 00098 00101 inline void swap(Matrix3& other) 00102 { 00103 std::swap(m[0][0], other.m[0][0]); 00104 std::swap(m[0][1], other.m[0][1]); 00105 std::swap(m[0][2], other.m[0][2]); 00106 std::swap(m[1][0], other.m[1][0]); 00107 std::swap(m[1][1], other.m[1][1]); 00108 std::swap(m[1][2], other.m[1][2]); 00109 std::swap(m[2][0], other.m[2][0]); 00110 std::swap(m[2][1], other.m[2][1]); 00111 std::swap(m[2][2], other.m[2][2]); 00112 } 00113 00114 // member access, allows use of construct mat[r][c] 00115 inline Real* operator[] (size_t iRow) const 00116 { 00117 return (Real*)m[iRow]; 00118 } 00119 /*inline operator Real* () 00120 { 00121 return (Real*)m[0]; 00122 }*/ 00123 Vector3 GetColumn (size_t iCol) const; 00124 void SetColumn(size_t iCol, const Vector3& vec); 00125 void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis); 00126 00127 // assignment and comparison 00128 inline Matrix3& operator= (const Matrix3& rkMatrix) 00129 { 00130 memcpy(m,rkMatrix.m,9*sizeof(Real)); 00131 return *this; 00132 } 00133 00136 bool operator== (const Matrix3& rkMatrix) const; 00137 00140 inline bool operator!= (const Matrix3& rkMatrix) const 00141 { 00142 return !operator==(rkMatrix); 00143 } 00144 00145 // arithmetic operations 00148 Matrix3 operator+ (const Matrix3& rkMatrix) const; 00149 00152 Matrix3 operator- (const Matrix3& rkMatrix) const; 00153 00156 Matrix3 operator* (const Matrix3& rkMatrix) const; 00157 Matrix3 operator- () const; 00158 00160 Vector3 operator* (const Vector3& rkVector) const; 00161 00163 _OgreExport friend Vector3 operator* (const Vector3& rkVector, 00164 const Matrix3& rkMatrix); 00165 00167 Matrix3 operator* (Real fScalar) const; 00168 00170 _OgreExport friend Matrix3 operator* (Real fScalar, const Matrix3& rkMatrix); 00171 00172 // utilities 00173 Matrix3 Transpose () const; 00174 bool Inverse (Matrix3& rkInverse, Real fTolerance = 1e-06) const; 00175 Matrix3 Inverse (Real fTolerance = 1e-06) const; 00176 Real Determinant () const; 00177 00178 // singular value decomposition 00179 void SingularValueDecomposition (Matrix3& rkL, Vector3& rkS, 00180 Matrix3& rkR) const; 00181 void SingularValueComposition (const Matrix3& rkL, 00182 const Vector3& rkS, const Matrix3& rkR); 00183 00185 void Orthonormalize (); 00186 00188 void QDUDecomposition (Matrix3& rkQ, Vector3& rkD, 00189 Vector3& rkU) const; 00190 00191 Real SpectralNorm () const; 00192 00193 // matrix must be orthonormal 00194 void ToAngleAxis (Vector3& rkAxis, Radian& rfAngle) const; 00195 inline void ToAngleAxis (Vector3& rkAxis, Degree& rfAngle) const { 00196 Radian r; 00197 ToAngleAxis ( rkAxis, r ); 00198 rfAngle = r; 00199 } 00200 void FromAngleAxis (const Vector3& rkAxis, const Radian& fRadians); 00201 00202 // The matrix must be orthonormal. The decomposition is yaw*pitch*roll 00203 // where yaw is rotation about the Up vector, pitch is rotation about the 00204 // Right axis, and roll is rotation about the Direction axis. 00205 bool ToEulerAnglesXYZ (Radian& rfYAngle, Radian& rfPAngle, 00206 Radian& rfRAngle) const; 00207 bool ToEulerAnglesXZY (Radian& rfYAngle, Radian& rfPAngle, 00208 Radian& rfRAngle) const; 00209 bool ToEulerAnglesYXZ (Radian& rfYAngle, Radian& rfPAngle, 00210 Radian& rfRAngle) const; 00211 bool ToEulerAnglesYZX (Radian& rfYAngle, Radian& rfPAngle, 00212 Radian& rfRAngle) const; 00213 bool ToEulerAnglesZXY (Radian& rfYAngle, Radian& rfPAngle, 00214 Radian& rfRAngle) const; 00215 bool ToEulerAnglesZYX (Radian& rfYAngle, Radian& rfPAngle, 00216 Radian& rfRAngle) const; 00217 void FromEulerAnglesXYZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00218 void FromEulerAnglesXZY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00219 void FromEulerAnglesYXZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00220 void FromEulerAnglesYZX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00221 void FromEulerAnglesZXY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00222 void FromEulerAnglesZYX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00224 void EigenSolveSymmetric (Real afEigenvalue[3], 00225 Vector3 akEigenvector[3]) const; 00226 00227 static void TensorProduct (const Vector3& rkU, const Vector3& rkV, 00228 Matrix3& rkProduct); 00229 00231 inline bool hasScale() const 00232 { 00233 // check magnitude of column vectors (==local axes) 00234 Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0]; 00235 if (!Math::RealEqual(t, 1.0, (Real)1e-04)) 00236 return true; 00237 t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1]; 00238 if (!Math::RealEqual(t, 1.0, (Real)1e-04)) 00239 return true; 00240 t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2]; 00241 if (!Math::RealEqual(t, 1.0, (Real)1e-04)) 00242 return true; 00243 00244 return false; 00245 } 00246 00249 inline _OgreExport friend std::ostream& operator << 00250 ( std::ostream& o, const Matrix3& mat ) 00251 { 00252 o << "Matrix3(" << mat[0][0] << ", " << mat[0][1] << ", " << mat[0][2] << ", " 00253 << mat[1][0] << ", " << mat[1][1] << ", " << mat[1][2] << ", " 00254 << mat[2][0] << ", " << mat[2][1] << ", " << mat[2][2] << ")"; 00255 return o; 00256 } 00257 00258 static const Real EPSILON; 00259 static const Matrix3 ZERO; 00260 static const Matrix3 IDENTITY; 00261 00262 protected: 00263 // support for eigensolver 00264 void Tridiagonal (Real afDiag[3], Real afSubDiag[3]); 00265 bool QLAlgorithm (Real afDiag[3], Real afSubDiag[3]); 00266 00267 // support for singular value decomposition 00268 static const Real msSvdEpsilon; 00269 static const unsigned int msSvdMaxIterations; 00270 static void Bidiagonalize (Matrix3& kA, Matrix3& kL, 00271 Matrix3& kR); 00272 static void GolubKahanStep (Matrix3& kA, Matrix3& kL, 00273 Matrix3& kR); 00274 00275 // support for spectral norm 00276 static Real MaxCubicRoot (Real afCoeff[3]); 00277 00278 Real m[3][3]; 00279 00280 // for faster access 00281 friend class Matrix4; 00282 }; 00285 } 00286 #endif
Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Fri May 25 23:36:24 2012