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-2013 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 00115 inline const Real* operator[] (size_t iRow) const 00116 { 00117 return m[iRow]; 00118 } 00119 00120 inline Real* operator[] (size_t iRow) 00121 { 00122 return m[iRow]; 00123 } 00124 00125 00126 00127 /*inline operator Real* () 00128 { 00129 return (Real*)m[0]; 00130 }*/ 00131 Vector3 GetColumn (size_t iCol) const; 00132 void SetColumn(size_t iCol, const Vector3& vec); 00133 void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis); 00134 00136 inline Matrix3& operator= (const Matrix3& rkMatrix) 00137 { 00138 memcpy(m,rkMatrix.m,9*sizeof(Real)); 00139 return *this; 00140 } 00141 00144 bool operator== (const Matrix3& rkMatrix) const; 00145 00148 inline bool operator!= (const Matrix3& rkMatrix) const 00149 { 00150 return !operator==(rkMatrix); 00151 } 00152 00153 // arithmetic operations 00156 Matrix3 operator+ (const Matrix3& rkMatrix) const; 00157 00160 Matrix3 operator- (const Matrix3& rkMatrix) const; 00161 00164 Matrix3 operator* (const Matrix3& rkMatrix) const; 00165 Matrix3 operator- () const; 00166 00168 Vector3 operator* (const Vector3& rkVector) const; 00169 00171 _OgreExport friend Vector3 operator* (const Vector3& rkVector, 00172 const Matrix3& rkMatrix); 00173 00175 Matrix3 operator* (Real fScalar) const; 00176 00178 _OgreExport friend Matrix3 operator* (Real fScalar, const Matrix3& rkMatrix); 00179 00180 // utilities 00181 Matrix3 Transpose () const; 00182 bool Inverse (Matrix3& rkInverse, Real fTolerance = 1e-06) const; 00183 Matrix3 Inverse (Real fTolerance = 1e-06) const; 00184 Real Determinant () const; 00185 00187 void SingularValueDecomposition (Matrix3& rkL, Vector3& rkS, 00188 Matrix3& rkR) const; 00189 void SingularValueComposition (const Matrix3& rkL, 00190 const Vector3& rkS, const Matrix3& rkR); 00191 00193 void Orthonormalize (); 00194 00196 void QDUDecomposition (Matrix3& rkQ, Vector3& rkD, 00197 Vector3& rkU) const; 00198 00199 Real SpectralNorm () const; 00200 00202 void ToAngleAxis (Vector3& rkAxis, Radian& rfAngle) const; 00203 inline void ToAngleAxis (Vector3& rkAxis, Degree& rfAngle) const { 00204 Radian r; 00205 ToAngleAxis ( rkAxis, r ); 00206 rfAngle = r; 00207 } 00208 void FromAngleAxis (const Vector3& rkAxis, const Radian& fRadians); 00209 00213 bool ToEulerAnglesXYZ (Radian& rfYAngle, Radian& rfPAngle, 00214 Radian& rfRAngle) const; 00215 bool ToEulerAnglesXZY (Radian& rfYAngle, Radian& rfPAngle, 00216 Radian& rfRAngle) const; 00217 bool ToEulerAnglesYXZ (Radian& rfYAngle, Radian& rfPAngle, 00218 Radian& rfRAngle) const; 00219 bool ToEulerAnglesYZX (Radian& rfYAngle, Radian& rfPAngle, 00220 Radian& rfRAngle) const; 00221 bool ToEulerAnglesZXY (Radian& rfYAngle, Radian& rfPAngle, 00222 Radian& rfRAngle) const; 00223 bool ToEulerAnglesZYX (Radian& rfYAngle, Radian& rfPAngle, 00224 Radian& rfRAngle) const; 00225 void FromEulerAnglesXYZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00226 void FromEulerAnglesXZY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00227 void FromEulerAnglesYXZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00228 void FromEulerAnglesYZX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00229 void FromEulerAnglesZXY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00230 void FromEulerAnglesZYX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00232 void EigenSolveSymmetric (Real afEigenvalue[3], 00233 Vector3 akEigenvector[3]) const; 00234 00235 static void TensorProduct (const Vector3& rkU, const Vector3& rkV, 00236 Matrix3& rkProduct); 00237 00239 inline bool hasScale() const 00240 { 00241 // check magnitude of column vectors (==local axes) 00242 Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0]; 00243 if (!Math::RealEqual(t, 1.0, (Real)1e-04)) 00244 return true; 00245 t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1]; 00246 if (!Math::RealEqual(t, 1.0, (Real)1e-04)) 00247 return true; 00248 t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2]; 00249 if (!Math::RealEqual(t, 1.0, (Real)1e-04)) 00250 return true; 00251 00252 return false; 00253 } 00254 00257 inline _OgreExport friend std::ostream& operator << 00258 ( std::ostream& o, const Matrix3& mat ) 00259 { 00260 o << "Matrix3(" << mat[0][0] << ", " << mat[0][1] << ", " << mat[0][2] << ", " 00261 << mat[1][0] << ", " << mat[1][1] << ", " << mat[1][2] << ", " 00262 << mat[2][0] << ", " << mat[2][1] << ", " << mat[2][2] << ")"; 00263 return o; 00264 } 00265 00266 static const Real EPSILON; 00267 static const Matrix3 ZERO; 00268 static const Matrix3 IDENTITY; 00269 00270 protected: 00271 // support for eigensolver 00272 void Tridiagonal (Real afDiag[3], Real afSubDiag[3]); 00273 bool QLAlgorithm (Real afDiag[3], Real afSubDiag[3]); 00274 00275 // support for singular value decomposition 00276 static const Real msSvdEpsilon; 00277 static const unsigned int msSvdMaxIterations; 00278 static void Bidiagonalize (Matrix3& kA, Matrix3& kL, 00279 Matrix3& kR); 00280 static void GolubKahanStep (Matrix3& kA, Matrix3& kL, 00281 Matrix3& kR); 00282 00283 // support for spectral norm 00284 static Real MaxCubicRoot (Real afCoeff[3]); 00285 00286 Real m[3][3]; 00287 00288 // for faster access 00289 friend class Matrix4; 00290 }; 00293 } 00294 #endif
Copyright © 2012 Torus Knot Software Ltd

This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Mon Jul 27 2020 13:40:44