OGRE  2.0
Object-Oriented Graphics Rendering Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
OgreMatrix4.h
Go to the documentation of this file.
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4  (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef __Matrix4__
29 #define __Matrix4__
30 
31 // Precompiler options
32 #include "OgrePrerequisites.h"
33 
34 //#include "Math/Array/OgreArrayConfig.h"
35 
36 #include "OgreMatrix3.h"
37 #include "OgreVector4.h"
38 #include "OgrePlane.h"
39 namespace Ogre
40 {
80  {
81  protected:
82  friend class ArrayMatrix4;
83  friend class ArrayMatrixAf4x3;
84  friend class SimpleMatrix4;
85  friend class SimpleMatrixAf4x3;
87  union {
88  /*OGRE_ALIGNED_DECL( Real, m[4][4], OGRE_SIMD_ALIGNMENT );
89  OGRE_ALIGNED_DECL( Real, _m[16], OGRE_SIMD_ALIGNMENT );*/
90  Real m[4][4];
91  Real _m[16];
92  };
93  public:
98  inline Matrix4()
99  {
100  }
101 
102  inline Matrix4(
103  Real m00, Real m01, Real m02, Real m03,
104  Real m10, Real m11, Real m12, Real m13,
105  Real m20, Real m21, Real m22, Real m23,
106  Real m30, Real m31, Real m32, Real m33 )
107  {
108  m[0][0] = m00;
109  m[0][1] = m01;
110  m[0][2] = m02;
111  m[0][3] = m03;
112  m[1][0] = m10;
113  m[1][1] = m11;
114  m[1][2] = m12;
115  m[1][3] = m13;
116  m[2][0] = m20;
117  m[2][1] = m21;
118  m[2][2] = m22;
119  m[2][3] = m23;
120  m[3][0] = m30;
121  m[3][1] = m31;
122  m[3][2] = m32;
123  m[3][3] = m33;
124  }
125 
129  inline Matrix4(const Matrix3& m3x3)
130  {
131  operator=(IDENTITY);
132  operator=(m3x3);
133  }
134 
138  inline Matrix4(const Quaternion& rot)
139  {
140  Matrix3 m3x3;
141  rot.ToRotationMatrix(m3x3);
142  operator=(IDENTITY);
143  operator=(m3x3);
144  }
145 
146 
149  inline void swap(Matrix4& other)
150  {
151  std::swap(m[0][0], other.m[0][0]);
152  std::swap(m[0][1], other.m[0][1]);
153  std::swap(m[0][2], other.m[0][2]);
154  std::swap(m[0][3], other.m[0][3]);
155  std::swap(m[1][0], other.m[1][0]);
156  std::swap(m[1][1], other.m[1][1]);
157  std::swap(m[1][2], other.m[1][2]);
158  std::swap(m[1][3], other.m[1][3]);
159  std::swap(m[2][0], other.m[2][0]);
160  std::swap(m[2][1], other.m[2][1]);
161  std::swap(m[2][2], other.m[2][2]);
162  std::swap(m[2][3], other.m[2][3]);
163  std::swap(m[3][0], other.m[3][0]);
164  std::swap(m[3][1], other.m[3][1]);
165  std::swap(m[3][2], other.m[3][2]);
166  std::swap(m[3][3], other.m[3][3]);
167  }
168 
169  inline Real* operator [] ( size_t iRow )
170  {
171  assert( iRow < 4 );
172  return m[iRow];
173  }
174 
175  inline const Real *operator [] ( size_t iRow ) const
176  {
177  assert( iRow < 4 );
178  return m[iRow];
179  }
180 
181 /*#if OGRE_CPU == OGRE_CPU_X86
182  inline Matrix4 concatenate(const Matrix4 &_m2) const
183  {
184  Matrix4 r;
185  ArrayReal m2[4];
186  m2[0] = _mm_load_ps( &_m2[0][0] );
187  m2[1] = _mm_load_ps( &_m2[1][0] );
188  m2[2] = _mm_load_ps( &_m2[2][0] );
189  m2[3] = _mm_load_ps( &_m2[3][0] );
190 
191  ArrayReal t = _mm_mul_ps( _mm_load_ps1( &m[0][0] ), m2[0] );
192  t = _mm_madd_ps( _mm_load_ps1( &m[0][1] ), m2[1], t );
193  t = _mm_madd_ps( _mm_load_ps1( &m[0][2] ), m2[2], t );
194  t = _mm_madd_ps( _mm_load_ps1( &m[0][3] ), m2[3], t );
195  _mm_store_ps( r._m+0, t );
196 
197  t = _mm_mul_ps( _mm_load_ps1( &m[1][0] ), m2[0] );
198  t = _mm_madd_ps( _mm_load_ps1( &m[1][1] ), m2[1], t );
199  t = _mm_madd_ps( _mm_load_ps1( &m[1][2] ), m2[2], t );
200  t = _mm_madd_ps( _mm_load_ps1( &m[1][3] ), m2[3], t );
201  _mm_store_ps( r._m+4, t );
202 
203  t = _mm_mul_ps( _mm_load_ps1( &m[2][0] ), m2[0] );
204  t = _mm_madd_ps( _mm_load_ps1( &m[2][1] ), m2[1], t );
205  t = _mm_madd_ps( _mm_load_ps1( &m[2][2] ), m2[2], t );
206  t = _mm_madd_ps( _mm_load_ps1( &m[2][3] ), m2[3], t );
207  _mm_store_ps( r._m+8, t );
208 
209  t = _mm_mul_ps( _mm_load_ps1( &m[3][0] ), m2[0] );
210  t = _mm_madd_ps( _mm_load_ps1( &m[3][1] ), m2[1], t );
211  t = _mm_madd_ps( _mm_load_ps1( &m[3][2] ), m2[2], t );
212  t = _mm_madd_ps( _mm_load_ps1( &m[3][3] ), m2[3], t );
213  _mm_store_ps( r._m+12, t );
214 
215  return r;
216  }
217 #else*/
218  inline Matrix4 concatenate(const Matrix4 &m2) const
219  {
220  Matrix4 r;
221  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];
222  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];
223  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];
224  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];
225 
226  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];
227  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];
228  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];
229  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];
230 
231  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];
232  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];
233  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];
234  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];
235 
236  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];
237  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];
238  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];
239  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];
240 
241  return r;
242  }
243 //#endif
244 
247  inline Matrix4 operator * ( const Matrix4 &m2 ) const
248  {
249  return concatenate( m2 );
250  }
251 
261  inline Vector3 operator * ( const Vector3 &v ) const
262  {
263  Vector3 r;
264 
265  Real fInvW = 1.0f / ( m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] );
266 
267  r.x = ( m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] ) * fInvW;
268  r.y = ( m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] ) * fInvW;
269  r.z = ( m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] ) * fInvW;
270 
271  return r;
272  }
273  inline Vector4 operator * (const Vector4& v) const
274  {
275  return Vector4(
276  m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w,
277  m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
278  m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
279  m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w
280  );
281  }
282  inline Plane operator * (const Plane& p) const
283  {
284  Plane ret;
285  Matrix4 invTrans = inverse().transpose();
286  Vector4 v4( p.normal.x, p.normal.y, p.normal.z, p.d );
287  v4 = invTrans * v4;
288  ret.normal.x = v4.x;
289  ret.normal.y = v4.y;
290  ret.normal.z = v4.z;
291  ret.d = v4.w / ret.normal.normalise();
292 
293  return ret;
294  }
295 
296 
299  inline Matrix4 operator + ( const Matrix4 &m2 ) const
300  {
301  Matrix4 r;
302 
303  r.m[0][0] = m[0][0] + m2.m[0][0];
304  r.m[0][1] = m[0][1] + m2.m[0][1];
305  r.m[0][2] = m[0][2] + m2.m[0][2];
306  r.m[0][3] = m[0][3] + m2.m[0][3];
307 
308  r.m[1][0] = m[1][0] + m2.m[1][0];
309  r.m[1][1] = m[1][1] + m2.m[1][1];
310  r.m[1][2] = m[1][2] + m2.m[1][2];
311  r.m[1][3] = m[1][3] + m2.m[1][3];
312 
313  r.m[2][0] = m[2][0] + m2.m[2][0];
314  r.m[2][1] = m[2][1] + m2.m[2][1];
315  r.m[2][2] = m[2][2] + m2.m[2][2];
316  r.m[2][3] = m[2][3] + m2.m[2][3];
317 
318  r.m[3][0] = m[3][0] + m2.m[3][0];
319  r.m[3][1] = m[3][1] + m2.m[3][1];
320  r.m[3][2] = m[3][2] + m2.m[3][2];
321  r.m[3][3] = m[3][3] + m2.m[3][3];
322 
323  return r;
324  }
325 
328  inline Matrix4 operator - ( const Matrix4 &m2 ) const
329  {
330  Matrix4 r;
331  r.m[0][0] = m[0][0] - m2.m[0][0];
332  r.m[0][1] = m[0][1] - m2.m[0][1];
333  r.m[0][2] = m[0][2] - m2.m[0][2];
334  r.m[0][3] = m[0][3] - m2.m[0][3];
335 
336  r.m[1][0] = m[1][0] - m2.m[1][0];
337  r.m[1][1] = m[1][1] - m2.m[1][1];
338  r.m[1][2] = m[1][2] - m2.m[1][2];
339  r.m[1][3] = m[1][3] - m2.m[1][3];
340 
341  r.m[2][0] = m[2][0] - m2.m[2][0];
342  r.m[2][1] = m[2][1] - m2.m[2][1];
343  r.m[2][2] = m[2][2] - m2.m[2][2];
344  r.m[2][3] = m[2][3] - m2.m[2][3];
345 
346  r.m[3][0] = m[3][0] - m2.m[3][0];
347  r.m[3][1] = m[3][1] - m2.m[3][1];
348  r.m[3][2] = m[3][2] - m2.m[3][2];
349  r.m[3][3] = m[3][3] - m2.m[3][3];
350 
351  return r;
352  }
353 
356  inline bool operator == ( const Matrix4& m2 ) const
357  {
358  if(
359  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] ||
360  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] ||
361  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] ||
362  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] )
363  return false;
364  return true;
365  }
366 
369  inline bool operator != ( const Matrix4& m2 ) const
370  {
371  if(
372  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] ||
373  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] ||
374  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] ||
375  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] )
376  return true;
377  return false;
378  }
379 
382  inline void operator = ( const Matrix3& mat3 )
383  {
384  m[0][0] = mat3.m[0][0]; m[0][1] = mat3.m[0][1]; m[0][2] = mat3.m[0][2];
385  m[1][0] = mat3.m[1][0]; m[1][1] = mat3.m[1][1]; m[1][2] = mat3.m[1][2];
386  m[2][0] = mat3.m[2][0]; m[2][1] = mat3.m[2][1]; m[2][2] = mat3.m[2][2];
387  }
388 
389  inline Matrix4 transpose(void) const
390  {
391  return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
392  m[0][1], m[1][1], m[2][1], m[3][1],
393  m[0][2], m[1][2], m[2][2], m[3][2],
394  m[0][3], m[1][3], m[2][3], m[3][3]);
395  }
396 
397  /*
398  -----------------------------------------------------------------------
399  Translation Transformation
400  -----------------------------------------------------------------------
401  */
404  inline void setTrans( const Vector3& v )
405  {
406  m[0][3] = v.x;
407  m[1][3] = v.y;
408  m[2][3] = v.z;
409  }
410 
413  inline Vector3 getTrans() const
414  {
415  return Vector3(m[0][3], m[1][3], m[2][3]);
416  }
417 
418 
421  inline void makeTrans( const Vector3& v )
422  {
423  m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = v.x;
424  m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = v.y;
425  m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = v.z;
426  m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
427  }
428 
429  inline void makeTrans( Real tx, Real ty, Real tz )
430  {
431  m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx;
432  m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty;
433  m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz;
434  m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
435  }
436 
439  inline static Matrix4 getTrans( const Vector3& v )
440  {
441  Matrix4 r;
442 
443  r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = v.x;
444  r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = v.y;
445  r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = v.z;
446  r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
447 
448  return r;
449  }
450 
453  inline static Matrix4 getTrans( Real t_x, Real t_y, Real t_z )
454  {
455  Matrix4 r;
456 
457  r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = t_x;
458  r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = t_y;
459  r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = t_z;
460  r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
461 
462  return r;
463  }
464 
465  /*
466  -----------------------------------------------------------------------
467  Scale Transformation
468  -----------------------------------------------------------------------
469  */
472  inline void setScale( const Vector3& v )
473  {
474  m[0][0] = v.x;
475  m[1][1] = v.y;
476  m[2][2] = v.z;
477  }
478 
481  inline static Matrix4 getScale( const Vector3& v )
482  {
483  Matrix4 r;
484  r.m[0][0] = v.x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
485  r.m[1][0] = 0.0; r.m[1][1] = v.y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
486  r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = v.z; r.m[2][3] = 0.0;
487  r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
488 
489  return r;
490  }
491 
494  inline static Matrix4 getScale( Real s_x, Real s_y, Real s_z )
495  {
496  Matrix4 r;
497  r.m[0][0] = s_x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
498  r.m[1][0] = 0.0; r.m[1][1] = s_y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
499  r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = s_z; r.m[2][3] = 0.0;
500  r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
501 
502  return r;
503  }
504 
508  inline void extract3x3Matrix(Matrix3& m3x3) const
509  {
510  m3x3.m[0][0] = m[0][0];
511  m3x3.m[0][1] = m[0][1];
512  m3x3.m[0][2] = m[0][2];
513  m3x3.m[1][0] = m[1][0];
514  m3x3.m[1][1] = m[1][1];
515  m3x3.m[1][2] = m[1][2];
516  m3x3.m[2][0] = m[2][0];
517  m3x3.m[2][1] = m[2][1];
518  m3x3.m[2][2] = m[2][2];
519 
520  }
521 
523  inline bool hasScale() const
524  {
525  // check magnitude of column vectors (==local axes)
526  Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0];
527  if (!Math::RealEqual(t, 1.0, (Real)1e-04))
528  return true;
529  t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1];
530  if (!Math::RealEqual(t, 1.0, (Real)1e-04))
531  return true;
532  t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2];
533  if (!Math::RealEqual(t, 1.0, (Real)1e-04))
534  return true;
535 
536  return false;
537  }
538 
540  inline bool hasNegativeScale() const
541  {
542  return determinant() < 0;
543  }
544 
548  {
549  Matrix3 m3x3;
550  extract3x3Matrix(m3x3);
551  return Quaternion(m3x3);
552  }
553 
554  static const Matrix4 ZERO;
555  static const Matrix4 ZEROAFFINE;
556  static const Matrix4 IDENTITY;
560 
561  inline Matrix4 operator*(Real scalar) const
562  {
563  return Matrix4(
564  scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3],
565  scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3],
566  scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3],
567  scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]);
568  }
569 
572  inline _OgreExport friend std::ostream& operator <<
573  ( std::ostream& o, const Matrix4& mat )
574  {
575  o << "Matrix4(";
576  for (size_t i = 0; i < 4; ++i)
577  {
578  o << " row" << (unsigned)i << "{";
579  for(size_t j = 0; j < 4; ++j)
580  {
581  o << mat[i][j] << " ";
582  }
583  o << "}";
584  }
585  o << ")";
586  return o;
587  }
588 
589  Matrix4 adjoint() const;
590  Real determinant() const;
591  Matrix4 inverse() const;
592 
599  void makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation);
600 
606  void makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation);
607 
610  void decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const;
611 
617  inline bool isAffine(void) const
618  {
619  return m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0 && m[3][3] == 1;
620  }
621 
626  Matrix4 inverseAffine(void) const;
627 
632  inline Matrix4 concatenateAffine(const Matrix4 &m2) const
633  {
634  assert(isAffine() && m2.isAffine());
635 
636  return Matrix4(
637  m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0],
638  m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1],
639  m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2],
640  m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3],
641 
642  m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0],
643  m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1],
644  m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2],
645  m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3],
646 
647  m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0],
648  m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1],
649  m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2],
650  m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3],
651 
652  0, 0, 0, 1);
653  }
654 
662  inline Vector3 transformAffine(const Vector3& v) const
663  {
664  assert(isAffine());
665 
666  return Vector3(
667  m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3],
668  m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3],
669  m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]);
670  }
671 
676  inline Vector4 transformAffine(const Vector4& v) const
677  {
678  assert(isAffine());
679 
680  return Vector4(
681  m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w,
682  m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
683  m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
684  v.w);
685  }
686  };
687 
688  /* Removed from Vector4 and made a non-member here because otherwise
689  OgreMatrix4.h and OgreVector4.h have to try to include and inline each
690  other, which frankly doesn't work ;)
691  */
692  inline Vector4 operator * (const Vector4& v, const Matrix4& mat)
693  {
694  return Vector4(
695  v.x*mat[0][0] + v.y*mat[1][0] + v.z*mat[2][0] + v.w*mat[3][0],
696  v.x*mat[0][1] + v.y*mat[1][1] + v.z*mat[2][1] + v.w*mat[3][1],
697  v.x*mat[0][2] + v.y*mat[1][2] + v.z*mat[2][2] + v.w*mat[3][2],
698  v.x*mat[0][3] + v.y*mat[1][3] + v.z*mat[2][3] + v.w*mat[3][3]
699  );
700  }
704 }
705 #endif
Matrix4()
Default constructor.
Definition: OgreMatrix4.h:98
Class encapsulating a standard 4x4 homogeneous matrix.
Definition: OgreMatrix4.h:79
static const Matrix4 ZERO
Definition: OgreMatrix4.h:554
float Real
Software floating point type.
Matrix4 concatenateAffine(const Matrix4 &m2) const
Concatenate two affine matrices.
Definition: OgreMatrix4.h:632
#define _OgreExport
Definition: OgrePlatform.h:255
Matrix4 concatenate(const Matrix4 &m2) const
Definition: OgreMatrix4.h:218
Defines a plane in 3D space.
Definition: OgrePlane.h:61
Cache-friendly container of 4x4 matrices represented as a SoA array.
Real m[4][4]
Definition: OgreMatrix4.h:90
static const Matrix4 ZEROAFFINE
Definition: OgreMatrix4.h:555
Real m[3][3]
Definition: OgreMatrix3.h:286
bool hasScale() const
Determines if this matrix involves a scaling.
Definition: OgreMatrix4.h:523
static const Matrix4 IDENTITY
Definition: OgreMatrix4.h:556
Matrix4(const Quaternion &rot)
Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling Qua...
Definition: OgreMatrix4.h:138
Matrix4(const Matrix3 &m3x3)
Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling 3x3...
Definition: OgreMatrix4.h:129
void setTrans(const Vector3 &v)
Sets the translation transformation part of the matrix.
Definition: OgreMatrix4.h:404
Cache-friendly container of AFFINE 4x4 matrices represented as a SoA array.
A 3x3 matrix which can represent rotations around axes.
Definition: OgreMatrix3.h:68
Simple wrap up to load an AoS matrix 4x4 using SSE.
Radian operator*(Real a, const Radian &b)
Definition: OgreMath.h:782
static bool RealEqual(Real a, Real b, Real tolerance=std::numeric_limits< Real >::epsilon())
Compare 2 reals, using tolerance for inaccuracies.
Implementation of a Quaternion, i.e.
bool isAffine(void) const
Check whether or not the matrix is affine matrix.
Definition: OgreMatrix4.h:617
void makeTrans(const Vector3 &v)
Builds a translation matrix.
Definition: OgreMatrix4.h:421
Vector3 getTrans() const
Extracts the translation transformation part of the matrix.
Definition: OgreMatrix4.h:413
void ToRotationMatrix(Matrix3 &kRot) const
Vector3 transformAffine(const Vector3 &v) const
3-D Vector transformation specially for an affine matrix.
Definition: OgreMatrix4.h:662
void swap(Matrix4 &other)
Exchange the contents of this matrix with another.
Definition: OgreMatrix4.h:149
void makeTrans(Real tx, Real ty, Real tz)
Definition: OgreMatrix4.h:429
Quaternion extractQuaternion() const
Extracts the rotation / scaling part as a quaternion from the Matrix.
Definition: OgreMatrix4.h:547
bool hasNegativeScale() const
Determines if this matrix involves a negative scaling.
Definition: OgreMatrix4.h:540
Matrix4(Real m00, Real m01, Real m02, Real m03, Real m10, Real m11, Real m12, Real m13, Real m20, Real m21, Real m22, Real m23, Real m30, Real m31, Real m32, Real m33)
Definition: OgreMatrix4.h:102
void extract3x3Matrix(Matrix3 &m3x3) const
Extracts the rotation / scaling part of the Matrix as a 3x3 matrix.
Definition: OgreMatrix4.h:508
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Standard 3-dimensional vector.
Definition: OgreVector3.h:50
Vector4 transformAffine(const Vector4 &v) const
4-D Vector transformation specially for an affine matrix.
Definition: OgreMatrix4.h:676
void setScale(const Vector3 &v)
Sets the scale part of the matrix.
Definition: OgreMatrix4.h:472
static Matrix4 getScale(const Vector3 &v)
Gets a scale matrix.
Definition: OgreMatrix4.h:481
Matrix4 transpose(void) const
Definition: OgreMatrix4.h:389
Vector3 normal
Definition: OgrePlane.h:144
static Matrix4 getScale(Real s_x, Real s_y, Real s_z)
Gets a scale matrix - variation for not using a vector.
Definition: OgreMatrix4.h:494
Real normalise()
Normalises the vector.
Definition: OgreVector3.h:445
Simple wrap up to load an AoS matrix 4x3 using SSE.
static Matrix4 getTrans(Real t_x, Real t_y, Real t_z)
Gets a translation matrix - variation for not using a vector.
Definition: OgreMatrix4.h:453
4-dimensional homogeneous vector.
Definition: OgreVector4.h:45
Matrix4 operator*(Real scalar) const
Definition: OgreMatrix4.h:561
static Matrix4 getTrans(const Vector3 &v)
Gets a translation matrix.
Definition: OgreMatrix4.h:439
static const Matrix4 CLIPSPACE2DTOIMAGESPACE
Useful little matrix which takes 2D clipspace {-1, 1} to {0,1} and inverts the Y. ...
Definition: OgreMatrix4.h:559
bool operator==(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)
bool operator!=(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)