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-2005 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #ifndef __Matrix3_H__ 00026 #define __Matrix3_H__ 00027 00028 #include "OgrePrerequisites.h" 00029 00030 #include "OgreVector3.h" 00031 00032 // NB All code adapted from Wild Magic 0.2 Matrix math (free source code) 00033 // http://www.geometrictools.com/ 00034 00035 // NOTE. The (x,y,z) coordinate system is assumed to be right-handed. 00036 // Coordinate axis rotation matrices are of the form 00037 // RX = 1 0 0 00038 // 0 cos(t) -sin(t) 00039 // 0 sin(t) cos(t) 00040 // where t > 0 indicates a counterclockwise rotation in the yz-plane 00041 // RY = cos(t) 0 sin(t) 00042 // 0 1 0 00043 // -sin(t) 0 cos(t) 00044 // where t > 0 indicates a counterclockwise rotation in the zx-plane 00045 // RZ = cos(t) -sin(t) 0 00046 // sin(t) cos(t) 0 00047 // 0 0 1 00048 // where t > 0 indicates a counterclockwise rotation in the xy-plane. 00049 00050 namespace Ogre 00051 { 00059 class _OgreExport Matrix3 00060 { 00061 public: 00066 inline Matrix3 () {}; 00067 inline explicit Matrix3 (const Real arr[3][3]) 00068 { 00069 memcpy(m,arr,9*sizeof(Real)); 00070 } 00071 inline Matrix3 (const Matrix3& rkMatrix) 00072 { 00073 memcpy(m,rkMatrix.m,9*sizeof(Real)); 00074 } 00075 Matrix3 (Real fEntry00, Real fEntry01, Real fEntry02, 00076 Real fEntry10, Real fEntry11, Real fEntry12, 00077 Real fEntry20, Real fEntry21, Real fEntry22) 00078 { 00079 m[0][0] = fEntry00; 00080 m[0][1] = fEntry01; 00081 m[0][2] = fEntry02; 00082 m[1][0] = fEntry10; 00083 m[1][1] = fEntry11; 00084 m[1][2] = fEntry12; 00085 m[2][0] = fEntry20; 00086 m[2][1] = fEntry21; 00087 m[2][2] = fEntry22; 00088 } 00089 00090 // member access, allows use of construct mat[r][c] 00091 inline Real* operator[] (size_t iRow) const 00092 { 00093 return (Real*)m[iRow]; 00094 } 00095 /*inline operator Real* () 00096 { 00097 return (Real*)m[0]; 00098 }*/ 00099 Vector3 GetColumn (size_t iCol) const; 00100 void SetColumn(size_t iCol, const Vector3& vec); 00101 void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis); 00102 00103 // assignment and comparison 00104 inline Matrix3& operator= (const Matrix3& rkMatrix) 00105 { 00106 memcpy(m,rkMatrix.m,9*sizeof(Real)); 00107 return *this; 00108 } 00109 bool operator== (const Matrix3& rkMatrix) const; 00110 inline bool operator!= (const Matrix3& rkMatrix) const 00111 { 00112 return !operator==(rkMatrix); 00113 } 00114 00115 // arithmetic operations 00116 Matrix3 operator+ (const Matrix3& rkMatrix) const; 00117 Matrix3 operator- (const Matrix3& rkMatrix) const; 00118 Matrix3 operator* (const Matrix3& rkMatrix) const; 00119 Matrix3 operator- () const; 00120 00121 // matrix * vector [3x3 * 3x1 = 3x1] 00122 Vector3 operator* (const Vector3& rkVector) const; 00123 00124 // vector * matrix [1x3 * 3x3 = 1x3] 00125 _OgreExport friend Vector3 operator* (const Vector3& rkVector, 00126 const Matrix3& rkMatrix); 00127 00128 // matrix * scalar 00129 Matrix3 operator* (Real fScalar) const; 00130 00131 // scalar * matrix 00132 _OgreExport friend Matrix3 operator* (Real fScalar, const Matrix3& rkMatrix); 00133 00134 // utilities 00135 Matrix3 Transpose () const; 00136 bool Inverse (Matrix3& rkInverse, Real fTolerance = 1e-06) const; 00137 Matrix3 Inverse (Real fTolerance = 1e-06) const; 00138 Real Determinant () const; 00139 00140 // singular value decomposition 00141 void SingularValueDecomposition (Matrix3& rkL, Vector3& rkS, 00142 Matrix3& rkR) const; 00143 void SingularValueComposition (const Matrix3& rkL, 00144 const Vector3& rkS, const Matrix3& rkR); 00145 00146 // Gram-Schmidt orthonormalization (applied to columns of rotation matrix) 00147 void Orthonormalize (); 00148 00149 // orthogonal Q, diagonal D, upper triangular U stored as (u01,u02,u12) 00150 void QDUDecomposition (Matrix3& rkQ, Vector3& rkD, 00151 Vector3& rkU) const; 00152 00153 Real SpectralNorm () const; 00154 00155 // matrix must be orthonormal 00156 void ToAxisAngle (Vector3& rkAxis, Radian& rfAngle) const; 00157 inline void ToAxisAngle (Vector3& rkAxis, Degree& rfAngle) const { 00158 Radian r; 00159 ToAxisAngle ( rkAxis, r ); 00160 rfAngle = r; 00161 } 00162 void FromAxisAngle (const Vector3& rkAxis, const Radian& fRadians); 00163 #ifndef OGRE_FORCE_ANGLE_TYPES 00164 inline void ToAxisAngle (Vector3& rkAxis, Real& rfRadians) const { 00165 Radian r; 00166 ToAxisAngle ( rkAxis, r ); 00167 rfRadians = r.valueRadians(); 00168 } 00169 inline void FromAxisAngle (const Vector3& rkAxis, Real fRadians) { 00170 FromAxisAngle ( rkAxis, Radian(fRadians) ); 00171 } 00172 #endif//OGRE_FORCE_ANGLE_TYPES 00173 00174 // The matrix must be orthonormal. The decomposition is yaw*pitch*roll 00175 // where yaw is rotation about the Up vector, pitch is rotation about the 00176 // Right axis, and roll is rotation about the Direction axis. 00177 bool ToEulerAnglesXYZ (Radian& rfYAngle, Radian& rfPAngle, 00178 Radian& rfRAngle) const; 00179 bool ToEulerAnglesXZY (Radian& rfYAngle, Radian& rfPAngle, 00180 Radian& rfRAngle) const; 00181 bool ToEulerAnglesYXZ (Radian& rfYAngle, Radian& rfPAngle, 00182 Radian& rfRAngle) const; 00183 bool ToEulerAnglesYZX (Radian& rfYAngle, Radian& rfPAngle, 00184 Radian& rfRAngle) const; 00185 bool ToEulerAnglesZXY (Radian& rfYAngle, Radian& rfPAngle, 00186 Radian& rfRAngle) const; 00187 bool ToEulerAnglesZYX (Radian& rfYAngle, Radian& rfPAngle, 00188 Radian& rfRAngle) const; 00189 void FromEulerAnglesXYZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00190 void FromEulerAnglesXZY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00191 void FromEulerAnglesYXZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00192 void FromEulerAnglesYZX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00193 void FromEulerAnglesZXY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00194 void FromEulerAnglesZYX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle); 00195 #ifndef OGRE_FORCE_ANGLE_TYPES 00196 inline bool ToEulerAnglesXYZ (float& rfYAngle, float& rfPAngle, 00197 float& rfRAngle) const { 00198 Radian y, p, r; 00199 bool b = ToEulerAnglesXYZ(y,p,r); 00200 rfYAngle = y.valueRadians(); 00201 rfPAngle = p.valueRadians(); 00202 rfRAngle = r.valueRadians(); 00203 return b; 00204 } 00205 inline bool ToEulerAnglesXZY (float& rfYAngle, float& rfPAngle, 00206 float& rfRAngle) const { 00207 Radian y, p, r; 00208 bool b = ToEulerAnglesXZY(y,p,r); 00209 rfYAngle = y.valueRadians(); 00210 rfPAngle = p.valueRadians(); 00211 rfRAngle = r.valueRadians(); 00212 return b; 00213 } 00214 inline bool ToEulerAnglesYXZ (float& rfYAngle, float& rfPAngle, 00215 float& rfRAngle) const { 00216 Radian y, p, r; 00217 bool b = ToEulerAnglesYXZ(y,p,r); 00218 rfYAngle = y.valueRadians(); 00219 rfPAngle = p.valueRadians(); 00220 rfRAngle = r.valueRadians(); 00221 return b; 00222 } 00223 inline bool ToEulerAnglesYZX (float& rfYAngle, float& rfPAngle, 00224 float& rfRAngle) const { 00225 Radian y, p, r; 00226 bool b = ToEulerAnglesYZX(y,p,r); 00227 rfYAngle = y.valueRadians(); 00228 rfPAngle = p.valueRadians(); 00229 rfRAngle = r.valueRadians(); 00230 return b; 00231 } 00232 inline bool ToEulerAnglesZXY (float& rfYAngle, float& rfPAngle, 00233 float& rfRAngle) const { 00234 Radian y, p, r; 00235 bool b = ToEulerAnglesZXY(y,p,r); 00236 rfYAngle = y.valueRadians(); 00237 rfPAngle = p.valueRadians(); 00238 rfRAngle = r.valueRadians(); 00239 return b; 00240 } 00241 inline bool ToEulerAnglesZYX (float& rfYAngle, float& rfPAngle, 00242 float& rfRAngle) const { 00243 Radian y, p, r; 00244 bool b = ToEulerAnglesZYX(y,p,r); 00245 rfYAngle = y.valueRadians(); 00246 rfPAngle = p.valueRadians(); 00247 rfRAngle = r.valueRadians(); 00248 return b; 00249 } 00250 inline void FromEulerAnglesXYZ (float fYAngle, float fPAngle, float fRAngle) { 00251 FromEulerAnglesXYZ ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) ); 00252 } 00253 inline void FromEulerAnglesXZY (float fYAngle, float fPAngle, float fRAngle) { 00254 FromEulerAnglesXZY ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) ); 00255 } 00256 inline void FromEulerAnglesYXZ (float fYAngle, float fPAngle, float fRAngle) { 00257 FromEulerAnglesYXZ ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) ); 00258 } 00259 inline void FromEulerAnglesYZX (float fYAngle, float fPAngle, float fRAngle) { 00260 FromEulerAnglesYZX ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) ); 00261 } 00262 inline void FromEulerAnglesZXY (float fYAngle, float fPAngle, float fRAngle) { 00263 FromEulerAnglesZXY ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) ); 00264 } 00265 inline void FromEulerAnglesZYX (float fYAngle, float fPAngle, float fRAngle) { 00266 FromEulerAnglesZYX ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) ); 00267 } 00268 #endif//OGRE_FORCE_ANGLE_TYPES 00269 // eigensolver, matrix must be symmetric 00270 void EigenSolveSymmetric (Real afEigenvalue[3], 00271 Vector3 akEigenvector[3]) const; 00272 00273 static void TensorProduct (const Vector3& rkU, const Vector3& rkV, 00274 Matrix3& rkProduct); 00275 00276 static const Real EPSILON; 00277 static const Matrix3 ZERO; 00278 static const Matrix3 IDENTITY; 00279 00280 protected: 00281 // support for eigensolver 00282 void Tridiagonal (Real afDiag[3], Real afSubDiag[3]); 00283 bool QLAlgorithm (Real afDiag[3], Real afSubDiag[3]); 00284 00285 // support for singular value decomposition 00286 static const Real ms_fSvdEpsilon; 00287 static const unsigned int ms_iSvdMaxIterations; 00288 static void Bidiagonalize (Matrix3& kA, Matrix3& kL, 00289 Matrix3& kR); 00290 static void GolubKahanStep (Matrix3& kA, Matrix3& kL, 00291 Matrix3& kR); 00292 00293 // support for spectral norm 00294 static Real MaxCubicRoot (Real afCoeff[3]); 00295 00296 Real m[3][3]; 00297 00298 // for faster access 00299 friend class Matrix4; 00300 }; 00301 } 00302 #endif
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Mar 12 14:37:44 2006