Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreMatrix3.h @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

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