All Classes Files Functions Variables Typedefs Pages
MatrixCore.hpp
Go to the documentation of this file.
1 #pragma once
2 
15 #include "VectorCore.hpp"
16 
17 #include <cstddef>
18 #include <cstring>
19 #include <stdexcept>
20 #include <xmmintrin.h>
21 
22 namespace lumina {
23 
24 namespace internal {
25 /*******************************************************************************
26 * Internal Helper: The following is for internal use only!
27 *******************************************************************************/
31 template <typename T>
32 class MatrixHelper {
33  // if a determinant is smaller than this value, it's treated as zero
34  static constexpr float detEpsilon = 1E-10;
35 
36 public:
40  template <std::size_t N>
41  static T det(const T (&m)[N][N]) {
42  throw std::runtime_error("Not implemented!");
43  }
44 
45  // overload for 2x2 matrix
46  static T det(const T (&m)[2][2]) {
47  return m[0][0] * m[1][1] - m[0][1] * m[1][0];
48  }
49 
50  // overload for 3x3 matrix
51  static T det(const T (&m)[3][3]) {
52  return m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0]
53  + m[0][2] * m[1][0] * m[2][1] - m[0][2] * m[1][1] * m[2][0]
54  - m[0][1] * m[1][0] * m[2][2] - m[0][0] * m[1][2] * m[2][1];
55  }
56 
57  // overload for 4x4 matrix
58  static T det(const T (&m)[4][4]) {
59  float s0 = m[0][0] * m[1][1] - m[1][0] * m[0][1];
60  float s1 = m[0][0] * m[1][2] - m[1][0] * m[0][2];
61  float s2 = m[0][0] * m[1][3] - m[1][0] * m[0][3];
62  float s3 = m[0][1] * m[1][2] - m[1][1] * m[0][2];
63  float s4 = m[0][1] * m[1][3] - m[1][1] * m[0][3];
64  float s5 = m[0][2] * m[1][3] - m[1][2] * m[0][3];
65 
66  float c5 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
67  float c4 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
68  float c3 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
69  float c2 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
70  float c1 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
71  float c0 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
72 
73  return (s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0);
74  }
75 
82  template <std::size_t N>
83  static void invert(const T (&m)[N][N], T (&out)[N][N]) {
84  throw std::runtime_error("Not implemented!");
85  }
86 
87  // overload für 2x2 matrix
88  static void invert(const T (&m)[2][2], T (&out)[2][2]) {
89  float det = det(m);
90  if(fabs(det) < detEpsilon) {
91  throw std::runtime_error("Matrix is not invertable: Determinant is "
92  "smaller than epsilon");
93  }
94 
95  float invdet = 1.f / det;
96 
97  out[0][0] = m[1][1] * invdet;
98  out[0][1] = -m[0][1] * invdet;
99  out[1][0] = -m[1][0] * invdet;
100  out[1][1] = m[0][0] * invdet;
101  }
102 
103  // overload for 3x3 matrix
104  static void invert(const T (&m)[3][3], T (&out)[3][3]) {
105  float det = det(m);
106  if(fabs(det) < detEpsilon) {
107  throw std::runtime_error("Matrix is not invertable: Determinant is "
108  "smaller than epsilon");
109  }
110 
111  float invdet = 1.f / det;
112 
113  out[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) * invdet;
114  out[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) * invdet;
115  out[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) * invdet;
116 
117  out[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) * invdet;
118  out[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) * invdet;
119  out[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) * invdet;
120 
121  out[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) * invdet;
122  out[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) * invdet;
123  out[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) * invdet;
124  }
125 
126  // overload for 4x4 matrix
127  static void invert(const T (&m)[4][4], T (&out)[4][4]) {
128  float s0 = m[0][0] * m[1][1] - m[1][0] * m[0][1];
129  float s1 = m[0][0] * m[1][2] - m[1][0] * m[0][2];
130  float s2 = m[0][0] * m[1][3] - m[1][0] * m[0][3];
131  float s3 = m[0][1] * m[1][2] - m[1][1] * m[0][2];
132  float s4 = m[0][1] * m[1][3] - m[1][1] * m[0][3];
133  float s5 = m[0][2] * m[1][3] - m[1][2] * m[0][3];
134 
135  float c5 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
136  float c4 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
137  float c3 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
138  float c2 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
139  float c1 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
140  float c0 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
141 
142  float det = (s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0);
143  if(fabs(det) < detEpsilon) {
144  throw std::runtime_error("Matrix is not invertable: Determinant is "
145  "smaller than epsilon");
146  }
147 
148  float invdet = 1.f / det;
149 
150  out[0][0] = ( m[1][1] * c5 - m[1][2] * c4 + m[1][3] * c3) * invdet;
151  out[0][1] = (-m[0][1] * c5 + m[0][2] * c4 - m[0][3] * c3) * invdet;
152  out[0][2] = ( m[3][1] * s5 - m[3][2] * s4 + m[3][3] * s3) * invdet;
153  out[0][3] = (-m[2][1] * s5 + m[2][2] * s4 - m[2][3] * s3) * invdet;
154 
155  out[1][0] = (-m[1][0] * c5 + m[1][2] * c2 - m[1][3] * c1) * invdet;
156  out[1][1] = ( m[0][0] * c5 - m[0][2] * c2 + m[0][3] * c1) * invdet;
157  out[1][2] = (-m[3][0] * s5 + m[3][2] * s2 - m[3][3] * s1) * invdet;
158  out[1][3] = ( m[2][0] * s5 - m[2][2] * s2 + m[2][3] * s1) * invdet;
159 
160  out[2][0] = ( m[1][0] * c4 - m[1][1] * c2 + m[1][3] * c0) * invdet;
161  out[2][1] = (-m[0][0] * c4 + m[0][1] * c2 - m[0][3] * c0) * invdet;
162  out[2][2] = ( m[3][0] * s4 - m[3][1] * s2 + m[3][3] * s0) * invdet;
163  out[2][3] = (-m[2][0] * s4 + m[2][1] * s2 - m[2][3] * s0) * invdet;
164 
165  out[3][0] = (-m[1][0] * c3 + m[1][1] * c1 - m[1][2] * c0) * invdet;
166  out[3][1] = ( m[0][0] * c3 - m[0][1] * c1 + m[0][2] * c0) * invdet;
167  out[3][2] = (-m[3][0] * s3 + m[3][1] * s1 - m[3][2] * s0) * invdet;
168  out[3][3] = ( m[2][0] * s3 - m[2][1] * s1 + m[2][2] * s0) * invdet;
169  }
170 
174  template <std::size_t R, std::size_t C>
175  static void transpose(const T (&m)[R][C], const T (&out)[C][R]) {
176  for(int i = 0; i< R; ++i) {
177  for(int j = 0; j < C; ++j) {
178  out[j][i] = m[i][j];
179  }
180  }
181  }
182 };
183 
192 template <typename Ta,
193  typename Tb,
194  std::size_t Ra,
195  std::size_t CR,
196  std::size_t Cb>
197 inline void matrixMultiply(const Ta (&lh)[Ra][CR],
198  const Tb (&rh)[CR][Cb],
199  decltype(Ta(0) * Tb(0)) (&out)[Ra][Cb]) {
200  for(int i = 0; i < Ra; ++i) {
201  for(int j = 0; j < Cb; ++j) {
202  out[i][j] = 0;
203  for(int k = 0; k < CR; ++k) {
204  out[i][j] += lh[i][k] * rh[k][j];
205  }
206  }
207  }
208 }
209 
210 // overload for 2x2
211 inline void matrixMultiply(const float (&lh)[2][2],
212  const float (&rh)[2][2],
213  float (&out)[2][2]) {
214  out[0][0] = lh[0][0]*rh[0][0] + lh[0][1]*rh[1][0];
215  out[0][1] = lh[0][0]*rh[0][1] + lh[0][1]*rh[1][1];
216  out[1][0] = lh[1][0]*rh[0][0] + lh[1][1]*rh[1][0];
217  out[1][1] = lh[1][0]*rh[0][1] + lh[1][1]*rh[1][1];
218 }
219 
220 // overload for 3x3
221 inline void matrixMultiply(const float (&lh)[3][3],
222  const float (&rh)[3][3],
223  float (&out)[3][3]) {
224  for(int i = 0; i < 3; ++i) {
225  for(int j = 0; j < 3; ++j) {
226  out[i][j] = lh[i][0] * rh[0][j] + lh[i][1] * rh[1][j] + lh[i][2]
227  * rh[2][j];
228  }
229  }
230 }
231 
232 // overload for 4x4 (uses SSE)
233 inline void matrixMultiply(const float (&lh)[4][4],
234  const float (&rh)[4][4],
235  float (&out)[4][4]) {
236  const __m128 a = _mm_loadu_ps(rh[0]);
237  const __m128 b = _mm_loadu_ps(rh[1]);
238  const __m128 c = _mm_loadu_ps(rh[2]);
239  const __m128 d = _mm_loadu_ps(rh[3]);
240  __m128 t1, t2;
241 
242  t1 = _mm_set_ps1(lh[0][0]);
243  t2 = _mm_mul_ps(a, t1);
244  t1 = _mm_set_ps1(lh[0][1]);
245  t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
246  t1 = _mm_set_ps1(lh[0][2]);
247  t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
248  t1 = _mm_set_ps1(lh[0][3]);
249  t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
250  _mm_storeu_ps(out[0], t2);
251 
252  t1 = _mm_set_ps1(lh[1][0]);
253  t2 = _mm_mul_ps(a, t1);
254  t1 = _mm_set_ps1(lh[1][1]);
255  t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
256  t1 = _mm_set_ps1(lh[1][2]);
257  t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
258  t1 = _mm_set_ps1(lh[1][3]);
259  t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
260  _mm_storeu_ps(out[1], t2);
261 
262  t1 = _mm_set_ps1(lh[2][0]);
263  t2 = _mm_mul_ps(a, t1);
264  t1 = _mm_set_ps1(lh[2][1]);
265  t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
266  t1 = _mm_set_ps1(lh[2][2]);
267  t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
268  t1 = _mm_set_ps1(lh[2][3]);
269  t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
270  _mm_storeu_ps(out[2], t2);
271 
272  t1 = _mm_set_ps1(lh[3][0]);
273  t2 = _mm_mul_ps(a, t1);
274  t1 = _mm_set_ps1(lh[3][1]);
275  t2 = _mm_add_ps(_mm_mul_ps(b, t1), t2);
276  t1 = _mm_set_ps1(lh[3][2]);
277  t2 = _mm_add_ps(_mm_mul_ps(c, t1), t2);
278  t1 = _mm_set_ps1(lh[3][3]);
279  t2 = _mm_add_ps(_mm_mul_ps(d, t1), t2);
280  _mm_storeu_ps(out[3], t2);
281 }
282 
283 
287 template <typename T, std::size_t R, std::size_t C>
288 struct MatrixImpl {
289  // matrix data
290  T data[R][C];
291 
292  using type = T;
293  static constexpr std::size_t numRows = R;
294  static constexpr std::size_t numColumns = C;
295 
296  MatrixImpl() {
297  setToZero();
298  }
299 
300  void setToZero() {
301  memset(data, 0, sizeof(data));
302  }
303 
304  Vector<T, C> getRow(std::size_t index) const {
305  if(index >= R)
306  throw std::out_of_range("Invalid row index");
307  Vector<T, C> out; // TODO: could memcpy for POD types
308  for(int i = 0; i < C; ++i) {
309  out.data[i] = data[index][i];
310  }
311  return out;
312  }
313 
314  Vector<T, R> getColumn(std::size_t index) const {
315  if(index >= C)
316  throw std::out_of_range("Invalid column index");
317  Vector<T, R> out;
318  for(int i = 0; i < R; ++i) {
319  out.data[i] = data[i][index];
320  }
321  return out;
322  }
323 
324  void setRow(std::size_t index, Vector<T, C> vec) {
325  if(index >= R)
326  throw std::out_of_range("Invalid row index");
327  for(int i = 0; i < C; ++i) {
328  data[index][i] = vec.data[i];
329  }
330  }
331 
332  void setColumn(std::size_t index, Vector<T, R> vec) {
333  if(index >= C)
334  throw std::out_of_range("Invalid column index");
335  for(int i = 0; i < R; ++i) {
336  data[i][index] = vec.data[i];
337  }
338  }
339 
340 };
341 
342 } // namespace internal
343 
344 
345 /*******************************************************************************
346 * Definition of Matrix
347 *******************************************************************************/
355 template <typename T, std::size_t R, std::size_t C>
356 struct Matrix : public internal::MatrixImpl<T, R, C> {
357  Matrix<T, C, R> transposed() const {
358  Matrix<T, C, R> out;
359  internal::MatrixHelper<T>::transpose(this->data, out.data);
360  return out;
361  }
362 };
363 
364 // specialization for quadratic matrices
365 template <typename T, std::size_t N>
366 struct Matrix<T, N, N> : public internal::MatrixImpl<T, N, N>{
367 
368  Matrix<T, N, N>& setToIdentity() {
369  for(int i = 0; i < N; ++i) {
370  this->data[i][i] = T(1);
371  }
372  return *this;
373  }
374 
375  Vector<T, N> getDiagonal() const {
376  Vector<T, N> out;
377  for(int i = 0; i < N; ++i) {
378  out.data[i] = this->data[i][i];
379  }
380  return out;
381  }
382 
383  Matrix<T, N, N>& setDiagonal(Vector<T, N> vec) {
384  for(int i = 0; i < N; ++i) {
385  this->data[i][i] = vec.data[i];
386  }
387  return *this;
388  }
389 
390  T determinant() const {
391  return internal::MatrixHelper<T>::det(this->data);
392  }
393 
394  Matrix<T, N, N> inverted() const {
395  Matrix<T, N, N> out;
396  internal::MatrixHelper<T>::invert(this->data, out.data);
397  return out;
398  }
399 
400  Matrix<T, N, N> transposed() const {
401  Matrix<T, N, N> out;
402  internal::MatrixHelper<T>::transpose(this->data, out.data);
403  return out;
404  }
405 };
406 
407 
408 
409 /*******************************************************************************
410 * Definition of non member functions for Matrix
411 *******************************************************************************/
412 /***** unary operators ********************************************************/
413 template <typename T, std::size_t R, std::size_t C>
414 Matrix<T, R, C> operator+(const Matrix<T, R, C>& m) {
415  return m;
416 }
417 
418 template <typename T, std::size_t R, std::size_t C>
419 Matrix<T, R, C> operator-(const Matrix<T, R, C>& m) {
420  // Matrix<T, R, C> out;
421  // for(int i = 0; i < R; ++i) {
422  // for(int j = 0; j < C; ++j) {
423  // out.data[i][j] = -m.data[i][j];
424  // }
425  // }
426  Matrix<T, R, C> out;
427  out -= m;
428  return out;
429 }
430 
431 
432 /***** assignment operators ***************************************************/
433 // matrix += matrix
434 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
435 Matrix<Ta, R, C>& operator+=(Matrix<Ta, R, C>& lh,
436  const Matrix<Tb, R, C>& rh) {
437  for(int i = 0; i < R; ++i) {
438  for(int j = 0; j < C; ++j) {
439  lh.data[i][j] += rh.data[i][j];
440  }
441  }
442  return lh;
443 }
444 
445 // matrix -= matrix
446 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
447 Matrix<Ta, R, C>& operator-=(Matrix<Ta, R, C>& lh,
448  const Matrix<Tb, R, C>& rh) {
449  for(int i = 0; i < R; ++i) {
450  for(int j = 0; j < C; ++j) {
451  lh.data[i][j] -= rh.data[i][j];
452  }
453  }
454  return lh;
455 }
456 
457 // matrix *= matrix
458 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
459 Matrix<Ta, R, C>& operator*=(Matrix<Ta, R, C>& lh,
460  const Matrix<Tb, R, C>& rh) {
461  internal::matrixMultiply(lh.data, rh.data, lh.data);
462  return lh;
463 }
464 
465 // matrix *= scalar
466 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
467 Matrix<Ta, R, C>& operator*=(Matrix<Ta, R, C>& lh, Tb rh) {
468  for(int i = 0; i < R; ++i) {
469  for(int j = 0; j < C; ++j) {
470  lh.data[i][j] *= rh;
471  }
472  }
473  return lh;
474 }
475 
476 // matrix /= scalar
477 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
478 Matrix<Ta, R, C>& operator/=(Matrix<Ta, R, C>& lh, Tb rh) {
479  for(int i = 0; i < R; ++i) {
480  for(int j = 0; j < C; ++j) {
481  lh.data[i][j] /= rh;
482  }
483  }
484  return lh;
485 }
486 
487 
488 /***** arithmetic operators ***************************************************/
489 // matrix * scalar
490 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
491 auto operator*(const Matrix<Ta, R, C>& lh, Tb rh)
492  -> Matrix<decltype(Ta(0) * Tb(0)), R, C> {
493  Matrix<decltype(Ta(0) * Tb(0)), R, C> out(lh);
494  out *= rh;
495  return out;
496 }
497 
498 // scalar * matrix
499 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
500 auto operator*(Tb lh, const Matrix<Ta, R, C>& rh)
501  -> Matrix<decltype(Ta(0) * Tb(0)), R, C> {
502  Matrix<decltype(Ta(0) * Tb(0)), R, C> out(rh);
503  out *= lh;
504  return out;
505 }
506 
507 // matrix / scalar
508 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
509 auto operator/(const Matrix<Ta, R, C>& lh, Tb rh)
510  -> Matrix<decltype(Ta(0) / Tb(0)), R, C> {
511  Matrix<decltype(Ta(0) / Tb(0)), R, C> out(lh);
512  out /= rh;
513  return out;
514 }
515 
516 // matrix + matrix
517 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
518 auto operator+(const Matrix<Ta, R, C>& lh, const Matrix<Tb, R, C>& rh)
519  -> Matrix<decltype(Ta(0) + Tb(0)), R, C> {
520  Matrix<decltype(Ta(0) + Tb(0)), R, C> out(lh);
521  out += rh;
522  return out;
523 }
524 
525 // matrix - matrix
526 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
527 auto operator-(const Matrix<Ta, R, C>& lh, const Matrix<Tb, R, C>& rh)
528  -> Matrix<decltype(Ta(0) - Tb(0)), R, C> {
529  Matrix<decltype(Ta(0) - Tb(0)), R, C> out(lh);
530  out -= rh;
531  return out;
532 }
533 
534 // matrix * matrix
535 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
536 auto operator*(const Matrix<Ta, R, C>& lh, const Matrix<Tb, R, C>& rh)
537  -> Matrix<decltype(Ta(0) * Tb(0)), R, C> {
538  Matrix<decltype(Ta(0) * Tb(0)), R, C> out(lh);
539  internal::matrixMultiply(lh.data, rh.data, out.data);
540  return out;
541 }
542 
543 // matrix * vector
544 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
545 auto operator*(const Matrix<Ta, R, C>& lh, Vector<Tb, C> rh)
546  -> Vector<decltype(Ta(0) + Tb(0)), R> {
547  Vector<decltype(Ta(0) + Tb(0)), R> out;
548  internal::matrixMultiply(lh.data,
549  reinterpret_cast<Tb(&)[C][1]>(rh.data),
550  reinterpret_cast<Tb(&)[C][1]>(out.data));
551  return out;
552 }
553 
554 // vector * matrix
555 template <typename Ta, typename Tb, std::size_t R, std::size_t C>
556 auto operator*(Vector<Tb, R> lh, const Matrix<Ta, R, C>& rh)
557  -> Vector<decltype(Ta(0) + Tb(0)), C> {
558  Vector<decltype(Ta(0) + Tb(0)), C> out;
559  internal::matrixMultiply(reinterpret_cast<Tb(&)[1][R]>(lh.data),
560  rh.data,
561  reinterpret_cast<Tb(&)[1][C]>(out.data));
562  return out;
563 }
564 
565 
566 
567 /*******************************************************************************
568 * Definition of matrix_cast
569 *******************************************************************************/
570 template <typename Tdst, typename Tsrc>
571 Tdst matrix_cast(const Tsrc& in) {
572  Tdst out; // init to 0
573 
574  // copy avaiable data
575  for(int i = 0; i < Tdst::numRows && i < Tsrc::numRows; ++i) {
576  for(int j = 0; j < Tdst::numColumns && j < Tsrc::numColumns; ++j) {
577  out.data[i][j] = static_cast<typename Tdst::type>(in.data[i][j]);
578  }
579  }
580 
581  // fill diagonal
582  for(int i = lxMin(Tsrc::numRows, Tsrc::numColumns);
583  i < lxMin(Tdst::numRows, Tdst::numColumns);
584  ++i) {
585  out.data[i][i] = typename Tdst::type(1);
586  }
587  return out;
588 }
589 
590 
591 /*******************************************************************************
592 * Typedefs for common types
593 *******************************************************************************/
594 template <typename T, std::size_t N>
595 using MatQ = Matrix<T, N, N>;
596 
597 template <std::size_t N>
598 using MatQf = MatQ<float, N>;
599 template <std::size_t N>
600 using MatQi = MatQ<int, N>;
601 
602 using Mat2f = MatQ<float, 2>;
603 using Mat2i = MatQ<int, 2>;
604 
605 using Mat3f = MatQ<float, 3>;
606 using Mat3i = MatQ<int, 3>;
607 
608 using Mat4f = MatQ<float, 4>;
609 using Mat4i = MatQ<int, 4>;
610 
611 using Mat2x3f = Matrix<float, 2, 3>;
612 using Mat2x4f = Matrix<float, 2, 4>;
613 using Mat3x2f = Matrix<float, 3, 2>;
614 using Mat3x4f = Matrix<float, 3, 4>;
615 using Mat4x2f = Matrix<float, 4, 2>;
616 using Mat4x3f = Matrix<float, 4, 3>;
617 
618 using Mat2x3i = Matrix<int, 2, 3>;
619 using Mat2x4i = Matrix<int, 2, 4>;
620 using Mat3x2i = Matrix<int, 3, 2>;
621 using Mat3x4i = Matrix<int, 3, 4>;
622 using Mat4x2i = Matrix<int, 4, 2>;
623 using Mat4x3i = Matrix<int, 4, 3>;
624 
625 
626 
627 } // namespace lumina
Represents a vector with arbitrary dimension and type of elements.
Definition: VectorCore.hpp:138
Helper struct for various algorithms.
Definition: MatrixCore.hpp:32
This file will define Vector and various vector functions.
Helper class for common Matrix stuff.
Definition: MatrixCore.hpp:288
static void invert(const T(&m)[N][N], T(&out)[N][N])
calculates the inverted matrix and writes it to out
Definition: MatrixCore.hpp:83
Definition: MatrixCore.hpp:366
static T det(const T(&m)[N][N])
calculates the determinant of the matrix
Definition: MatrixCore.hpp:41
static void transpose(const T(&m)[R][C], const T(&out)[C][R])
Transposes the matrix m and writes result into out.
Definition: MatrixCore.hpp:175
Represents a RxC matrix with elements of type T.
Definition: MatrixCore.hpp:356