Leviathan  0.8.0.0
Leviathan game engine
Matrix.h
Go to the documentation of this file.
1 // Leviathan Game Engine
2 // Copyright (c) 2012-2020 Henri Hyyryläinen
3 #pragma once
4 #include "Define.h"
5 // ------------------------------------ //
6 #include "Quaternion.h"
7 #include "Types.h"
8 
9 #include "bsfUtility/Math/BsMatrix4.h"
10 
11 namespace Leviathan {
12 
13 
14 // This file contains a lot of code from bs::framework with modifications, see License.txt for
15 // details. Original copyright notice:
16 //************************************ bs::framework - Copyright 2018 Marko Pintera
17 //**************************************//
18 //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not
19 // to be removed. ***********//
20 
23 enum class EulerAngleOrder { XYZ, XZY, YXZ, YZX, ZXY, ZYX };
24 
25 Matrix3 operator*(float lhs, const Matrix3& rhs);
26 
28 struct Matrix3 {
29  friend Matrix3 operator*(float lhs, const Matrix3& rhs);
30 
32  int a, b, c;
33  float sign;
34  };
35 
36 public:
37  Matrix3() = default;
38  constexpr Matrix3(const Matrix3&) = default;
39  constexpr Matrix3& operator=(const Matrix3&) = default;
40 
41  constexpr Matrix3(float m00, float m01, float m02, float m10, float m11, float m12,
42  float m20, float m21, float m22) :
43  m{{m00, m01, m02}, {m10, m11, m12}, {m20, m21, m22}}
44  {}
45 
47  explicit Matrix3(const Quaternion& rotation)
48  {
49  FromQuaternion(rotation);
50  }
51 
53  explicit Matrix3(const Quaternion& rotation, const Float3& scale)
54  {
55  FromQuaternion(rotation);
56 
57  for(int row = 0; row < 3; row++) {
58  for(int col = 0; col < 3; col++)
59  m[row][col] = scale[row] * m[row][col];
60  }
61  }
62 
64  explicit Matrix3(const Float3& axis, const Radian& angle)
65  {
66  FromAxisAngle(axis, angle);
67  }
68 
70  explicit Matrix3(const Float3& xaxis, const Float3& yaxis, const Float3& zaxis)
71  {
72  FromAxes(xaxis, yaxis, zaxis);
73  }
74 
80  explicit Matrix3(const Radian& xAngle, const Radian& yAngle, const Radian& zAngle)
81  {
82  FromEulerAngles(xAngle, yAngle, zAngle);
83  }
84 
90  explicit Matrix3(const Radian& xAngle, const Radian& yAngle, const Radian& zAngle,
91  EulerAngleOrder order)
92  {
93  FromEulerAngles(xAngle, yAngle, zAngle, order);
94  }
95 
97  void swap(Matrix3& other)
98  {
99  std::swap(m[0][0], other.m[0][0]);
100  std::swap(m[0][1], other.m[0][1]);
101  std::swap(m[0][2], other.m[0][2]);
102  std::swap(m[1][0], other.m[1][0]);
103  std::swap(m[1][1], other.m[1][1]);
104  std::swap(m[1][2], other.m[1][2]);
105  std::swap(m[2][0], other.m[2][0]);
106  std::swap(m[2][1], other.m[2][1]);
107  std::swap(m[2][2], other.m[2][2]);
108  }
109 
111  float* operator[](uint32_t row) const
112  {
113  // assert(row < 3);
114 
115  return (float*)m[row];
116  }
117 
118  inline Float3 GetColumn(uint32_t col) const
119  {
120  LEVIATHAN_ASSERT(col < 3, "col out of range");
121 
122  return Float3(m[0][col], m[1][col], m[2][col]);
123  }
124 
125  inline void SetColumn(uint32_t col, const Float3& vec)
126  {
127  LEVIATHAN_ASSERT(col < 3, "col out of range");
128 
129  m[0][col] = vec.X;
130  m[1][col] = vec.Y;
131  m[2][col] = vec.Z;
132  }
133 
134  inline bool operator!=(const Matrix3& rhs) const
135  {
136  return !operator==(rhs);
137  }
138 
139  inline bool operator==(const Matrix3& rhs) const
140  {
141  for(uint32_t row = 0; row < 3; row++) {
142  for(uint32_t col = 0; col < 3; col++) {
143  if(m[row][col] != rhs.m[row][col])
144  return false;
145  }
146  }
147 
148  return true;
149  }
150 
151  inline Matrix3 operator+(const Matrix3& rhs) const
152  {
153  Matrix3 sum;
154  for(uint32_t row = 0; row < 3; row++) {
155  for(uint32_t col = 0; col < 3; col++) {
156  sum.m[row][col] = m[row][col] + rhs.m[row][col];
157  }
158  }
159 
160  return sum;
161  }
162 
163  inline Matrix3 operator-(const Matrix3& rhs) const
164  {
165  Matrix3 diff;
166  for(uint32_t row = 0; row < 3; row++) {
167  for(uint32_t col = 0; col < 3; col++) {
168  diff.m[row][col] = m[row][col] - rhs.m[row][col];
169  }
170  }
171 
172  return diff;
173  }
174 
175  inline Matrix3 operator*(const Matrix3& rhs) const
176  {
177  Matrix3 prod;
178  for(uint32_t row = 0; row < 3; row++) {
179  for(uint32_t col = 0; col < 3; col++) {
180  prod.m[row][col] = m[row][0] * rhs.m[0][col] + m[row][1] * rhs.m[1][col] +
181  m[row][2] * rhs.m[2][col];
182  }
183  }
184 
185  return prod;
186  }
187 
188  inline Matrix3 operator-() const
189  {
190  Matrix3 neg;
191  for(uint32_t row = 0; row < 3; row++) {
192  for(uint32_t col = 0; col < 3; col++)
193  neg[row][col] = -m[row][col];
194  }
195 
196  return neg;
197  }
198 
199  inline Matrix3 operator*(float rhs) const
200  {
201  Matrix3 prod;
202  for(uint32_t row = 0; row < 3; row++) {
203  for(uint32_t col = 0; col < 3; col++)
204  prod[row][col] = rhs * m[row][col];
205  }
206 
207  return prod;
208  }
209 
211  DLLEXPORT Float3 Multiply(const Float3& vec) const;
212 
214  DLLEXPORT Matrix3 Transpose() const;
215 
224  DLLEXPORT bool Inverse(Matrix3& mat, float fTolerance = 1e-06f) const;
225 
234  DLLEXPORT Matrix3 Inverse(float fTolerance = 1e-06f) const;
235 
237  DLLEXPORT float Determinant() const;
238 
247  DLLEXPORT void Decomposition(Quaternion& rotation, Float3& scale) const;
248 
262  Matrix3& matL, Float3& matS, Matrix3& matR) const;
263 
274  DLLEXPORT void QDUDecomposition(Matrix3& matQ, Float3& vecD, Float3& vecU) const;
275 
277  DLLEXPORT void Orthonormalize();
278 
284  DLLEXPORT void ToAxisAngle(Float3& axis, Radian& angle) const;
285 
287  DLLEXPORT void FromAxisAngle(const Float3& axis, const Radian& angle);
288 
294  DLLEXPORT void ToQuaternion(Quaternion& quat) const;
295 
297  DLLEXPORT void FromQuaternion(const Quaternion& quat);
298 
300  DLLEXPORT void FromAxes(const Float3& xAxis, const Float3& yAxis, const Float3& zAxis);
301 
312  DLLEXPORT bool ToEulerAngles(Radian& xAngle, Radian& yAngle, Radian& zAngle) const;
313 
327  const Radian& xAngle, const Radian& yAngle, const Radian& zAngle);
328 
340  DLLEXPORT void FromEulerAngles(const Radian& xAngle, const Radian& yAngle,
341  const Radian& zAngle, EulerAngleOrder order);
342 
351  DLLEXPORT void EigenSolveSymmetric(float eigenValues[3], Float3 eigenVectors[3]) const;
352 
354 
355 protected:
356  friend struct Matrix4;
357 
358  // Support for eigensolver
359  void tridiagonal(float diag[3], float subDiag[3]);
360  bool QLAlgorithm(float diag[3], float subDiag[3]);
361 
362  // Support for singular value decomposition
363  static constexpr const float SVD_EPSILON = 1e-04f;
364 
365  static constexpr const unsigned int SVD_MAX_ITERS = 32;
366  static void bidiagonalize(Matrix3& matA, Matrix3& matL, Matrix3& matR);
367  static void golubKahanStep(Matrix3& matA, Matrix3& matL, Matrix3& matR);
368 
369 public:
370  float m[3][3];
371 
372 
373  // static constexpr const float EPSILON = 1e-06f;
374  DLLEXPORT static const Matrix3 IDENTITY;
375  DLLEXPORT static const Matrix3 ZERO;
376 };
377 
379 struct Matrix4 {
380 public:
381  inline Matrix4() = default;
382  constexpr inline Matrix4(const Matrix4& other) = default;
383 
384  inline Matrix4(const Float3& translation, const Quaternion& rotation, const Float3& scale)
385  {
386  SetTRS(translation, rotation, scale);
387  }
388 
389  constexpr Matrix4(float m00, float m01, float m02, float m03, float m10, float m11,
390  float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31,
391  float m32, float m33) :
392  m{{m00, m01, m02, m03}, {m10, m11, m12, m13}, {m20, m21, m22, m23},
393  {m30, m31, m32, m33}}
394  {}
395 
398  constexpr explicit Matrix4(const Matrix3& mat3) :
399  m{{mat3.m[0][0], mat3.m[0][1], mat3.m[0][2], 0.0f},
400  {mat3.m[1][0], mat3.m[1][1], mat3.m[1][2], 0.0f},
401  {mat3.m[2][0], mat3.m[2][1], mat3.m[2][2], 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}
402  {}
403 
405  void swap(Matrix4& other)
406  {
407  std::swap(m[0][0], other.m[0][0]);
408  std::swap(m[0][1], other.m[0][1]);
409  std::swap(m[0][2], other.m[0][2]);
410  std::swap(m[0][3], other.m[0][3]);
411  std::swap(m[1][0], other.m[1][0]);
412  std::swap(m[1][1], other.m[1][1]);
413  std::swap(m[1][2], other.m[1][2]);
414  std::swap(m[1][3], other.m[1][3]);
415  std::swap(m[2][0], other.m[2][0]);
416  std::swap(m[2][1], other.m[2][1]);
417  std::swap(m[2][2], other.m[2][2]);
418  std::swap(m[2][3], other.m[2][3]);
419  std::swap(m[3][0], other.m[3][0]);
420  std::swap(m[3][1], other.m[3][1]);
421  std::swap(m[3][2], other.m[3][2]);
422  std::swap(m[3][3], other.m[3][3]);
423  }
424 
425  constexpr Matrix4& operator=(const Matrix4&) = default;
426 
429  {
430  assert(row < 4);
431 
432  return *reinterpret_cast<Float4*>(m[row]);
433  }
434 
436  const Float4& operator[](uint32_t row) const
437  {
438  assert(row < 4);
439 
440  return *reinterpret_cast<const Float4*>(m[row]);
441  }
442 
443  Matrix4 operator*(const Matrix4& rhs) const
444  {
445  Matrix4 r;
446 
447  r.m[0][0] = m[0][0] * rhs.m[0][0] + m[0][1] * rhs.m[1][0] + m[0][2] * rhs.m[2][0] +
448  m[0][3] * rhs.m[3][0];
449  r.m[0][1] = m[0][0] * rhs.m[0][1] + m[0][1] * rhs.m[1][1] + m[0][2] * rhs.m[2][1] +
450  m[0][3] * rhs.m[3][1];
451  r.m[0][2] = m[0][0] * rhs.m[0][2] + m[0][1] * rhs.m[1][2] + m[0][2] * rhs.m[2][2] +
452  m[0][3] * rhs.m[3][2];
453  r.m[0][3] = m[0][0] * rhs.m[0][3] + m[0][1] * rhs.m[1][3] + m[0][2] * rhs.m[2][3] +
454  m[0][3] * rhs.m[3][3];
455 
456  r.m[1][0] = m[1][0] * rhs.m[0][0] + m[1][1] * rhs.m[1][0] + m[1][2] * rhs.m[2][0] +
457  m[1][3] * rhs.m[3][0];
458  r.m[1][1] = m[1][0] * rhs.m[0][1] + m[1][1] * rhs.m[1][1] + m[1][2] * rhs.m[2][1] +
459  m[1][3] * rhs.m[3][1];
460  r.m[1][2] = m[1][0] * rhs.m[0][2] + m[1][1] * rhs.m[1][2] + m[1][2] * rhs.m[2][2] +
461  m[1][3] * rhs.m[3][2];
462  r.m[1][3] = m[1][0] * rhs.m[0][3] + m[1][1] * rhs.m[1][3] + m[1][2] * rhs.m[2][3] +
463  m[1][3] * rhs.m[3][3];
464 
465  r.m[2][0] = m[2][0] * rhs.m[0][0] + m[2][1] * rhs.m[1][0] + m[2][2] * rhs.m[2][0] +
466  m[2][3] * rhs.m[3][0];
467  r.m[2][1] = m[2][0] * rhs.m[0][1] + m[2][1] * rhs.m[1][1] + m[2][2] * rhs.m[2][1] +
468  m[2][3] * rhs.m[3][1];
469  r.m[2][2] = m[2][0] * rhs.m[0][2] + m[2][1] * rhs.m[1][2] + m[2][2] * rhs.m[2][2] +
470  m[2][3] * rhs.m[3][2];
471  r.m[2][3] = m[2][0] * rhs.m[0][3] + m[2][1] * rhs.m[1][3] + m[2][2] * rhs.m[2][3] +
472  m[2][3] * rhs.m[3][3];
473 
474  r.m[3][0] = m[3][0] * rhs.m[0][0] + m[3][1] * rhs.m[1][0] + m[3][2] * rhs.m[2][0] +
475  m[3][3] * rhs.m[3][0];
476  r.m[3][1] = m[3][0] * rhs.m[0][1] + m[3][1] * rhs.m[1][1] + m[3][2] * rhs.m[2][1] +
477  m[3][3] * rhs.m[3][1];
478  r.m[3][2] = m[3][0] * rhs.m[0][2] + m[3][1] * rhs.m[1][2] + m[3][2] * rhs.m[2][2] +
479  m[3][3] * rhs.m[3][2];
480  r.m[3][3] = m[3][0] * rhs.m[0][3] + m[3][1] * rhs.m[1][3] + m[3][2] * rhs.m[2][3] +
481  m[3][3] * rhs.m[3][3];
482 
483  return r;
484  }
485 
486  Matrix4 operator+(const Matrix4& rhs) const
487  {
488  Matrix4 r;
489 
490  r.m[0][0] = m[0][0] + rhs.m[0][0];
491  r.m[0][1] = m[0][1] + rhs.m[0][1];
492  r.m[0][2] = m[0][2] + rhs.m[0][2];
493  r.m[0][3] = m[0][3] + rhs.m[0][3];
494 
495  r.m[1][0] = m[1][0] + rhs.m[1][0];
496  r.m[1][1] = m[1][1] + rhs.m[1][1];
497  r.m[1][2] = m[1][2] + rhs.m[1][2];
498  r.m[1][3] = m[1][3] + rhs.m[1][3];
499 
500  r.m[2][0] = m[2][0] + rhs.m[2][0];
501  r.m[2][1] = m[2][1] + rhs.m[2][1];
502  r.m[2][2] = m[2][2] + rhs.m[2][2];
503  r.m[2][3] = m[2][3] + rhs.m[2][3];
504 
505  r.m[3][0] = m[3][0] + rhs.m[3][0];
506  r.m[3][1] = m[3][1] + rhs.m[3][1];
507  r.m[3][2] = m[3][2] + rhs.m[3][2];
508  r.m[3][3] = m[3][3] + rhs.m[3][3];
509 
510  return r;
511  }
512 
513  Matrix4 operator-(const Matrix4& rhs) const
514  {
515  Matrix4 r;
516  r.m[0][0] = m[0][0] - rhs.m[0][0];
517  r.m[0][1] = m[0][1] - rhs.m[0][1];
518  r.m[0][2] = m[0][2] - rhs.m[0][2];
519  r.m[0][3] = m[0][3] - rhs.m[0][3];
520 
521  r.m[1][0] = m[1][0] - rhs.m[1][0];
522  r.m[1][1] = m[1][1] - rhs.m[1][1];
523  r.m[1][2] = m[1][2] - rhs.m[1][2];
524  r.m[1][3] = m[1][3] - rhs.m[1][3];
525 
526  r.m[2][0] = m[2][0] - rhs.m[2][0];
527  r.m[2][1] = m[2][1] - rhs.m[2][1];
528  r.m[2][2] = m[2][2] - rhs.m[2][2];
529  r.m[2][3] = m[2][3] - rhs.m[2][3];
530 
531  r.m[3][0] = m[3][0] - rhs.m[3][0];
532  r.m[3][1] = m[3][1] - rhs.m[3][1];
533  r.m[3][2] = m[3][2] - rhs.m[3][2];
534  r.m[3][3] = m[3][3] - rhs.m[3][3];
535 
536  return r;
537  }
538 
539  inline bool operator==(const Matrix4& rhs) const
540  {
541  if(m[0][0] != rhs.m[0][0] || m[0][1] != rhs.m[0][1] || m[0][2] != rhs.m[0][2] ||
542  m[0][3] != rhs.m[0][3] || m[1][0] != rhs.m[1][0] || m[1][1] != rhs.m[1][1] ||
543  m[1][2] != rhs.m[1][2] || m[1][3] != rhs.m[1][3] || m[2][0] != rhs.m[2][0] ||
544  m[2][1] != rhs.m[2][1] || m[2][2] != rhs.m[2][2] || m[2][3] != rhs.m[2][3] ||
545  m[3][0] != rhs.m[3][0] || m[3][1] != rhs.m[3][1] || m[3][2] != rhs.m[3][2] ||
546  m[3][3] != rhs.m[3][3]) {
547  return false;
548  }
549 
550  return true;
551  }
552 
553  inline bool operator!=(const Matrix4& rhs) const
554  {
555  return !operator==(rhs);
556  }
557 
558  Matrix4 operator*(float rhs) const
559  {
560  return Matrix4(rhs * m[0][0], rhs * m[0][1], rhs * m[0][2], rhs * m[0][3],
561  rhs * m[1][0], rhs * m[1][1], rhs * m[1][2], rhs * m[1][3], rhs * m[2][0],
562  rhs * m[2][1], rhs * m[2][2], rhs * m[2][3], rhs * m[3][0], rhs * m[3][1],
563  rhs * m[3][2], rhs * m[3][3]);
564  }
565 
566  operator bs::Matrix4() const
567  {
568  bs::Matrix4 result;
569 
570  result.setColumn(0, GetColumn4D(0));
571  result.setColumn(1, GetColumn4D(1));
572  result.setColumn(2, GetColumn4D(2));
573  result.setColumn(3, GetColumn4D(3));
574  return result;
575  }
576 
579  {
580  return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1],
581  m[0][2], m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);
582  }
583 
586  {
587  assert(col < 4);
588 
589  return Float3(m[0][col], m[1][col], m[2][col]);
590  }
591 
594  {
595  assert(col < 4);
596 
597  return Float4(m[0][col], m[1][col], m[2][col], m[3][col]);
598  }
599 
601  void SetColumn(uint32_t idx, const Float4& column)
602  {
603  m[0][idx] = column.X;
604  m[1][idx] = column.Y;
605  m[2][idx] = column.Z;
606  m[3][idx] = column.W;
607  }
608 
610  void SetRow(uint32_t idx, const Float4& column)
611  {
612  m[idx][0] = column.X;
613  m[idx][1] = column.Y;
614  m[idx][2] = column.Z;
615  m[idx][3] = column.W;
616  }
617 
619  Matrix3 get3x3() const
620  {
621  Matrix3 m3x3;
622  m3x3.m[0][0] = m[0][0];
623  m3x3.m[0][1] = m[0][1];
624  m3x3.m[0][2] = m[0][2];
625  m3x3.m[1][0] = m[1][0];
626  m3x3.m[1][1] = m[1][1];
627  m3x3.m[1][2] = m[1][2];
628  m3x3.m[2][0] = m[2][0];
629  m3x3.m[2][1] = m[2][1];
630  m3x3.m[2][2] = m[2][2];
631 
632  return m3x3;
633  }
634 
636  DLLEXPORT Matrix4 Adjoint() const;
637 
639  DLLEXPORT float Determinant() const;
640 
642  DLLEXPORT float Determinant3x3() const;
643 
645  DLLEXPORT Matrix4 Inverse() const;
646 
652  DLLEXPORT void SetTRS(
653  const Float3& translation, const Quaternion& rotation, const Float3& scale);
654 
661  const Float3& translation, const Quaternion& rotation, const Float3& scale);
662 
674  DLLEXPORT void Decomposition(Float3& position, Quaternion& rotation, Float3& scale) const;
675 
677  inline Float3 GetTranslation() const
678  {
679  return Float3(m[0][3], m[1][3], m[2][3]);
680  }
681 
688  inline bool IsAffine() const
689  {
690  return m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0 && m[3][3] == 1;
691  }
692 
699 
705  Matrix4 ConcatenateAffine(const Matrix4& other) const
706  {
707  return Matrix4(
708  m[0][0] * other.m[0][0] + m[0][1] * other.m[1][0] + m[0][2] * other.m[2][0],
709  m[0][0] * other.m[0][1] + m[0][1] * other.m[1][1] + m[0][2] * other.m[2][1],
710  m[0][0] * other.m[0][2] + m[0][1] * other.m[1][2] + m[0][2] * other.m[2][2],
711  m[0][0] * other.m[0][3] + m[0][1] * other.m[1][3] + m[0][2] * other.m[2][3] +
712  m[0][3],
713 
714  m[1][0] * other.m[0][0] + m[1][1] * other.m[1][0] + m[1][2] * other.m[2][0],
715  m[1][0] * other.m[0][1] + m[1][1] * other.m[1][1] + m[1][2] * other.m[2][1],
716  m[1][0] * other.m[0][2] + m[1][1] * other.m[1][2] + m[1][2] * other.m[2][2],
717  m[1][0] * other.m[0][3] + m[1][1] * other.m[1][3] + m[1][2] * other.m[2][3] +
718  m[1][3],
719 
720  m[2][0] * other.m[0][0] + m[2][1] * other.m[1][0] + m[2][2] * other.m[2][0],
721  m[2][0] * other.m[0][1] + m[2][1] * other.m[1][1] + m[2][2] * other.m[2][1],
722  m[2][0] * other.m[0][2] + m[2][1] * other.m[1][2] + m[2][2] * other.m[2][2],
723  m[2][0] * other.m[0][3] + m[2][1] * other.m[1][3] + m[2][2] * other.m[2][3] +
724  m[2][3],
725 
726  0, 0, 0, 1);
727  }
728 
729  // /**
730  // * Transform a plane by this matrix.
731  // *
732  // * @note Matrix must be affine.
733  // */
734  // Plane multiplyAffine(const Plane& p) const
735  // {
736  // Float4 localNormal(p.normal.x, p.normal.y, p.normal.z, 0.0f);
737  // Float4 localPoint = localNormal * p.d;
738  // localPoint.w = 1.0f;
739 
740  // Matrix4 itMat = inverse().transpose();
741  // Float4 worldNormal = itMat.multiplyAffine(localNormal);
742  // Float4 worldPoint = multiplyAffine(localPoint);
743 
744  // float d = worldNormal.dot(worldPoint);
745 
746  // return Plane(worldNormal.x, worldNormal.y, worldNormal.z, d);
747  // }
748 
754  inline Float3 MultiplyAffine(const Float3& v) const
755  {
756  return Float3(m[0][0] * v.X + m[0][1] * v.Y + m[0][2] * v.Z + m[0][3],
757  m[1][0] * v.X + m[1][1] * v.Y + m[1][2] * v.Z + m[1][3],
758  m[2][0] * v.X + m[2][1] * v.Y + m[2][2] * v.Z + m[2][3]);
759  }
760 
766  inline Float4 MultiplyAffine(const Float4& v) const
767  {
768  return Float4(m[0][0] * v.X + m[0][1] * v.Y + m[0][2] * v.Z + m[0][3] * v.W,
769  m[1][0] * v.X + m[1][1] * v.Y + m[1][2] * v.Z + m[1][3] * v.W,
770  m[2][0] * v.X + m[2][1] * v.Y + m[2][2] * v.Z + m[2][3] * v.W, v.W);
771  }
772 
774  inline Float3 MultiplyDirection(const Float3& v) const
775  {
776  return Float3(m[0][0] * v.X + m[0][1] * v.Y + m[0][2] * v.Z,
777  m[1][0] * v.X + m[1][1] * v.Y + m[1][2] * v.Z,
778  m[2][0] * v.X + m[2][1] * v.Y + m[2][2] * v.Z);
779  }
780 
791  inline Float3 Multiply(const Float3& v) const
792  {
793  Float3 r;
794 
795  float fInvW = 1.0f / (m[3][0] * v.X + m[3][1] * v.Y + m[3][2] * v.Z + m[3][3]);
796 
797  r.X = (m[0][0] * v.X + m[0][1] * v.Y + m[0][2] * v.Z + m[0][3]) * fInvW;
798  r.Y = (m[1][0] * v.X + m[1][1] * v.Y + m[1][2] * v.Z + m[1][3]) * fInvW;
799  r.Z = (m[2][0] * v.X + m[2][1] * v.Y + m[2][2] * v.Z + m[2][3]) * fInvW;
800 
801  return r;
802  }
803 
810  inline Float4 Multiply(const Float4& v) const
811  {
812  return Float4(m[0][0] * v.X + m[0][1] * v.Y + m[0][2] * v.Z + m[0][3] * v.W,
813  m[1][0] * v.X + m[1][1] * v.Y + m[1][2] * v.Z + m[1][3] * v.W,
814  m[2][0] * v.X + m[2][1] * v.Y + m[2][2] * v.Z + m[2][3] * v.W,
815  m[3][0] * v.X + m[3][1] * v.Y + m[3][2] * v.Z + m[3][3] * v.W);
816  }
817 
819  DLLEXPORT void MakeView(const Float3& position, const Quaternion& orientation);
820 
829  float left, float right, float top, float bottom, float near, float far);
830 
842  const Degree& horzFOV, float aspect, float near, float far, bool positiveZ = false);
843 
846  float left, float right, float top, float bottom, float near, float far);
847 
849  DLLEXPORT static Matrix4 View(const Float3& position, const Quaternion& orientation);
850 
856  DLLEXPORT static Matrix4 FromTRS(
857  const Float3& translation, const Quaternion& rotation, const Float3& scale);
858 
865  const Float3& translation, const Quaternion& rotation, const Float3& scale);
866 
867 
869 
870 public:
871  float m[4][4];
872 
873  DLLEXPORT static const Matrix4 IDENTITY;
874  DLLEXPORT static const Matrix4 ZERO;
875 };
876 
877 } // namespace Leviathan
878 
879 #ifdef LEAK_INTO_GLOBAL
880 using Leviathan::Matrix3;
881 using Leviathan::Matrix4;
882 #endif
EulerAngleOrder
Definition: Matrix.h:23
DLLEXPORT Matrix4 InverseAffine() const
Definition: Matrix.cpp:955
DLLEXPORT void SetTRS(const Float3 &translation, const Quaternion &rotation, const Float3 &scale)
Definition: Matrix.cpp:997
static DLLEXPORT const Matrix4 ZERO
Definition: Matrix.h:874
void swap(Matrix3 &other)
Definition: Matrix.h:97
bool operator==(const Matrix3 &rhs) const
Definition: Matrix.h:139
static constexpr const float SVD_EPSILON
Definition: Matrix.h:363
float m[4][4]
Definition: Matrix.h:871
DLLEXPORT Matrix3 Transpose() const
Definition: Matrix.cpp:35
static DLLEXPORT Matrix4 FromInverseTRS(const Float3 &translation, const Quaternion &rotation, const Float3 &scale)
Definition: Matrix.cpp:1224
Matrix3(const Quaternion &rotation)
Definition: Matrix.h:47
void SetColumn(uint32_t idx, const Float4 &column)
Definition: Matrix.h:601
friend Matrix3 operator*(float lhs, const Matrix3 &rhs)
bool IsAffine() const
Definition: Matrix.h:688
A 3x3 rotation and scale matrix.
Definition: Matrix.h:28
static void golubKahanStep(Matrix3 &matA, Matrix3 &matL, Matrix3 &matR)
Definition: Matrix.cpp:193
DLLEXPORT float Determinant() const
Definition: Matrix.cpp:79
Matrix3 operator*(float lhs, const Matrix3 &rhs)
Definition: Matrix.cpp:837
bool operator!=(const Matrix4 &rhs) const
Definition: Matrix.h:553
const Float4 & operator[](uint32_t row) const
Definition: Matrix.h:436
Float3 GetColumn(uint32_t col) const
Definition: Matrix.h:118
DLLEXPORT float Determinant() const
Definition: Matrix.cpp:878
Matrix3 operator+(const Matrix3 &rhs) const
Definition: Matrix.h:151
void tridiagonal(float diag[3], float subDiag[3])
Definition: Matrix.cpp:684
Matrix4 ConcatenateAffine(const Matrix4 &other) const
Definition: Matrix.h:705
Matrix4(const Float3 &translation, const Quaternion &rotation, const Float3 &scale)
Definition: Matrix.h:384
Matrix4 Transpose() const
Definition: Matrix.h:578
void SetColumn(uint32_t col, const Float3 &vec)
Definition: Matrix.h:125
static constexpr const unsigned int SVD_MAX_ITERS
Definition: Matrix.h:365
DLLEXPORT Matrix4 Adjoint() const
Definition: Matrix.cpp:863
Float3 Multiply(const Float3 &v) const
Definition: Matrix.h:791
Matrix4 operator*(const Matrix4 &rhs) const
Definition: Matrix.h:443
Float3 MultiplyDirection(const Float3 &v) const
Definition: Matrix.h:774
float * operator[](uint32_t row) const
Definition: Matrix.h:111
Matrix3(const Float3 &axis, const Radian &angle)
Definition: Matrix.h:64
static DLLEXPORT const Matrix3 ZERO
Definition: Matrix.h:375
static DLLEXPORT Matrix4 ProjectionPerspective(const Degree &horzFOV, float aspect, float near, float far, bool positiveZ=false)
Definition: Matrix.cpp:1139
Float3 GetTranslation() const
Definition: Matrix.h:677
void swap(Value &a, Value &b)
Definition: json.h:1359
static DLLEXPORT const Matrix3 IDENTITY
Definition: Matrix.h:374
DLLEXPORT void FromQuaternion(const Quaternion &quat)
Definition: Matrix.cpp:600
Represents an angle in radians.
Definition: Types.h:129
constexpr Matrix4(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
Definition: Matrix.h:389
DLLEXPORT Float3 Multiply(const Float3 &vec) const
Definition: Matrix.cpp:25
Matrix3 operator-() const
Definition: Matrix.h:188
DLLEXPORT void EigenSolveSymmetric(float eigenValues[3], Float3 eigenVectors[3]) const
Definition: Matrix.cpp:814
Float3 GetColumn(uint32_t col) const
Definition: Matrix.h:585
DLLEXPORT void FromAxes(const Float3 &xAxis, const Float3 &yAxis, const Float3 &zAxis)
Definition: Matrix.cpp:18
bool operator==(const Matrix4 &rhs) const
Definition: Matrix.h:539
Float4 GetColumn4D(uint32_t col) const
Definition: Matrix.h:593
Matrix3(const Float3 &xaxis, const Float3 &yaxis, const Float3 &zaxis)
Definition: Matrix.h:70
DLLEXPORT void SingularValueDecomposition(Matrix3 &matL, Float3 &matS, Matrix3 &matR) const
Definition: Matrix.cpp:292
Float4 Multiply(const Float4 &v) const
Definition: Matrix.h:810
constexpr Matrix4(const Matrix3 &mat3)
Definition: Matrix.h:398
DLLEXPORT void QDUDecomposition(Matrix3 &matQ, Float3 &vecD, Float3 &vecU) const
Definition: Matrix.cpp:445
DLLEXPORT void ToAxisAngle(Float3 &axis, Radian &angle) const
Definition: Matrix.cpp:513
float m[3][3]
Definition: Matrix.h:370
constexpr Matrix3 & operator=(const Matrix3 &)=default
Represents an angle in degrees.
Definition: Types.h:174
Matrix4 operator-(const Matrix4 &rhs) const
Definition: Matrix.h:513
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:100
static void bidiagonalize(Matrix3 &matA, Matrix3 &matL, Matrix3 &matR)
Definition: Matrix.cpp:90
static DLLEXPORT Matrix4 View(const Float3 &position, const Quaternion &orientation)
Definition: Matrix.cpp:1207
DLLEXPORT bool Inverse(Matrix3 &mat, float fTolerance=1e-06f) const
Definition: Matrix.cpp:46
Matrix4 operator+(const Matrix4 &rhs) const
Definition: Matrix.h:486
Float4 MultiplyAffine(const Float4 &v) const
Definition: Matrix.h:766
constexpr Matrix3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
Definition: Matrix.h:41
Matrix3 operator*(const Matrix3 &rhs) const
Definition: Matrix.h:175
DLLEXPORT void MakeProjectionOrtho(float left, float right, float top, float bottom, float near, float far)
Definition: Matrix.cpp:1100
A Quaternion type to make quaternion specific operations easier to access.
Definition: Quaternion.h:14
DLLEXPORT void Decomposition(Quaternion &rotation, Float3 &scale) const
Definition: Matrix.cpp:436
Matrix3(const Radian &xAngle, const Radian &yAngle, const Radian &zAngle)
Definition: Matrix.h:80
static DLLEXPORT Matrix4 ProjectionOrthographic(float left, float right, float top, float bottom, float near, float far)
Definition: Matrix.cpp:1198
bool operator!=(const Matrix3 &rhs) const
Definition: Matrix.h:134
Matrix3 operator*(float rhs) const
Definition: Matrix.h:199
DLLEXPORT void ToQuaternion(Quaternion &quat) const
Definition: Matrix.cpp:595
#define DLLEXPORT
Definition: Include.h:84
bool QLAlgorithm(float diag[3], float subDiag[3])
Definition: Matrix.cpp:739
DLLEXPORT void FromEulerAngles(const Radian &xAngle, const Radian &yAngle, const Radian &zAngle)
Definition: Matrix.cpp:633
DLLEXPORT void SetInverseTRS(const Float3 &translation, const Quaternion &rotation, const Float3 &scale)
Definition: Matrix.cpp:1023
DLLEXPORT bool ToEulerAngles(Radian &xAngle, Radian &yAngle, Radian &zAngle) const
Definition: Matrix.cpp:605
constexpr Matrix4 & operator=(const Matrix4 &)=default
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
Matrix3 operator-(const Matrix3 &rhs) const
Definition: Matrix.h:163
unsigned int uint32_t
Definition: core.h:40
void swap(Matrix4 &other)
Definition: Matrix.h:405
void SetRow(uint32_t idx, const Float4 &column)
Definition: Matrix.h:610
Matrix4 operator*(float rhs) const
Definition: Matrix.h:558
DLLEXPORT void FromAxisAngle(const Float3 &axis, const Radian &angle)
Definition: Matrix.cpp:569
DLLEXPORT void MakeView(const Float3 &position, const Quaternion &orientation)
Definition: Matrix.cpp:1074
static DLLEXPORT Matrix4 FromTRS(const Float3 &translation, const Quaternion &rotation, const Float3 &scale)
Definition: Matrix.cpp:1215
DLLEXPORT void Decomposition(Float3 &position, Quaternion &rotation, Float3 &scale) const
Definition: Matrix.cpp:1061
DLLEXPORT float Determinant3x3() const
Definition: Matrix.cpp:885
DLLEXPORT void Orthonormalize()
Definition: Matrix.cpp:398
Float3 MultiplyAffine(const Float3 &v) const
Definition: Matrix.h:754
Matrix3 get3x3() const
Definition: Matrix.h:619
DLLEXPORT Matrix4 Inverse() const
Definition: Matrix.cpp:896
A 4x4 matrix type.
Definition: Matrix.h:379
static DLLEXPORT const Matrix4 IDENTITY
Definition: Matrix.h:873
Matrix3(const Quaternion &rotation, const Float3 &scale)
Definition: Matrix.h:53
Float4 & operator[](uint32_t row)
Definition: Matrix.h:428
Matrix3(const Radian &xAngle, const Radian &yAngle, const Radian &zAngle, EulerAngleOrder order)
Definition: Matrix.h:90