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