Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: sandbox_light/src/external/ogremath/OgreMatrix3.h @ 6539

Last change on this file since 6539 was 5789, checked in by rgrieder, 15 years ago

Stripped sandbox further down to get a light version that excludes almost all core features.
Also, the Ogre dependency has been removed and a little ogremath library been added.

  • Property svn:eol-style set to native
File size: 8.7 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#ifndef __Matrix3_H__
30#define __Matrix3_H__
31
32#include "OgrePrerequisites.h"
33
34#include "OgreVector3.h"
35#include <ostream>
36
37// NB All code adapted from Wild Magic 0.2 Matrix math (free source code)
38// http://www.geometrictools.com/
39
40// NOTE.  The (x,y,z) coordinate system is assumed to be right-handed.
41// Coordinate axis rotation matrices are of the form
42//   RX =    1       0       0
43//           0     cos(t) -sin(t)
44//           0     sin(t)  cos(t)
45// where t > 0 indicates a counterclockwise rotation in the yz-plane
46//   RY =  cos(t)    0     sin(t)
47//           0       1       0
48//        -sin(t)    0     cos(t)
49// where t > 0 indicates a counterclockwise rotation in the zx-plane
50//   RZ =  cos(t) -sin(t)    0
51//         sin(t)  cos(t)    0
52//           0       0       1
53// where t > 0 indicates a counterclockwise rotation in the xy-plane.
54
55namespace Ogre
56{
57    /** A 3x3 matrix which can represent rotations around axes.
58        @note
59            <b>All the code is adapted from the Wild Magic 0.2 Matrix
60            library (http://www.geometrictools.com/).</b>
61        @par
62            The coordinate system is assumed to be <b>right-handed</b>.
63    */
64    class _OgreExport Matrix3
65    {
66    public:
67        /** Default constructor.
68            @note
69                It does <b>NOT</b> initialize the matrix for efficiency.
70        */
71                inline Matrix3 () {};
72        inline explicit Matrix3 (const Real arr[3][3])
73                {
74                        memcpy(m,arr,9*sizeof(Real));
75                }
76        inline Matrix3 (const Matrix3& rkMatrix)
77                {
78                        memcpy(m,rkMatrix.m,9*sizeof(Real));
79                }
80        Matrix3 (Real fEntry00, Real fEntry01, Real fEntry02,
81                    Real fEntry10, Real fEntry11, Real fEntry12,
82                    Real fEntry20, Real fEntry21, Real fEntry22)
83                {
84                        m[0][0] = fEntry00;
85                        m[0][1] = fEntry01;
86                        m[0][2] = fEntry02;
87                        m[1][0] = fEntry10;
88                        m[1][1] = fEntry11;
89                        m[1][2] = fEntry12;
90                        m[2][0] = fEntry20;
91                        m[2][1] = fEntry21;
92                        m[2][2] = fEntry22;
93                }
94
95        // member access, allows use of construct mat[r][c]
96        inline Real* operator[] (size_t iRow) const
97                {
98                        return (Real*)m[iRow];
99                }
100        /*inline operator Real* ()
101                {
102                        return (Real*)m[0];
103                }*/
104        Vector3 GetColumn (size_t iCol) const;
105        void SetColumn(size_t iCol, const Vector3& vec);
106        void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
107
108        // assignment and comparison
109        inline Matrix3& operator= (const Matrix3& rkMatrix)
110                {
111                        memcpy(m,rkMatrix.m,9*sizeof(Real));
112                        return *this;
113                }
114        bool operator== (const Matrix3& rkMatrix) const;
115        inline bool operator!= (const Matrix3& rkMatrix) const
116                {
117                        return !operator==(rkMatrix);
118                }
119
120        // arithmetic operations
121        Matrix3 operator+ (const Matrix3& rkMatrix) const;
122        Matrix3 operator- (const Matrix3& rkMatrix) const;
123        Matrix3 operator* (const Matrix3& rkMatrix) const;
124        Matrix3 operator- () const;
125
126        // matrix * vector [3x3 * 3x1 = 3x1]
127        Vector3 operator* (const Vector3& rkVector) const;
128
129        // vector * matrix [1x3 * 3x3 = 1x3]
130        _OgreExport friend Vector3 operator* (const Vector3& rkVector,
131            const Matrix3& rkMatrix);
132
133        // matrix * scalar
134        Matrix3 operator* (Real fScalar) const;
135
136        // scalar * matrix
137        _OgreExport friend Matrix3 operator* (Real fScalar, const Matrix3& rkMatrix);
138
139        // utilities
140        Matrix3 Transpose () const;
141        bool Inverse (Matrix3& rkInverse, Real fTolerance = 1e-06) const;
142        Matrix3 Inverse (Real fTolerance = 1e-06) const;
143        Real Determinant () const;
144
145        // singular value decomposition
146        void SingularValueDecomposition (Matrix3& rkL, Vector3& rkS,
147            Matrix3& rkR) const;
148        void SingularValueComposition (const Matrix3& rkL,
149            const Vector3& rkS, const Matrix3& rkR);
150
151        // Gram-Schmidt orthonormalization (applied to columns of rotation matrix)
152        void Orthonormalize ();
153
154        // orthogonal Q, diagonal D, upper triangular U stored as (u01,u02,u12)
155        void QDUDecomposition (Matrix3& rkQ, Vector3& rkD,
156            Vector3& rkU) const;
157
158        Real SpectralNorm () const;
159
160        // matrix must be orthonormal
161        void ToAxisAngle (Vector3& rkAxis, Radian& rfAngle) const;
162                inline void ToAxisAngle (Vector3& rkAxis, Degree& rfAngle) const {
163                        Radian r;
164                        ToAxisAngle ( rkAxis, r );
165                        rfAngle = r;
166                }
167        void FromAxisAngle (const Vector3& rkAxis, const Radian& fRadians);
168
169        // The matrix must be orthonormal.  The decomposition is yaw*pitch*roll
170        // where yaw is rotation about the Up vector, pitch is rotation about the
171        // Right axis, and roll is rotation about the Direction axis.
172        bool ToEulerAnglesXYZ (Radian& rfYAngle, Radian& rfPAngle,
173            Radian& rfRAngle) const;
174        bool ToEulerAnglesXZY (Radian& rfYAngle, Radian& rfPAngle,
175            Radian& rfRAngle) const;
176        bool ToEulerAnglesYXZ (Radian& rfYAngle, Radian& rfPAngle,
177            Radian& rfRAngle) const;
178        bool ToEulerAnglesYZX (Radian& rfYAngle, Radian& rfPAngle,
179            Radian& rfRAngle) const;
180        bool ToEulerAnglesZXY (Radian& rfYAngle, Radian& rfPAngle,
181            Radian& rfRAngle) const;
182        bool ToEulerAnglesZYX (Radian& rfYAngle, Radian& rfPAngle,
183            Radian& rfRAngle) const;
184        void FromEulerAnglesXYZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
185        void FromEulerAnglesXZY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
186        void FromEulerAnglesYXZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
187        void FromEulerAnglesYZX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
188        void FromEulerAnglesZXY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
189        void FromEulerAnglesZYX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
190        // eigensolver, matrix must be symmetric
191        void EigenSolveSymmetric (Real afEigenvalue[3],
192            Vector3 akEigenvector[3]) const;
193
194        static void TensorProduct (const Vector3& rkU, const Vector3& rkV,
195            Matrix3& rkProduct);
196
197                /** Determines if this matrix involves a scaling. */
198                inline bool hasScale() const
199                {
200                        // check magnitude of column vectors (==local axes)
201                        Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0];
202                        if (!Math::RealEqual(t, 1.0, 1e-04))
203                                return true;
204                        t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1];
205                        if (!Math::RealEqual(t, 1.0, 1e-04))
206                                return true;
207                        t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2];
208                        if (!Math::RealEqual(t, 1.0, 1e-04))
209                                return true;
210
211                        return false;
212                }
213
214
215        static const Real EPSILON;
216        static const Matrix3 ZERO;
217        static const Matrix3 IDENTITY;
218
219    protected:
220        // support for eigensolver
221        void Tridiagonal (Real afDiag[3], Real afSubDiag[3]);
222        bool QLAlgorithm (Real afDiag[3], Real afSubDiag[3]);
223
224        // support for singular value decomposition
225        static const Real ms_fSvdEpsilon;
226        static const unsigned int ms_iSvdMaxIterations;
227        static void Bidiagonalize (Matrix3& kA, Matrix3& kL,
228            Matrix3& kR);
229        static void GolubKahanStep (Matrix3& kA, Matrix3& kL,
230            Matrix3& kR);
231
232        // support for spectral norm
233        static Real MaxCubicRoot (Real afCoeff[3]);
234
235        Real m[3][3];
236
237        // for faster access
238        friend class Matrix4;
239    };
240}
241#endif
Note: See TracBrowser for help on using the repository browser.