Atoms Crowd  7.0.0
ImathMatrix.h
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 //
7 // 2x2, 3x3, and 4x4 transformation matrix templates
8 //
9 
10 #ifndef INCLUDED_ATOMSMATHMATRIX_H
11 #define INCLUDED_ATOMSMATHMATRIX_H
12 
13 #include <AtomsMath/ImathFun.h>
14 #include <AtomsMath/ImathNamespace.h>
15 #include <AtomsMath/ImathPlatform.h>
16 #include <AtomsMath/ImathShear.h>
17 #include <AtomsMath/ImathVec.h>
18 
19 #include <cstring>
20 #include <iomanip>
21 #include <iostream>
22 #include <limits>
23 #include <string.h>
24 
25 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
26 // suppress exception specification warnings
27 # pragma warning(disable : 4290)
28 #endif
29 
30 ATOMSMATH_INTERNAL_NAMESPACE_HEADER_ENTER
31 
34 enum Uninitialized
35 {
36  UNINITIALIZED
37 };
38 
42 
43 template <class T> class Matrix22
44 {
45  public:
46 
49 
51  T x[2][2];
52 
54 
56  ATOMSMATH_HOSTDEVICE T* operator[] (int i) noexcept;
57 
59  ATOMSMATH_HOSTDEVICE const T* operator[] (int i) const noexcept;
60 
63 
65  //ATOMSMATH_HOSTDEVICE Matrix22 (Uninitialized) noexcept {}
66 
71  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22() noexcept;
72 
77  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22 (T a) noexcept;
78 
83  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22 (const T a[2][2]) noexcept;
84 
89  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22 (T a, T b, T c, T d) noexcept;
90 
92  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22 (const Matrix22& v) noexcept;
93 
95  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 explicit Matrix22 (const Matrix22<S>& v) noexcept;
96 
98  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator= (const Matrix22& v) noexcept;
99 
101  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator= (T a) noexcept;
102 
104  ~Matrix22() noexcept = default;
105 
107 
110 
112  ATOMSMATH_HOSTDEVICE T* getValue() noexcept;
113 
115  ATOMSMATH_HOSTDEVICE const T* getValue() const noexcept;
116 
118  template <class S> ATOMSMATH_HOSTDEVICE void getValue (Matrix22<S>& v) const noexcept;
119 
121  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22& setValue (const Matrix22<S>& v) noexcept;
122 
124  template <class S>
125  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22& setTheMatrix (const Matrix22<S>& v) noexcept;
126 
128 
131 
133  ATOMSMATH_HOSTDEVICE constexpr bool operator== (const Matrix22& v) const noexcept;
134 
136  ATOMSMATH_HOSTDEVICE constexpr bool operator!= (const Matrix22& v) const noexcept;
137 
143  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix22<T>& v, T e) const noexcept;
144 
150  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithRelError (const Matrix22<T>& v, T e) const noexcept;
151 
153  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator+= (const Matrix22& v) noexcept;
154 
156  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator+= (T a) noexcept;
157 
159  ATOMSMATH_HOSTDEVICE constexpr Matrix22 operator+ (const Matrix22& v) const noexcept;
160 
162  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator-= (const Matrix22& v) noexcept;
163 
165  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator-= (T a) noexcept;
166 
168  ATOMSMATH_HOSTDEVICE constexpr Matrix22 operator- (const Matrix22& v) const noexcept;
169 
171  ATOMSMATH_HOSTDEVICE constexpr Matrix22 operator-() const noexcept;
172 
174  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& negate() noexcept;
175 
177  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator*= (T a) noexcept;
178 
180  ATOMSMATH_HOSTDEVICE constexpr Matrix22 operator* (T a) const noexcept;
181 
183  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator/= (T a) noexcept;
184 
186  ATOMSMATH_HOSTDEVICE constexpr Matrix22 operator/ (T a) const noexcept;
187 
189  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& operator*= (const Matrix22& v) noexcept;
190 
192  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22 operator* (const Matrix22& v) const noexcept;
193 
197  template <class S> ATOMSMATH_HOSTDEVICE void multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const noexcept;
198 
200 
203 
205  ATOMSMATH_HOSTDEVICE void makeIdentity() noexcept;
206 
208  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& transpose() noexcept;
209 
211  ATOMSMATH_HOSTDEVICE constexpr Matrix22 transposed() const noexcept;
212 
216  ATOMSMATH_CONSTEXPR14 const Matrix22& invert (bool singExc);
217 
220  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& invert() noexcept;
221 
224  ATOMSMATH_CONSTEXPR14 Matrix22<T> inverse (bool singExc) const;
225 
227  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22<T> inverse() const noexcept;
228 
230  ATOMSMATH_HOSTDEVICE constexpr T determinant() const noexcept;
231 
234  template <class S> ATOMSMATH_HOSTDEVICE const Matrix22& setRotation (S r) noexcept;
235 
238  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& rotate (S r) noexcept;
239 
242  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& setScale (T s) noexcept;
243 
246  template <class S>
247  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& setScale (const Vec2<S>& s) noexcept;
248 
249  // Scale the matrix by s
251  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22& scale (const Vec2<S>& s) noexcept;
252 
254 
257 
259  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeLowest() noexcept { return std::numeric_limits<T>::lowest(); }
260 
262  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return std::numeric_limits<T>::max(); }
263 
265  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return std::numeric_limits<T>::min(); }
266 
268  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return std::numeric_limits<T>::epsilon(); }
269 
271 
273  ATOMSMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 2; }
274 
277  typedef T BaseType;
278 
281 
282  private:
283  template <typename R, typename S> struct isSameType
284  {
285  enum
286  {
287  value = 0
288  };
289  };
290 
291  template <typename R> struct isSameType<R, R>
292  {
293  enum
294  {
295  value = 1
296  };
297  };
298 };
299 
303 
304 template <class T> class Matrix33
305 {
306  public:
307 
310 
312  T x[3][3];
313 
315 
317  ATOMSMATH_HOSTDEVICE T* operator[] (int i) noexcept;
318 
320  ATOMSMATH_HOSTDEVICE const T* operator[] (int i) const noexcept;
321 
324 
326  //ATOMSMATH_HOSTDEVICE Matrix33 (Uninitialized) noexcept {}
327 
332  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33() noexcept;
333 
338  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33 (T a) noexcept;
339 
344  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33 (const T a[3][3]) noexcept;
345 
350  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i) noexcept;
351 
353  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33 (const Matrix33& v) noexcept;
354 
356  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 explicit Matrix33 (const Matrix33<S>& v) noexcept;
357 
359  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator= (const Matrix33& v) noexcept;
360 
362  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator= (T a) noexcept;
363 
365  ~Matrix33() noexcept = default;
366 
368 
371 
373  ATOMSMATH_HOSTDEVICE T* getValue() noexcept;
374 
376  ATOMSMATH_HOSTDEVICE const T* getValue() const noexcept;
377 
379  template <class S> ATOMSMATH_HOSTDEVICE void getValue (Matrix33<S>& v) const noexcept;
380 
382  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33& setValue (const Matrix33<S>& v) noexcept;
383 
385  template <class S>
386  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33& setTheMatrix (const Matrix33<S>& v) noexcept;
387 
389 
392 
394  ATOMSMATH_HOSTDEVICE constexpr bool operator== (const Matrix33& v) const noexcept;
395 
397  ATOMSMATH_HOSTDEVICE constexpr bool operator!= (const Matrix33& v) const noexcept;
398 
404  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix33<T>& v, T e) const noexcept;
405 
411  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithRelError (const Matrix33<T>& v, T e) const noexcept;
412 
414  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator+= (const Matrix33& v) noexcept;
415 
417  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator+= (T a) noexcept;
418 
420  ATOMSMATH_HOSTDEVICE constexpr Matrix33 operator+ (const Matrix33& v) const noexcept;
421 
423  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator-= (const Matrix33& v) noexcept;
424 
426  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator-= (T a) noexcept;
427 
429  ATOMSMATH_HOSTDEVICE constexpr Matrix33 operator- (const Matrix33& v) const noexcept;
430 
432  ATOMSMATH_HOSTDEVICE constexpr Matrix33 operator-() const noexcept;
433 
435  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& negate() noexcept;
436 
438  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator*= (T a) noexcept;
439 
441  ATOMSMATH_HOSTDEVICE constexpr Matrix33 operator* (T a) const noexcept;
442 
444  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator/= (T a) noexcept;
445 
447  ATOMSMATH_HOSTDEVICE constexpr Matrix33 operator/ (T a) const noexcept;
448 
450  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& operator*= (const Matrix33& v) noexcept;
451 
453  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33 operator* (const Matrix33& v) const noexcept;
454 
460  template <class S> ATOMSMATH_HOSTDEVICE void multVecMatrix (const Vec2<S>& src, Vec2<S>& dst) const noexcept;
461 
466  template <class S> ATOMSMATH_HOSTDEVICE void multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const noexcept;
467 
469 
472 
474  ATOMSMATH_HOSTDEVICE void makeIdentity() noexcept;
475 
477  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& transpose() noexcept;
478 
480  ATOMSMATH_HOSTDEVICE constexpr Matrix33 transposed() const noexcept;
481 
485  ATOMSMATH_CONSTEXPR14 const Matrix33& invert (bool singExc);
486 
489  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& invert() noexcept;
490 
493  ATOMSMATH_CONSTEXPR14 Matrix33<T> inverse (bool singExc) const;
494 
496  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33<T> inverse() const noexcept;
497 
502  const Matrix33& gjInvert (bool singExc);
503 
507  ATOMSMATH_HOSTDEVICE const Matrix33& gjInvert() noexcept;
508 
511  Matrix33<T> gjInverse (bool singExc) const;
512 
515  ATOMSMATH_HOSTDEVICE Matrix33<T> gjInverse() const noexcept;
516 
518  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 T minorOf (const int r, const int c) const noexcept;
519 
521  ATOMSMATH_HOSTDEVICE
522  constexpr T fastMinor (const int r0, const int r1, const int c0, const int c1) const noexcept;
523 
525  ATOMSMATH_HOSTDEVICE constexpr T determinant() const noexcept;
526 
529  template <class S> ATOMSMATH_HOSTDEVICE const Matrix33& setRotation (S r) noexcept;
530 
531  // Rotate the given matrix by r (in radians)
533  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& rotate (S r) noexcept;
534 
537  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& setScale (T s) noexcept;
538 
541  template <class S>
542  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& setScale (const Vec2<S>& s) noexcept;
543 
546  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& scale (const Vec2<S>& s) noexcept;
547 
550  template <class S>
551  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& setTranslation (const Vec2<S>& t) noexcept;
552 
554  ATOMSMATH_HOSTDEVICE constexpr Vec2<T> translation() const noexcept;
555 
558  template <class S>
559  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& translate (const Vec2<S>& t) noexcept;
560 
563  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& setShear (const S& h) noexcept;
564 
568  template <class S>
569  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& setShear (const Vec2<S>& h) noexcept;
570 
573  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& shear (const S& xy) noexcept;
574 
578  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33& shear (const Vec2<S>& h) noexcept;
579 
581 
584 
586  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeLowest() noexcept { return std::numeric_limits<T>::lowest(); }
587 
589  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return std::numeric_limits<T>::max(); }
590 
592  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return std::numeric_limits<T>::min(); }
593 
595  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return std::numeric_limits<T>::epsilon(); }
596 
598 
600  ATOMSMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 3; }
601 
603  typedef T BaseType;
604 
607 
608  private:
609  template <typename R, typename S> struct isSameType
610  {
611  enum
612  {
613  value = 0
614  };
615  };
616 
617  template <typename R> struct isSameType<R, R>
618  {
619  enum
620  {
621  value = 1
622  };
623  };
624 };
625 
629 
630 template <class T> class Matrix44
631 {
632  public:
633 
636 
638  T x[4][4];
639 
641 
643  ATOMSMATH_HOSTDEVICE T* operator[] (int i) noexcept;
644 
646  ATOMSMATH_HOSTDEVICE const T* operator[] (int i) const noexcept;
647 
650 
652  //ATOMSMATH_HOSTDEVICE constexpr Matrix44 (Uninitialized) noexcept {}
653 
659  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44() noexcept;
660 
666  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44 (T a) noexcept;
667 
673  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44 (const T a[4][4]) noexcept;
674 
680  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14
681  Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p) noexcept;
682 
683 
689  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44 (Matrix33<T> r, Vec3<T> t) noexcept;
690 
692  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44 (const Matrix44& v) noexcept;
693 
695  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 explicit Matrix44 (const Matrix44<S>& v) noexcept;
696 
698  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator= (const Matrix44& v) noexcept;
699 
701  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator= (T a) noexcept;
702 
704  ~Matrix44() noexcept = default;
705 
707 
710 
712  ATOMSMATH_HOSTDEVICE T* getValue() noexcept;
713 
715  ATOMSMATH_HOSTDEVICE const T* getValue() const noexcept;
716 
718  template <class S> ATOMSMATH_HOSTDEVICE void getValue (Matrix44<S>& v) const noexcept;
719 
721  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44& setValue (const Matrix44<S>& v) noexcept;
722 
724  template <class S>
725  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44& setTheMatrix (const Matrix44<S>& v) noexcept;
726 
728 
731 
733  ATOMSMATH_HOSTDEVICE constexpr bool operator== (const Matrix44& v) const noexcept;
734 
736  ATOMSMATH_HOSTDEVICE constexpr bool operator!= (const Matrix44& v) const noexcept;
737 
743  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix44<T>& v, T e) const noexcept;
744 
750  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithRelError (const Matrix44<T>& v, T e) const noexcept;
751 
753  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator+= (const Matrix44& v) noexcept;
754 
756  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator+= (T a) noexcept;
757 
759  ATOMSMATH_HOSTDEVICE constexpr Matrix44 operator+ (const Matrix44& v) const noexcept;
760 
762  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator-= (const Matrix44& v) noexcept;
763 
765  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator-= (T a) noexcept;
766 
768  ATOMSMATH_HOSTDEVICE constexpr Matrix44 operator- (const Matrix44& v) const noexcept;
769 
771  ATOMSMATH_HOSTDEVICE constexpr Matrix44 operator-() const noexcept;
772 
774  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& negate() noexcept;
775 
777  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator*= (T a) noexcept;
778 
780  ATOMSMATH_HOSTDEVICE constexpr Matrix44 operator* (T a) const noexcept;
781 
783  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator/= (T a) noexcept;
784 
786  ATOMSMATH_HOSTDEVICE constexpr Matrix44 operator/ (T a) const noexcept;
787 
789  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& operator*= (const Matrix44& v) noexcept;
790 
792  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44 operator* (const Matrix44& v) const noexcept;
793 
795  ATOMSMATH_HOSTDEVICE
796  static void multiply (const Matrix44& a, // assumes that
797  const Matrix44& b, // &a != &c and
798  Matrix44& c) noexcept; // &b != &c.
799 
805  template <class S> ATOMSMATH_HOSTDEVICE void multVecMatrix (const Vec3<S>& src, Vec3<S>& dst) const noexcept;
806 
811  template <class S> ATOMSMATH_HOSTDEVICE void multDirMatrix (const Vec3<S>& src, Vec3<S>& dst) const noexcept;
812 
814 
817 
819  ATOMSMATH_HOSTDEVICE void makeIdentity() noexcept;
820 
822  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& transpose() noexcept;
823 
825  ATOMSMATH_HOSTDEVICE constexpr Matrix44 transposed() const noexcept;
826 
830  ATOMSMATH_CONSTEXPR14 const Matrix44& invert (bool singExc);
831 
834  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& invert() noexcept;
835 
838  ATOMSMATH_CONSTEXPR14 Matrix44<T> inverse (bool singExc) const;
839 
841  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44<T> inverse() const noexcept;
842 
847  ATOMSMATH_CONSTEXPR14 const Matrix44& gjInvert (bool singExc);
848 
852  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& gjInvert() noexcept;
853 
856  Matrix44<T> gjInverse (bool singExc) const;
857 
860  ATOMSMATH_HOSTDEVICE Matrix44<T> gjInverse() const noexcept;
861 
863  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 T minorOf (const int r, const int c) const noexcept;
864 
866  ATOMSMATH_HOSTDEVICE
867  constexpr T fastMinor (const int r0,
868  const int r1,
869  const int r2,
870  const int c0,
871  const int c1,
872  const int c2) const noexcept;
873 
875  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 T determinant() const noexcept;
876 
879  template <class S> ATOMSMATH_HOSTDEVICE const Matrix44& setEulerAngles (const Vec3<S>& r) noexcept;
880 
883  template <class S>
884  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& setAxisAngle (const Vec3<S>& ax, S ang) noexcept;
885 
888  template <class S> ATOMSMATH_HOSTDEVICE const Matrix44& rotate (const Vec3<S>& r) noexcept;
889 
892  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& setScale (T s) noexcept;
893 
896  template <class S>
897  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& setScale (const Vec3<S>& s) noexcept;
898 
901  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& scale (const Vec3<S>& s) noexcept;
902 
905  template <class S>
906  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& setTranslation (const Vec3<S>& t) noexcept;
907 
909  ATOMSMATH_HOSTDEVICE constexpr const Vec3<T> translation() const noexcept;
910 
913  template <class S>
914  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& translate (const Vec3<S>& t) noexcept;
915 
921  template <class S>
922  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& setShear (const Vec3<S>& h) noexcept;
923 
932  template <class S>
933  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& setShear (const Shear6<S>& h) noexcept;
934 
941  template <class S> ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& shear (const Vec3<S>& h) noexcept;
942 
952  template <class S>
953  ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44& shear (const Shear6<S>& h) noexcept;
954 
956 
959 
961  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeLowest() noexcept { return std::numeric_limits<T>::lowest(); }
962 
964  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeMax() noexcept { return std::numeric_limits<T>::max(); }
965 
967  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeSmallest() noexcept { return std::numeric_limits<T>::min(); }
968 
970  ATOMSMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() noexcept { return std::numeric_limits<T>::epsilon(); }
971 
973 
975  ATOMSMATH_HOSTDEVICE constexpr static unsigned int dimensions() noexcept { return 4; }
976 
978  typedef T BaseType;
979 
982 
983  private:
984  template <typename R, typename S> struct isSameType
985  {
986  enum
987  {
988  value = 0
989  };
990  };
991 
992  template <typename R> struct isSameType<R, R>
993  {
994  enum
995  {
996  value = 1
997  };
998  };
999 };
1000 
1002 template <class T> std::ostream& operator<< (std::ostream& s, const Matrix22<T>& m);
1003 
1005 template <class T> std::ostream& operator<< (std::ostream& s, const Matrix33<T>& m);
1006 
1008 template <class T> std::ostream& operator<< (std::ostream& s, const Matrix44<T>& m);
1009 
1010 //---------------------------------------------
1011 // Vector-times-matrix multiplication operators
1012 //---------------------------------------------
1013 
1015 template <class S, class T>
1016 ATOMSMATH_HOSTDEVICE inline const Vec2<S>& operator*= (Vec2<S>& v, const Matrix22<T>& m) noexcept;
1017 
1019 template <class S, class T>
1020 ATOMSMATH_HOSTDEVICE inline Vec2<S> operator* (const Vec2<S>& v, const Matrix22<T>& m) noexcept;
1021 
1023 template <class S, class T>
1024 ATOMSMATH_HOSTDEVICE inline const Vec2<S>& operator*= (Vec2<S>& v, const Matrix33<T>& m) noexcept;
1025 
1027 template <class S, class T>
1028 ATOMSMATH_HOSTDEVICE inline Vec2<S> operator* (const Vec2<S>& v, const Matrix33<T>& m) noexcept;
1029 
1031 template <class S, class T>
1032 ATOMSMATH_HOSTDEVICE inline const Vec3<S>& operator*= (Vec3<S>& v, const Matrix33<T>& m) noexcept;
1033 
1035 template <class S, class T>
1036 ATOMSMATH_HOSTDEVICE inline Vec3<S> operator* (const Vec3<S>& v, const Matrix33<T>& m) noexcept;
1037 
1039 template <class S, class T>
1040 ATOMSMATH_HOSTDEVICE inline const Vec3<S>& operator*= (Vec3<S>& v, const Matrix44<T>& m) noexcept;
1041 
1043 template <class S, class T>
1044 ATOMSMATH_HOSTDEVICE inline Vec3<S> operator* (const Vec3<S>& v, const Matrix44<T>& m) noexcept;
1045 
1047 template <class S, class T>
1048 ATOMSMATH_HOSTDEVICE inline const Vec4<S>& operator*= (Vec4<S>& v, const Matrix44<T>& m) noexcept;
1049 
1051 template <class S, class T>
1052 ATOMSMATH_HOSTDEVICE inline Vec4<S> operator* (const Vec4<S>& v, const Matrix44<T>& m) noexcept;
1053 
1054 //-------------------------
1055 // Typedefs for convenience
1056 //-------------------------
1057 
1059 typedef Matrix22<float> M22f;
1060 
1062 typedef Matrix22<double> M22d;
1063 
1065 typedef Matrix33<float> M33f;
1066 
1068 typedef Matrix33<double> M33d;
1069 
1071 typedef Matrix44<float> M44f;
1072 
1074 typedef Matrix44<double> M44d;
1075 
1076 //---------------------------
1077 // Implementation of Matrix22
1078 //---------------------------
1079 
1080 template <class T>
1081 inline T*
1083 {
1084  return x[i];
1085 }
1086 
1087 template <class T>
1088 inline const T*
1089 Matrix22<T>::operator[] (int i) const noexcept
1090 {
1091  return x[i];
1092 }
1093 
1094 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22() noexcept
1095 {
1096  x[0][0] = 1;
1097  x[0][1] = 0;
1098  x[1][0] = 0;
1099  x[1][1] = 1;
1100 }
1101 
1102 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (T a) noexcept
1103 {
1104  x[0][0] = a;
1105  x[0][1] = a;
1106  x[1][0] = a;
1107  x[1][1] = a;
1108 }
1109 
1110 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (const T a[2][2]) noexcept
1111 {
1112  // Function calls and aliasing issues can inhibit vectorization versus
1113  // straight assignment of data members, so instead of this:
1114  // memcpy (x, a, sizeof (x));
1115  // we do this:
1116  x[0][0] = a[0][0];
1117  x[0][1] = a[0][1];
1118  x[1][0] = a[1][0];
1119  x[1][1] = a[1][1];
1120 }
1121 
1122 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (T a, T b, T c, T d) noexcept
1123 {
1124  x[0][0] = a;
1125  x[0][1] = b;
1126  x[1][0] = c;
1127  x[1][1] = d;
1128 }
1129 
1130 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (const Matrix22& v) noexcept
1131 {
1132  // Function calls and aliasing issues can inhibit vectorization versus
1133  // straight assignment of data members, so we don't do this:
1134  // memcpy (x, v.x, sizeof (x));
1135  // we do this:
1136  x[0][0] = v.x[0][0];
1137  x[0][1] = v.x[0][1];
1138  x[1][0] = v.x[1][0];
1139  x[1][1] = v.x[1][1];
1140 }
1141 
1142 template <class T>
1143 template <class S>
1144 ATOMSMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (const Matrix22<S>& v) noexcept
1145 {
1146  x[0][0] = T (v.x[0][0]);
1147  x[0][1] = T (v.x[0][1]);
1148  x[1][0] = T (v.x[1][0]);
1149  x[1][1] = T (v.x[1][1]);
1150 }
1151 
1152 template <class T>
1153 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1155 {
1156  // Function calls and aliasing issues can inhibit vectorization versus
1157  // straight assignment of data members, so we don't do this:
1158  // memcpy (x, v.x, sizeof (x));
1159  // we do this:
1160  x[0][0] = v.x[0][0];
1161  x[0][1] = v.x[0][1];
1162  x[1][0] = v.x[1][0];
1163  x[1][1] = v.x[1][1];
1164  return *this;
1165 }
1166 
1167 template <class T>
1168 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1170 {
1171  x[0][0] = a;
1172  x[0][1] = a;
1173  x[1][0] = a;
1174  x[1][1] = a;
1175  return *this;
1176 }
1177 
1178 template <class T>
1179 inline T*
1181 {
1182  return (T*) &x[0][0];
1183 }
1184 
1185 template <class T>
1186 inline const T*
1187 Matrix22<T>::getValue() const noexcept
1188 {
1189  return (const T*) &x[0][0];
1190 }
1191 
1192 template <class T>
1193 template <class S>
1194 inline void
1195 Matrix22<T>::getValue (Matrix22<S>& v) const noexcept
1196 {
1197  v.x[0][0] = x[0][0];
1198  v.x[0][1] = x[0][1];
1199  v.x[1][0] = x[1][0];
1200  v.x[1][1] = x[1][1];
1201 }
1202 
1203 template <class T>
1204 template <class S>
1205 ATOMSMATH_CONSTEXPR14 inline Matrix22<T>&
1206 Matrix22<T>::setValue (const Matrix22<S>& v) noexcept
1207 {
1208  x[0][0] = v.x[0][0];
1209  x[0][1] = v.x[0][1];
1210  x[1][0] = v.x[1][0];
1211  x[1][1] = v.x[1][1];
1212  return *this;
1213 }
1214 
1215 template <class T>
1216 template <class S>
1217 ATOMSMATH_CONSTEXPR14 inline Matrix22<T>&
1218 Matrix22<T>::setTheMatrix (const Matrix22<S>& v) noexcept
1219 {
1220  x[0][0] = v.x[0][0];
1221  x[0][1] = v.x[0][1];
1222  x[1][0] = v.x[1][0];
1223  x[1][1] = v.x[1][1];
1224  return *this;
1225 }
1226 
1227 template <class T>
1228 inline void
1230 {
1231  x[0][0] = 1;
1232  x[0][1] = 0;
1233  x[1][0] = 0;
1234  x[1][1] = 1;
1235 }
1236 
1237 template <class T>
1238 constexpr inline bool
1239 Matrix22<T>::operator== (const Matrix22& v) const noexcept
1240 {
1241  return x[0][0] == v.x[0][0] && x[0][1] == v.x[0][1] && x[1][0] == v.x[1][0] &&
1242  x[1][1] == v.x[1][1];
1243 }
1244 
1245 template <class T>
1246 constexpr inline bool
1247 Matrix22<T>::operator!= (const Matrix22& v) const noexcept
1248 {
1249  return x[0][0] != v.x[0][0] || x[0][1] != v.x[0][1] || x[1][0] != v.x[1][0] ||
1250  x[1][1] != v.x[1][1];
1251 }
1252 
1253 template <class T>
1254 ATOMSMATH_CONSTEXPR14 inline bool
1255 Matrix22<T>::equalWithAbsError (const Matrix22<T>& m, T e) const noexcept
1256 {
1257  for (int i = 0; i < 2; i++)
1258  for (int j = 0; j < 2; j++)
1259  if (!ATOMSMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
1260  return false;
1261 
1262  return true;
1263 }
1264 
1265 template <class T>
1266 ATOMSMATH_CONSTEXPR14 inline bool
1267 Matrix22<T>::equalWithRelError (const Matrix22<T>& m, T e) const noexcept
1268 {
1269  for (int i = 0; i < 2; i++)
1270  for (int j = 0; j < 2; j++)
1271  if (!ATOMSMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
1272  return false;
1273 
1274  return true;
1275 }
1276 
1277 template <class T>
1278 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1280 {
1281  x[0][0] += v.x[0][0];
1282  x[0][1] += v.x[0][1];
1283  x[1][0] += v.x[1][0];
1284  x[1][1] += v.x[1][1];
1285 
1286  return *this;
1287 }
1288 
1289 template <class T>
1290 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1292 {
1293  x[0][0] += a;
1294  x[0][1] += a;
1295  x[1][0] += a;
1296  x[1][1] += a;
1297 
1298  return *this;
1299 }
1300 
1301 template <class T>
1302 constexpr inline Matrix22<T>
1303 Matrix22<T>::operator+ (const Matrix22<T>& v) const noexcept
1304 {
1305  return Matrix22 (x[0][0] + v.x[0][0],
1306  x[0][1] + v.x[0][1],
1307  x[1][0] + v.x[1][0],
1308  x[1][1] + v.x[1][1]);
1309 }
1310 
1311 template <class T>
1312 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1314 {
1315  x[0][0] -= v.x[0][0];
1316  x[0][1] -= v.x[0][1];
1317  x[1][0] -= v.x[1][0];
1318  x[1][1] -= v.x[1][1];
1319 
1320  return *this;
1321 }
1322 
1323 template <class T>
1324 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1326 {
1327  x[0][0] -= a;
1328  x[0][1] -= a;
1329  x[1][0] -= a;
1330  x[1][1] -= a;
1331 
1332  return *this;
1333 }
1334 
1335 template <class T>
1336 constexpr inline Matrix22<T>
1337 Matrix22<T>::operator- (const Matrix22<T>& v) const noexcept
1338 {
1339  return Matrix22 (x[0][0] - v.x[0][0],
1340  x[0][1] - v.x[0][1],
1341  x[1][0] - v.x[1][0],
1342  x[1][1] - v.x[1][1]);
1343 }
1344 
1345 template <class T>
1346 constexpr inline Matrix22<T>
1347 Matrix22<T>::operator-() const noexcept
1348 {
1349  return Matrix22 (-x[0][0], -x[0][1], -x[1][0], -x[1][1]);
1350 }
1351 
1352 template <class T>
1353 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1355 {
1356  x[0][0] = -x[0][0];
1357  x[0][1] = -x[0][1];
1358  x[1][0] = -x[1][0];
1359  x[1][1] = -x[1][1];
1360 
1361  return *this;
1362 }
1363 
1364 template <class T>
1365 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1367 {
1368  x[0][0] *= a;
1369  x[0][1] *= a;
1370  x[1][0] *= a;
1371  x[1][1] *= a;
1372 
1373  return *this;
1374 }
1375 
1376 template <class T>
1377 constexpr inline Matrix22<T>
1378 Matrix22<T>::operator* (T a) const noexcept
1379 {
1380  return Matrix22 (x[0][0] * a, x[0][1] * a, x[1][0] * a, x[1][1] * a);
1381 }
1382 
1384 template <class T>
1385 inline Matrix22<T>
1386 operator* (T a, const Matrix22<T>& v) noexcept
1387 {
1388  return v * a;
1389 }
1390 
1391 template <class T>
1392 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1394 {
1395  Matrix22 tmp (T (0));
1396 
1397  for (int i = 0; i < 2; i++)
1398  for (int j = 0; j < 2; j++)
1399  for (int k = 0; k < 2; k++)
1400  tmp.x[i][j] += x[i][k] * v.x[k][j];
1401 
1402  *this = tmp;
1403  return *this;
1404 }
1405 
1406 template <class T>
1407 ATOMSMATH_CONSTEXPR14 inline Matrix22<T>
1408 Matrix22<T>::operator* (const Matrix22<T>& v) const noexcept
1409 {
1410  Matrix22 tmp (T (0));
1411 
1412  for (int i = 0; i < 2; i++)
1413  for (int j = 0; j < 2; j++)
1414  for (int k = 0; k < 2; k++)
1415  tmp.x[i][j] += x[i][k] * v.x[k][j];
1416 
1417  return tmp;
1418 }
1419 
1420 template <class T>
1421 template <class S>
1422 inline void
1423 Matrix22<T>::multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const noexcept
1424 {
1425  S a, b;
1426 
1427  a = src.x * x[0][0] + src.y * x[1][0];
1428  b = src.x * x[0][1] + src.y * x[1][1];
1429 
1430  dst.x = a;
1431  dst.y = b;
1432 }
1433 
1434 template <class T>
1435 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1437 {
1438  x[0][0] /= a;
1439  x[0][1] /= a;
1440  x[1][0] /= a;
1441  x[1][1] /= a;
1442 
1443  return *this;
1444 }
1445 
1446 template <class T>
1447 constexpr inline Matrix22<T>
1448 Matrix22<T>::operator/ (T a) const noexcept
1449 {
1450  return Matrix22 (x[0][0] / a, x[0][1] / a, x[1][0] / a, x[1][1] / a);
1451 }
1452 
1453 template <class T>
1454 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1456 {
1457  Matrix22 tmp (x[0][0], x[1][0], x[0][1], x[1][1]);
1458  *this = tmp;
1459  return *this;
1460 }
1461 
1462 template <class T>
1463 constexpr inline Matrix22<T>
1464 Matrix22<T>::transposed() const noexcept
1465 {
1466  return Matrix22 (x[0][0], x[1][0], x[0][1], x[1][1]);
1467 }
1468 
1469 template <class T>
1470 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1471 Matrix22<T>::invert (bool singExc)
1472 {
1473  *this = inverse (singExc);
1474  return *this;
1475 }
1476 
1477 template <class T>
1478 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1480 {
1481  *this = inverse();
1482  return *this;
1483 }
1484 
1485 template <class T>
1486 ATOMSMATH_CONSTEXPR14 inline Matrix22<T>
1487 Matrix22<T>::inverse (bool singExc) const
1488 {
1489  Matrix22 s (x[1][1], -x[0][1], -x[1][0], x[0][0]);
1490 
1491  T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
1492 
1493  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
1494  {
1495  for (int i = 0; i < 2; ++i)
1496  {
1497  for (int j = 0; j < 2; ++j)
1498  {
1499  s[i][j] /= r;
1500  }
1501  }
1502  }
1503  else
1504  {
1505  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
1506 
1507  for (int i = 0; i < 2; ++i)
1508  {
1509  for (int j = 0; j < 2; ++j)
1510  {
1511  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
1512  {
1513  s[i][j] /= r;
1514  }
1515  else
1516  {
1517  #ifdef ATOMS_USE_EXCEPTIONS
1518  if (singExc)
1519  throw std::invalid_argument ("Cannot invert "
1520  "singular matrix.");
1521  #endif
1522  return Matrix22();
1523  }
1524  }
1525  }
1526  }
1527  return s;
1528 }
1529 
1530 template <class T>
1531 ATOMSMATH_CONSTEXPR14 inline Matrix22<T>
1532 Matrix22<T>::inverse() const noexcept
1533 {
1534  Matrix22 s (x[1][1], -x[0][1], -x[1][0], x[0][0]);
1535 
1536  T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
1537 
1538  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
1539  {
1540  for (int i = 0; i < 2; ++i)
1541  {
1542  for (int j = 0; j < 2; ++j)
1543  {
1544  s[i][j] /= r;
1545  }
1546  }
1547  }
1548  else
1549  {
1550  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
1551 
1552  for (int i = 0; i < 2; ++i)
1553  {
1554  for (int j = 0; j < 2; ++j)
1555  {
1556  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
1557  {
1558  s[i][j] /= r;
1559  }
1560  else
1561  {
1562  return Matrix22();
1563  }
1564  }
1565  }
1566  }
1567  return s;
1568 }
1569 
1570 template <class T>
1571 constexpr inline T
1573 {
1574  return x[0][0] * x[1][1] - x[1][0] * x[0][1];
1575 }
1576 
1577 template <class T>
1578 template <class S>
1579 inline const Matrix22<T>&
1580 Matrix22<T>::setRotation (S r) noexcept
1581 {
1582  S cos_r, sin_r;
1583 
1584  cos_r = cos ((T) r);
1585  sin_r = sin ((T) r);
1586 
1587  x[0][0] = cos_r;
1588  x[0][1] = sin_r;
1589 
1590  x[1][0] = -sin_r;
1591  x[1][1] = cos_r;
1592 
1593  return *this;
1594 }
1595 
1596 template <class T>
1597 template <class S>
1598 
1599 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1600 Matrix22<T>::rotate (S r) noexcept
1601 {
1602  *this *= Matrix22<T>().setRotation (r);
1603  return *this;
1604 }
1605 
1606 template <class T>
1607 
1608 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1610 {
1611  //
1612  // Set the matrix to:
1613  // | s 0 |
1614  // | 0 s |
1615  //
1616 
1617  x[0][0] = s;
1618  x[0][1] = static_cast<T> (0);
1619  x[1][0] = static_cast<T> (0);
1620  x[1][1] = s;
1621 
1622  return *this;
1623 }
1624 
1625 template <class T>
1626 template <class S>
1627 
1628 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1629 Matrix22<T>::setScale (const Vec2<S>& s) noexcept
1630 {
1631  //
1632  // Set the matrix to:
1633  // | s.x 0 |
1634  // | 0 s.y |
1635  //
1636 
1637  x[0][0] = s.x;
1638  x[0][1] = static_cast<T> (0);
1639  x[1][0] = static_cast<T> (0);
1640  x[1][1] = s.y;
1641 
1642  return *this;
1643 }
1644 
1645 template <class T>
1646 template <class S>
1647 
1648 ATOMSMATH_CONSTEXPR14 inline const Matrix22<T>&
1649 Matrix22<T>::scale (const Vec2<S>& s) noexcept
1650 {
1651  x[0][0] *= s.x;
1652  x[0][1] *= s.x;
1653 
1654  x[1][0] *= s.y;
1655  x[1][1] *= s.y;
1656 
1657  return *this;
1658 }
1659 
1660 //---------------------------
1661 // Implementation of Matrix33
1662 //---------------------------
1663 
1664 template <class T>
1665 inline T*
1667 {
1668  return x[i];
1669 }
1670 
1671 template <class T>
1672 inline const T*
1673 Matrix33<T>::operator[] (int i) const noexcept
1674 {
1675  return x[i];
1676 }
1677 
1678 template <class T>
1679 inline ATOMSMATH_CONSTEXPR14
1681 {
1682  x[0][0] = 1;
1683  x[0][1] = 0;
1684  x[0][2] = 0;
1685  x[1][0] = 0;
1686  x[1][1] = 1;
1687  x[1][2] = 0;
1688  x[2][0] = 0;
1689  x[2][1] = 0;
1690  x[2][2] = 1;
1691 }
1692 
1693 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (T a) noexcept
1694 {
1695  x[0][0] = a;
1696  x[0][1] = a;
1697  x[0][2] = a;
1698  x[1][0] = a;
1699  x[1][1] = a;
1700  x[1][2] = a;
1701  x[2][0] = a;
1702  x[2][1] = a;
1703  x[2][2] = a;
1704 }
1705 
1706 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (const T a[3][3]) noexcept
1707 {
1708  // Function calls and aliasing issues can inhibit vectorization versus
1709  // straight assignment of data members, so instead of this:
1710  // memcpy (x, a, sizeof (x));
1711  // we do this:
1712  x[0][0] = a[0][0];
1713  x[0][1] = a[0][1];
1714  x[0][2] = a[0][2];
1715  x[1][0] = a[1][0];
1716  x[1][1] = a[1][1];
1717  x[1][2] = a[1][2];
1718  x[2][0] = a[2][0];
1719  x[2][1] = a[2][1];
1720  x[2][2] = a[2][2];
1721 }
1722 
1723 template <class T>
1724 
1725 ATOMSMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i) noexcept
1726 {
1727  x[0][0] = a;
1728  x[0][1] = b;
1729  x[0][2] = c;
1730  x[1][0] = d;
1731  x[1][1] = e;
1732  x[1][2] = f;
1733  x[2][0] = g;
1734  x[2][1] = h;
1735  x[2][2] = i;
1736 }
1737 
1738 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (const Matrix33& v) noexcept
1739 {
1740  // Function calls and aliasing issues can inhibit vectorization versus
1741  // straight assignment of data members, so instead of this:
1742  // memcpy (x, v.x, sizeof (x));
1743  // we do this:
1744  x[0][0] = v.x[0][0];
1745  x[0][1] = v.x[0][1];
1746  x[0][2] = v.x[0][2];
1747  x[1][0] = v.x[1][0];
1748  x[1][1] = v.x[1][1];
1749  x[1][2] = v.x[1][2];
1750  x[2][0] = v.x[2][0];
1751  x[2][1] = v.x[2][1];
1752  x[2][2] = v.x[2][2];
1753 }
1754 
1755 template <class T>
1756 template <class S>
1757 
1758 ATOMSMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (const Matrix33<S>& v) noexcept
1759 {
1760  x[0][0] = T (v.x[0][0]);
1761  x[0][1] = T (v.x[0][1]);
1762  x[0][2] = T (v.x[0][2]);
1763  x[1][0] = T (v.x[1][0]);
1764  x[1][1] = T (v.x[1][1]);
1765  x[1][2] = T (v.x[1][2]);
1766  x[2][0] = T (v.x[2][0]);
1767  x[2][1] = T (v.x[2][1]);
1768  x[2][2] = T (v.x[2][2]);
1769 }
1770 
1771 template <class T>
1772 
1773 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
1775 {
1776  // Function calls and aliasing issues can inhibit vectorization versus
1777  // straight assignment of data members, so instead of this:
1778  // memcpy (x, v.x, sizeof (x));
1779  // we do this:
1780  x[0][0] = v.x[0][0];
1781  x[0][1] = v.x[0][1];
1782  x[0][2] = v.x[0][2];
1783  x[1][0] = v.x[1][0];
1784  x[1][1] = v.x[1][1];
1785  x[1][2] = v.x[1][2];
1786  x[2][0] = v.x[2][0];
1787  x[2][1] = v.x[2][1];
1788  x[2][2] = v.x[2][2];
1789  return *this;
1790 }
1791 
1792 template <class T>
1793 
1794 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
1796 {
1797  x[0][0] = a;
1798  x[0][1] = a;
1799  x[0][2] = a;
1800  x[1][0] = a;
1801  x[1][1] = a;
1802  x[1][2] = a;
1803  x[2][0] = a;
1804  x[2][1] = a;
1805  x[2][2] = a;
1806  return *this;
1807 }
1808 
1809 template <class T>
1810 inline T*
1812 {
1813  return (T*) &x[0][0];
1814 }
1815 
1816 template <class T>
1817 inline const T*
1818 Matrix33<T>::getValue() const noexcept
1819 {
1820  return (const T*) &x[0][0];
1821 }
1822 
1823 template <class T>
1824 template <class S>
1825 inline void
1826 Matrix33<T>::getValue (Matrix33<S>& v) const noexcept
1827 {
1828  v.x[0][0] = x[0][0];
1829  v.x[0][1] = x[0][1];
1830  v.x[0][2] = x[0][2];
1831  v.x[1][0] = x[1][0];
1832  v.x[1][1] = x[1][1];
1833  v.x[1][2] = x[1][2];
1834  v.x[2][0] = x[2][0];
1835  v.x[2][1] = x[2][1];
1836  v.x[2][2] = x[2][2];
1837 }
1838 
1839 template <class T>
1840 template <class S>
1841 ATOMSMATH_CONSTEXPR14 inline Matrix33<T>&
1842 Matrix33<T>::setValue (const Matrix33<S>& v) noexcept
1843 {
1844  x[0][0] = v.x[0][0];
1845  x[0][1] = v.x[0][1];
1846  x[0][2] = v.x[0][2];
1847  x[1][0] = v.x[1][0];
1848  x[1][1] = v.x[1][1];
1849  x[1][2] = v.x[1][2];
1850  x[2][0] = v.x[2][0];
1851  x[2][1] = v.x[2][1];
1852  x[2][2] = v.x[2][2];
1853  return *this;
1854 }
1855 
1856 template <class T>
1857 template <class S>
1858 ATOMSMATH_CONSTEXPR14 inline Matrix33<T>&
1859 Matrix33<T>::setTheMatrix (const Matrix33<S>& v) noexcept
1860 {
1861  x[0][0] = v.x[0][0];
1862  x[0][1] = v.x[0][1];
1863  x[0][2] = v.x[0][2];
1864  x[1][0] = v.x[1][0];
1865  x[1][1] = v.x[1][1];
1866  x[1][2] = v.x[1][2];
1867  x[2][0] = v.x[2][0];
1868  x[2][1] = v.x[2][1];
1869  x[2][2] = v.x[2][2];
1870  return *this;
1871 }
1872 
1873 template <class T>
1874 inline void
1876 {
1877  x[0][0] = 1;
1878  x[0][1] = 0;
1879  x[0][2] = 0;
1880  x[1][0] = 0;
1881  x[1][1] = 1;
1882  x[1][2] = 0;
1883  x[2][0] = 0;
1884  x[2][1] = 0;
1885  x[2][2] = 1;
1886 }
1887 
1888 template <class T>
1889 constexpr inline bool
1890 Matrix33<T>::operator== (const Matrix33& v) const noexcept
1891 {
1892  return x[0][0] == v.x[0][0] && x[0][1] == v.x[0][1] && x[0][2] == v.x[0][2] &&
1893  x[1][0] == v.x[1][0] && x[1][1] == v.x[1][1] && x[1][2] == v.x[1][2] &&
1894  x[2][0] == v.x[2][0] && x[2][1] == v.x[2][1] && x[2][2] == v.x[2][2];
1895 }
1896 
1897 template <class T>
1898 constexpr inline bool
1899 Matrix33<T>::operator!= (const Matrix33& v) const noexcept
1900 {
1901  return x[0][0] != v.x[0][0] || x[0][1] != v.x[0][1] || x[0][2] != v.x[0][2] ||
1902  x[1][0] != v.x[1][0] || x[1][1] != v.x[1][1] || x[1][2] != v.x[1][2] ||
1903  x[2][0] != v.x[2][0] || x[2][1] != v.x[2][1] || x[2][2] != v.x[2][2];
1904 }
1905 
1906 template <class T>
1907 ATOMSMATH_CONSTEXPR14 inline bool
1908 Matrix33<T>::equalWithAbsError (const Matrix33<T>& m, T e) const noexcept
1909 {
1910  for (int i = 0; i < 3; i++)
1911  for (int j = 0; j < 3; j++)
1912  if (!ATOMSMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
1913  return false;
1914 
1915  return true;
1916 }
1917 
1918 template <class T>
1919 ATOMSMATH_CONSTEXPR14 inline bool
1920 Matrix33<T>::equalWithRelError (const Matrix33<T>& m, T e) const noexcept
1921 {
1922  for (int i = 0; i < 3; i++)
1923  for (int j = 0; j < 3; j++)
1924  if (!ATOMSMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
1925  return false;
1926 
1927  return true;
1928 }
1929 
1930 template <class T>
1931 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
1933 {
1934  x[0][0] += v.x[0][0];
1935  x[0][1] += v.x[0][1];
1936  x[0][2] += v.x[0][2];
1937  x[1][0] += v.x[1][0];
1938  x[1][1] += v.x[1][1];
1939  x[1][2] += v.x[1][2];
1940  x[2][0] += v.x[2][0];
1941  x[2][1] += v.x[2][1];
1942  x[2][2] += v.x[2][2];
1943 
1944  return *this;
1945 }
1946 
1947 template <class T>
1948 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
1950 {
1951  x[0][0] += a;
1952  x[0][1] += a;
1953  x[0][2] += a;
1954  x[1][0] += a;
1955  x[1][1] += a;
1956  x[1][2] += a;
1957  x[2][0] += a;
1958  x[2][1] += a;
1959  x[2][2] += a;
1960 
1961  return *this;
1962 }
1963 
1964 template <class T>
1965 constexpr inline Matrix33<T>
1966 Matrix33<T>::operator+ (const Matrix33<T>& v) const noexcept
1967 {
1968  return Matrix33 (x[0][0] + v.x[0][0],
1969  x[0][1] + v.x[0][1],
1970  x[0][2] + v.x[0][2],
1971  x[1][0] + v.x[1][0],
1972  x[1][1] + v.x[1][1],
1973  x[1][2] + v.x[1][2],
1974  x[2][0] + v.x[2][0],
1975  x[2][1] + v.x[2][1],
1976  x[2][2] + v.x[2][2]);
1977 }
1978 
1979 template <class T>
1980 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
1982 {
1983  x[0][0] -= v.x[0][0];
1984  x[0][1] -= v.x[0][1];
1985  x[0][2] -= v.x[0][2];
1986  x[1][0] -= v.x[1][0];
1987  x[1][1] -= v.x[1][1];
1988  x[1][2] -= v.x[1][2];
1989  x[2][0] -= v.x[2][0];
1990  x[2][1] -= v.x[2][1];
1991  x[2][2] -= v.x[2][2];
1992 
1993  return *this;
1994 }
1995 
1996 template <class T>
1997 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
1999 {
2000  x[0][0] -= a;
2001  x[0][1] -= a;
2002  x[0][2] -= a;
2003  x[1][0] -= a;
2004  x[1][1] -= a;
2005  x[1][2] -= a;
2006  x[2][0] -= a;
2007  x[2][1] -= a;
2008  x[2][2] -= a;
2009 
2010  return *this;
2011 }
2012 
2013 template <class T>
2014 constexpr inline Matrix33<T>
2015 Matrix33<T>::operator- (const Matrix33<T>& v) const noexcept
2016 {
2017  return Matrix33 (x[0][0] - v.x[0][0],
2018  x[0][1] - v.x[0][1],
2019  x[0][2] - v.x[0][2],
2020  x[1][0] - v.x[1][0],
2021  x[1][1] - v.x[1][1],
2022  x[1][2] - v.x[1][2],
2023  x[2][0] - v.x[2][0],
2024  x[2][1] - v.x[2][1],
2025  x[2][2] - v.x[2][2]);
2026 }
2027 
2028 template <class T>
2029 constexpr inline Matrix33<T>
2030 Matrix33<T>::operator-() const noexcept
2031 {
2032  return Matrix33 (-x[0][0],
2033  -x[0][1],
2034  -x[0][2],
2035  -x[1][0],
2036  -x[1][1],
2037  -x[1][2],
2038  -x[2][0],
2039  -x[2][1],
2040  -x[2][2]);
2041 }
2042 
2043 template <class T>
2044 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2046 {
2047  x[0][0] = -x[0][0];
2048  x[0][1] = -x[0][1];
2049  x[0][2] = -x[0][2];
2050  x[1][0] = -x[1][0];
2051  x[1][1] = -x[1][1];
2052  x[1][2] = -x[1][2];
2053  x[2][0] = -x[2][0];
2054  x[2][1] = -x[2][1];
2055  x[2][2] = -x[2][2];
2056 
2057  return *this;
2058 }
2059 
2060 template <class T>
2061 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2063 {
2064  x[0][0] *= a;
2065  x[0][1] *= a;
2066  x[0][2] *= a;
2067  x[1][0] *= a;
2068  x[1][1] *= a;
2069  x[1][2] *= a;
2070  x[2][0] *= a;
2071  x[2][1] *= a;
2072  x[2][2] *= a;
2073 
2074  return *this;
2075 }
2076 
2077 template <class T>
2078 constexpr inline Matrix33<T>
2079 Matrix33<T>::operator* (T a) const noexcept
2080 {
2081  return Matrix33 (x[0][0] * a,
2082  x[0][1] * a,
2083  x[0][2] * a,
2084  x[1][0] * a,
2085  x[1][1] * a,
2086  x[1][2] * a,
2087  x[2][0] * a,
2088  x[2][1] * a,
2089  x[2][2] * a);
2090 }
2091 
2093 template <class T>
2094 inline Matrix33<T> constexpr
2095 operator* (T a, const Matrix33<T>& v) noexcept
2096 {
2097  return v * a;
2098 }
2099 
2100 template <class T>
2101 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2103 {
2104  // Avoid initializing with 0 values before immediately overwriting them,
2105  // and unroll all loops for the best autovectorization.
2106  Matrix33 tmp (ATOMSMATH_NAMESPACE::UNINITIALIZED);
2107 
2108  tmp.x[0][0] = x[0][0] * v.x[0][0] + x[0][1] * v.x[1][0] + x[0][2] * v.x[2][0];
2109  tmp.x[0][1] = x[0][0] * v.x[0][1] + x[0][1] * v.x[1][1] + x[0][2] * v.x[2][1];
2110  tmp.x[0][2] = x[0][0] * v.x[0][2] + x[0][1] * v.x[1][2] + x[0][2] * v.x[2][2];
2111 
2112  tmp.x[1][0] = x[1][0] * v.x[0][0] + x[1][1] * v.x[1][0] + x[1][2] * v.x[2][0];
2113  tmp.x[1][1] = x[1][0] * v.x[0][1] + x[1][1] * v.x[1][1] + x[1][2] * v.x[2][1];
2114  tmp.x[1][2] = x[1][0] * v.x[0][2] + x[1][1] * v.x[1][2] + x[1][2] * v.x[2][2];
2115 
2116  tmp.x[2][0] = x[2][0] * v.x[0][0] + x[2][1] * v.x[1][0] + x[2][2] * v.x[2][0];
2117  tmp.x[2][1] = x[2][0] * v.x[0][1] + x[2][1] * v.x[1][1] + x[2][2] * v.x[2][1];
2118  tmp.x[2][2] = x[2][0] * v.x[0][2] + x[2][1] * v.x[1][2] + x[2][2] * v.x[2][2];
2119 
2120  *this = tmp;
2121  return *this;
2122 }
2123 
2124 template <class T>
2125 ATOMSMATH_CONSTEXPR14 inline Matrix33<T>
2126 Matrix33<T>::operator* (const Matrix33<T>& v) const noexcept
2127 {
2128  // Avoid initializing with 0 values before immediately overwriting them,
2129  // and unroll all loops for the best autovectorization.
2130  Matrix33 tmp (ATOMSMATH_NAMESPACE::UNINITIALIZED);
2131 
2132  tmp.x[0][0] = x[0][0] * v.x[0][0] + x[0][1] * v.x[1][0] + x[0][2] * v.x[2][0];
2133  tmp.x[0][1] = x[0][0] * v.x[0][1] + x[0][1] * v.x[1][1] + x[0][2] * v.x[2][1];
2134  tmp.x[0][2] = x[0][0] * v.x[0][2] + x[0][1] * v.x[1][2] + x[0][2] * v.x[2][2];
2135 
2136  tmp.x[1][0] = x[1][0] * v.x[0][0] + x[1][1] * v.x[1][0] + x[1][2] * v.x[2][0];
2137  tmp.x[1][1] = x[1][0] * v.x[0][1] + x[1][1] * v.x[1][1] + x[1][2] * v.x[2][1];
2138  tmp.x[1][2] = x[1][0] * v.x[0][2] + x[1][1] * v.x[1][2] + x[1][2] * v.x[2][2];
2139 
2140  tmp.x[2][0] = x[2][0] * v.x[0][0] + x[2][1] * v.x[1][0] + x[2][2] * v.x[2][0];
2141  tmp.x[2][1] = x[2][0] * v.x[0][1] + x[2][1] * v.x[1][1] + x[2][2] * v.x[2][1];
2142  tmp.x[2][2] = x[2][0] * v.x[0][2] + x[2][1] * v.x[1][2] + x[2][2] * v.x[2][2];
2143 
2144  return tmp;
2145 }
2146 
2147 template <class T>
2148 template <class S>
2149 inline void
2150 Matrix33<T>::multVecMatrix (const Vec2<S>& src, Vec2<S>& dst) const noexcept
2151 {
2152  S a, b, w;
2153 
2154  a = src.x * x[0][0] + src.y * x[1][0] + x[2][0];
2155  b = src.x * x[0][1] + src.y * x[1][1] + x[2][1];
2156  w = src.x * x[0][2] + src.y * x[1][2] + x[2][2];
2157 
2158  dst.x = a / w;
2159  dst.y = b / w;
2160 }
2161 
2162 template <class T>
2163 template <class S>
2164 inline void
2165 Matrix33<T>::multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const noexcept
2166 {
2167  S a, b;
2168 
2169  a = src.x * x[0][0] + src.y * x[1][0];
2170  b = src.x * x[0][1] + src.y * x[1][1];
2171 
2172  dst.x = a;
2173  dst.y = b;
2174 }
2175 
2176 template <class T>
2177 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2179 {
2180  x[0][0] /= a;
2181  x[0][1] /= a;
2182  x[0][2] /= a;
2183  x[1][0] /= a;
2184  x[1][1] /= a;
2185  x[1][2] /= a;
2186  x[2][0] /= a;
2187  x[2][1] /= a;
2188  x[2][2] /= a;
2189 
2190  return *this;
2191 }
2192 
2193 template <class T>
2194 constexpr inline Matrix33<T>
2195 Matrix33<T>::operator/ (T a) const noexcept
2196 {
2197  return Matrix33 (x[0][0] / a,
2198  x[0][1] / a,
2199  x[0][2] / a,
2200  x[1][0] / a,
2201  x[1][1] / a,
2202  x[1][2] / a,
2203  x[2][0] / a,
2204  x[2][1] / a,
2205  x[2][2] / a);
2206 }
2207 
2208 template <class T>
2209 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2211 {
2212  Matrix33 tmp (x[0][0], x[1][0], x[2][0], x[0][1], x[1][1], x[2][1], x[0][2], x[1][2], x[2][2]);
2213  *this = tmp;
2214  return *this;
2215 }
2216 
2217 template <class T>
2218 constexpr inline Matrix33<T>
2219 Matrix33<T>::transposed() const noexcept
2220 {
2221  return Matrix33 (x[0][0],
2222  x[1][0],
2223  x[2][0],
2224  x[0][1],
2225  x[1][1],
2226  x[2][1],
2227  x[0][2],
2228  x[1][2],
2229  x[2][2]);
2230 }
2231 
2232 template <class T>
2233 const inline Matrix33<T>&
2235 {
2236  *this = gjInverse (singExc);
2237  return *this;
2238 }
2239 
2240 template <class T>
2241 const inline Matrix33<T>&
2243 {
2244  *this = gjInverse();
2245  return *this;
2246 }
2247 
2248 template <class T>
2249 inline Matrix33<T>
2250 Matrix33<T>::gjInverse (bool singExc) const
2251 {
2252  int i, j, k;
2253  Matrix33 s;
2254  Matrix33 t (*this);
2255 
2256  // Forward elimination
2257 
2258  for (i = 0; i < 2; i++)
2259  {
2260  int pivot = i;
2261 
2262  T pivotsize = t[i][i];
2263 
2264  if (pivotsize < 0)
2265  pivotsize = -pivotsize;
2266 
2267  for (j = i + 1; j < 3; j++)
2268  {
2269  T tmp = t[j][i];
2270 
2271  if (tmp < 0)
2272  tmp = -tmp;
2273 
2274  if (tmp > pivotsize)
2275  {
2276  pivot = j;
2277  pivotsize = tmp;
2278  }
2279  }
2280 
2281  if (pivotsize == 0)
2282  {
2283  #ifdef ATOMS_USE_EXCEPTIONS
2284  if (singExc)
2285  throw std::invalid_argument ("Cannot invert singular matrix.");
2286  #endif
2287  return Matrix33();
2288  }
2289 
2290  if (pivot != i)
2291  {
2292  for (j = 0; j < 3; j++)
2293  {
2294  T tmp;
2295 
2296  tmp = t[i][j];
2297  t[i][j] = t[pivot][j];
2298  t[pivot][j] = tmp;
2299 
2300  tmp = s[i][j];
2301  s[i][j] = s[pivot][j];
2302  s[pivot][j] = tmp;
2303  }
2304  }
2305 
2306  for (j = i + 1; j < 3; j++)
2307  {
2308  T f = t[j][i] / t[i][i];
2309 
2310  for (k = 0; k < 3; k++)
2311  {
2312  t[j][k] -= f * t[i][k];
2313  s[j][k] -= f * s[i][k];
2314  }
2315  }
2316  }
2317 
2318  // Backward substitution
2319 
2320  for (i = 2; i >= 0; --i)
2321  {
2322  T f;
2323 
2324  if ((f = t[i][i]) == 0)
2325  {
2326  #ifdef ATOMS_USE_EXCEPTIONS
2327  if (singExc)
2328  throw std::invalid_argument ("Cannot invert singular matrix.");
2329  #endif
2330  return Matrix33();
2331  }
2332 
2333  for (j = 0; j < 3; j++)
2334  {
2335  t[i][j] /= f;
2336  s[i][j] /= f;
2337  }
2338 
2339  for (j = 0; j < i; j++)
2340  {
2341  f = t[j][i];
2342 
2343  for (k = 0; k < 3; k++)
2344  {
2345  t[j][k] -= f * t[i][k];
2346  s[j][k] -= f * s[i][k];
2347  }
2348  }
2349  }
2350 
2351  return s;
2352 }
2353 
2354 template <class T>
2355 inline Matrix33<T>
2356 Matrix33<T>::gjInverse() const noexcept
2357 {
2358  int i, j, k;
2359  Matrix33 s;
2360  Matrix33 t (*this);
2361 
2362  // Forward elimination
2363 
2364  for (i = 0; i < 2; i++)
2365  {
2366  int pivot = i;
2367 
2368  T pivotsize = t[i][i];
2369 
2370  if (pivotsize < 0)
2371  pivotsize = -pivotsize;
2372 
2373  for (j = i + 1; j < 3; j++)
2374  {
2375  T tmp = t[j][i];
2376 
2377  if (tmp < 0)
2378  tmp = -tmp;
2379 
2380  if (tmp > pivotsize)
2381  {
2382  pivot = j;
2383  pivotsize = tmp;
2384  }
2385  }
2386 
2387  if (pivotsize == 0)
2388  {
2389  return Matrix33();
2390  }
2391 
2392  if (pivot != i)
2393  {
2394  for (j = 0; j < 3; j++)
2395  {
2396  T tmp;
2397 
2398  tmp = t[i][j];
2399  t[i][j] = t[pivot][j];
2400  t[pivot][j] = tmp;
2401 
2402  tmp = s[i][j];
2403  s[i][j] = s[pivot][j];
2404  s[pivot][j] = tmp;
2405  }
2406  }
2407 
2408  for (j = i + 1; j < 3; j++)
2409  {
2410  T f = t[j][i] / t[i][i];
2411 
2412  for (k = 0; k < 3; k++)
2413  {
2414  t[j][k] -= f * t[i][k];
2415  s[j][k] -= f * s[i][k];
2416  }
2417  }
2418  }
2419 
2420  // Backward substitution
2421 
2422  for (i = 2; i >= 0; --i)
2423  {
2424  T f;
2425 
2426  if ((f = t[i][i]) == 0)
2427  {
2428  return Matrix33();
2429  }
2430 
2431  for (j = 0; j < 3; j++)
2432  {
2433  t[i][j] /= f;
2434  s[i][j] /= f;
2435  }
2436 
2437  for (j = 0; j < i; j++)
2438  {
2439  f = t[j][i];
2440 
2441  for (k = 0; k < 3; k++)
2442  {
2443  t[j][k] -= f * t[i][k];
2444  s[j][k] -= f * s[i][k];
2445  }
2446  }
2447  }
2448 
2449  return s;
2450 }
2451 
2452 template <class T>
2453 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2454 Matrix33<T>::invert (bool singExc)
2455 {
2456  *this = inverse (singExc);
2457  return *this;
2458 }
2459 
2460 template <class T>
2461 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2463 {
2464  *this = inverse();
2465  return *this;
2466 }
2467 
2468 template <class T>
2469 ATOMSMATH_CONSTEXPR14 inline Matrix33<T>
2470 Matrix33<T>::inverse (bool singExc) const
2471 {
2472  if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
2473  {
2474  Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
2475  x[2][1] * x[0][2] - x[0][1] * x[2][2],
2476  x[0][1] * x[1][2] - x[1][1] * x[0][2],
2477 
2478  x[2][0] * x[1][2] - x[1][0] * x[2][2],
2479  x[0][0] * x[2][2] - x[2][0] * x[0][2],
2480  x[1][0] * x[0][2] - x[0][0] * x[1][2],
2481 
2482  x[1][0] * x[2][1] - x[2][0] * x[1][1],
2483  x[2][0] * x[0][1] - x[0][0] * x[2][1],
2484  x[0][0] * x[1][1] - x[1][0] * x[0][1]);
2485 
2486  T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
2487 
2488  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2489  {
2490  for (int i = 0; i < 3; ++i)
2491  {
2492  for (int j = 0; j < 3; ++j)
2493  {
2494  s[i][j] /= r;
2495  }
2496  }
2497  }
2498  else
2499  {
2500  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2501 
2502  for (int i = 0; i < 3; ++i)
2503  {
2504  for (int j = 0; j < 3; ++j)
2505  {
2506  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
2507  {
2508  s[i][j] /= r;
2509  }
2510  else
2511  {
2512  #ifdef ATOMS_USE_EXCEPTIONS
2513  if (singExc)
2514  throw std::invalid_argument ("Cannot invert "
2515  "singular matrix.");
2516  #endif
2517  return Matrix33();
2518  }
2519  }
2520  }
2521  }
2522 
2523  return s;
2524  }
2525  else
2526  {
2527  Matrix33 s (x[1][1],
2528  -x[0][1],
2529  0,
2530 
2531  -x[1][0],
2532  x[0][0],
2533  0,
2534 
2535  0,
2536  0,
2537  1);
2538 
2539  T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
2540 
2541  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2542  {
2543  for (int i = 0; i < 2; ++i)
2544  {
2545  for (int j = 0; j < 2; ++j)
2546  {
2547  s[i][j] /= r;
2548  }
2549  }
2550  }
2551  else
2552  {
2553  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2554 
2555  for (int i = 0; i < 2; ++i)
2556  {
2557  for (int j = 0; j < 2; ++j)
2558  {
2559  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
2560  {
2561  s[i][j] /= r;
2562  }
2563  else
2564  {
2565  #ifdef ATOMS_USE_EXCEPTIONS
2566  if (singExc)
2567  throw std::invalid_argument ("Cannot invert "
2568  "singular matrix.");
2569  #endif
2570  return Matrix33();
2571  }
2572  }
2573  }
2574  }
2575 
2576  s[2][0] = -x[2][0] * s[0][0] - x[2][1] * s[1][0];
2577  s[2][1] = -x[2][0] * s[0][1] - x[2][1] * s[1][1];
2578 
2579  return s;
2580  }
2581 }
2582 
2583 template <class T>
2584 ATOMSMATH_CONSTEXPR14 inline Matrix33<T>
2585 Matrix33<T>::inverse() const noexcept
2586 {
2587  if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
2588  {
2589  Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
2590  x[2][1] * x[0][2] - x[0][1] * x[2][2],
2591  x[0][1] * x[1][2] - x[1][1] * x[0][2],
2592 
2593  x[2][0] * x[1][2] - x[1][0] * x[2][2],
2594  x[0][0] * x[2][2] - x[2][0] * x[0][2],
2595  x[1][0] * x[0][2] - x[0][0] * x[1][2],
2596 
2597  x[1][0] * x[2][1] - x[2][0] * x[1][1],
2598  x[2][0] * x[0][1] - x[0][0] * x[2][1],
2599  x[0][0] * x[1][1] - x[1][0] * x[0][1]);
2600 
2601  T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
2602 
2603  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2604  {
2605  for (int i = 0; i < 3; ++i)
2606  {
2607  for (int j = 0; j < 3; ++j)
2608  {
2609  s[i][j] /= r;
2610  }
2611  }
2612  }
2613  else
2614  {
2615  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2616 
2617  for (int i = 0; i < 3; ++i)
2618  {
2619  for (int j = 0; j < 3; ++j)
2620  {
2621  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
2622  {
2623  s[i][j] /= r;
2624  }
2625  else
2626  {
2627  return Matrix33();
2628  }
2629  }
2630  }
2631  }
2632 
2633  return s;
2634  }
2635  else
2636  {
2637  Matrix33 s (x[1][1],
2638  -x[0][1],
2639  0,
2640 
2641  -x[1][0],
2642  x[0][0],
2643  0,
2644 
2645  0,
2646  0,
2647  1);
2648 
2649  T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
2650 
2651  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2652  {
2653  for (int i = 0; i < 2; ++i)
2654  {
2655  for (int j = 0; j < 2; ++j)
2656  {
2657  s[i][j] /= r;
2658  }
2659  }
2660  }
2661  else
2662  {
2663  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2664 
2665  for (int i = 0; i < 2; ++i)
2666  {
2667  for (int j = 0; j < 2; ++j)
2668  {
2669  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
2670  {
2671  s[i][j] /= r;
2672  }
2673  else
2674  {
2675  return Matrix33();
2676  }
2677  }
2678  }
2679  }
2680 
2681  s[2][0] = -x[2][0] * s[0][0] - x[2][1] * s[1][0];
2682  s[2][1] = -x[2][0] * s[0][1] - x[2][1] * s[1][1];
2683 
2684  return s;
2685  }
2686 }
2687 
2688 template <class T>
2689 ATOMSMATH_CONSTEXPR14 inline T
2690 Matrix33<T>::minorOf (const int r, const int c) const noexcept
2691 {
2692  int r0 = 0 + (r < 1 ? 1 : 0);
2693  int r1 = 1 + (r < 2 ? 1 : 0);
2694  int c0 = 0 + (c < 1 ? 1 : 0);
2695  int c1 = 1 + (c < 2 ? 1 : 0);
2696 
2697  return x[r0][c0] * x[r1][c1] - x[r1][c0] * x[r0][c1];
2698 }
2699 
2700 template <class T>
2701 constexpr inline T
2702 Matrix33<T>::fastMinor (const int r0, const int r1, const int c0, const int c1) const noexcept
2703 {
2704  return x[r0][c0] * x[r1][c1] - x[r0][c1] * x[r1][c0];
2705 }
2706 
2707 template <class T>
2708 constexpr inline T
2710 {
2711  return x[0][0] * (x[1][1] * x[2][2] - x[1][2] * x[2][1]) +
2712  x[0][1] * (x[1][2] * x[2][0] - x[1][0] * x[2][2]) +
2713  x[0][2] * (x[1][0] * x[2][1] - x[1][1] * x[2][0]);
2714 }
2715 
2716 template <class T>
2717 template <class S>
2718 inline const Matrix33<T>&
2719 Matrix33<T>::setRotation (S r) noexcept
2720 {
2721  S cos_r, sin_r;
2722 
2723  cos_r = cos ((T) r);
2724  sin_r = sin ((T) r);
2725 
2726  x[0][0] = cos_r;
2727  x[0][1] = sin_r;
2728  x[0][2] = 0;
2729 
2730  x[1][0] = -sin_r;
2731  x[1][1] = cos_r;
2732  x[1][2] = 0;
2733 
2734  x[2][0] = 0;
2735  x[2][1] = 0;
2736  x[2][2] = 1;
2737 
2738  return *this;
2739 }
2740 
2741 template <class T>
2742 template <class S>
2743 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2744 Matrix33<T>::rotate (S r) noexcept
2745 {
2746  *this *= Matrix33<T>().setRotation (r);
2747  return *this;
2748 }
2749 
2750 template <class T>
2751 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2753 {
2754  //
2755  // Set the matrix to a 2D homogeneous transform scale:
2756  // | s 0 0 |
2757  // | 0 s 0 |
2758  // | 0 0 1 |
2759  //
2760 
2761  x[0][0] = s;
2762  x[0][1] = 0;
2763  x[0][2] = 0;
2764  x[1][0] = 0;
2765  x[1][1] = s;
2766  x[1][2] = 0;
2767  x[2][0] = 0;
2768  x[2][1] = 0;
2769  x[2][2] = 1;
2770  return *this;
2771 }
2772 
2773 template <class T>
2774 template <class S>
2775 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2776 Matrix33<T>::setScale (const Vec2<S>& s) noexcept
2777 {
2778  //
2779  // Set the matrix to a 2D homogeneous transform scale:
2780  // | s.x 0 0 |
2781  // | 0 s.y 0 |
2782  // | 0 0 1 |
2783  //
2784 
2785  x[0][0] = s.x;
2786  x[0][1] = 0;
2787  x[0][2] = 0;
2788  x[1][0] = 0;
2789  x[1][1] = s.y;
2790  x[1][2] = 0;
2791  x[2][0] = 0;
2792  x[2][1] = 0;
2793  x[2][2] = 1;
2794  return *this;
2795 }
2796 
2797 template <class T>
2798 template <class S>
2799 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2800 Matrix33<T>::scale (const Vec2<S>& s) noexcept
2801 {
2802  x[0][0] *= s.x;
2803  x[0][1] *= s.x;
2804  x[0][2] *= s.x;
2805 
2806  x[1][0] *= s.y;
2807  x[1][1] *= s.y;
2808  x[1][2] *= s.y;
2809 
2810  return *this;
2811 }
2812 
2813 template <class T>
2814 template <class S>
2815 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2816 Matrix33<T>::setTranslation (const Vec2<S>& t) noexcept
2817 {
2818  x[0][0] = 1;
2819  x[0][1] = 0;
2820  x[0][2] = 0;
2821 
2822  x[1][0] = 0;
2823  x[1][1] = 1;
2824  x[1][2] = 0;
2825 
2826  x[2][0] = t.x;
2827  x[2][1] = t.y;
2828  x[2][2] = 1;
2829 
2830  return *this;
2831 }
2832 
2833 template <class T>
2834 constexpr inline Vec2<T>
2836 {
2837  return Vec2<T> (x[2][0], x[2][1]);
2838 }
2839 
2840 template <class T>
2841 template <class S>
2842 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2843 Matrix33<T>::translate (const Vec2<S>& t) noexcept
2844 {
2845  x[2][0] += t.x * x[0][0] + t.y * x[1][0];
2846  x[2][1] += t.x * x[0][1] + t.y * x[1][1];
2847  x[2][2] += t.x * x[0][2] + t.y * x[1][2];
2848 
2849  return *this;
2850 }
2851 
2852 template <class T>
2853 template <class S>
2854 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2855 Matrix33<T>::setShear (const S& xy) noexcept
2856 {
2857  x[0][0] = 1;
2858  x[0][1] = 0;
2859  x[0][2] = 0;
2860 
2861  x[1][0] = xy;
2862  x[1][1] = 1;
2863  x[1][2] = 0;
2864 
2865  x[2][0] = 0;
2866  x[2][1] = 0;
2867  x[2][2] = 1;
2868 
2869  return *this;
2870 }
2871 
2872 template <class T>
2873 template <class S>
2874 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2875 Matrix33<T>::setShear (const Vec2<S>& h) noexcept
2876 {
2877  x[0][0] = 1;
2878  x[0][1] = h.y;
2879  x[0][2] = 0;
2880 
2881  x[1][0] = h.x;
2882  x[1][1] = 1;
2883  x[1][2] = 0;
2884 
2885  x[2][0] = 0;
2886  x[2][1] = 0;
2887  x[2][2] = 1;
2888 
2889  return *this;
2890 }
2891 
2892 template <class T>
2893 template <class S>
2894 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2895 Matrix33<T>::shear (const S& xy) noexcept
2896 {
2897  //
2898  // In this case, we don't need a temp. copy of the matrix
2899  // because we never use a value on the RHS after we've
2900  // changed it on the LHS.
2901  //
2902 
2903  x[1][0] += xy * x[0][0];
2904  x[1][1] += xy * x[0][1];
2905  x[1][2] += xy * x[0][2];
2906 
2907  return *this;
2908 }
2909 
2910 template <class T>
2911 template <class S>
2912 ATOMSMATH_CONSTEXPR14 inline const Matrix33<T>&
2913 Matrix33<T>::shear (const Vec2<S>& h) noexcept
2914 {
2915  Matrix33<T> P (*this);
2916 
2917  x[0][0] = P[0][0] + h.y * P[1][0];
2918  x[0][1] = P[0][1] + h.y * P[1][1];
2919  x[0][2] = P[0][2] + h.y * P[1][2];
2920 
2921  x[1][0] = P[1][0] + h.x * P[0][0];
2922  x[1][1] = P[1][1] + h.x * P[0][1];
2923  x[1][2] = P[1][2] + h.x * P[0][2];
2924 
2925  return *this;
2926 }
2927 
2928 //---------------------------
2929 // Implementation of Matrix44
2930 //---------------------------
2931 
2932 template <class T>
2933 inline T*
2935 {
2936  return x[i];
2937 }
2938 
2939 template <class T>
2940 inline const T*
2941 Matrix44<T>::operator[] (int i) const noexcept
2942 {
2943  return x[i];
2944 }
2945 
2946 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44() noexcept
2947 {
2948  x[0][0] = 1;
2949  x[0][1] = 0;
2950  x[0][2] = 0;
2951  x[0][3] = 0;
2952  x[1][0] = 0;
2953  x[1][1] = 1;
2954  x[1][2] = 0;
2955  x[1][3] = 0;
2956  x[2][0] = 0;
2957  x[2][1] = 0;
2958  x[2][2] = 1;
2959  x[2][3] = 0;
2960  x[3][0] = 0;
2961  x[3][1] = 0;
2962  x[3][2] = 0;
2963  x[3][3] = 1;
2964 }
2965 
2966 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (T a) noexcept
2967 {
2968  x[0][0] = a;
2969  x[0][1] = a;
2970  x[0][2] = a;
2971  x[0][3] = a;
2972  x[1][0] = a;
2973  x[1][1] = a;
2974  x[1][2] = a;
2975  x[1][3] = a;
2976  x[2][0] = a;
2977  x[2][1] = a;
2978  x[2][2] = a;
2979  x[2][3] = a;
2980  x[3][0] = a;
2981  x[3][1] = a;
2982  x[3][2] = a;
2983  x[3][3] = a;
2984 }
2985 
2986 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (const T a[4][4]) noexcept
2987 {
2988  x[0][0] = a[0][0];
2989  x[0][1] = a[0][1];
2990  x[0][2] = a[0][2];
2991  x[0][3] = a[0][3];
2992  x[1][0] = a[1][0];
2993  x[1][1] = a[1][1];
2994  x[1][2] = a[1][2];
2995  x[1][3] = a[1][3];
2996  x[2][0] = a[2][0];
2997  x[2][1] = a[2][1];
2998  x[2][2] = a[2][2];
2999  x[2][3] = a[2][3];
3000  x[3][0] = a[3][0];
3001  x[3][1] = a[3][1];
3002  x[3][2] = a[3][2];
3003  x[3][3] = a[3][3];
3004 }
3005 
3006 template <class T>
3007 ATOMSMATH_CONSTEXPR14 inline Matrix44<
3008  T>::Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p) noexcept
3009 {
3010  x[0][0] = a;
3011  x[0][1] = b;
3012  x[0][2] = c;
3013  x[0][3] = d;
3014  x[1][0] = e;
3015  x[1][1] = f;
3016  x[1][2] = g;
3017  x[1][3] = h;
3018  x[2][0] = i;
3019  x[2][1] = j;
3020  x[2][2] = k;
3021  x[2][3] = l;
3022  x[3][0] = m;
3023  x[3][1] = n;
3024  x[3][2] = o;
3025  x[3][3] = p;
3026 }
3027 
3028 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (Matrix33<T> r, Vec3<T> t) noexcept
3029 {
3030  x[0][0] = r[0][0];
3031  x[0][1] = r[0][1];
3032  x[0][2] = r[0][2];
3033  x[0][3] = 0;
3034  x[1][0] = r[1][0];
3035  x[1][1] = r[1][1];
3036  x[1][2] = r[1][2];
3037  x[1][3] = 0;
3038  x[2][0] = r[2][0];
3039  x[2][1] = r[2][1];
3040  x[2][2] = r[2][2];
3041  x[2][3] = 0;
3042  x[3][0] = t.x;
3043  x[3][1] = t.y;
3044  x[3][2] = t.z;
3045  x[3][3] = 1;
3046 }
3047 
3048 template <class T> ATOMSMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (const Matrix44& v) noexcept
3049 {
3050  x[0][0] = v.x[0][0];
3051  x[0][1] = v.x[0][1];
3052  x[0][2] = v.x[0][2];
3053  x[0][3] = v.x[0][3];
3054  x[1][0] = v.x[1][0];
3055  x[1][1] = v.x[1][1];
3056  x[1][2] = v.x[1][2];
3057  x[1][3] = v.x[1][3];
3058  x[2][0] = v.x[2][0];
3059  x[2][1] = v.x[2][1];
3060  x[2][2] = v.x[2][2];
3061  x[2][3] = v.x[2][3];
3062  x[3][0] = v.x[3][0];
3063  x[3][1] = v.x[3][1];
3064  x[3][2] = v.x[3][2];
3065  x[3][3] = v.x[3][3];
3066 }
3067 
3068 template <class T>
3069 template <class S>
3070 ATOMSMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (const Matrix44<S>& v) noexcept
3071 {
3072  x[0][0] = T (v.x[0][0]);
3073  x[0][1] = T (v.x[0][1]);
3074  x[0][2] = T (v.x[0][2]);
3075  x[0][3] = T (v.x[0][3]);
3076  x[1][0] = T (v.x[1][0]);
3077  x[1][1] = T (v.x[1][1]);
3078  x[1][2] = T (v.x[1][2]);
3079  x[1][3] = T (v.x[1][3]);
3080  x[2][0] = T (v.x[2][0]);
3081  x[2][1] = T (v.x[2][1]);
3082  x[2][2] = T (v.x[2][2]);
3083  x[2][3] = T (v.x[2][3]);
3084  x[3][0] = T (v.x[3][0]);
3085  x[3][1] = T (v.x[3][1]);
3086  x[3][2] = T (v.x[3][2]);
3087  x[3][3] = T (v.x[3][3]);
3088 }
3089 
3090 template <class T>
3091 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3093 {
3094  x[0][0] = v.x[0][0];
3095  x[0][1] = v.x[0][1];
3096  x[0][2] = v.x[0][2];
3097  x[0][3] = v.x[0][3];
3098  x[1][0] = v.x[1][0];
3099  x[1][1] = v.x[1][1];
3100  x[1][2] = v.x[1][2];
3101  x[1][3] = v.x[1][3];
3102  x[2][0] = v.x[2][0];
3103  x[2][1] = v.x[2][1];
3104  x[2][2] = v.x[2][2];
3105  x[2][3] = v.x[2][3];
3106  x[3][0] = v.x[3][0];
3107  x[3][1] = v.x[3][1];
3108  x[3][2] = v.x[3][2];
3109  x[3][3] = v.x[3][3];
3110  return *this;
3111 }
3112 
3113 template <class T>
3114 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3116 {
3117  x[0][0] = a;
3118  x[0][1] = a;
3119  x[0][2] = a;
3120  x[0][3] = a;
3121  x[1][0] = a;
3122  x[1][1] = a;
3123  x[1][2] = a;
3124  x[1][3] = a;
3125  x[2][0] = a;
3126  x[2][1] = a;
3127  x[2][2] = a;
3128  x[2][3] = a;
3129  x[3][0] = a;
3130  x[3][1] = a;
3131  x[3][2] = a;
3132  x[3][3] = a;
3133  return *this;
3134 }
3135 
3136 template <class T>
3137 inline T*
3139 {
3140  return (T*) &x[0][0];
3141 }
3142 
3143 template <class T>
3144 inline const T*
3145 Matrix44<T>::getValue() const noexcept
3146 {
3147  return (const T*) &x[0][0];
3148 }
3149 
3150 template <class T>
3151 template <class S>
3152 inline void
3153 Matrix44<T>::getValue (Matrix44<S>& v) const noexcept
3154 {
3155  v.x[0][0] = x[0][0];
3156  v.x[0][1] = x[0][1];
3157  v.x[0][2] = x[0][2];
3158  v.x[0][3] = x[0][3];
3159  v.x[1][0] = x[1][0];
3160  v.x[1][1] = x[1][1];
3161  v.x[1][2] = x[1][2];
3162  v.x[1][3] = x[1][3];
3163  v.x[2][0] = x[2][0];
3164  v.x[2][1] = x[2][1];
3165  v.x[2][2] = x[2][2];
3166  v.x[2][3] = x[2][3];
3167  v.x[3][0] = x[3][0];
3168  v.x[3][1] = x[3][1];
3169  v.x[3][2] = x[3][2];
3170  v.x[3][3] = x[3][3];
3171 }
3172 
3173 template <class T>
3174 template <class S>
3175 ATOMSMATH_CONSTEXPR14 inline Matrix44<T>&
3176 Matrix44<T>::setValue (const Matrix44<S>& v) noexcept
3177 {
3178  x[0][0] = v.x[0][0];
3179  x[0][1] = v.x[0][1];
3180  x[0][2] = v.x[0][2];
3181  x[0][3] = v.x[0][3];
3182  x[1][0] = v.x[1][0];
3183  x[1][1] = v.x[1][1];
3184  x[1][2] = v.x[1][2];
3185  x[1][3] = v.x[1][3];
3186  x[2][0] = v.x[2][0];
3187  x[2][1] = v.x[2][1];
3188  x[2][2] = v.x[2][2];
3189  x[2][3] = v.x[2][3];
3190  x[3][0] = v.x[3][0];
3191  x[3][1] = v.x[3][1];
3192  x[3][2] = v.x[3][2];
3193  x[3][3] = v.x[3][3];
3194  return *this;
3195 }
3196 
3197 template <class T>
3198 template <class S>
3199 ATOMSMATH_CONSTEXPR14 inline Matrix44<T>&
3200 Matrix44<T>::setTheMatrix (const Matrix44<S>& v) noexcept
3201 {
3202  x[0][0] = v.x[0][0];
3203  x[0][1] = v.x[0][1];
3204  x[0][2] = v.x[0][2];
3205  x[0][3] = v.x[0][3];
3206  x[1][0] = v.x[1][0];
3207  x[1][1] = v.x[1][1];
3208  x[1][2] = v.x[1][2];
3209  x[1][3] = v.x[1][3];
3210  x[2][0] = v.x[2][0];
3211  x[2][1] = v.x[2][1];
3212  x[2][2] = v.x[2][2];
3213  x[2][3] = v.x[2][3];
3214  x[3][0] = v.x[3][0];
3215  x[3][1] = v.x[3][1];
3216  x[3][2] = v.x[3][2];
3217  x[3][3] = v.x[3][3];
3218  return *this;
3219 }
3220 
3221 template <class T>
3222 inline void
3224 {
3225  x[0][0] = 1;
3226  x[0][1] = 0;
3227  x[0][2] = 0;
3228  x[0][3] = 0;
3229  x[1][0] = 0;
3230  x[1][1] = 1;
3231  x[1][2] = 0;
3232  x[1][3] = 0;
3233  x[2][0] = 0;
3234  x[2][1] = 0;
3235  x[2][2] = 1;
3236  x[2][3] = 0;
3237  x[3][0] = 0;
3238  x[3][1] = 0;
3239  x[3][2] = 0;
3240  x[3][3] = 1;
3241 }
3242 
3243 template <class T>
3244 constexpr inline bool
3245 Matrix44<T>::operator== (const Matrix44& v) const noexcept
3246 {
3247  return x[0][0] == v.x[0][0] && x[0][1] == v.x[0][1] && x[0][2] == v.x[0][2] &&
3248  x[0][3] == v.x[0][3] && x[1][0] == v.x[1][0] && x[1][1] == v.x[1][1] &&
3249  x[1][2] == v.x[1][2] && x[1][3] == v.x[1][3] && x[2][0] == v.x[2][0] &&
3250  x[2][1] == v.x[2][1] && x[2][2] == v.x[2][2] && x[2][3] == v.x[2][3] &&
3251  x[3][0] == v.x[3][0] && x[3][1] == v.x[3][1] && x[3][2] == v.x[3][2] &&
3252  x[3][3] == v.x[3][3];
3253 }
3254 
3255 template <class T>
3256 constexpr inline bool
3257 Matrix44<T>::operator!= (const Matrix44& v) const noexcept
3258 {
3259  return x[0][0] != v.x[0][0] || x[0][1] != v.x[0][1] || x[0][2] != v.x[0][2] ||
3260  x[0][3] != v.x[0][3] || x[1][0] != v.x[1][0] || x[1][1] != v.x[1][1] ||
3261  x[1][2] != v.x[1][2] || x[1][3] != v.x[1][3] || x[2][0] != v.x[2][0] ||
3262  x[2][1] != v.x[2][1] || x[2][2] != v.x[2][2] || x[2][3] != v.x[2][3] ||
3263  x[3][0] != v.x[3][0] || x[3][1] != v.x[3][1] || x[3][2] != v.x[3][2] ||
3264  x[3][3] != v.x[3][3];
3265 }
3266 
3267 template <class T>
3268 ATOMSMATH_CONSTEXPR14 inline bool
3269 Matrix44<T>::equalWithAbsError (const Matrix44<T>& m, T e) const noexcept
3270 {
3271  for (int i = 0; i < 4; i++)
3272  for (int j = 0; j < 4; j++)
3273  if (!ATOMSMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
3274  return false;
3275 
3276  return true;
3277 }
3278 
3279 template <class T>
3280 ATOMSMATH_CONSTEXPR14 inline bool
3281 Matrix44<T>::equalWithRelError (const Matrix44<T>& m, T e) const noexcept
3282 {
3283  for (int i = 0; i < 4; i++)
3284  for (int j = 0; j < 4; j++)
3285  if (!ATOMSMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
3286  return false;
3287 
3288  return true;
3289 }
3290 
3291 template <class T>
3292 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3294 {
3295  x[0][0] += v.x[0][0];
3296  x[0][1] += v.x[0][1];
3297  x[0][2] += v.x[0][2];
3298  x[0][3] += v.x[0][3];
3299  x[1][0] += v.x[1][0];
3300  x[1][1] += v.x[1][1];
3301  x[1][2] += v.x[1][2];
3302  x[1][3] += v.x[1][3];
3303  x[2][0] += v.x[2][0];
3304  x[2][1] += v.x[2][1];
3305  x[2][2] += v.x[2][2];
3306  x[2][3] += v.x[2][3];
3307  x[3][0] += v.x[3][0];
3308  x[3][1] += v.x[3][1];
3309  x[3][2] += v.x[3][2];
3310  x[3][3] += v.x[3][3];
3311 
3312  return *this;
3313 }
3314 
3315 template <class T>
3316 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3318 {
3319  x[0][0] += a;
3320  x[0][1] += a;
3321  x[0][2] += a;
3322  x[0][3] += a;
3323  x[1][0] += a;
3324  x[1][1] += a;
3325  x[1][2] += a;
3326  x[1][3] += a;
3327  x[2][0] += a;
3328  x[2][1] += a;
3329  x[2][2] += a;
3330  x[2][3] += a;
3331  x[3][0] += a;
3332  x[3][1] += a;
3333  x[3][2] += a;
3334  x[3][3] += a;
3335 
3336  return *this;
3337 }
3338 
3339 template <class T>
3340 constexpr inline Matrix44<T>
3341 Matrix44<T>::operator+ (const Matrix44<T>& v) const noexcept
3342 {
3343  return Matrix44 (x[0][0] + v.x[0][0],
3344  x[0][1] + v.x[0][1],
3345  x[0][2] + v.x[0][2],
3346  x[0][3] + v.x[0][3],
3347  x[1][0] + v.x[1][0],
3348  x[1][1] + v.x[1][1],
3349  x[1][2] + v.x[1][2],
3350  x[1][3] + v.x[1][3],
3351  x[2][0] + v.x[2][0],
3352  x[2][1] + v.x[2][1],
3353  x[2][2] + v.x[2][2],
3354  x[2][3] + v.x[2][3],
3355  x[3][0] + v.x[3][0],
3356  x[3][1] + v.x[3][1],
3357  x[3][2] + v.x[3][2],
3358  x[3][3] + v.x[3][3]);
3359 }
3360 
3361 template <class T>
3362 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3364 {
3365  x[0][0] -= v.x[0][0];
3366  x[0][1] -= v.x[0][1];
3367  x[0][2] -= v.x[0][2];
3368  x[0][3] -= v.x[0][3];
3369  x[1][0] -= v.x[1][0];
3370  x[1][1] -= v.x[1][1];
3371  x[1][2] -= v.x[1][2];
3372  x[1][3] -= v.x[1][3];
3373  x[2][0] -= v.x[2][0];
3374  x[2][1] -= v.x[2][1];
3375  x[2][2] -= v.x[2][2];
3376  x[2][3] -= v.x[2][3];
3377  x[3][0] -= v.x[3][0];
3378  x[3][1] -= v.x[3][1];
3379  x[3][2] -= v.x[3][2];
3380  x[3][3] -= v.x[3][3];
3381 
3382  return *this;
3383 }
3384 
3385 template <class T>
3386 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3388 {
3389  x[0][0] -= a;
3390  x[0][1] -= a;
3391  x[0][2] -= a;
3392  x[0][3] -= a;
3393  x[1][0] -= a;
3394  x[1][1] -= a;
3395  x[1][2] -= a;
3396  x[1][3] -= a;
3397  x[2][0] -= a;
3398  x[2][1] -= a;
3399  x[2][2] -= a;
3400  x[2][3] -= a;
3401  x[3][0] -= a;
3402  x[3][1] -= a;
3403  x[3][2] -= a;
3404  x[3][3] -= a;
3405 
3406  return *this;
3407 }
3408 
3409 template <class T>
3410 constexpr inline Matrix44<T>
3411 Matrix44<T>::operator- (const Matrix44<T>& v) const noexcept
3412 {
3413  return Matrix44 (x[0][0] - v.x[0][0],
3414  x[0][1] - v.x[0][1],
3415  x[0][2] - v.x[0][2],
3416  x[0][3] - v.x[0][3],
3417  x[1][0] - v.x[1][0],
3418  x[1][1] - v.x[1][1],
3419  x[1][2] - v.x[1][2],
3420  x[1][3] - v.x[1][3],
3421  x[2][0] - v.x[2][0],
3422  x[2][1] - v.x[2][1],
3423  x[2][2] - v.x[2][2],
3424  x[2][3] - v.x[2][3],
3425  x[3][0] - v.x[3][0],
3426  x[3][1] - v.x[3][1],
3427  x[3][2] - v.x[3][2],
3428  x[3][3] - v.x[3][3]);
3429 }
3430 
3431 template <class T>
3432 constexpr inline Matrix44<T>
3433 Matrix44<T>::operator-() const noexcept
3434 {
3435  return Matrix44 (-x[0][0],
3436  -x[0][1],
3437  -x[0][2],
3438  -x[0][3],
3439  -x[1][0],
3440  -x[1][1],
3441  -x[1][2],
3442  -x[1][3],
3443  -x[2][0],
3444  -x[2][1],
3445  -x[2][2],
3446  -x[2][3],
3447  -x[3][0],
3448  -x[3][1],
3449  -x[3][2],
3450  -x[3][3]);
3451 }
3452 
3453 template <class T>
3454 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3456 {
3457  x[0][0] = -x[0][0];
3458  x[0][1] = -x[0][1];
3459  x[0][2] = -x[0][2];
3460  x[0][3] = -x[0][3];
3461  x[1][0] = -x[1][0];
3462  x[1][1] = -x[1][1];
3463  x[1][2] = -x[1][2];
3464  x[1][3] = -x[1][3];
3465  x[2][0] = -x[2][0];
3466  x[2][1] = -x[2][1];
3467  x[2][2] = -x[2][2];
3468  x[2][3] = -x[2][3];
3469  x[3][0] = -x[3][0];
3470  x[3][1] = -x[3][1];
3471  x[3][2] = -x[3][2];
3472  x[3][3] = -x[3][3];
3473 
3474  return *this;
3475 }
3476 
3477 template <class T>
3478 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3480 {
3481  x[0][0] *= a;
3482  x[0][1] *= a;
3483  x[0][2] *= a;
3484  x[0][3] *= a;
3485  x[1][0] *= a;
3486  x[1][1] *= a;
3487  x[1][2] *= a;
3488  x[1][3] *= a;
3489  x[2][0] *= a;
3490  x[2][1] *= a;
3491  x[2][2] *= a;
3492  x[2][3] *= a;
3493  x[3][0] *= a;
3494  x[3][1] *= a;
3495  x[3][2] *= a;
3496  x[3][3] *= a;
3497 
3498  return *this;
3499 }
3500 
3501 template <class T>
3502 constexpr inline Matrix44<T>
3503 Matrix44<T>::operator* (T a) const noexcept
3504 {
3505  return Matrix44 (x[0][0] * a,
3506  x[0][1] * a,
3507  x[0][2] * a,
3508  x[0][3] * a,
3509  x[1][0] * a,
3510  x[1][1] * a,
3511  x[1][2] * a,
3512  x[1][3] * a,
3513  x[2][0] * a,
3514  x[2][1] * a,
3515  x[2][2] * a,
3516  x[2][3] * a,
3517  x[3][0] * a,
3518  x[3][1] * a,
3519  x[3][2] * a,
3520  x[3][3] * a);
3521 }
3522 
3524 template <class T>
3525 inline Matrix44<T>
3526 operator* (T a, const Matrix44<T>& v) noexcept
3527 {
3528  return v * a;
3529 }
3530 
3531 template <class T>
3532 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3534 {
3535  Matrix44 tmp (T (0));
3536 
3537  multiply (*this, v, tmp);
3538  *this = tmp;
3539  return *this;
3540 }
3541 
3542 template <class T>
3543 ATOMSMATH_CONSTEXPR14 inline Matrix44<T>
3544 Matrix44<T>::operator* (const Matrix44<T>& v) const noexcept
3545 {
3546  Matrix44 tmp (T (0));
3547 
3548  multiply (*this, v, tmp);
3549  return tmp;
3550 }
3551 
3552 template <class T>
3553 inline void
3555 {
3556  const T* ATOMSMATH_RESTRICT ap = &a.x[0][0];
3557  const T* ATOMSMATH_RESTRICT bp = &b.x[0][0];
3558  T* ATOMSMATH_RESTRICT cp = &c.x[0][0];
3559 
3560  T a0, a1, a2, a3;
3561 
3562  a0 = ap[0];
3563  a1 = ap[1];
3564  a2 = ap[2];
3565  a3 = ap[3];
3566 
3567  cp[0] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
3568  cp[1] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
3569  cp[2] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
3570  cp[3] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
3571 
3572  a0 = ap[4];
3573  a1 = ap[5];
3574  a2 = ap[6];
3575  a3 = ap[7];
3576 
3577  cp[4] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
3578  cp[5] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
3579  cp[6] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
3580  cp[7] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
3581 
3582  a0 = ap[8];
3583  a1 = ap[9];
3584  a2 = ap[10];
3585  a3 = ap[11];
3586 
3587  cp[8] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
3588  cp[9] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
3589  cp[10] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
3590  cp[11] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
3591 
3592  a0 = ap[12];
3593  a1 = ap[13];
3594  a2 = ap[14];
3595  a3 = ap[15];
3596 
3597  cp[12] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12];
3598  cp[13] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13];
3599  cp[14] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14];
3600  cp[15] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15];
3601 }
3602 
3603 template <class T>
3604 template <class S>
3605 inline void
3606 Matrix44<T>::multVecMatrix (const Vec3<S>& src, Vec3<S>& dst) const noexcept
3607 {
3608  S a, b, c, w;
3609 
3610  a = src.x * x[0][0] + src.y * x[1][0] + src.z * x[2][0] + x[3][0];
3611  b = src.x * x[0][1] + src.y * x[1][1] + src.z * x[2][1] + x[3][1];
3612  c = src.x * x[0][2] + src.y * x[1][2] + src.z * x[2][2] + x[3][2];
3613  w = src.x * x[0][3] + src.y * x[1][3] + src.z * x[2][3] + x[3][3];
3614 
3615  dst.x = a / w;
3616  dst.y = b / w;
3617  dst.z = c / w;
3618 }
3619 
3620 template <class T>
3621 template <class S>
3622 inline void
3623 Matrix44<T>::multDirMatrix (const Vec3<S>& src, Vec3<S>& dst) const noexcept
3624 {
3625  S a, b, c;
3626 
3627  a = src.x * x[0][0] + src.y * x[1][0] + src.z * x[2][0];
3628  b = src.x * x[0][1] + src.y * x[1][1] + src.z * x[2][1];
3629  c = src.x * x[0][2] + src.y * x[1][2] + src.z * x[2][2];
3630 
3631  dst.x = a;
3632  dst.y = b;
3633  dst.z = c;
3634 }
3635 
3636 template <class T>
3637 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3639 {
3640  x[0][0] /= a;
3641  x[0][1] /= a;
3642  x[0][2] /= a;
3643  x[0][3] /= a;
3644  x[1][0] /= a;
3645  x[1][1] /= a;
3646  x[1][2] /= a;
3647  x[1][3] /= a;
3648  x[2][0] /= a;
3649  x[2][1] /= a;
3650  x[2][2] /= a;
3651  x[2][3] /= a;
3652  x[3][0] /= a;
3653  x[3][1] /= a;
3654  x[3][2] /= a;
3655  x[3][3] /= a;
3656 
3657  return *this;
3658 }
3659 
3660 template <class T>
3661 constexpr inline Matrix44<T>
3662 Matrix44<T>::operator/ (T a) const noexcept
3663 {
3664  return Matrix44 (x[0][0] / a,
3665  x[0][1] / a,
3666  x[0][2] / a,
3667  x[0][3] / a,
3668  x[1][0] / a,
3669  x[1][1] / a,
3670  x[1][2] / a,
3671  x[1][3] / a,
3672  x[2][0] / a,
3673  x[2][1] / a,
3674  x[2][2] / a,
3675  x[2][3] / a,
3676  x[3][0] / a,
3677  x[3][1] / a,
3678  x[3][2] / a,
3679  x[3][3] / a);
3680 }
3681 
3682 template <class T>
3683 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3685 {
3686  Matrix44 tmp (x[0][0],
3687  x[1][0],
3688  x[2][0],
3689  x[3][0],
3690  x[0][1],
3691  x[1][1],
3692  x[2][1],
3693  x[3][1],
3694  x[0][2],
3695  x[1][2],
3696  x[2][2],
3697  x[3][2],
3698  x[0][3],
3699  x[1][3],
3700  x[2][3],
3701  x[3][3]);
3702  *this = tmp;
3703  return *this;
3704 }
3705 
3706 template <class T>
3707 constexpr inline Matrix44<T>
3708 Matrix44<T>::transposed() const noexcept
3709 {
3710  return Matrix44 (x[0][0],
3711  x[1][0],
3712  x[2][0],
3713  x[3][0],
3714  x[0][1],
3715  x[1][1],
3716  x[2][1],
3717  x[3][1],
3718  x[0][2],
3719  x[1][2],
3720  x[2][2],
3721  x[3][2],
3722  x[0][3],
3723  x[1][3],
3724  x[2][3],
3725  x[3][3]);
3726 }
3727 
3728 template <class T>
3729 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3731 {
3732  *this = gjInverse (singExc);
3733  return *this;
3734 }
3735 
3736 template <class T>
3737 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3739 {
3740  *this = gjInverse();
3741  return *this;
3742 }
3743 
3744 template <class T>
3745 inline Matrix44<T>
3746 Matrix44<T>::gjInverse (bool singExc) const
3747 {
3748  int i, j, k;
3749  Matrix44 s;
3750  Matrix44 t (*this);
3751 
3752  // Forward elimination
3753 
3754  for (i = 0; i < 3; i++)
3755  {
3756  int pivot = i;
3757 
3758  T pivotsize = t[i][i];
3759 
3760  if (pivotsize < 0)
3761  pivotsize = -pivotsize;
3762 
3763  for (j = i + 1; j < 4; j++)
3764  {
3765  T tmp = t[j][i];
3766 
3767  if (tmp < 0)
3768  tmp = -tmp;
3769 
3770  if (tmp > pivotsize)
3771  {
3772  pivot = j;
3773  pivotsize = tmp;
3774  }
3775  }
3776 
3777  if (pivotsize == 0)
3778  {
3779  #ifdef ATOMS_USE_EXCEPTIONS
3780  if (singExc)
3781  throw std::invalid_argument ("Cannot invert singular matrix.");
3782  #endif
3783  return Matrix44();
3784  }
3785 
3786  if (pivot != i)
3787  {
3788  for (j = 0; j < 4; j++)
3789  {
3790  T tmp;
3791 
3792  tmp = t[i][j];
3793  t[i][j] = t[pivot][j];
3794  t[pivot][j] = tmp;
3795 
3796  tmp = s[i][j];
3797  s[i][j] = s[pivot][j];
3798  s[pivot][j] = tmp;
3799  }
3800  }
3801 
3802  for (j = i + 1; j < 4; j++)
3803  {
3804  T f = t[j][i] / t[i][i];
3805 
3806  for (k = 0; k < 4; k++)
3807  {
3808  t[j][k] -= f * t[i][k];
3809  s[j][k] -= f * s[i][k];
3810  }
3811  }
3812  }
3813 
3814  // Backward substitution
3815 
3816  for (i = 3; i >= 0; --i)
3817  {
3818  T f;
3819 
3820  if ((f = t[i][i]) == 0)
3821  {
3822  #ifdef ATOMS_USE_EXCEPTIONS
3823  if (singExc)
3824  throw std::invalid_argument ("Cannot invert singular matrix.");
3825  #endif
3826  return Matrix44();
3827  }
3828 
3829  for (j = 0; j < 4; j++)
3830  {
3831  t[i][j] /= f;
3832  s[i][j] /= f;
3833  }
3834 
3835  for (j = 0; j < i; j++)
3836  {
3837  f = t[j][i];
3838 
3839  for (k = 0; k < 4; k++)
3840  {
3841  t[j][k] -= f * t[i][k];
3842  s[j][k] -= f * s[i][k];
3843  }
3844  }
3845  }
3846 
3847  return s;
3848 }
3849 
3850 template <class T>
3851 inline Matrix44<T>
3852 Matrix44<T>::gjInverse() const noexcept
3853 {
3854  int i, j, k;
3855  Matrix44 s;
3856  Matrix44 t (*this);
3857 
3858  // Forward elimination
3859 
3860  for (i = 0; i < 3; i++)
3861  {
3862  int pivot = i;
3863 
3864  T pivotsize = t[i][i];
3865 
3866  if (pivotsize < 0)
3867  pivotsize = -pivotsize;
3868 
3869  for (j = i + 1; j < 4; j++)
3870  {
3871  T tmp = t[j][i];
3872 
3873  if (tmp < 0)
3874  tmp = -tmp;
3875 
3876  if (tmp > pivotsize)
3877  {
3878  pivot = j;
3879  pivotsize = tmp;
3880  }
3881  }
3882 
3883  if (pivotsize == 0)
3884  {
3885  return Matrix44();
3886  }
3887 
3888  if (pivot != i)
3889  {
3890  for (j = 0; j < 4; j++)
3891  {
3892  T tmp;
3893 
3894  tmp = t[i][j];
3895  t[i][j] = t[pivot][j];
3896  t[pivot][j] = tmp;
3897 
3898  tmp = s[i][j];
3899  s[i][j] = s[pivot][j];
3900  s[pivot][j] = tmp;
3901  }
3902  }
3903 
3904  for (j = i + 1; j < 4; j++)
3905  {
3906  T f = t[j][i] / t[i][i];
3907 
3908  for (k = 0; k < 4; k++)
3909  {
3910  t[j][k] -= f * t[i][k];
3911  s[j][k] -= f * s[i][k];
3912  }
3913  }
3914  }
3915 
3916  // Backward substitution
3917 
3918  for (i = 3; i >= 0; --i)
3919  {
3920  T f;
3921 
3922  if ((f = t[i][i]) == 0)
3923  {
3924  return Matrix44();
3925  }
3926 
3927  for (j = 0; j < 4; j++)
3928  {
3929  t[i][j] /= f;
3930  s[i][j] /= f;
3931  }
3932 
3933  for (j = 0; j < i; j++)
3934  {
3935  f = t[j][i];
3936 
3937  for (k = 0; k < 4; k++)
3938  {
3939  t[j][k] -= f * t[i][k];
3940  s[j][k] -= f * s[i][k];
3941  }
3942  }
3943  }
3944 
3945  return s;
3946 }
3947 
3948 template <class T>
3949 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3950 Matrix44<T>::invert (bool singExc)
3951 {
3952  *this = inverse (singExc);
3953  return *this;
3954 }
3955 
3956 template <class T>
3957 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
3959 {
3960  *this = inverse();
3961  return *this;
3962 }
3963 
3964 template <class T>
3965 ATOMSMATH_CONSTEXPR14 inline Matrix44<T>
3966 Matrix44<T>::inverse (bool singExc) const
3967 {
3968  if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
3969  return gjInverse (singExc);
3970 
3971  Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
3972  x[2][1] * x[0][2] - x[0][1] * x[2][2],
3973  x[0][1] * x[1][2] - x[1][1] * x[0][2],
3974  0,
3975 
3976  x[2][0] * x[1][2] - x[1][0] * x[2][2],
3977  x[0][0] * x[2][2] - x[2][0] * x[0][2],
3978  x[1][0] * x[0][2] - x[0][0] * x[1][2],
3979  0,
3980 
3981  x[1][0] * x[2][1] - x[2][0] * x[1][1],
3982  x[2][0] * x[0][1] - x[0][0] * x[2][1],
3983  x[0][0] * x[1][1] - x[1][0] * x[0][1],
3984  0,
3985 
3986  0,
3987  0,
3988  0,
3989  1);
3990 
3991  T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
3992 
3993  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
3994  {
3995  for (int i = 0; i < 3; ++i)
3996  {
3997  for (int j = 0; j < 3; ++j)
3998  {
3999  s[i][j] /= r;
4000  }
4001  }
4002  }
4003  else
4004  {
4005  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
4006 
4007  for (int i = 0; i < 3; ++i)
4008  {
4009  for (int j = 0; j < 3; ++j)
4010  {
4011  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
4012  {
4013  s[i][j] /= r;
4014  }
4015  else
4016  {
4017  #ifdef ATOMS_USE_EXCEPTIONS
4018  if (singExc)
4019  throw std::invalid_argument ("Cannot invert singular matrix.");
4020  #endif
4021  return Matrix44();
4022  }
4023  }
4024  }
4025  }
4026 
4027  s[3][0] = -x[3][0] * s[0][0] - x[3][1] * s[1][0] - x[3][2] * s[2][0];
4028  s[3][1] = -x[3][0] * s[0][1] - x[3][1] * s[1][1] - x[3][2] * s[2][1];
4029  s[3][2] = -x[3][0] * s[0][2] - x[3][1] * s[1][2] - x[3][2] * s[2][2];
4030 
4031  return s;
4032 }
4033 
4034 template <class T>
4035 ATOMSMATH_CONSTEXPR14 inline Matrix44<T>
4036 Matrix44<T>::inverse() const noexcept
4037 {
4038  if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
4039  return gjInverse();
4040 
4041  Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
4042  x[2][1] * x[0][2] - x[0][1] * x[2][2],
4043  x[0][1] * x[1][2] - x[1][1] * x[0][2],
4044  0,
4045 
4046  x[2][0] * x[1][2] - x[1][0] * x[2][2],
4047  x[0][0] * x[2][2] - x[2][0] * x[0][2],
4048  x[1][0] * x[0][2] - x[0][0] * x[1][2],
4049  0,
4050 
4051  x[1][0] * x[2][1] - x[2][0] * x[1][1],
4052  x[2][0] * x[0][1] - x[0][0] * x[2][1],
4053  x[0][0] * x[1][1] - x[1][0] * x[0][1],
4054  0,
4055 
4056  0,
4057  0,
4058  0,
4059  1);
4060 
4061  T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
4062 
4063  if (ATOMSMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
4064  {
4065  for (int i = 0; i < 3; ++i)
4066  {
4067  for (int j = 0; j < 3; ++j)
4068  {
4069  s[i][j] /= r;
4070  }
4071  }
4072  }
4073  else
4074  {
4075  T mr = ATOMSMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
4076 
4077  for (int i = 0; i < 3; ++i)
4078  {
4079  for (int j = 0; j < 3; ++j)
4080  {
4081  if (mr > ATOMSMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
4082  {
4083  s[i][j] /= r;
4084  }
4085  else
4086  {
4087  return Matrix44();
4088  }
4089  }
4090  }
4091  }
4092 
4093  s[3][0] = -x[3][0] * s[0][0] - x[3][1] * s[1][0] - x[3][2] * s[2][0];
4094  s[3][1] = -x[3][0] * s[0][1] - x[3][1] * s[1][1] - x[3][2] * s[2][1];
4095  s[3][2] = -x[3][0] * s[0][2] - x[3][1] * s[1][2] - x[3][2] * s[2][2];
4096 
4097  return s;
4098 }
4099 
4100 template <class T>
4101 constexpr inline T
4103  const int r1,
4104  const int r2,
4105  const int c0,
4106  const int c1,
4107  const int c2) const noexcept
4108 {
4109  return x[r0][c0] * (x[r1][c1] * x[r2][c2] - x[r1][c2] * x[r2][c1]) +
4110  x[r0][c1] * (x[r1][c2] * x[r2][c0] - x[r1][c0] * x[r2][c2]) +
4111  x[r0][c2] * (x[r1][c0] * x[r2][c1] - x[r1][c1] * x[r2][c0]);
4112 }
4113 
4114 template <class T>
4115 ATOMSMATH_CONSTEXPR14 inline T
4116 Matrix44<T>::minorOf (const int r, const int c) const noexcept
4117 {
4118  int r0 = 0 + (r < 1 ? 1 : 0);
4119  int r1 = 1 + (r < 2 ? 1 : 0);
4120  int r2 = 2 + (r < 3 ? 1 : 0);
4121  int c0 = 0 + (c < 1 ? 1 : 0);
4122  int c1 = 1 + (c < 2 ? 1 : 0);
4123  int c2 = 2 + (c < 3 ? 1 : 0);
4124 
4125  Matrix33<T> working (x[r0][c0],
4126  x[r1][c0],
4127  x[r2][c0],
4128  x[r0][c1],
4129  x[r1][c1],
4130  x[r2][c1],
4131  x[r0][c2],
4132  x[r1][c2],
4133  x[r2][c2]);
4134 
4135  return working.determinant();
4136 }
4137 
4138 template <class T>
4139 ATOMSMATH_CONSTEXPR14 inline T
4141 {
4142  T sum = (T) 0;
4143 
4144  if (x[0][3] != 0.)
4145  sum -= x[0][3] * fastMinor (1, 2, 3, 0, 1, 2);
4146  if (x[1][3] != 0.)
4147  sum += x[1][3] * fastMinor (0, 2, 3, 0, 1, 2);
4148  if (x[2][3] != 0.)
4149  sum -= x[2][3] * fastMinor (0, 1, 3, 0, 1, 2);
4150  if (x[3][3] != 0.)
4151  sum += x[3][3] * fastMinor (0, 1, 2, 0, 1, 2);
4152 
4153  return sum;
4154 }
4155 
4156 template <class T>
4157 template <class S>
4158 inline const Matrix44<T>&
4159 Matrix44<T>::setEulerAngles (const Vec3<S>& r) noexcept
4160 {
4161  S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
4162 
4163  cos_rz = cos ((T) r.z);
4164  cos_ry = cos ((T) r.y);
4165  cos_rx = cos ((T) r.x);
4166 
4167  sin_rz = sin ((T) r.z);
4168  sin_ry = sin ((T) r.y);
4169  sin_rx = sin ((T) r.x);
4170 
4171  x[0][0] = cos_rz * cos_ry;
4172  x[0][1] = sin_rz * cos_ry;
4173  x[0][2] = -sin_ry;
4174  x[0][3] = 0;
4175 
4176  x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
4177  x[1][1] = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
4178  x[1][2] = cos_ry * sin_rx;
4179  x[1][3] = 0;
4180 
4181  x[2][0] = sin_rz * sin_rx + cos_rz * sin_ry * cos_rx;
4182  x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx;
4183  x[2][2] = cos_ry * cos_rx;
4184  x[2][3] = 0;
4185 
4186  x[3][0] = 0;
4187  x[3][1] = 0;
4188  x[3][2] = 0;
4189  x[3][3] = 1;
4190 
4191  return *this;
4192 }
4193 
4194 template <class T>
4195 template <class S>
4196 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4197 Matrix44<T>::setAxisAngle (const Vec3<S>& axis, S angle) noexcept
4198 {
4199  Vec3<S> unit (axis.normalized());
4200  S sine = std::sin (angle);
4201  S cosine = std::cos (angle);
4202 
4203  x[0][0] = unit.x * unit.x * (1 - cosine) + cosine;
4204  x[0][1] = unit.x * unit.y * (1 - cosine) + unit.z * sine;
4205  x[0][2] = unit.x * unit.z * (1 - cosine) - unit.y * sine;
4206  x[0][3] = 0;
4207 
4208  x[1][0] = unit.x * unit.y * (1 - cosine) - unit.z * sine;
4209  x[1][1] = unit.y * unit.y * (1 - cosine) + cosine;
4210  x[1][2] = unit.y * unit.z * (1 - cosine) + unit.x * sine;
4211  x[1][3] = 0;
4212 
4213  x[2][0] = unit.x * unit.z * (1 - cosine) + unit.y * sine;
4214  x[2][1] = unit.y * unit.z * (1 - cosine) - unit.x * sine;
4215  x[2][2] = unit.z * unit.z * (1 - cosine) + cosine;
4216  x[2][3] = 0;
4217 
4218  x[3][0] = 0;
4219  x[3][1] = 0;
4220  x[3][2] = 0;
4221  x[3][3] = 1;
4222 
4223  return *this;
4224 }
4225 
4226 template <class T>
4227 template <class S>
4228 inline const Matrix44<T>&
4229 Matrix44<T>::rotate (const Vec3<S>& r) noexcept
4230 {
4231  S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
4232  S m00, m01, m02;
4233  S m10, m11, m12;
4234  S m20, m21, m22;
4235 
4236  cos_rz = cos ((S) r.z);
4237  cos_ry = cos ((S) r.y);
4238  cos_rx = cos ((S) r.x);
4239 
4240  sin_rz = sin ((S) r.z);
4241  sin_ry = sin ((S) r.y);
4242  sin_rx = sin ((S) r.x);
4243 
4244  m00 = cos_rz * cos_ry;
4245  m01 = sin_rz * cos_ry;
4246  m02 = -sin_ry;
4247  m10 = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
4248  m11 = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
4249  m12 = cos_ry * sin_rx;
4250  m20 = -sin_rz * -sin_rx + cos_rz * sin_ry * cos_rx;
4251  m21 = cos_rz * -sin_rx + sin_rz * sin_ry * cos_rx;
4252  m22 = cos_ry * cos_rx;
4253 
4254  Matrix44<T> P (*this);
4255 
4256  x[0][0] = P[0][0] * m00 + P[1][0] * m01 + P[2][0] * m02;
4257  x[0][1] = P[0][1] * m00 + P[1][1] * m01 + P[2][1] * m02;
4258  x[0][2] = P[0][2] * m00 + P[1][2] * m01 + P[2][2] * m02;
4259  x[0][3] = P[0][3] * m00 + P[1][3] * m01 + P[2][3] * m02;
4260 
4261  x[1][0] = P[0][0] * m10 + P[1][0] * m11 + P[2][0] * m12;
4262  x[1][1] = P[0][1] * m10 + P[1][1] * m11 + P[2][1] * m12;
4263  x[1][2] = P[0][2] * m10 + P[1][2] * m11 + P[2][2] * m12;
4264  x[1][3] = P[0][3] * m10 + P[1][3] * m11 + P[2][3] * m12;
4265 
4266  x[2][0] = P[0][0] * m20 + P[1][0] * m21 + P[2][0] * m22;
4267  x[2][1] = P[0][1] * m20 + P[1][1] * m21 + P[2][1] * m22;
4268  x[2][2] = P[0][2] * m20 + P[1][2] * m21 + P[2][2] * m22;
4269  x[2][3] = P[0][3] * m20 + P[1][3] * m21 + P[2][3] * m22;
4270 
4271  return *this;
4272 }
4273 
4274 template <class T>
4275 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4277 {
4278  //
4279  // Set the matrix to a 3D homogeneous transform scale:
4280  // | s 0 0 0 |
4281  // | 0 s 0 0 |
4282  // | 0 0 s 0 |
4283  // | 0 0 0 1 |
4284  //
4285 
4286  x[0][0] = s;
4287  x[0][1] = 0;
4288  x[0][2] = 0;
4289  x[0][3] = 0;
4290  x[1][0] = 0;
4291  x[1][1] = s;
4292  x[1][2] = 0;
4293  x[1][3] = 0;
4294  x[2][0] = 0;
4295  x[2][1] = 0;
4296  x[2][2] = s;
4297  x[2][3] = 0;
4298  x[3][0] = 0;
4299  x[3][1] = 0;
4300  x[3][2] = 0;
4301  x[3][3] = 1;
4302  return *this;
4303 }
4304 
4305 template <class T>
4306 template <class S>
4307 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4308 Matrix44<T>::setScale (const Vec3<S>& s) noexcept
4309 {
4310  //
4311  // Set the matrix to a 3D homogeneous transform scale:
4312  // | s.x 0 0 0 |
4313  // | 0 s.y 0 0 |
4314  // | 0 0 s.z 0 |
4315  // | 0 0 0 1 |
4316  //
4317 
4318  x[0][0] = s.x;
4319  x[0][1] = 0;
4320  x[0][2] = 0;
4321  x[0][3] = 0;
4322  x[1][0] = 0;
4323  x[1][1] = s.y;
4324  x[1][2] = 0;
4325  x[1][3] = 0;
4326  x[2][0] = 0;
4327  x[2][1] = 0;
4328  x[2][2] = s.z;
4329  x[2][3] = 0;
4330  x[3][0] = 0;
4331  x[3][1] = 0;
4332  x[3][2] = 0;
4333  x[3][3] = 1;
4334  return *this;
4335 }
4336 
4337 template <class T>
4338 template <class S>
4339 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4340 Matrix44<T>::scale (const Vec3<S>& s) noexcept
4341 {
4342  x[0][0] *= s.x;
4343  x[0][1] *= s.x;
4344  x[0][2] *= s.x;
4345  x[0][3] *= s.x;
4346 
4347  x[1][0] *= s.y;
4348  x[1][1] *= s.y;
4349  x[1][2] *= s.y;
4350  x[1][3] *= s.y;
4351 
4352  x[2][0] *= s.z;
4353  x[2][1] *= s.z;
4354  x[2][2] *= s.z;
4355  x[2][3] *= s.z;
4356 
4357  return *this;
4358 }
4359 
4360 template <class T>
4361 template <class S>
4362 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4363 Matrix44<T>::setTranslation (const Vec3<S>& t) noexcept
4364 {
4365  x[0][0] = 1;
4366  x[0][1] = 0;
4367  x[0][2] = 0;
4368  x[0][3] = 0;
4369 
4370  x[1][0] = 0;
4371  x[1][1] = 1;
4372  x[1][2] = 0;
4373  x[1][3] = 0;
4374 
4375  x[2][0] = 0;
4376  x[2][1] = 0;
4377  x[2][2] = 1;
4378  x[2][3] = 0;
4379 
4380  x[3][0] = t.x;
4381  x[3][1] = t.y;
4382  x[3][2] = t.z;
4383  x[3][3] = 1;
4384 
4385  return *this;
4386 }
4387 
4388 template <class T>
4389 constexpr inline const Vec3<T>
4391 {
4392  return Vec3<T> (x[3][0], x[3][1], x[3][2]);
4393 }
4394 
4395 template <class T>
4396 template <class S>
4397 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4398 Matrix44<T>::translate (const Vec3<S>& t) noexcept
4399 {
4400  x[3][0] += t.x * x[0][0] + t.y * x[1][0] + t.z * x[2][0];
4401  x[3][1] += t.x * x[0][1] + t.y * x[1][1] + t.z * x[2][1];
4402  x[3][2] += t.x * x[0][2] + t.y * x[1][2] + t.z * x[2][2];
4403  x[3][3] += t.x * x[0][3] + t.y * x[1][3] + t.z * x[2][3];
4404 
4405  return *this;
4406 }
4407 
4408 template <class T>
4409 template <class S>
4410 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4411 Matrix44<T>::setShear (const Vec3<S>& h) noexcept
4412 {
4413  x[0][0] = 1;
4414  x[0][1] = 0;
4415  x[0][2] = 0;
4416  x[0][3] = 0;
4417 
4418  x[1][0] = h.x;
4419  x[1][1] = 1;
4420  x[1][2] = 0;
4421  x[1][3] = 0;
4422 
4423  x[2][0] = h.y;
4424  x[2][1] = h.z;
4425  x[2][2] = 1;
4426  x[2][3] = 0;
4427 
4428  x[3][0] = 0;
4429  x[3][1] = 0;
4430  x[3][2] = 0;
4431  x[3][3] = 1;
4432 
4433  return *this;
4434 }
4435 
4436 template <class T>
4437 template <class S>
4438 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4439 Matrix44<T>::setShear (const Shear6<S>& h) noexcept
4440 {
4441  x[0][0] = 1;
4442  x[0][1] = h.yx;
4443  x[0][2] = h.zx;
4444  x[0][3] = 0;
4445 
4446  x[1][0] = h.xy;
4447  x[1][1] = 1;
4448  x[1][2] = h.zy;
4449  x[1][3] = 0;
4450 
4451  x[2][0] = h.xz;
4452  x[2][1] = h.yz;
4453  x[2][2] = 1;
4454  x[2][3] = 0;
4455 
4456  x[3][0] = 0;
4457  x[3][1] = 0;
4458  x[3][2] = 0;
4459  x[3][3] = 1;
4460 
4461  return *this;
4462 }
4463 
4464 template <class T>
4465 template <class S>
4466 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4467 Matrix44<T>::shear (const Vec3<S>& h) noexcept
4468 {
4469  //
4470  // In this case, we don't need a temp. copy of the matrix
4471  // because we never use a value on the RHS after we've
4472  // changed it on the LHS.
4473  //
4474 
4475  for (int i = 0; i < 4; i++)
4476  {
4477  x[2][i] += h.y * x[0][i] + h.z * x[1][i];
4478  x[1][i] += h.x * x[0][i];
4479  }
4480 
4481  return *this;
4482 }
4483 
4484 template <class T>
4485 template <class S>
4486 ATOMSMATH_CONSTEXPR14 inline const Matrix44<T>&
4487 Matrix44<T>::shear (const Shear6<S>& h) noexcept
4488 {
4489  Matrix44<T> P (*this);
4490 
4491  for (int i = 0; i < 4; i++)
4492  {
4493  x[0][i] = P[0][i] + h.yx * P[1][i] + h.zx * P[2][i];
4494  x[1][i] = h.xy * P[0][i] + P[1][i] + h.zy * P[2][i];
4495  x[2][i] = h.xz * P[0][i] + h.yz * P[1][i] + P[2][i];
4496  }
4497 
4498  return *this;
4499 }
4500 
4501 //--------------------------------
4502 // Implementation of stream output
4503 //--------------------------------
4504 
4505 template <class T>
4506 std::ostream&
4507 operator<< (std::ostream& s, const Matrix22<T>& m)
4508 {
4509  std::ios_base::fmtflags oldFlags = s.flags();
4510  int width;
4511 
4512  if (s.flags() & std::ios_base::fixed)
4513  {
4514  s.setf (std::ios_base::showpoint);
4515  width = static_cast<int> (s.precision()) + 5;
4516  }
4517  else
4518  {
4519  s.setf (std::ios_base::scientific);
4520  s.setf (std::ios_base::showpoint);
4521  width = static_cast<int> (s.precision()) + 8;
4522  }
4523 
4524  s << "(" << std::setw (width) << m[0][0] << ", " << std::setw (width) << m[0][1] << ",\n"
4525  <<
4526 
4527  " " << std::setw (width) << m[1][0] << ", " << std::setw (width) << m[1][1] << ")\n";
4528 
4529  s.flags (oldFlags);
4530  return s;
4531 }
4532 
4533 template <class T>
4534 std::ostream&
4535 operator<< (std::ostream& s, const Matrix33<T>& m)
4536 {
4537  std::ios_base::fmtflags oldFlags = s.flags();
4538  int width;
4539 
4540  if (s.flags() & std::ios_base::fixed)
4541  {
4542  s.setf (std::ios_base::showpoint);
4543  width = static_cast<int> (s.precision()) + 5;
4544  }
4545  else
4546  {
4547  s.setf (std::ios_base::scientific);
4548  s.setf (std::ios_base::showpoint);
4549  width = static_cast<int> (s.precision()) + 8;
4550  }
4551 
4552  s << "(" << std::setw (width) << m[0][0] << ", " << std::setw (width) << m[0][1] << ", "
4553  << std::setw (width) << m[0][2] << ",\n"
4554  <<
4555 
4556  " " << std::setw (width) << m[1][0] << ", " << std::setw (width) << m[1][1] << ", "
4557  << std::setw (width) << m[1][2] << ",\n"
4558  <<
4559 
4560  " " << std::setw (width) << m[2][0] << ", " << std::setw (width) << m[2][1] << ", "
4561  << std::setw (width) << m[2][2] << ")\n";
4562 
4563  s.flags (oldFlags);
4564  return s;
4565 }
4566 
4567 template <class T>
4568 std::ostream&
4569 operator<< (std::ostream& s, const Matrix44<T>& m)
4570 {
4571  std::ios_base::fmtflags oldFlags = s.flags();
4572  int width;
4573 
4574  if (s.flags() & std::ios_base::fixed)
4575  {
4576  s.setf (std::ios_base::showpoint);
4577  width = static_cast<int> (s.precision()) + 5;
4578  }
4579  else
4580  {
4581  s.setf (std::ios_base::scientific);
4582  s.setf (std::ios_base::showpoint);
4583  width = static_cast<int> (s.precision()) + 8;
4584  }
4585 
4586  s << "(" << std::setw (width) << m[0][0] << ", " << std::setw (width) << m[0][1] << ", "
4587  << std::setw (width) << m[0][2] << ", " << std::setw (width) << m[0][3] << ",\n"
4588  <<
4589 
4590  " " << std::setw (width) << m[1][0] << ", " << std::setw (width) << m[1][1] << ", "
4591  << std::setw (width) << m[1][2] << ", " << std::setw (width) << m[1][3] << ",\n"
4592  <<
4593 
4594  " " << std::setw (width) << m[2][0] << ", " << std::setw (width) << m[2][1] << ", "
4595  << std::setw (width) << m[2][2] << ", " << std::setw (width) << m[2][3] << ",\n"
4596  <<
4597 
4598  " " << std::setw (width) << m[3][0] << ", " << std::setw (width) << m[3][1] << ", "
4599  << std::setw (width) << m[3][2] << ", " << std::setw (width) << m[3][3] << ")\n";
4600 
4601  s.flags (oldFlags);
4602  return s;
4603 }
4604 
4605 //---------------------------------------------------------------
4606 // Implementation of vector-times-matrix multiplication operators
4607 //---------------------------------------------------------------
4608 
4609 template <class S, class T>
4610 inline const Vec2<S>&
4611 operator*= (Vec2<S>& v, const Matrix22<T>& m) noexcept
4612 {
4613  S x = S (v.x * m[0][0] + v.y * m[1][0]);
4614  S y = S (v.x * m[0][1] + v.y * m[1][1]);
4615 
4616  v.x = x;
4617  v.y = y;
4618 
4619  return v;
4620 }
4621 
4622 template <class S, class T>
4623 inline Vec2<S>
4624 operator* (const Vec2<S>& v, const Matrix22<T>& m) noexcept
4625 {
4626  S x = S (v.x * m[0][0] + v.y * m[1][0]);
4627  S y = S (v.x * m[0][1] + v.y * m[1][1]);
4628 
4629  return Vec2<S> (x, y);
4630 }
4631 
4632 template <class S, class T>
4633 inline const Vec2<S>&
4634 operator*= (Vec2<S>& v, const Matrix33<T>& m) noexcept
4635 {
4636  S x = S (v.x * m[0][0] + v.y * m[1][0] + m[2][0]);
4637  S y = S (v.x * m[0][1] + v.y * m[1][1] + m[2][1]);
4638  S w = S (v.x * m[0][2] + v.y * m[1][2] + m[2][2]);
4639 
4640  v.x = x / w;
4641  v.y = y / w;
4642 
4643  return v;
4644 }
4645 
4646 template <class S, class T>
4647 inline Vec2<S>
4648 operator* (const Vec2<S>& v, const Matrix33<T>& m) noexcept
4649 {
4650  S x = S (v.x * m[0][0] + v.y * m[1][0] + m[2][0]);
4651  S y = S (v.x * m[0][1] + v.y * m[1][1] + m[2][1]);
4652  S w = S (v.x * m[0][2] + v.y * m[1][2] + m[2][2]);
4653 
4654  return Vec2<S> (x / w, y / w);
4655 }
4656 
4657 template <class S, class T>
4658 inline const Vec3<S>&
4659 operator*= (Vec3<S>& v, const Matrix33<T>& m) noexcept
4660 {
4661  S x = S (v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);
4662  S y = S (v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);
4663  S z = S (v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);
4664 
4665  v.x = x;
4666  v.y = y;
4667  v.z = z;
4668 
4669  return v;
4670 }
4671 
4672 template <class S, class T>
4673 inline Vec3<S>
4674 operator* (const Vec3<S>& v, const Matrix33<T>& m) noexcept
4675 {
4676  S x = S (v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]);
4677  S y = S (v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]);
4678  S z = S (v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);
4679 
4680  return Vec3<S> (x, y, z);
4681 }
4682 
4683 template <class S, class T>
4684 inline const Vec3<S>&
4685 operator*= (Vec3<S>& v, const Matrix44<T>& m) noexcept
4686 {
4687  S x = S (v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);
4688  S y = S (v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);
4689  S z = S (v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);
4690  S w = S (v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);
4691 
4692  v.x = x / w;
4693  v.y = y / w;
4694  v.z = z / w;
4695 
4696  return v;
4697 }
4698 
4699 template <class S, class T>
4700 inline Vec3<S>
4701 operator* (const Vec3<S>& v, const Matrix44<T>& m) noexcept
4702 {
4703  S x = S (v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]);
4704  S y = S (v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]);
4705  S z = S (v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]);
4706  S w = S (v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]);
4707 
4708  return Vec3<S> (x / w, y / w, z / w);
4709 }
4710 
4711 template <class S, class T>
4712 inline const Vec4<S>&
4713 operator*= (Vec4<S>& v, const Matrix44<T>& m) noexcept
4714 {
4715  S x = S (v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);
4716  S y = S (v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);
4717  S z = S (v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);
4718  S w = S (v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);
4719 
4720  v.x = x;
4721  v.y = y;
4722  v.z = z;
4723  v.w = w;
4724 
4725  return v;
4726 }
4727 
4728 template <class S, class T>
4729 inline Vec4<S>
4730 operator* (const Vec4<S>& v, const Matrix44<T>& m) noexcept
4731 {
4732  S x = S (v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]);
4733  S y = S (v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]);
4734  S z = S (v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]);
4735  S w = S (v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);
4736 
4737  return Vec4<S> (x, y, z, w);
4738 }
4739 
4740 ATOMSMATH_INTERNAL_NAMESPACE_HEADER_EXIT
4741 
4742 #endif // INCLUDED_ATOMSMATHMATRIX_H
Definition: ImathMatrix.h:44
ATOMSMATH_HOSTDEVICE void multDirMatrix(const Vec2< S > &src, Vec2< S > &dst) const noexcept
constexpr ATOMSMATH_HOSTDEVICE Matrix22 operator-() const noexcept
Component-wise multiplication by -1.
Definition: ImathMatrix.h:1347
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & operator+=(const Matrix22 &v) noexcept
Component-wise addition.
Definition: ImathMatrix.h:1279
Vec2< T > BaseVecType
The base vector type.
Definition: ImathMatrix.h:280
constexpr ATOMSMATH_HOSTDEVICE Matrix22 transposed() const noexcept
Return the transpose.
Definition: ImathMatrix.h:1464
ATOMSMATH_HOSTDEVICE T * getValue() noexcept
Return a raw pointer to the array of values.
Definition: ImathMatrix.h:1180
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithRelError(const Matrix22< T > &v, T e) const noexcept
Definition: ImathMatrix.h:1267
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeMax() noexcept
Largest possible positive value.
Definition: ImathMatrix.h:262
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & invert() noexcept
Definition: ImathMatrix.h:1479
constexpr ATOMSMATH_HOSTDEVICE Matrix22 operator+(const Matrix22 &v) const noexcept
Component-wise addition.
Definition: ImathMatrix.h:1303
constexpr ATOMSMATH_HOSTDEVICE Matrix22 operator/(T a) const noexcept
Component-wise division.
Definition: ImathMatrix.h:1448
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22< T > inverse() const noexcept
Return the inverse, leaving this unmodified.
Definition: ImathMatrix.h:1532
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22() noexcept
Uninitialized.
Definition: ImathMatrix.h:1094
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & transpose() noexcept
Transpose.
Definition: ImathMatrix.h:1455
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeSmallest() noexcept
Smallest possible positive value.
Definition: ImathMatrix.h:265
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22 & setTheMatrix(const Matrix22< S > &v) noexcept
Set the value.
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix22 & setValue(const Matrix22< S > &v) noexcept
Set the value.
constexpr ATOMSMATH_HOSTDEVICE Matrix22 operator*(T a) const noexcept
Component-wise multiplication.
Definition: ImathMatrix.h:1378
constexpr static ATOMSMATH_HOSTDEVICE unsigned int dimensions() noexcept
Return the number of the row and column dimensions, i.e. 2.
Definition: ImathMatrix.h:273
ATOMSMATH_HOSTDEVICE T * operator[](int i) noexcept
Row access.
Definition: ImathMatrix.h:1082
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & operator/=(T a) noexcept
Component-wise division.
Definition: ImathMatrix.h:1436
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithAbsError(const Matrix22< T > &v, T e) const noexcept
Definition: ImathMatrix.h:1255
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & rotate(S r) noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & setScale(T s) noexcept
Definition: ImathMatrix.h:1609
T x[2][2]
Matrix elements.
Definition: ImathMatrix.h:51
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & negate() noexcept
Component-wise multiplication by -1.
Definition: ImathMatrix.h:1354
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & operator*=(T a) noexcept
Component-wise multiplication.
Definition: ImathMatrix.h:1366
constexpr ATOMSMATH_HOSTDEVICE bool operator!=(const Matrix22 &v) const noexcept
Inequality.
Definition: ImathMatrix.h:1247
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & operator=(const Matrix22 &v) noexcept
Assignment.
Definition: ImathMatrix.h:1154
T BaseType
Definition: ImathMatrix.h:277
ATOMSMATH_HOSTDEVICE const Matrix22 & setRotation(S r) noexcept
constexpr ATOMSMATH_HOSTDEVICE T determinant() const noexcept
Determinant.
Definition: ImathMatrix.h:1572
ATOMSMATH_HOSTDEVICE void makeIdentity() noexcept
Set to the identity.
Definition: ImathMatrix.h:1229
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & operator-=(const Matrix22 &v) noexcept
Component-wise subtraction.
Definition: ImathMatrix.h:1313
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeLowest() noexcept
Largest possible negative value.
Definition: ImathMatrix.h:259
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeEpsilon() noexcept
Smallest possible e for which 1+e != 1.
Definition: ImathMatrix.h:268
constexpr ATOMSMATH_HOSTDEVICE bool operator==(const Matrix22 &v) const noexcept
Equality.
Definition: ImathMatrix.h:1239
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix22 & scale(const Vec2< S > &s) noexcept
Definition: ImathMatrix.h:305
constexpr ATOMSMATH_HOSTDEVICE Matrix33 operator/(T a) const noexcept
Component-wise division.
Definition: ImathMatrix.h:2195
constexpr ATOMSMATH_HOSTDEVICE bool operator==(const Matrix33 &v) const noexcept
Equality.
Definition: ImathMatrix.h:1890
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & operator-=(const Matrix33 &v) noexcept
Component-wise subtraction.
Definition: ImathMatrix.h:1981
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 T minorOf(const int r, const int c) const noexcept
Calculate the matrix minor of the (r,c) element.
Definition: ImathMatrix.h:2690
constexpr ATOMSMATH_HOSTDEVICE T determinant() const noexcept
Determinant.
Definition: ImathMatrix.h:2709
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33() noexcept
Uninitialized.
Definition: ImathMatrix.h:1680
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeSmallest() noexcept
Smallest possible positive value.
Definition: ImathMatrix.h:592
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & setShear(const S &h) noexcept
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeLowest() noexcept
Largest possible negative value.
Definition: ImathMatrix.h:586
Vec3< T > BaseVecType
The base vector type.
Definition: ImathMatrix.h:606
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & operator/=(T a) noexcept
Component-wise division.
Definition: ImathMatrix.h:2178
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & invert() noexcept
Definition: ImathMatrix.h:2462
constexpr ATOMSMATH_HOSTDEVICE Matrix33 transposed() const noexcept
Return the transpose.
Definition: ImathMatrix.h:2219
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & setScale(T s) noexcept
Definition: ImathMatrix.h:2752
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & translate(const Vec2< S > &t) noexcept
ATOMSMATH_HOSTDEVICE T * operator[](int i) noexcept
Row access.
Definition: ImathMatrix.h:1666
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & scale(const Vec2< S > &s) noexcept
constexpr ATOMSMATH_HOSTDEVICE Matrix33 operator*(T a) const noexcept
Component-wise multiplication.
Definition: ImathMatrix.h:2079
constexpr ATOMSMATH_HOSTDEVICE Vec2< T > translation() const noexcept
Return the translation component.
Definition: ImathMatrix.h:2835
T x[3][3]
Matrix elements.
Definition: ImathMatrix.h:312
ATOMSMATH_HOSTDEVICE const Matrix33 & setRotation(S r) noexcept
ATOMSMATH_HOSTDEVICE void multDirMatrix(const Vec2< S > &src, Vec2< S > &dst) const noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & negate() noexcept
Component-wise multiplication by -1.
Definition: ImathMatrix.h:2045
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33< T > inverse() const noexcept
Return the inverse using the determinant, leaving this unmodified.
Definition: ImathMatrix.h:2585
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33 & setTheMatrix(const Matrix33< S > &v) noexcept
Set the value.
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & operator=(const Matrix33 &v) noexcept
Assignment operator.
Definition: ImathMatrix.h:1774
constexpr ATOMSMATH_HOSTDEVICE bool operator!=(const Matrix33 &v) const noexcept
Inequality.
Definition: ImathMatrix.h:1899
constexpr ATOMSMATH_HOSTDEVICE Matrix33 operator+(const Matrix33 &v) const noexcept
Component-wise addition.
Definition: ImathMatrix.h:1966
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & shear(const S &xy) noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & transpose() noexcept
Transpose.
Definition: ImathMatrix.h:2210
constexpr ATOMSMATH_HOSTDEVICE T fastMinor(const int r0, const int r1, const int c0, const int c1) const noexcept
Build a minor using the specified rows and columns.
Definition: ImathMatrix.h:2702
ATOMSMATH_HOSTDEVICE const Matrix33 & gjInvert() noexcept
Definition: ImathMatrix.h:2242
ATOMSMATH_HOSTDEVICE void makeIdentity() noexcept
Set to the identity matrix.
Definition: ImathMatrix.h:1875
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeEpsilon() noexcept
Smallest possible e for which 1+e != 1.
Definition: ImathMatrix.h:595
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix33 & setValue(const Matrix33< S > &v) noexcept
Set the value.
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithAbsError(const Matrix33< T > &v, T e) const noexcept
Definition: ImathMatrix.h:1908
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeMax() noexcept
Largest possible positive value.
Definition: ImathMatrix.h:589
ATOMSMATH_HOSTDEVICE T * getValue() noexcept
Return a raw pointer to the array of values.
Definition: ImathMatrix.h:1811
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & rotate(S r) noexcept
ATOMSMATH_HOSTDEVICE Matrix33< T > gjInverse() const noexcept
Definition: ImathMatrix.h:2356
constexpr static ATOMSMATH_HOSTDEVICE unsigned int dimensions() noexcept
Return the number of the row and column dimensions, i.e. 3.
Definition: ImathMatrix.h:600
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & operator*=(T a) noexcept
Component-wise multiplication.
Definition: ImathMatrix.h:2062
ATOMSMATH_HOSTDEVICE void multVecMatrix(const Vec2< S > &src, Vec2< S > &dst) const noexcept
constexpr ATOMSMATH_HOSTDEVICE Matrix33 operator-() const noexcept
Component-wise multiplication by -1.
Definition: ImathMatrix.h:2030
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & operator+=(const Matrix33 &v) noexcept
Component-wise addition.
Definition: ImathMatrix.h:1932
T BaseType
The base type: In templates that accept a parameter V (could be a Color4), you can refer to T as V::B...
Definition: ImathMatrix.h:603
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix33 & setTranslation(const Vec2< S > &t) noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithRelError(const Matrix33< T > &v, T e) const noexcept
Definition: ImathMatrix.h:1920
Definition: ImathMatrix.h:631
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & setAxisAngle(const Vec3< S > &ax, S ang) noexcept
constexpr ATOMSMATH_HOSTDEVICE bool operator==(const Matrix44 &v) const noexcept
Equality.
Definition: ImathMatrix.h:3245
constexpr static ATOMSMATH_HOSTDEVICE unsigned int dimensions() noexcept
Return the number of the row and column dimensions, i.e. 4.
Definition: ImathMatrix.h:975
constexpr ATOMSMATH_HOSTDEVICE Matrix44 operator/(T a) const noexcept
Component-wise division.
Definition: ImathMatrix.h:3662
constexpr ATOMSMATH_HOSTDEVICE Matrix44 transposed() const noexcept
Return the transpose.
Definition: ImathMatrix.h:3708
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & gjInvert() noexcept
Definition: ImathMatrix.h:3738
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeMax() noexcept
Largest possible positive value.
Definition: ImathMatrix.h:964
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeSmallest() noexcept
Smallest possible positive value.
Definition: ImathMatrix.h:967
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & operator+=(const Matrix44 &v) noexcept
Component-wise addition.
Definition: ImathMatrix.h:3293
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44 & setTheMatrix(const Matrix44< S > &v) noexcept
Set the value.
constexpr ATOMSMATH_HOSTDEVICE bool operator!=(const Matrix44 &v) const noexcept
Inequality.
Definition: ImathMatrix.h:3257
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44 & setValue(const Matrix44< S > &v) noexcept
Set the value.
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & operator=(const Matrix44 &v) noexcept
Assignment operator.
Definition: ImathMatrix.h:3092
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithRelError(const Matrix44< T > &v, T e) const noexcept
Definition: ImathMatrix.h:3281
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & scale(const Vec3< S > &s) noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & negate() noexcept
Component-wise multiplication by -1.
Definition: ImathMatrix.h:3455
constexpr ATOMSMATH_HOSTDEVICE T fastMinor(const int r0, const int r1, const int r2, const int c0, const int c1, const int c2) const noexcept
Build a minor using the specified rows and columns.
Definition: ImathMatrix.h:4102
ATOMSMATH_HOSTDEVICE void makeIdentity() noexcept
Set to the identity matrix.
Definition: ImathMatrix.h:3223
ATOMSMATH_HOSTDEVICE void multDirMatrix(const Vec3< S > &src, Vec3< S > &dst) const noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 bool equalWithAbsError(const Matrix44< T > &v, T e) const noexcept
Definition: ImathMatrix.h:3269
constexpr ATOMSMATH_HOSTDEVICE Matrix44 operator-() const noexcept
Component-wise multiplication by -1.
Definition: ImathMatrix.h:3433
Vec4< T > BaseVecType
The base vector type.
Definition: ImathMatrix.h:981
ATOMSMATH_HOSTDEVICE T * operator[](int i) noexcept
Row access.
Definition: ImathMatrix.h:2934
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeLowest() noexcept
Largest possible negative value.
Definition: ImathMatrix.h:961
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & operator/=(T a) noexcept
Component-wise division.
Definition: ImathMatrix.h:3638
T BaseType
The base type: In templates that accept a parameter V (could be a Color4), you can refer to T as V::B...
Definition: ImathMatrix.h:978
ATOMSMATH_HOSTDEVICE T * getValue() noexcept
Return a raw pointer to the array of values.
Definition: ImathMatrix.h:3138
constexpr static ATOMSMATH_HOSTDEVICE T baseTypeEpsilon() noexcept
Smallest possible e for which 1+e != 1.
Definition: ImathMatrix.h:970
static ATOMSMATH_HOSTDEVICE void multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &c) noexcept
Matrix-matrix multiplication: compute c = a * b.
Definition: ImathMatrix.h:3554
T x[4][4]
Matrix elements.
Definition: ImathMatrix.h:638
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & setShear(const Vec3< S > &h) noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & translate(const Vec3< S > &t) noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & operator*=(T a) noexcept
Component-wise multiplication.
Definition: ImathMatrix.h:3479
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & operator-=(const Matrix44 &v) noexcept
Component-wise subtraction.
Definition: ImathMatrix.h:3363
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & transpose() noexcept
Transpose.
Definition: ImathMatrix.h:3684
ATOMSMATH_HOSTDEVICE const Matrix44 & rotate(const Vec3< S > &r) noexcept
ATOMSMATH_HOSTDEVICE const Matrix44 & setEulerAngles(const Vec3< S > &r) noexcept
constexpr ATOMSMATH_HOSTDEVICE const Vec3< T > translation() const noexcept
Return translation component.
Definition: ImathMatrix.h:4390
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & setScale(T s) noexcept
Definition: ImathMatrix.h:4276
constexpr ATOMSMATH_HOSTDEVICE Matrix44 operator+(const Matrix44 &v) const noexcept
Component-wise addition.
Definition: ImathMatrix.h:3341
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & setTranslation(const Vec3< S > &t) noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44() noexcept
Uninitialized.
Definition: ImathMatrix.h:2946
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 T determinant() const noexcept
Determinant.
Definition: ImathMatrix.h:4140
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 Matrix44< T > inverse() const noexcept
Return the inverse using the determinant, leaving this unmodified.
Definition: ImathMatrix.h:4036
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & invert() noexcept
Definition: ImathMatrix.h:3958
constexpr ATOMSMATH_HOSTDEVICE Matrix44 operator*(T a) const noexcept
Component-wise multiplication.
Definition: ImathMatrix.h:3503
ATOMSMATH_HOSTDEVICE Matrix44< T > gjInverse() const noexcept
Definition: ImathMatrix.h:3852
ATOMSMATH_HOSTDEVICE void multVecMatrix(const Vec3< S > &src, Vec3< S > &dst) const noexcept
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 T minorOf(const int r, const int c) const noexcept
Calculate the matrix minor of the (r,c) element.
Definition: ImathMatrix.h:4116
ATOMSMATH_HOSTDEVICE ATOMSMATH_CONSTEXPR14 const Matrix44 & shear(const Vec3< S > &h) noexcept
Definition: ImathShear.h:114
Definition: ImathVec.h:43
Definition: ImathVec.h:260
Definition: ImathVec.h:486