Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

=update

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