OGRE  1.8
Object-Oriented Graphics Rendering Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
OgreMatrix3.h
Go to the documentation of this file.
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4  (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2013 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef __Matrix3_H__
29 #define __Matrix3_H__
30 
31 #include "OgrePrerequisites.h"
32 
33 #include "OgreVector3.h"
34 
35 // NB All code adapted from Wild Magic 0.2 Matrix math (free source code)
36 // http://www.geometrictools.com/
37 
38 // NOTE. The (x,y,z) coordinate system is assumed to be right-handed.
39 // Coordinate axis rotation matrices are of the form
40 // RX = 1 0 0
41 // 0 cos(t) -sin(t)
42 // 0 sin(t) cos(t)
43 // where t > 0 indicates a counterclockwise rotation in the yz-plane
44 // RY = cos(t) 0 sin(t)
45 // 0 1 0
46 // -sin(t) 0 cos(t)
47 // where t > 0 indicates a counterclockwise rotation in the zx-plane
48 // RZ = cos(t) -sin(t) 0
49 // sin(t) cos(t) 0
50 // 0 0 1
51 // where t > 0 indicates a counterclockwise rotation in the xy-plane.
52 
53 namespace Ogre
54 {
69  {
70  public:
75  inline Matrix3 () {}
76  inline explicit Matrix3 (const Real arr[3][3])
77  {
78  memcpy(m,arr,9*sizeof(Real));
79  }
80  inline Matrix3 (const Matrix3& rkMatrix)
81  {
82  memcpy(m,rkMatrix.m,9*sizeof(Real));
83  }
84  Matrix3 (Real fEntry00, Real fEntry01, Real fEntry02,
85  Real fEntry10, Real fEntry11, Real fEntry12,
86  Real fEntry20, Real fEntry21, Real fEntry22)
87  {
88  m[0][0] = fEntry00;
89  m[0][1] = fEntry01;
90  m[0][2] = fEntry02;
91  m[1][0] = fEntry10;
92  m[1][1] = fEntry11;
93  m[1][2] = fEntry12;
94  m[2][0] = fEntry20;
95  m[2][1] = fEntry21;
96  m[2][2] = fEntry22;
97  }
98 
101  inline void swap(Matrix3& other)
102  {
103  std::swap(m[0][0], other.m[0][0]);
104  std::swap(m[0][1], other.m[0][1]);
105  std::swap(m[0][2], other.m[0][2]);
106  std::swap(m[1][0], other.m[1][0]);
107  std::swap(m[1][1], other.m[1][1]);
108  std::swap(m[1][2], other.m[1][2]);
109  std::swap(m[2][0], other.m[2][0]);
110  std::swap(m[2][1], other.m[2][1]);
111  std::swap(m[2][2], other.m[2][2]);
112  }
113 
114  // member access, allows use of construct mat[r][c]
115  inline Real* operator[] (size_t iRow) const
116  {
117  return (Real*)m[iRow];
118  }
119  /*inline operator Real* ()
120  {
121  return (Real*)m[0];
122  }*/
123  Vector3 GetColumn (size_t iCol) const;
124  void SetColumn(size_t iCol, const Vector3& vec);
125  void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
126 
127  // assignment and comparison
128  inline Matrix3& operator= (const Matrix3& rkMatrix)
129  {
130  memcpy(m,rkMatrix.m,9*sizeof(Real));
131  return *this;
132  }
133 
136  bool operator== (const Matrix3& rkMatrix) const;
137 
140  inline bool operator!= (const Matrix3& rkMatrix) const
141  {
142  return !operator==(rkMatrix);
143  }
144 
145  // arithmetic operations
148  Matrix3 operator+ (const Matrix3& rkMatrix) const;
149 
152  Matrix3 operator- (const Matrix3& rkMatrix) const;
153 
156  Matrix3 operator* (const Matrix3& rkMatrix) const;
157  Matrix3 operator- () const;
158 
160  Vector3 operator* (const Vector3& rkVector) const;
161 
163  _OgreExport friend Vector3 operator* (const Vector3& rkVector,
164  const Matrix3& rkMatrix);
165 
167  Matrix3 operator* (Real fScalar) const;
168 
170  _OgreExport friend Matrix3 operator* (Real fScalar, const Matrix3& rkMatrix);
171 
172  // utilities
173  Matrix3 Transpose () const;
174  bool Inverse (Matrix3& rkInverse, Real fTolerance = 1e-06) const;
175  Matrix3 Inverse (Real fTolerance = 1e-06) const;
176  Real Determinant () const;
177 
178  // singular value decomposition
179  void SingularValueDecomposition (Matrix3& rkL, Vector3& rkS,
180  Matrix3& rkR) const;
181  void SingularValueComposition (const Matrix3& rkL,
182  const Vector3& rkS, const Matrix3& rkR);
183 
185  void Orthonormalize ();
186 
188  void QDUDecomposition (Matrix3& rkQ, Vector3& rkD,
189  Vector3& rkU) const;
190 
191  Real SpectralNorm () const;
192 
193  // matrix must be orthonormal
194  void ToAngleAxis (Vector3& rkAxis, Radian& rfAngle) const;
195  inline void ToAngleAxis (Vector3& rkAxis, Degree& rfAngle) const {
196  Radian r;
197  ToAngleAxis ( rkAxis, r );
198  rfAngle = r;
199  }
200  void FromAngleAxis (const Vector3& rkAxis, const Radian& fRadians);
201 
202  // The matrix must be orthonormal. The decomposition is yaw*pitch*roll
203  // where yaw is rotation about the Up vector, pitch is rotation about the
204  // Right axis, and roll is rotation about the Direction axis.
205  bool ToEulerAnglesXYZ (Radian& rfYAngle, Radian& rfPAngle,
206  Radian& rfRAngle) const;
207  bool ToEulerAnglesXZY (Radian& rfYAngle, Radian& rfPAngle,
208  Radian& rfRAngle) const;
209  bool ToEulerAnglesYXZ (Radian& rfYAngle, Radian& rfPAngle,
210  Radian& rfRAngle) const;
211  bool ToEulerAnglesYZX (Radian& rfYAngle, Radian& rfPAngle,
212  Radian& rfRAngle) const;
213  bool ToEulerAnglesZXY (Radian& rfYAngle, Radian& rfPAngle,
214  Radian& rfRAngle) const;
215  bool ToEulerAnglesZYX (Radian& rfYAngle, Radian& rfPAngle,
216  Radian& rfRAngle) const;
217  void FromEulerAnglesXYZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
218  void FromEulerAnglesXZY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
219  void FromEulerAnglesYXZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
220  void FromEulerAnglesYZX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
221  void FromEulerAnglesZXY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
222  void FromEulerAnglesZYX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
224  void EigenSolveSymmetric (Real afEigenvalue[3],
225  Vector3 akEigenvector[3]) const;
226 
227  static void TensorProduct (const Vector3& rkU, const Vector3& rkV,
228  Matrix3& rkProduct);
229 
231  inline bool hasScale() const
232  {
233  // check magnitude of column vectors (==local axes)
234  Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0];
235  if (!Math::RealEqual(t, 1.0, (Real)1e-04))
236  return true;
237  t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1];
238  if (!Math::RealEqual(t, 1.0, (Real)1e-04))
239  return true;
240  t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2];
241  if (!Math::RealEqual(t, 1.0, (Real)1e-04))
242  return true;
243 
244  return false;
245  }
246 
249  inline _OgreExport friend std::ostream& operator <<
250  ( std::ostream& o, const Matrix3& mat )
251  {
252  o << "Matrix3(" << mat[0][0] << ", " << mat[0][1] << ", " << mat[0][2] << ", "
253  << mat[1][0] << ", " << mat[1][1] << ", " << mat[1][2] << ", "
254  << mat[2][0] << ", " << mat[2][1] << ", " << mat[2][2] << ")";
255  return o;
256  }
257 
258  static const Real EPSILON;
259  static const Matrix3 ZERO;
260  static const Matrix3 IDENTITY;
261 
262  protected:
263  // support for eigensolver
264  void Tridiagonal (Real afDiag[3], Real afSubDiag[3]);
265  bool QLAlgorithm (Real afDiag[3], Real afSubDiag[3]);
266 
267  // support for singular value decomposition
268  static const Real msSvdEpsilon;
269  static const unsigned int msSvdMaxIterations;
270  static void Bidiagonalize (Matrix3& kA, Matrix3& kL,
271  Matrix3& kR);
272  static void GolubKahanStep (Matrix3& kA, Matrix3& kL,
273  Matrix3& kR);
274 
275  // support for spectral norm
276  static Real MaxCubicRoot (Real afCoeff[3]);
277 
278  Real m[3][3];
279 
280  // for faster access
281  friend class Matrix4;
282  };
285 }
286 #endif
Class encapsulating a standard 4x4 homogeneous matrix.
Definition: OgreMatrix4.h:78
float Real
Software floating point type.
#define _OgreExport
Definition: OgrePlatform.h:233
static const Real msSvdEpsilon
Definition: OgreMatrix3.h:268
Matrix3(Real fEntry00, Real fEntry01, Real fEntry02, Real fEntry10, Real fEntry11, Real fEntry12, Real fEntry20, Real fEntry21, Real fEntry22)
Definition: OgreMatrix3.h:84
void swap(Matrix3 &other)
Exchange the contents of this matrix with another.
Definition: OgreMatrix3.h:101
Real m[3][3]
Definition: OgreMatrix3.h:278
static const Matrix3 IDENTITY
Definition: OgreMatrix3.h:260
A 3x3 matrix which can represent rotations around axes.
Definition: OgreMatrix3.h:68
Radian operator*(Real a, const Radian &b)
Definition: OgreMath.h:720
static bool RealEqual(Real a, Real b, Real tolerance=std::numeric_limits< Real >::epsilon())
Compare 2 reals, using tolerance for inaccuracies.
Matrix3(const Real arr[3][3])
Definition: OgreMatrix3.h:76
Matrix3()
Default constructor.
Definition: OgreMatrix3.h:75
Wrapper class which indicates a given angle value is in Degrees.
Definition: OgreMath.h:97
bool hasScale() const
Determines if this matrix involves a scaling.
Definition: OgreMatrix3.h:231
Matrix3(const Matrix3 &rkMatrix)
Definition: OgreMatrix3.h:80
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Standard 3-dimensional vector.
Definition: OgreVector3.h:51
static const unsigned int msSvdMaxIterations
Definition: OgreMatrix3.h:269
Wrapper class which indicates a given angle value is in Radians.
Definition: OgreMath.h:46
static const Matrix3 ZERO
Definition: OgreMatrix3.h:259
void ToAngleAxis(Vector3 &rkAxis, Degree &rfAngle) const
Definition: OgreMatrix3.h:195
static const Real EPSILON
Definition: OgreMatrix3.h:258
bool operator==(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)
bool operator!=(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)