Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/forks/sandbox_light/src/external/ogremath/OgreMatrix4.h

Last change on this file was 7908, checked in by rgrieder, 14 years ago

Stripped down trunk to form a new light sandbox.

  • Property svn:eol-style set to native
File size: 23.4 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 __Matrix4__
30#define __Matrix4__
31
32// Precompiler options
33#include "OgrePrerequisites.h"
34
35#include "OgreVector3.h"
36#include "OgreMatrix3.h"
37#include "OgreVector4.h"
38#include <ostream>
39
40namespace Ogre
41{
42    /** Class encapsulating a standard 4x4 homogeneous matrix.
43        @remarks
44            OGRE uses column vectors when applying matrix multiplications,
45            This means a vector is represented as a single column, 4-row
46            matrix. This has the effect that the transformations implemented
47            by the matrices happens right-to-left e.g. if vector V is to be
48            transformed by M1 then M2 then M3, the calculation would be
49            M3 * M2 * M1 * V. The order that matrices are concatenated is
50            vital since matrix multiplication is not cummatative, i.e. you
51            can get a different result if you concatenate in the wrong order.
52        @par
53            The use of column vectors and right-to-left ordering is the
54            standard in most mathematical texts, and id the same as used in
55            OpenGL. It is, however, the opposite of Direct3D, which has
56            inexplicably chosen to differ from the accepted standard and uses
57            row vectors and left-to-right matrix multiplication.
58        @par
59            OGRE deals with the differences between D3D and OpenGL etc.
60            internally when operating through different render systems. OGRE
61            users only need to conform to standard maths conventions, i.e.
62            right-to-left matrix multiplication, (OGRE transposes matrices it
63            passes to D3D to compensate).
64        @par
65            The generic form M * V which shows the layout of the matrix
66            entries is shown below:
67            <pre>
68                [ m[0][0]  m[0][1]  m[0][2]  m[0][3] ]   {x}
69                | m[1][0]  m[1][1]  m[1][2]  m[1][3] | * {y}
70                | m[2][0]  m[2][1]  m[2][2]  m[2][3] |   {z}
71                [ m[3][0]  m[3][1]  m[3][2]  m[3][3] ]   {1}
72            </pre>
73    */
74    class _OgreExport Matrix4
75    {
76    protected:
77        /// The matrix entries, indexed by [row][col].
78        union {
79            Real m[4][4];
80            Real _m[16];
81        };
82    public:
83        /** Default constructor.
84            @note
85                It does <b>NOT</b> initialize the matrix for efficiency.
86        */
87        inline Matrix4()
88        {
89        }
90
91        inline Matrix4(
92            Real m00, Real m01, Real m02, Real m03,
93            Real m10, Real m11, Real m12, Real m13,
94            Real m20, Real m21, Real m22, Real m23,
95            Real m30, Real m31, Real m32, Real m33 )
96        {
97            m[0][0] = m00;
98            m[0][1] = m01;
99            m[0][2] = m02;
100            m[0][3] = m03;
101            m[1][0] = m10;
102            m[1][1] = m11;
103            m[1][2] = m12;
104            m[1][3] = m13;
105            m[2][0] = m20;
106            m[2][1] = m21;
107            m[2][2] = m22;
108            m[2][3] = m23;
109            m[3][0] = m30;
110            m[3][1] = m31;
111            m[3][2] = m32;
112            m[3][3] = m33;
113        }
114
115        /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling 3x3 matrix.
116         */
117
118        inline Matrix4(const Matrix3& m3x3)
119        {
120          operator=(IDENTITY);
121          operator=(m3x3);
122        }
123
124        /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling Quaternion.
125         */
126       
127        inline Matrix4(const Quaternion& rot)
128        {
129          Matrix3 m3x3;
130          rot.ToRotationMatrix(m3x3);
131          operator=(IDENTITY);
132          operator=(m3x3);
133        }
134       
135
136        inline Real* operator [] ( size_t iRow )
137        {
138            assert( iRow < 4 );
139            return m[iRow];
140        }
141
142        inline const Real *const operator [] ( size_t iRow ) const
143        {
144            assert( iRow < 4 );
145            return m[iRow];
146        }
147
148        inline Matrix4 concatenate(const Matrix4 &m2) const
149        {
150            Matrix4 r;
151            r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0];
152            r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1];
153            r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2];
154            r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3];
155
156            r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0];
157            r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1];
158            r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2];
159            r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3];
160
161            r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0];
162            r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1];
163            r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2];
164            r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3];
165
166            r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0];
167            r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1];
168            r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2];
169            r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3];
170
171            return r;
172        }
173
174        /** Matrix concatenation using '*'.
175        */
176        inline Matrix4 operator * ( const Matrix4 &m2 ) const
177        {
178            return concatenate( m2 );
179        }
180
181        /** Vector transformation using '*'.
182            @remarks
183                Transforms the given 3-D vector by the matrix, projecting the
184                result back into <i>w</i> = 1.
185            @note
186                This means that the initial <i>w</i> is considered to be 1.0,
187                and then all the tree elements of the resulting 3-D vector are
188                divided by the resulting <i>w</i>.
189        */
190        inline Vector3 operator * ( const Vector3 &v ) const
191        {
192            Vector3 r;
193
194            Real fInvW = 1.0 / ( m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] );
195
196            r.x = ( m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] ) * fInvW;
197            r.y = ( m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] ) * fInvW;
198            r.z = ( m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] ) * fInvW;
199
200            return r;
201        }
202        inline Vector4 operator * (const Vector4& v) const
203        {
204            return Vector4(
205                m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, 
206                m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
207                m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
208                m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w
209                );
210        }
211
212
213        /** Matrix addition.
214        */
215        inline Matrix4 operator + ( const Matrix4 &m2 ) const
216        {
217            Matrix4 r;
218
219            r.m[0][0] = m[0][0] + m2.m[0][0];
220            r.m[0][1] = m[0][1] + m2.m[0][1];
221            r.m[0][2] = m[0][2] + m2.m[0][2];
222            r.m[0][3] = m[0][3] + m2.m[0][3];
223
224            r.m[1][0] = m[1][0] + m2.m[1][0];
225            r.m[1][1] = m[1][1] + m2.m[1][1];
226            r.m[1][2] = m[1][2] + m2.m[1][2];
227            r.m[1][3] = m[1][3] + m2.m[1][3];
228
229            r.m[2][0] = m[2][0] + m2.m[2][0];
230            r.m[2][1] = m[2][1] + m2.m[2][1];
231            r.m[2][2] = m[2][2] + m2.m[2][2];
232            r.m[2][3] = m[2][3] + m2.m[2][3];
233
234            r.m[3][0] = m[3][0] + m2.m[3][0];
235            r.m[3][1] = m[3][1] + m2.m[3][1];
236            r.m[3][2] = m[3][2] + m2.m[3][2];
237            r.m[3][3] = m[3][3] + m2.m[3][3];
238
239            return r;
240        }
241
242        /** Matrix subtraction.
243        */
244        inline Matrix4 operator - ( const Matrix4 &m2 ) const
245        {
246            Matrix4 r;
247            r.m[0][0] = m[0][0] - m2.m[0][0];
248            r.m[0][1] = m[0][1] - m2.m[0][1];
249            r.m[0][2] = m[0][2] - m2.m[0][2];
250            r.m[0][3] = m[0][3] - m2.m[0][3];
251
252            r.m[1][0] = m[1][0] - m2.m[1][0];
253            r.m[1][1] = m[1][1] - m2.m[1][1];
254            r.m[1][2] = m[1][2] - m2.m[1][2];
255            r.m[1][3] = m[1][3] - m2.m[1][3];
256
257            r.m[2][0] = m[2][0] - m2.m[2][0];
258            r.m[2][1] = m[2][1] - m2.m[2][1];
259            r.m[2][2] = m[2][2] - m2.m[2][2];
260            r.m[2][3] = m[2][3] - m2.m[2][3];
261
262            r.m[3][0] = m[3][0] - m2.m[3][0];
263            r.m[3][1] = m[3][1] - m2.m[3][1];
264            r.m[3][2] = m[3][2] - m2.m[3][2];
265            r.m[3][3] = m[3][3] - m2.m[3][3];
266
267            return r;
268        }
269
270        /** Tests 2 matrices for equality.
271        */
272        inline bool operator == ( const Matrix4& m2 ) const
273        {
274            if( 
275                m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
276                m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
277                m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
278                m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
279                return false;
280            return true;
281        }
282
283        /** Tests 2 matrices for inequality.
284        */
285        inline bool operator != ( const Matrix4& m2 ) const
286        {
287            if( 
288                m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
289                m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
290                m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
291                m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
292                return true;
293            return false;
294        }
295
296        /** Assignment from 3x3 matrix.
297        */
298        inline void operator = ( const Matrix3& mat3 )
299        {
300            m[0][0] = mat3.m[0][0]; m[0][1] = mat3.m[0][1]; m[0][2] = mat3.m[0][2];
301            m[1][0] = mat3.m[1][0]; m[1][1] = mat3.m[1][1]; m[1][2] = mat3.m[1][2];
302            m[2][0] = mat3.m[2][0]; m[2][1] = mat3.m[2][1]; m[2][2] = mat3.m[2][2];
303        }
304
305        inline Matrix4 transpose(void) const
306        {
307            return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
308                           m[0][1], m[1][1], m[2][1], m[3][1],
309                           m[0][2], m[1][2], m[2][2], m[3][2],
310                           m[0][3], m[1][3], m[2][3], m[3][3]);
311        }
312
313        /*
314        -----------------------------------------------------------------------
315        Translation Transformation
316        -----------------------------------------------------------------------
317        */
318        /** Sets the translation transformation part of the matrix.
319        */
320        inline void setTrans( const Vector3& v )
321        {
322            m[0][3] = v.x;
323            m[1][3] = v.y;
324            m[2][3] = v.z;
325        }
326
327        /** Extracts the translation transformation part of the matrix.
328         */
329        inline Vector3 getTrans() const
330        {
331          return Vector3(m[0][3], m[1][3], m[2][3]);
332        }
333       
334
335        /** Builds a translation matrix
336        */
337        inline void makeTrans( const Vector3& v )
338        {
339            m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = v.x;
340            m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = v.y;
341            m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = v.z;
342            m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
343        }
344
345        inline void makeTrans( Real tx, Real ty, Real tz )
346        {
347            m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx;
348            m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty;
349            m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz;
350            m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
351        }
352
353        /** Gets a translation matrix.
354        */
355        inline static Matrix4 getTrans( const Vector3& v )
356        {
357            Matrix4 r;
358
359            r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = v.x;
360            r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = v.y;
361            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = v.z;
362            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
363
364            return r;
365        }
366
367        /** Gets a translation matrix - variation for not using a vector.
368        */
369        inline static Matrix4 getTrans( Real t_x, Real t_y, Real t_z )
370        {
371            Matrix4 r;
372
373            r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = t_x;
374            r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = t_y;
375            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = t_z;
376            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
377
378            return r;
379        }
380
381        /*
382        -----------------------------------------------------------------------
383        Scale Transformation
384        -----------------------------------------------------------------------
385        */
386        /** Sets the scale part of the matrix.
387        */
388        inline void setScale( const Vector3& v )
389        {
390            m[0][0] = v.x;
391            m[1][1] = v.y;
392            m[2][2] = v.z;
393        }
394
395        /** Gets a scale matrix.
396        */
397        inline static Matrix4 getScale( const Vector3& v )
398        {
399            Matrix4 r;
400            r.m[0][0] = v.x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
401            r.m[1][0] = 0.0; r.m[1][1] = v.y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
402            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = v.z; r.m[2][3] = 0.0;
403            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
404
405            return r;
406        }
407
408        /** Gets a scale matrix - variation for not using a vector.
409        */
410        inline static Matrix4 getScale( Real s_x, Real s_y, Real s_z )
411        {
412            Matrix4 r;
413            r.m[0][0] = s_x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
414            r.m[1][0] = 0.0; r.m[1][1] = s_y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
415            r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = s_z; r.m[2][3] = 0.0;
416            r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
417
418            return r;
419        }
420
421        /** Extracts the rotation / scaling part of the Matrix as a 3x3 matrix.
422        @param m3x3 Destination Matrix3
423        */
424        inline void extract3x3Matrix(Matrix3& m3x3) const
425        {
426            m3x3.m[0][0] = m[0][0];
427            m3x3.m[0][1] = m[0][1];
428            m3x3.m[0][2] = m[0][2];
429            m3x3.m[1][0] = m[1][0];
430            m3x3.m[1][1] = m[1][1];
431            m3x3.m[1][2] = m[1][2];
432            m3x3.m[2][0] = m[2][0];
433            m3x3.m[2][1] = m[2][1];
434            m3x3.m[2][2] = m[2][2];
435
436        }
437
438                /** Determines if this matrix involves a scaling. */
439                inline bool hasScale() const
440                {
441                        // check magnitude of column vectors (==local axes)
442                        Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0];
443                        if (!Math::RealEqual(t, 1.0, 1e-04))
444                                return true;
445                        t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1];
446                        if (!Math::RealEqual(t, 1.0, 1e-04))
447                                return true;
448                        t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2];
449                        if (!Math::RealEqual(t, 1.0, 1e-04))
450                                return true;
451
452                        return false;
453                }
454
455                /** Determines if this matrix involves a negative scaling. */
456                inline bool hasNegativeScale() const
457                {
458                        return determinant() < 0;
459                }
460
461                /** Extracts the rotation / scaling part as a quaternion from the Matrix.
462         */
463        inline Quaternion extractQuaternion() const
464        {
465          Matrix3 m3x3;
466          extract3x3Matrix(m3x3);
467          return Quaternion(m3x3);
468        }
469
470        static const Matrix4 ZERO;
471        static const Matrix4 IDENTITY;
472        /** Useful little matrix which takes 2D clipspace {-1, 1} to {0,1}
473            and inverts the Y. */
474        static const Matrix4 CLIPSPACE2DTOIMAGESPACE;
475
476        inline Matrix4 operator*(Real scalar) const
477        {
478            return Matrix4(
479                scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3],
480                scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3],
481                scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3],
482                scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]);
483        }
484
485        /** Function for writing to a stream.
486        */
487        inline _OgreExport friend std::ostream& operator <<
488            ( std::ostream& o, const Matrix4& m )
489        {
490            o << "Matrix4(";
491                        for (size_t i = 0; i < 4; ++i)
492            {
493                o << " row" << (unsigned)i << "{";
494                for(size_t j = 0; j < 4; ++j)
495                {
496                    o << m[i][j] << " ";
497                }
498                o << "}";
499            }
500            o << ")";
501            return o;
502        }
503               
504                Matrix4 adjoint() const;
505                Real determinant() const;
506                Matrix4 inverse() const;
507
508        /** Building a Matrix4 from orientation / scale / position.
509        @remarks
510            Transform is performed in the order scale, rotate, translation, i.e. translation is independent
511            of orientation axes, scale does not affect size of translation, rotation and scaling are always
512            centered on the origin.
513        */
514        void makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation);
515
516        /** Building an inverse Matrix4 from orientation / scale / position.
517        @remarks
518            As makeTransform except it build the inverse given the same data as makeTransform, so
519            performing -translation, -rotate, 1/scale in that order.
520        */
521        void makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation);
522
523        /** Check whether or not the matrix is affine matrix.
524            @remarks
525                An affine matrix is a 4x4 matrix with row 3 equal to (0, 0, 0, 1),
526                e.g. no projective coefficients.
527        */
528        inline bool isAffine(void) const
529        {
530            return m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0 && m[3][3] == 1;
531        }
532
533        /** Returns the inverse of the affine matrix.
534            @note
535                The matrix must be an affine matrix. @see Matrix4::isAffine.
536        */
537        Matrix4 inverseAffine(void) const;
538
539        /** Concatenate two affine matrix.
540            @note
541                The matrices must be affine matrix. @see Matrix4::isAffine.
542        */
543        inline Matrix4 concatenateAffine(const Matrix4 &m2) const
544        {
545            assert(isAffine() && m2.isAffine());
546
547            return Matrix4(
548                m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0],
549                m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1],
550                m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2],
551                m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3],
552
553                m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0],
554                m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1],
555                m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2],
556                m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3],
557
558                m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0],
559                m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1],
560                m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2],
561                m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3],
562
563                0, 0, 0, 1);
564        }
565
566        /** 3-D Vector transformation specially for affine matrix.
567            @remarks
568                Transforms the given 3-D vector by the matrix, projecting the
569                result back into <i>w</i> = 1.
570            @note
571                The matrix must be an affine matrix. @see Matrix4::isAffine.
572        */
573        inline Vector3 transformAffine(const Vector3& v) const
574        {
575            assert(isAffine());
576
577            return Vector3(
578                    m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3], 
579                    m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3],
580                    m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]);
581        }
582
583        /** 4-D Vector transformation specially for affine matrix.
584            @note
585                The matrix must be an affine matrix. @see Matrix4::isAffine.
586        */
587        inline Vector4 transformAffine(const Vector4& v) const
588        {
589            assert(isAffine());
590
591            return Vector4(
592                m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, 
593                m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
594                m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
595                v.w);
596        }
597    };
598
599    /* Removed from Vector4 and made a non-member here because otherwise
600       OgreMatrix4.h and OgreVector4.h have to try to include and inline each
601       other, which frankly doesn't work ;)
602   */
603    inline Vector4 operator * (const Vector4& v, const Matrix4& mat)
604    {
605        return Vector4(
606            v.x*mat[0][0] + v.y*mat[1][0] + v.z*mat[2][0] + v.w*mat[3][0],
607            v.x*mat[0][1] + v.y*mat[1][1] + v.z*mat[2][1] + v.w*mat[3][1],
608            v.x*mat[0][2] + v.y*mat[1][2] + v.z*mat[2][2] + v.w*mat[3][2],
609            v.x*mat[0][3] + v.y*mat[1][3] + v.z*mat[2][3] + v.w*mat[3][3]
610            );
611    }
612
613}
614#endif
Note: See TracBrowser for help on using the repository browser.