Pioneer
matrix4x4.h
Go to the documentation of this file.
1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _MATRIX4X4_H
5 #define _MATRIX4X4_H
6 
7 #include "matrix3x3.h"
8 #include "vector3.h"
9 #include <math.h>
10 #include <stdio.h>
11 #include <type_traits>
12 
13 template <typename T>
14 class matrix4x4 {
15 private:
16  T cell[16];
17  using other_float_t = typename std::conditional<std::is_same<T, float>::value, double, float>::type;
18 
19 public:
20  matrix4x4() {}
22  {
23  cell[0] = cell[1] = cell[2] = cell[3] = cell[4] = cell[5] = cell[6] =
24  cell[7] = cell[8] = cell[9] = cell[10] = cell[11] = cell[12] = cell[13] =
25  cell[14] = cell[15] = val;
26  }
27  matrix4x4(const T *vals)
28  {
29  memcpy(cell, vals, sizeof(T) * 16);
30  }
32  {
34  }
35  matrix4x4(const matrix3x3<T> &m, const vector3<T> &v)
36  {
38  SetTranslate(v);
39  }
41  {
42  for (int i = 0; i < 16; i++)
43  cell[i] = T(m[i]);
44  }
45 
46  void SetTranslate(const vector3<T> &v)
47  {
48  cell[12] = v.x;
49  cell[13] = v.y;
50  cell[14] = v.z;
51  }
52  vector3<T> GetTranslate() const { return vector3<T>(cell[12], cell[13], cell[14]); }
53  void SetRotationOnly(const matrix4x4 &m)
54  {
55  for (int i = 0; i < 12; i++)
56  cell[i] = m.cell[i];
57  }
59  {
60  matrix3x3<T> m;
61  m[0] = cell[0];
62  m[1] = cell[4];
63  m[2] = cell[8];
64  m[3] = cell[1];
65  m[4] = cell[5];
66  m[5] = cell[9];
67  m[6] = cell[2];
68  m[7] = cell[6];
69  m[8] = cell[10];
70  return m;
71  }
72  // row-major 3x3 matrix
73  void LoadFrom3x3Matrix(const T *r)
74  {
75  cell[0] = r[0];
76  cell[4] = r[1];
77  cell[8] = r[2];
78  cell[12] = 0;
79  cell[1] = r[3];
80  cell[5] = r[4];
81  cell[9] = r[5];
82  cell[13] = 0;
83  cell[2] = r[6];
84  cell[6] = r[7];
85  cell[10] = r[8];
86  cell[14] = 0;
87  cell[3] = 0;
88  cell[7] = 0;
89  cell[11] = 0;
90  cell[15] = 1;
91  }
92  // row-major
93  void SaveTo3x3Matrix(T *r) const
94  {
95  r[0] = cell[0];
96  r[1] = cell[4];
97  r[2] = cell[8];
98  r[3] = cell[1];
99  r[4] = cell[5];
100  r[5] = cell[9];
101  r[6] = cell[2];
102  r[7] = cell[6];
103  r[8] = cell[10];
104  }
106  {
107  matrix4x4 m = matrix4x4(0.0);
108  m.cell[0] = m.cell[5] = m.cell[10] = m.cell[15] = 1.0f;
109  return m;
110  }
111  //glscale equivalent
112  void Scale(T x, T y, T z)
113  {
114  *this = (*this) * ScaleMatrix(x, y, z);
115  }
116  void Scale(T s)
117  {
118  *this = (*this) * ScaleMatrix(s, s, s);
119  }
120  static matrix4x4 ScaleMatrix(T x, T y, T z)
121  {
122  matrix4x4 m;
123  m[0] = x;
124  m[1] = m[2] = m[3] = 0;
125  m[5] = y;
126  m[4] = m[6] = m[7] = 0;
127  m[10] = z;
128  m[8] = m[9] = m[11] = 0;
129  m[12] = m[13] = m[14] = 0;
130  m[15] = 1;
131  return m;
132  }
133  static matrix4x4 ScaleMatrix(T scale)
134  {
135  matrix4x4 m;
136  m[0] = scale;
137  m[1] = m[2] = m[3] = 0;
138  m[5] = scale;
139  m[4] = m[6] = m[7] = 0;
140  m[10] = scale;
141  m[8] = m[9] = m[11] = 0;
142  m[12] = m[13] = m[14] = 0;
143  m[15] = 1;
144  return m;
145  }
146  static matrix4x4 MakeRotMatrix(const vector3<T> &rx, const vector3<T> &ry, const vector3<T> &rz)
147  {
148  matrix4x4 m;
149  m[0] = rx.x;
150  m[4] = rx.y;
151  m[8] = rx.z;
152  m[12] = 0;
153  m[1] = ry.x;
154  m[5] = ry.y;
155  m[9] = ry.z;
156  m[13] = 0;
157  m[2] = rz.x;
158  m[6] = rz.y;
159  m[10] = rz.z;
160  m[14] = 0;
161  m[3] = 0;
162  m[7] = 0;
163  m[11] = 0;
164  m[15] = 1;
165  return m;
166  }
167  static matrix4x4 MakeInvRotMatrix(const vector3<T> &rx, const vector3<T> &ry, const vector3<T> &rz)
168  {
169  matrix4x4 m;
170  m[0] = rx.x;
171  m[4] = ry.x;
172  m[8] = rz.x;
173  m[12] = 0;
174  m[1] = rx.y;
175  m[5] = ry.y;
176  m[9] = rz.y;
177  m[13] = 0;
178  m[2] = rx.z;
179  m[6] = ry.z;
180  m[10] = rz.z;
181  m[14] = 0;
182  m[3] = 0;
183  m[7] = 0;
184  m[11] = 0;
185  m[15] = 1;
186  return m;
187  }
188 
190  // Matrix Construction Functions
191  // NOTE: all matrix functions here are optimized for reverse-Z depth buffers.
192  // Compared to "standard" DirectX or OpenGL matricies they invert the Z value
193  // so it ranges from 1.0 at the near plane to 0.0 at the far plane.
195 
196  // Construct a perspective projection matrix based on arbitrary left/right/top/bottom
197  // plane positions.
198  // This method is slower than the others, but supports view frustrums that are not
199  // aligned with the Z-axis. Unless you know what you're doing, you shouldn't use this.
200  //
201  // @param left - the minimum x-value of the view volume at the near plane
202  // @param right - the maxiumum x-value of the view volume at the near plane
203  // @param bottom - the maxiumum y-value of the view volume at the near plane
204  // @param top - the maxiumum y-value of the view volume at the near plane
205  // @param znear - the near clipping plane
206  // @param zfar - the far clipping plane
207  static matrix4x4 FrustumMatrix(T left, T right, T bottom, T top, T znear, T zfar)
208  {
209  assert((znear > T(0)) && (zfar > T(0)));
210  // these expressions come from the documentation for glFrustum
211  const T sx = (T(2) * znear) / (right - left);
212  const T sy = (T(2) * znear) / (top - bottom);
213  const T A = (right + left) / (right - left);
214  const T B = (top + bottom) / (top - bottom);
215  const T C = (zfar) / (zfar - znear) - 1;
216  const T D = (zfar * znear) / (zfar - znear);
217  matrix4x4 m;
218 
219  // http://glprogramming.com/red/appendixf.html
220  // OpenGL 'Red Book' on Perspective Projection
221  // Presented here in row-major notation (because that's what matrix4x4f uses internally)
222  T perspective[16] = {
223  sx, 0, 0, 0,
224  0, sy, 0, 0,
225  A, B, C, -1,
226  0, 0, D, 0
227  };
228  return matrix4x4(&perspective[0]);
229  }
230 
231  // Construct a perspective projection matrix based field of view and aspect ratio.
232  // This method is the optimized case when you know your screen aspect ratio and
233  // field of view and aren't interested in fancy math. Use this function or
234  // InfinitePerspectiveMatrix if at all possible.
235  //
236  // @param fovR - the camera FOV in radians
237  // @param aspect - the aspect ratio (width / height) of the viewport
238  // @param znear - the near clipping plane
239  // @param zfar - the far clipping plane
240  // @param fovX - whether the field of view is horizontal or vertical (default)
241  static matrix4x4 PerspectiveMatrix(T fovR, T aspect, T znear, T zfar, bool fovX = false)
242  {
243  assert((znear > T(0)) && (zfar > znear));
244 
245  const T e = 1 / tan(fovR / T(2));
246  const T x = fovX ? e : e / aspect;
247  const T y = fovX ? e / aspect : e;
248  const T z = (znear) / (zfar - znear);
249  const T w = (zfar * znear) / (zfar - znear);
250 
251  // Based on: http://www.terathon.com/gdc07_lengyel.pdf
252  // Unlike gluProject / FrustumMatrix, this projection matrix can only be
253  // symmetric about the Z axis.
254  // This is what you want in 99% of cases, and simplifies the math a good deal.
255  T perspective[16] = {
256  x, 0, 0, 0,
257  0, y, 0, 0,
258  0, 0, z, -1,
259  0, 0, w, 0
260  };
261 
262  return matrix4x4(&perspective[0]);
263  }
264 
265  // Construct an infinite far-plane perspective projection matrix.
266  // Unless you specifically want to clip objects beyond a specific distance,
267  // this projection will work for any object at any distance.
268  //
269  // @param fovR - the camera FOV in radians
270  // @param aspect - the aspect ratio (width / height) of the viewport
271  // @param znear - the near clipping plane
272  // @param fovX - whether the field of view is horizontal or vertical (default)
273  static matrix4x4 InfinitePerspectiveMatrix(T fovR, T aspect, T znear, bool fovX = false)
274  {
275  assert(znear > T(0));
276 
277  const T e = 1 / tan(fovR / T(2));
278  const T x = fovX ? e : e / aspect;
279  const T y = fovX ? e / aspect : e;
280  const T w = znear;
281 
282  // Based on: http://dev.theomader.com/depth-precision/
283  // An 'infinite far-plane' projection matrix. There is no concept of a zFar value,
284  // and it can handle everything up to and including homogeneous coordinates with w=0.
285  T perspective[16] = {
286  x, 0, 0, 0,
287  0, y, 0, 0,
288  0, 0, 0, -1,
289  0, 0, w, 0
290  };
291 
292  return matrix4x4(&perspective[0]);
293  }
294 
296  // set a orthographic frustum with 6 params similar to glOrtho()
297  // (left, right, bottom, top, near, far)
298  //
299  // Derived from:
300  // [1] https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixorthorh
301  // [2] https://thxforthefish.com/posts/reverse_z/
302  //
303  // Specifically, the `tz` and `c` terms are based on a right-handed DirectX-style
304  // (Z=0..1) matrix [1], multiplied by the given reversing matrix [2].
305  // If looking at the sources, keep in mind that [1] is presented in row-major order
306  // and [2] is presented in column-major order, and thus multiplication occurs in
307  // column-column fashion.
309  static matrix4x4 OrthoFrustum(T left, T right, T bottom, T top, T znear, T zfar)
310  {
311  assert((znear >= T(-1)) && (zfar > T(0)));
312  T a = T(2) / (right - left);
313  T b = T(2) / (top - bottom);
314  T c = T(1) / (zfar - znear);
315 
316  T tx = (right + left) / (left - right);
317  T ty = (top + bottom) / (bottom - top);
318  T tz = (zfar) / (zfar - znear);
319 
320  T ortho[16] = {
321  a, 0, 0, 0,
322  0, b, 0, 0,
323  0, 0, c, 0,
324  tx, ty, tz, 1
325  };
326  matrix4x4 m(&ortho[0]);
327  return m;
328  }
329 
330  // Optimized form that takes width/height and near/far planes
331  static matrix4x4 OrthoMatrix(T width, T height, T znear, T zfar)
332  {
333  assert((znear >= T(-1)) && (zfar > T(0)));
334  T a = T(2) / width;
335  T b = T(2) / height;
336  T c = T(1) / (zfar - znear);
337 
338  T tz = (zfar) / (zfar - znear);
339 
340  T ortho[16] = {
341  a, 0, 0, 0,
342  0, b, 0, 0,
343  0, 0, c, 0,
344  0, 0, tz, 1
345  };
346  matrix4x4 m(&ortho[0]);
347  return m;
348  }
349 
350  //glRotate equivalent (except radians instead of degrees)
351  void Rotate(T ang, T x, T y, T z)
352  {
353  *this = (*this) * RotateMatrix(ang, x, y, z);
354  }
355  // (x,y,z) must be normalized
356  static matrix4x4 RotateMatrix(T ang, T x, T y, T z)
357  {
358  matrix4x4 m;
359  T c = cos(ang);
360  T s = sin(ang);
361  m[0] = x * x * (1 - c) + c;
362  m[1] = y * x * (1 - c) + z * s;
363  m[2] = x * z * (1 - c) - y * s;
364  m[3] = 0;
365  m[4] = x * y * (1 - c) - z * s;
366  m[5] = y * y * (1 - c) + c;
367  m[6] = y * z * (1 - c) + x * s;
368  m[7] = 0;
369  m[8] = x * z * (1 - c) + y * s;
370  m[9] = y * z * (1 - c) - x * s;
371  m[10] = z * z * (1 - c) + c;
372  m[11] = 0;
373  m[12] = 0;
374  m[13] = 0;
375  m[14] = 0;
376  m[15] = 1;
377  return m;
378  }
379  void RotateZ(T radians) { *this = (*this) * RotateZMatrix(radians); }
380  void RotateY(T radians) { *this = (*this) * RotateYMatrix(radians); }
381  void RotateX(T radians) { *this = (*this) * RotateXMatrix(radians); }
382  static matrix4x4 RotateXMatrix(T radians)
383  {
384  matrix4x4 m;
385  T cos_r = cosf(float(radians));
386  T sin_r = sinf(float(radians));
387  m[0] = 1.0f;
388  m[1] = 0;
389  m[2] = 0;
390  m[3] = 0;
391 
392  m[4] = 0;
393  m[5] = cos_r;
394  m[6] = -sin_r;
395  m[7] = 0;
396 
397  m[8] = 0;
398  m[9] = sin_r;
399  m[10] = cos_r;
400  m[11] = 0;
401 
402  m[12] = 0;
403  m[13] = 0;
404  m[14] = 0;
405  m[15] = 1.0f;
406  return m;
407  }
408  static matrix4x4 RotateYMatrix(T radians)
409  {
410  matrix4x4 m;
411  T cos_r = cosf(float(radians));
412  T sin_r = sinf(float(radians));
413  m[0] = cos_r;
414  m[1] = 0;
415  m[2] = sin_r;
416  m[3] = 0;
417 
418  m[4] = 0;
419  m[5] = 1;
420  m[6] = 0;
421  m[7] = 0;
422 
423  m[8] = -sin_r;
424  m[9] = 0;
425  m[10] = cos_r;
426  m[11] = 0;
427 
428  m[12] = 0;
429  m[13] = 0;
430  m[14] = 0;
431  m[15] = 1.0f;
432  return m;
433  }
434  static matrix4x4 RotateZMatrix(T radians)
435  {
436  matrix4x4 m;
437  T cos_r = cosf(float(radians));
438  T sin_r = sinf(float(radians));
439  m[0] = cos_r;
440  m[1] = -sin_r;
441  m[2] = 0;
442  m[3] = 0;
443 
444  m[4] = sin_r;
445  m[5] = cos_r;
446  m[6] = 0;
447  m[7] = 0;
448 
449  m[8] = 0;
450  m[9] = 0;
451  m[10] = 1.0f;
452  m[11] = 0;
453 
454  m[12] = 0;
455  m[13] = 0;
456  m[14] = 0;
457  m[15] = 1.0f;
458  return m;
459  }
460  void Renormalize()
461  {
462  vector3<T> x(cell[0], cell[4], cell[8]);
463  vector3<T> y(cell[1], cell[5], cell[9]);
464  vector3<T> z(cell[2], cell[6], cell[10]);
465  x = x.Normalized();
466  z = x.Cross(y).Normalized();
467  y = z.Cross(x).Normalized();
468  cell[0] = x.x;
469  cell[4] = x.y;
470  cell[8] = x.z;
471  cell[1] = y.x;
472  cell[5] = y.y;
473  cell[9] = y.z;
474  cell[2] = z.x;
475  cell[6] = z.y;
476  cell[10] = z.z;
477  }
479  {
480  cell[12] = 0;
481  cell[13] = 0;
482  cell[14] = 0;
483  }
484  T &operator[](const size_t i) { return cell[i]; }
485  const T &operator[](const size_t i) const { return cell[i]; }
486  const T *Data() const { return cell; }
487  T *Data() { return cell; }
488  friend matrix4x4 operator+(const matrix4x4 &a, const matrix4x4 &b)
489  {
490  matrix4x4 m;
491  for (int i = 0; i < 16; i++)
492  m.cell[i] = a.cell[i] + b.cell[i];
493  return m;
494  }
495  friend matrix4x4 operator-(const matrix4x4 &a, const matrix4x4 &b)
496  {
497  matrix4x4 m;
498  for (int i = 0; i < 16; i++)
499  m.cell[i] = a.cell[i] - b.cell[i];
500  return m;
501  }
502  friend matrix4x4 operator-(const matrix4x4 &a)
503  {
504  matrix4x4 m;
505  for (int i = 0; i < 16; ++i) {
506  m.cell[i] = -a.cell[i];
507  }
508  return m;
509  }
510  friend matrix4x4 operator*(const matrix4x4 &a, const matrix4x4 &b)
511  {
512  matrix4x4 m;
513  m.cell[0] = a.cell[0] * b.cell[0] + a.cell[4] * b.cell[1] + a.cell[8] * b.cell[2] + a.cell[12] * b.cell[3];
514  m.cell[1] = a.cell[1] * b.cell[0] + a.cell[5] * b.cell[1] + a.cell[9] * b.cell[2] + a.cell[13] * b.cell[3];
515  m.cell[2] = a.cell[2] * b.cell[0] + a.cell[6] * b.cell[1] + a.cell[10] * b.cell[2] + a.cell[14] * b.cell[3];
516  m.cell[3] = a.cell[3] * b.cell[0] + a.cell[7] * b.cell[1] + a.cell[11] * b.cell[2] + a.cell[15] * b.cell[3];
517 
518  m.cell[4] = a.cell[0] * b.cell[4] + a.cell[4] * b.cell[5] + a.cell[8] * b.cell[6] + a.cell[12] * b.cell[7];
519  m.cell[5] = a.cell[1] * b.cell[4] + a.cell[5] * b.cell[5] + a.cell[9] * b.cell[6] + a.cell[13] * b.cell[7];
520  m.cell[6] = a.cell[2] * b.cell[4] + a.cell[6] * b.cell[5] + a.cell[10] * b.cell[6] + a.cell[14] * b.cell[7];
521  m.cell[7] = a.cell[3] * b.cell[4] + a.cell[7] * b.cell[5] + a.cell[11] * b.cell[6] + a.cell[15] * b.cell[7];
522 
523  m.cell[8] = a.cell[0] * b.cell[8] + a.cell[4] * b.cell[9] + a.cell[8] * b.cell[10] + a.cell[12] * b.cell[11];
524  m.cell[9] = a.cell[1] * b.cell[8] + a.cell[5] * b.cell[9] + a.cell[9] * b.cell[10] + a.cell[13] * b.cell[11];
525  m.cell[10] = a.cell[2] * b.cell[8] + a.cell[6] * b.cell[9] + a.cell[10] * b.cell[10] + a.cell[14] * b.cell[11];
526  m.cell[11] = a.cell[3] * b.cell[8] + a.cell[7] * b.cell[9] + a.cell[11] * b.cell[10] + a.cell[15] * b.cell[11];
527 
528  m.cell[12] = a.cell[0] * b.cell[12] + a.cell[4] * b.cell[13] + a.cell[8] * b.cell[14] + a.cell[12] * b.cell[15];
529  m.cell[13] = a.cell[1] * b.cell[12] + a.cell[5] * b.cell[13] + a.cell[9] * b.cell[14] + a.cell[13] * b.cell[15];
530  m.cell[14] = a.cell[2] * b.cell[12] + a.cell[6] * b.cell[13] + a.cell[10] * b.cell[14] + a.cell[14] * b.cell[15];
531  m.cell[15] = a.cell[3] * b.cell[12] + a.cell[7] * b.cell[13] + a.cell[11] * b.cell[14] + a.cell[15] * b.cell[15];
532  return m;
533  }
534  friend vector3<T> operator*(const matrix4x4 &a, const vector3<T> &v)
535  {
536  vector3<T> out;
537  out.x = a.cell[0] * v.x + a.cell[4] * v.y + a.cell[8] * v.z + a.cell[12];
538  out.y = a.cell[1] * v.x + a.cell[5] * v.y + a.cell[9] * v.z + a.cell[13];
539  out.z = a.cell[2] * v.x + a.cell[6] * v.y + a.cell[10] * v.z + a.cell[14];
540  return out;
541  }
542  // scam for doing a transpose operation
543  friend vector3<T> operator*(const vector3<T> &v, const matrix4x4 &a)
544  {
545  vector3<T> out;
546  out.x = a.cell[0] * v.x + a.cell[1] * v.y + a.cell[2] * v.z;
547  out.y = a.cell[4] * v.x + a.cell[5] * v.y + a.cell[6] * v.z;
548  out.z = a.cell[8] * v.x + a.cell[9] * v.y + a.cell[10] * v.z;
549  return out;
550  }
551 
552  // Transform a vector by the affine inverse of a matrix4x4
553  // internally this does a transpose operation, and thus only works on
554  // Euclidean (translation + rotation) matricies.
556  {
557  // Formula derivation from songho (https://songho.ca/opengl):
558  //
559  // M = [ R | T ]
560  // [ --+-- ] (R denotes 3x3 rotation/reflection matrix)
561  // [ 0 | 1 ] (T denotes 1x3 translation matrix)
562  //
563  // y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^T*y - R^T*T
564  // (R is orthogonal, R^-1 = R^T)
565 
566  // thanks to https://stackoverflow.com/a/2625420
567  // "Depending on your situation, it may be faster to compute the result of
568  // inv(A) * x instead of actually forming inv(A)..."
569  //
570  // inv(A) * [x] = [ inv(M) * (x - b) ]
571  // [1] = [ 1 ]
572  //
573 
574  vector3<T> v = inVec - GetTranslate();
575  vector3<T> out;
576  out.x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z;
577  out.y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z;
578  out.z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z;
579  return out;
580  }
581 
582  friend matrix4x4 operator*(const matrix4x4 &a, T v)
583  {
584  matrix4x4 m;
585  for (int i = 0; i < 16; i++)
586  m[i] = a.cell[i] * v;
587  return m;
588  }
589  friend matrix4x4 operator*(T v, const matrix4x4 &a)
590  {
591  return (a * v);
592  }
594  {
595  vector3<T> out;
596  out.x = cell[0] * v.x + cell[4] * v.y + cell[8] * v.z;
597  out.y = cell[1] * v.x + cell[5] * v.y + cell[9] * v.z;
598  out.z = cell[2] * v.x + cell[6] * v.y + cell[10] * v.z;
599  return out;
600  }
601  //gltranslate equivalent
602  void Translate(const vector3<T> &t)
603  {
604  Translate(t.x, t.y, t.z);
605  }
606  void Translate(T x, T y, T z)
607  {
608  matrix4x4 m = Identity();
609  m[12] = x;
610  m[13] = y;
611  m[14] = z;
612  *this = (*this) * m;
613  }
615  {
616  return Translation(v.x, v.y, v.z);
617  }
618  static matrix4x4 Translation(T x, T y, T z)
619  {
620  matrix4x4 m = Identity();
621  m[12] = x;
622  m[13] = y;
623  m[14] = z;
624  return m;
625  }
627  {
628  matrix4x4 m;
629  // this only works for matrices containing only rotation and transform
630  m[0] = cell[0];
631  m[1] = cell[4];
632  m[2] = cell[8];
633  m[4] = cell[1];
634  m[5] = cell[5];
635  m[6] = cell[9];
636  m[8] = cell[2];
637  m[9] = cell[6];
638  m[10] = cell[10];
639  m[12] = -(cell[0] * cell[12] + cell[1] * cell[13] + cell[2] * cell[14]);
640  m[13] = -(cell[4] * cell[12] + cell[5] * cell[13] + cell[6] * cell[14]);
641  m[14] = -(cell[8] * cell[12] + cell[9] * cell[13] + cell[10] * cell[14]);
642  m[3] = m[7] = m[11] = 0;
643  m[15] = 1.0f;
644 
645  return m;
646  }
648  {
649  matrix4x4 m;
650  m[0] = cell[0];
651  m[1] = cell[4];
652  m[2] = cell[8];
653  m[3] = cell[12];
654  m[4] = cell[1];
655  m[5] = cell[5];
656  m[6] = cell[9];
657  m[7] = cell[13];
658  m[8] = cell[2];
659  m[9] = cell[6];
660  m[10] = cell[10];
661  m[11] = cell[14];
662  m[12] = cell[3];
663  m[13] = cell[7];
664  m[14] = cell[11];
665  m[15] = cell[15];
666  return m;
667  }
668  void Print() const
669  {
670  for (int i = 0; i < 4; i++) {
671  printf("%.12f %.12f %.12f %.12f\n", cell[i], cell[i + 4], cell[i + 8], cell[i + 12]);
672  }
673  printf("\n");
674  }
675 
676  //convenience accessors for getting right/up/back vectors
677  //from rotation matrices
679  {
680  return vector3<T>(cell[0], cell[4], cell[8]);
681  }
682 
683  vector3<T> Up() const
684  {
685  return vector3<T>(cell[1], cell[5], cell[9]);
686  }
687 
688  vector3<T> Back() const
689  {
690  return vector3<T>(cell[2], cell[6], cell[10]);
691  }
692 };
693 
696 
697 static const matrix4x4f matrix4x4fIdentity(matrix4x4f::Identity());
698 static const matrix4x4d matrix4x4dIdentity(matrix4x4d::Identity());
699 
700 #endif /* _MATRIX4X4_H */
double val
Definition: PrecalcPath.cpp:40
Definition: matrix3x3.h:13
const T * Data() const
Definition: matrix3x3.h:38
Definition: matrix4x4.h:14
void Translate(const vector3< T > &t)
Definition: matrix4x4.h:602
static matrix4x4 OrthoFrustum(T left, T right, T bottom, T top, T znear, T zfar)
Definition: matrix4x4.h:309
static matrix4x4 Translation(const vector3< T > &v)
Definition: matrix4x4.h:614
static matrix4x4 FrustumMatrix(T left, T right, T bottom, T top, T znear, T zfar)
Definition: matrix4x4.h:207
matrix4x4 Inverse() const
Definition: matrix4x4.h:626
matrix4x4()
Definition: matrix4x4.h:20
static matrix4x4 PerspectiveMatrix(T fovR, T aspect, T znear, T zfar, bool fovX=false)
Definition: matrix4x4.h:241
static matrix4x4 ScaleMatrix(T scale)
Definition: matrix4x4.h:133
const T & operator[](const size_t i) const
Definition: matrix4x4.h:485
T * Data()
Definition: matrix4x4.h:487
friend vector3< T > operator*(const matrix4x4 &a, const vector3< T > &v)
Definition: matrix4x4.h:534
vector3< T > GetTranslate() const
Definition: matrix4x4.h:52
static matrix4x4 RotateXMatrix(T radians)
Definition: matrix4x4.h:382
void SaveTo3x3Matrix(T *r) const
Definition: matrix4x4.h:93
matrix4x4 Transpose() const
Definition: matrix4x4.h:647
vector3< T > Right() const
Definition: matrix4x4.h:678
friend matrix4x4 operator-(const matrix4x4 &a, const matrix4x4 &b)
Definition: matrix4x4.h:495
void Rotate(T ang, T x, T y, T z)
Definition: matrix4x4.h:351
T & operator[](const size_t i)
Definition: matrix4x4.h:484
static matrix4x4 Translation(T x, T y, T z)
Definition: matrix4x4.h:618
vector3< T > InvTransform(const vector3< T > &inVec)
Definition: matrix4x4.h:555
void RotateZ(T radians)
Definition: matrix4x4.h:379
const T * Data() const
Definition: matrix4x4.h:486
void RotateX(T radians)
Definition: matrix4x4.h:381
vector3< T > Up() const
Definition: matrix4x4.h:683
vector3< T > ApplyRotationOnly(const vector3< T > &v) const
Definition: matrix4x4.h:593
matrix4x4(const matrix3x3< T > &m, const vector3< T > &v)
Definition: matrix4x4.h:35
matrix3x3< T > GetOrient() const
Definition: matrix4x4.h:58
void ClearToRotOnly()
Definition: matrix4x4.h:478
void Renormalize()
Definition: matrix4x4.h:460
void Scale(T s)
Definition: matrix4x4.h:116
void RotateY(T radians)
Definition: matrix4x4.h:380
static matrix4x4 InfinitePerspectiveMatrix(T fovR, T aspect, T znear, bool fovX=false)
Definition: matrix4x4.h:273
static matrix4x4 RotateZMatrix(T radians)
Definition: matrix4x4.h:434
friend matrix4x4 operator*(const matrix4x4 &a, T v)
Definition: matrix4x4.h:582
friend matrix4x4 operator+(const matrix4x4 &a, const matrix4x4 &b)
Definition: matrix4x4.h:488
void LoadFrom3x3Matrix(const T *r)
Definition: matrix4x4.h:73
void Translate(T x, T y, T z)
Definition: matrix4x4.h:606
friend vector3< T > operator*(const vector3< T > &v, const matrix4x4 &a)
Definition: matrix4x4.h:543
void SetRotationOnly(const matrix4x4 &m)
Definition: matrix4x4.h:53
static matrix4x4 MakeRotMatrix(const vector3< T > &rx, const vector3< T > &ry, const vector3< T > &rz)
Definition: matrix4x4.h:146
static matrix4x4 RotateMatrix(T ang, T x, T y, T z)
Definition: matrix4x4.h:356
static matrix4x4 ScaleMatrix(T x, T y, T z)
Definition: matrix4x4.h:120
matrix4x4(T val)
Definition: matrix4x4.h:21
void SetTranslate(const vector3< T > &v)
Definition: matrix4x4.h:46
static matrix4x4 Identity()
Definition: matrix4x4.h:105
friend matrix4x4 operator-(const matrix4x4 &a)
Definition: matrix4x4.h:502
static matrix4x4 OrthoMatrix(T width, T height, T znear, T zfar)
Definition: matrix4x4.h:331
static matrix4x4 RotateYMatrix(T radians)
Definition: matrix4x4.h:408
void Print() const
Definition: matrix4x4.h:668
void Scale(T x, T y, T z)
Definition: matrix4x4.h:112
friend matrix4x4 operator*(T v, const matrix4x4 &a)
Definition: matrix4x4.h:589
matrix4x4(const matrix3x3< T > &m)
Definition: matrix4x4.h:31
friend matrix4x4 operator*(const matrix4x4 &a, const matrix4x4 &b)
Definition: matrix4x4.h:510
matrix4x4(const matrix4x4< other_float_t > &m)
Definition: matrix4x4.h:40
matrix4x4(const T *vals)
Definition: matrix4x4.h:27
static matrix4x4 MakeInvRotMatrix(const vector3< T > &rx, const vector3< T > &ry, const vector3< T > &rz)
Definition: matrix4x4.h:167
vector3< T > Back() const
Definition: matrix4x4.h:688
Definition: vector3.h:16
T y
Definition: vector3.h:18
T x
Definition: vector3.h:18
T z
Definition: vector3.h:18
vector3 Normalized() const
Definition: vector3.h:121
vector3 Cross(const vector3 &b) const
Definition: vector3.h:113
matrix4x4< double > matrix4x4d
Definition: matrix4x4.h:695
matrix4x4< float > matrix4x4f
Definition: matrix4x4.h:694
Definition: msvc_bug.cpp:33