source: GTP/trunk/Lib/Geom/OgreStuff/include/OgreMatrix3.h @ 1809

Revision 1809, 11.3 KB checked in by gumbau, 18 years ago (diff)
RevLine 
[1809]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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25#ifndef __Matrix3_H__
26#define __Matrix3_H__
27
28#include "OgrePrerequisites.h"
29
30#include "OgreVector3.h"
31
32// NB All code adapted from Wild Magic 0.2 Matrix math (free source code)
33// http://www.geometrictools.com/
34
35// NOTE.  The (x,y,z) coordinate system is assumed to be right-handed.
36// Coordinate axis rotation matrices are of the form
37//   RX =    1       0       0
38//           0     cos(t) -sin(t)
39//           0     sin(t)  cos(t)
40// where t > 0 indicates a counterclockwise rotation in the yz-plane
41//   RY =  cos(t)    0     sin(t)
42//           0       1       0
43//        -sin(t)    0     cos(t)
44// where t > 0 indicates a counterclockwise rotation in the zx-plane
45//   RZ =  cos(t) -sin(t)    0
46//         sin(t)  cos(t)    0
47//           0       0       1
48// where t > 0 indicates a counterclockwise rotation in the xy-plane.
49
50namespace Ogre
51{
52    /** A 3x3 matrix which can represent rotations around axes.
53        @note
54            <b>All the code is adapted from the Wild Magic 0.2 Matrix
55            library (http://www.geometrictools.com/).</b>
56        @par
57            The coordinate system is assumed to be <b>right-handed</b>.
58    */
59    class _OgreExport Matrix3
60    {
61    public:
62        /** Default constructor.
63            @note
64                It does <b>NOT</b> initialize the matrix for efficiency.
65        */
66                inline Matrix3 () {};
67        inline explicit Matrix3 (const Real arr[3][3])
68                {
69                        memcpy(m,arr,9*sizeof(Real));
70                }
71        inline Matrix3 (const Matrix3& rkMatrix)
72                {
73                        memcpy(m,rkMatrix.m,9*sizeof(Real));
74                }
75        Matrix3 (Real fEntry00, Real fEntry01, Real fEntry02,
76                    Real fEntry10, Real fEntry11, Real fEntry12,
77                    Real fEntry20, Real fEntry21, Real fEntry22)
78                {
79                        m[0][0] = fEntry00;
80                        m[0][1] = fEntry01;
81                        m[0][2] = fEntry02;
82                        m[1][0] = fEntry10;
83                        m[1][1] = fEntry11;
84                        m[1][2] = fEntry12;
85                        m[2][0] = fEntry20;
86                        m[2][1] = fEntry21;
87                        m[2][2] = fEntry22;
88                }
89
90        // member access, allows use of construct mat[r][c]
91        inline Real* operator[] (size_t iRow) const
92                {
93                        return (Real*)m[iRow];
94                }
95        /*inline operator Real* ()
96                {
97                        return (Real*)m[0];
98                }*/
99        Vector3 GetColumn (size_t iCol) const;
100        void SetColumn(size_t iCol, const Vector3& vec);
101        void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
102
103        // assignment and comparison
104        inline Matrix3& operator= (const Matrix3& rkMatrix)
105                {
106                        memcpy(m,rkMatrix.m,9*sizeof(Real));
107                        return *this;
108                }
109        bool operator== (const Matrix3& rkMatrix) const;
110        inline bool operator!= (const Matrix3& rkMatrix) const
111                {
112                        return !operator==(rkMatrix);
113                }
114
115        // arithmetic operations
116        Matrix3 operator+ (const Matrix3& rkMatrix) const;
117        Matrix3 operator- (const Matrix3& rkMatrix) const;
118        Matrix3 operator* (const Matrix3& rkMatrix) const;
119        Matrix3 operator- () const;
120
121        // matrix * vector [3x3 * 3x1 = 3x1]
122        Vector3 operator* (const Vector3& rkVector) const;
123
124        // vector * matrix [1x3 * 3x3 = 1x3]
125        _OgreExport friend Vector3 operator* (const Vector3& rkVector,
126            const Matrix3& rkMatrix);
127
128        // matrix * scalar
129        Matrix3 operator* (Real fScalar) const;
130
131        // scalar * matrix
132        _OgreExport friend Matrix3 operator* (Real fScalar, const Matrix3& rkMatrix);
133
134        // utilities
135        Matrix3 Transpose () const;
136        bool Inverse (Matrix3& rkInverse, Real fTolerance = 1e-06) const;
137        Matrix3 Inverse (Real fTolerance = 1e-06) const;
138        Real Determinant () const;
139
140        // singular value decomposition
141        void SingularValueDecomposition (Matrix3& rkL, Vector3& rkS,
142            Matrix3& rkR) const;
143        void SingularValueComposition (const Matrix3& rkL,
144            const Vector3& rkS, const Matrix3& rkR);
145
146        // Gram-Schmidt orthonormalization (applied to columns of rotation matrix)
147        void Orthonormalize ();
148
149        // orthogonal Q, diagonal D, upper triangular U stored as (u01,u02,u12)
150        void QDUDecomposition (Matrix3& rkQ, Vector3& rkD,
151            Vector3& rkU) const;
152
153        Real SpectralNorm () const;
154
155        // matrix must be orthonormal
156        void ToAxisAngle (Vector3& rkAxis, Radian& rfAngle) const;
157                inline void ToAxisAngle (Vector3& rkAxis, Degree& rfAngle) const {
158                        Radian r;
159                        ToAxisAngle ( rkAxis, r );
160                        rfAngle = r;
161                }
162        void FromAxisAngle (const Vector3& rkAxis, const Radian& fRadians);
163#ifndef OGRE_FORCE_ANGLE_TYPES
164        inline void ToAxisAngle (Vector3& rkAxis, Real& rfRadians) const {
165                        Radian r;
166                        ToAxisAngle ( rkAxis, r );
167                        rfRadians = r.valueRadians();
168                }
169        inline void FromAxisAngle (const Vector3& rkAxis, Real fRadians) {
170                        FromAxisAngle ( rkAxis, Radian(fRadians) );
171                }
172#endif//OGRE_FORCE_ANGLE_TYPES
173
174        // The matrix must be orthonormal.  The decomposition is yaw*pitch*roll
175        // where yaw is rotation about the Up vector, pitch is rotation about the
176        // Right axis, and roll is rotation about the Direction axis.
177        bool ToEulerAnglesXYZ (Radian& rfYAngle, Radian& rfPAngle,
178            Radian& rfRAngle) const;
179        bool ToEulerAnglesXZY (Radian& rfYAngle, Radian& rfPAngle,
180            Radian& rfRAngle) const;
181        bool ToEulerAnglesYXZ (Radian& rfYAngle, Radian& rfPAngle,
182            Radian& rfRAngle) const;
183        bool ToEulerAnglesYZX (Radian& rfYAngle, Radian& rfPAngle,
184            Radian& rfRAngle) const;
185        bool ToEulerAnglesZXY (Radian& rfYAngle, Radian& rfPAngle,
186            Radian& rfRAngle) const;
187        bool ToEulerAnglesZYX (Radian& rfYAngle, Radian& rfPAngle,
188            Radian& rfRAngle) const;
189        void FromEulerAnglesXYZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
190        void FromEulerAnglesXZY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
191        void FromEulerAnglesYXZ (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
192        void FromEulerAnglesYZX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
193        void FromEulerAnglesZXY (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
194        void FromEulerAnglesZYX (const Radian& fYAngle, const Radian& fPAngle, const Radian& fRAngle);
195#ifndef OGRE_FORCE_ANGLE_TYPES
196        inline bool ToEulerAnglesXYZ (float& rfYAngle, float& rfPAngle,
197            float& rfRAngle) const {
198                        Radian y, p, r;
199                        bool b = ToEulerAnglesXYZ(y,p,r);
200                        rfYAngle = y.valueRadians();
201                        rfPAngle = p.valueRadians();
202                        rfRAngle = r.valueRadians();
203                        return b;
204                }
205        inline bool ToEulerAnglesXZY (float& rfYAngle, float& rfPAngle,
206            float& rfRAngle) const {
207                        Radian y, p, r;
208                        bool b = ToEulerAnglesXZY(y,p,r);
209                        rfYAngle = y.valueRadians();
210                        rfPAngle = p.valueRadians();
211                        rfRAngle = r.valueRadians();
212                        return b;
213                }
214        inline bool ToEulerAnglesYXZ (float& rfYAngle, float& rfPAngle,
215            float& rfRAngle) const {
216                        Radian y, p, r;
217                        bool b = ToEulerAnglesYXZ(y,p,r);
218                        rfYAngle = y.valueRadians();
219                        rfPAngle = p.valueRadians();
220                        rfRAngle = r.valueRadians();
221                        return b;
222                }
223        inline bool ToEulerAnglesYZX (float& rfYAngle, float& rfPAngle,
224            float& rfRAngle) const {
225                        Radian y, p, r;
226                        bool b = ToEulerAnglesYZX(y,p,r);
227                        rfYAngle = y.valueRadians();
228                        rfPAngle = p.valueRadians();
229                        rfRAngle = r.valueRadians();
230                        return b;
231                }
232        inline bool ToEulerAnglesZXY (float& rfYAngle, float& rfPAngle,
233            float& rfRAngle) const {
234                        Radian y, p, r;
235                        bool b = ToEulerAnglesZXY(y,p,r);
236                        rfYAngle = y.valueRadians();
237                        rfPAngle = p.valueRadians();
238                        rfRAngle = r.valueRadians();
239                        return b;
240                }
241        inline bool ToEulerAnglesZYX (float& rfYAngle, float& rfPAngle,
242            float& rfRAngle) const {
243                        Radian y, p, r;
244                        bool b = ToEulerAnglesZYX(y,p,r);
245                        rfYAngle = y.valueRadians();
246                        rfPAngle = p.valueRadians();
247                        rfRAngle = r.valueRadians();
248                        return b;
249                }
250        inline void FromEulerAnglesXYZ (float fYAngle, float fPAngle, float fRAngle) {
251                        FromEulerAnglesXYZ ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
252                }
253        inline void FromEulerAnglesXZY (float fYAngle, float fPAngle, float fRAngle) {
254                        FromEulerAnglesXZY ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
255                }
256        inline void FromEulerAnglesYXZ (float fYAngle, float fPAngle, float fRAngle) {
257                        FromEulerAnglesYXZ ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
258                }
259        inline void FromEulerAnglesYZX (float fYAngle, float fPAngle, float fRAngle) {
260                        FromEulerAnglesYZX ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
261                }
262        inline void FromEulerAnglesZXY (float fYAngle, float fPAngle, float fRAngle) {
263                        FromEulerAnglesZXY ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
264                }
265        inline void FromEulerAnglesZYX (float fYAngle, float fPAngle, float fRAngle) {
266                        FromEulerAnglesZYX ( Radian(fYAngle), Radian(fPAngle), Radian(fRAngle) );
267                }
268#endif//OGRE_FORCE_ANGLE_TYPES
269        // eigensolver, matrix must be symmetric
270        void EigenSolveSymmetric (Real afEigenvalue[3],
271            Vector3 akEigenvector[3]) const;
272
273        static void TensorProduct (const Vector3& rkU, const Vector3& rkV,
274            Matrix3& rkProduct);
275
276        static const Real EPSILON;
277        static const Matrix3 ZERO;
278        static const Matrix3 IDENTITY;
279
280    protected:
281        // support for eigensolver
282        void Tridiagonal (Real afDiag[3], Real afSubDiag[3]);
283        bool QLAlgorithm (Real afDiag[3], Real afSubDiag[3]);
284
285        // support for singular value decomposition
286        static const Real ms_fSvdEpsilon;
287        static const unsigned int ms_iSvdMaxIterations;
288        static void Bidiagonalize (Matrix3& kA, Matrix3& kL,
289            Matrix3& kR);
290        static void GolubKahanStep (Matrix3& kA, Matrix3& kL,
291            Matrix3& kR);
292
293        // support for spectral norm
294        static Real MaxCubicRoot (Real afCoeff[3]);
295
296        Real m[3][3];
297
298        // for faster access
299        friend class Matrix4;
300    };
301}
302#endif
Note: See TracBrowser for help on using the repository browser.