Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreMatrix4.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

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