2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
7 // 2x2, 3x3, and 4x4 transformation matrix templates
10 #ifndef INCLUDED_IMATHMATRIX_H
11 #define INCLUDED_IMATHMATRIX_H
13 #include "ImathExport.h"
14 #include "ImathNamespace.h"
17 #include "ImathPlatform.h"
18 #include "ImathShear.h"
27 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
28 // suppress exception specification warnings
29 # pragma warning(disable : 4290)
32 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
34 /// Enum used to indicate uninitialized construction of Matrix22,
35 /// Matrix33, Matrix44
36 enum IMATH_EXPORT_ENUM Uninitialized
42 /// 2x2 transformation matrix
45 template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Matrix22
50 /// @name Direct access to elements
58 IMATH_HOSTDEVICE T* operator[] (int i) IMATH_NOEXCEPT;
61 IMATH_HOSTDEVICE const T* operator[] (int i) const IMATH_NOEXCEPT;
64 /// @name Constructors and Assignment
67 IMATH_HOSTDEVICE Matrix22 (Uninitialized) IMATH_NOEXCEPT {}
69 /// Default constructor: initialize to identity
73 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22() IMATH_NOEXCEPT;
75 /// Initialize to scalar constant:
79 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (T a) IMATH_NOEXCEPT;
81 /// Construct from 2x2 array:
85 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (const T a[2][2]) IMATH_NOEXCEPT;
86 /// Construct from given scalar values:
90 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (T a, T b, T c, T d) IMATH_NOEXCEPT;
93 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 (const Matrix22& v) IMATH_NOEXCEPT;
95 /// Construct from Matrix22 of another base type
96 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Matrix22 (const Matrix22<S>& v) IMATH_NOEXCEPT;
99 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator= (const Matrix22& v) IMATH_NOEXCEPT;
101 /// Assignment from scalar
102 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator= (T a) IMATH_NOEXCEPT;
105 ~Matrix22() IMATH_NOEXCEPT = default;
109 #if IMATH_FOREIGN_VECTOR_INTEROP
111 /// @name Interoperability with other matrix types
113 /// Construction and assignment are allowed from other classes that
114 /// appear to be equivalent matrix types, provided that they support
115 /// double-subscript (i.e., `m[j][i]`) giving the same type as the
116 /// elements of this matrix, and their total size appears to be the
117 /// right number of matrix elements.
119 /// This functionality is disabled for gcc 4.x, which seems to have a
120 /// compiler bug that results in spurious errors. It can also be
121 /// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
122 /// including any Imath header files.
124 template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,2,2>::value)>
125 IMATH_HOSTDEVICE explicit Matrix22 (const M& m)
126 : Matrix22(T(m[0][0]), T(m[0][1]), T(m[1][0]), T(m[1][1]))
129 template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,2,2>::value)>
130 IMATH_HOSTDEVICE const Matrix22& operator= (const M& m)
132 *this = Matrix22(T(m[0][0]), T(m[0][1]), T(m[1][0]), T(m[1][1]));
139 /// @name Compatibility with Sb
141 /// Return a raw pointer to the array of values
142 IMATH_HOSTDEVICE T* getValue() IMATH_NOEXCEPT;
144 /// Return a raw pointer to the array of values
145 IMATH_HOSTDEVICE const T* getValue() const IMATH_NOEXCEPT;
147 /// Return the value in `v`
148 template <class S> IMATH_HOSTDEVICE void getValue (Matrix22<S>& v) const IMATH_NOEXCEPT;
151 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22& setValue (const Matrix22<S>& v) IMATH_NOEXCEPT;
155 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22& setTheMatrix (const Matrix22<S>& v) IMATH_NOEXCEPT;
160 /// @name Arithmetic and Comparison
163 IMATH_HOSTDEVICE constexpr bool operator== (const Matrix22& v) const IMATH_NOEXCEPT;
166 IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix22& v) const IMATH_NOEXCEPT;
168 /// Compare two matrices and test if they are "approximately equal":
169 /// @return True if the coefficients of this and `m` are the same
170 /// with an absolute error of no more than e, i.e., for all i, j:
172 /// abs (this[i][j] - m[i][j]) <= e
173 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix22<T>& v, T e) const IMATH_NOEXCEPT;
175 /// Compare two matrices and test if they are "approximately equal":
176 /// @return True if the coefficients of this and m are the same with
177 /// a relative error of no more than e, i.e., for all i, j:
179 /// abs (this[i] - v[i][j]) <= e * abs (this[i][j])
180 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix22<T>& v, T e) const IMATH_NOEXCEPT;
182 /// Component-wise addition
183 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator+= (const Matrix22& v) IMATH_NOEXCEPT;
185 /// Component-wise addition
186 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator+= (T a) IMATH_NOEXCEPT;
188 /// Component-wise addition
189 IMATH_HOSTDEVICE constexpr Matrix22 operator+ (const Matrix22& v) const IMATH_NOEXCEPT;
191 /// Component-wise subtraction
192 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator-= (const Matrix22& v) IMATH_NOEXCEPT;
194 /// Component-wise subtraction
195 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator-= (T a) IMATH_NOEXCEPT;
197 /// Component-wise subtraction
198 IMATH_HOSTDEVICE constexpr Matrix22 operator- (const Matrix22& v) const IMATH_NOEXCEPT;
200 /// Component-wise multiplication by -1
201 IMATH_HOSTDEVICE constexpr Matrix22 operator-() const IMATH_NOEXCEPT;
203 /// Component-wise multiplication by -1
204 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& negate() IMATH_NOEXCEPT;
206 /// Component-wise multiplication
207 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator*= (T a) IMATH_NOEXCEPT;
209 /// Component-wise multiplication
210 IMATH_HOSTDEVICE constexpr Matrix22 operator* (T a) const IMATH_NOEXCEPT;
212 /// Component-wise division
213 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator/= (T a) IMATH_NOEXCEPT;
215 /// Component-wise division
216 IMATH_HOSTDEVICE constexpr Matrix22 operator/ (T a) const IMATH_NOEXCEPT;
218 /// Matrix-matrix multiplication
219 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& operator*= (const Matrix22& v) IMATH_NOEXCEPT;
221 /// Matrix-matrix multiplication
222 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22 operator* (const Matrix22& v) const IMATH_NOEXCEPT;
224 /// Vector * matrix multiplication
225 /// @param[in] src Input vector
226 /// @param[out] dst transformed vector
227 template <class S> IMATH_HOSTDEVICE void multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const IMATH_NOEXCEPT;
232 /// @name Maniplation
234 /// Set to the identity
235 IMATH_HOSTDEVICE void makeIdentity() IMATH_NOEXCEPT;
238 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& transpose() IMATH_NOEXCEPT;
240 /// Return the transpose
241 IMATH_HOSTDEVICE constexpr Matrix22 transposed() const IMATH_NOEXCEPT;
244 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
245 /// @return const reference to this
246 IMATH_CONSTEXPR14 const Matrix22& invert (bool singExc);
249 /// @return const reference to this
250 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& invert() IMATH_NOEXCEPT;
252 /// Return the inverse, leaving this unmodified.
253 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
254 IMATH_CONSTEXPR14 Matrix22<T> inverse (bool singExc) const;
256 /// Return the inverse, leaving this unmodified.
257 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix22<T> inverse() const IMATH_NOEXCEPT;
260 IMATH_HOSTDEVICE constexpr T determinant() const IMATH_NOEXCEPT;
263 IMATH_HOSTDEVICE constexpr T trace() const IMATH_NOEXCEPT;
265 /// Set matrix to rotation by r (in radians)
266 /// @return const referenced to this
267 template <class S> IMATH_HOSTDEVICE const Matrix22& setRotation (S r) IMATH_NOEXCEPT;
269 /// Rotate the given matrix by r (in radians)
270 /// @return const referenced to this
271 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& rotate (S r) IMATH_NOEXCEPT;
273 /// Set matrix to scale by given uniform factor
274 /// @return const referenced to this
275 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& setScale (T s) IMATH_NOEXCEPT;
277 /// Set matrix to scale by given vector
278 /// @return const referenced to this
280 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& setScale (const Vec2<S>& s) IMATH_NOEXCEPT;
282 // Scale the matrix by s
283 /// @return const referenced to this
284 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix22& scale (const Vec2<S>& s) IMATH_NOEXCEPT;
289 /// @name Numeric Limits
291 /// Largest possible negative value
292 IMATH_HOSTDEVICE constexpr static T baseTypeLowest() IMATH_NOEXCEPT { return std::numeric_limits<T>::lowest(); }
294 /// Largest possible positive value
295 IMATH_HOSTDEVICE constexpr static T baseTypeMax() IMATH_NOEXCEPT { return std::numeric_limits<T>::max(); }
297 /// Smallest possible positive value
298 IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() IMATH_NOEXCEPT { return std::numeric_limits<T>::min(); }
300 /// Smallest possible e for which 1+e != 1
301 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() IMATH_NOEXCEPT { return std::numeric_limits<T>::epsilon(); }
305 /// Return the number of the row and column dimensions, i.e. 2.
306 IMATH_HOSTDEVICE constexpr static unsigned int dimensions() IMATH_NOEXCEPT { return 2; }
308 /// The base type: In templates that accept a parameter `V`, you
309 /// can refer to `T` as `V::BaseType`
312 /// The base vector type
313 typedef Vec2<T> BaseVecType;
317 /// 3x3 transformation matrix
320 template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Matrix33
325 /// @name Direct access to elements
333 IMATH_HOSTDEVICE T* operator[] (int i) IMATH_NOEXCEPT;
336 IMATH_HOSTDEVICE const T* operator[] (int i) const IMATH_NOEXCEPT;
339 /// @name Constructors and Assignment
342 IMATH_HOSTDEVICE Matrix33 (Uninitialized) IMATH_NOEXCEPT {}
344 /// Default constructor: initialize to identity
348 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33() IMATH_NOEXCEPT;
350 /// Initialize to scalar constant
354 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (T a) IMATH_NOEXCEPT;
356 /// Construct from 3x3 array
357 /// a[0][0] a[0][1] a[0][2]
358 /// a[1][0] a[1][1] a[1][2]
359 /// a[2][0] a[2][1] a[2][2]
360 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (const T a[3][3]) IMATH_NOEXCEPT;
361 /// Construct from given scalar values
365 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i) IMATH_NOEXCEPT;
368 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 (const Matrix33& v) IMATH_NOEXCEPT;
370 /// Construct from Matrix33 of another base type
371 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Matrix33 (const Matrix33<S>& v) IMATH_NOEXCEPT;
373 /// Assignment operator
374 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator= (const Matrix33& v) IMATH_NOEXCEPT;
376 /// Assignment from scalar
377 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator= (T a) IMATH_NOEXCEPT;
380 ~Matrix33() IMATH_NOEXCEPT = default;
384 #if IMATH_FOREIGN_VECTOR_INTEROP
386 /// @name Interoperability with other matrix types
388 /// Construction and assignment are allowed from other classes that
389 /// appear to be equivalent matrix types, provided that they support
390 /// double-subscript (i.e., `m[j][i]`) giving the same type as the
391 /// elements of this matrix, and their total size appears to be the
392 /// right number of matrix elements.
394 /// This functionality is disabled for gcc 4.x, which seems to have a
395 /// compiler bug that results in spurious errors. It can also be
396 /// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
397 /// including any Imath header files.
399 template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,3,3>::value)>
400 IMATH_HOSTDEVICE explicit Matrix33 (const M& m)
401 : Matrix33(T(m[0][0]), T(m[0][1]), T(m[0][2]),
402 T(m[1][0]), T(m[1][1]), T(m[1][2]),
403 T(m[2][0]), T(m[2][1]), T(m[2][2]))
406 /// Interoperability assignment from another type that behaves as if it
407 /// were an equivalent matrix.
408 template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,3,3>::value)>
409 IMATH_HOSTDEVICE const Matrix33& operator= (const M& m)
411 *this = Matrix33(T(m[0][0]), T(m[0][1]), T(m[0][2]),
412 T(m[1][0]), T(m[1][1]), T(m[1][2]),
413 T(m[2][0]), T(m[2][1]), T(m[2][2]));
420 /// @name Compatibility with Sb
422 /// Return a raw pointer to the array of values
423 IMATH_HOSTDEVICE T* getValue() IMATH_NOEXCEPT;
425 /// Return a raw pointer to the array of values
426 IMATH_HOSTDEVICE const T* getValue() const IMATH_NOEXCEPT;
428 /// Return the value in `v`
429 template <class S> IMATH_HOSTDEVICE void getValue (Matrix33<S>& v) const IMATH_NOEXCEPT;
432 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33& setValue (const Matrix33<S>& v) IMATH_NOEXCEPT;
436 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33& setTheMatrix (const Matrix33<S>& v) IMATH_NOEXCEPT;
441 /// @name Arithmetic and Comparison
444 IMATH_HOSTDEVICE constexpr bool operator== (const Matrix33& v) const IMATH_NOEXCEPT;
447 IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix33& v) const IMATH_NOEXCEPT;
449 /// Compare two matrices and test if they are "approximately equal":
450 /// @return True if the coefficients of this and `m` are the same
451 /// with an absolute error of no more than e, i.e., for all i, j:
453 /// abs (this[i][j] - m[i][j]) <= e
454 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix33<T>& v, T e) const IMATH_NOEXCEPT;
456 /// Compare two matrices and test if they are "approximately equal":
457 /// @return True if the coefficients of this and m are the same with
458 /// a relative error of no more than e, i.e., for all i, j:
460 /// abs (this[i] - v[i][j]) <= e * abs (this[i][j])
461 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix33<T>& v, T e) const IMATH_NOEXCEPT;
463 /// Component-wise addition
464 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator+= (const Matrix33& v) IMATH_NOEXCEPT;
466 /// Component-wise addition
467 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator+= (T a) IMATH_NOEXCEPT;
469 /// Component-wise addition
470 IMATH_HOSTDEVICE constexpr Matrix33 operator+ (const Matrix33& v) const IMATH_NOEXCEPT;
472 /// Component-wise subtraction
473 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator-= (const Matrix33& v) IMATH_NOEXCEPT;
475 /// Component-wise subtraction
476 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator-= (T a) IMATH_NOEXCEPT;
478 /// Component-wise subtraction
479 IMATH_HOSTDEVICE constexpr Matrix33 operator- (const Matrix33& v) const IMATH_NOEXCEPT;
481 /// Component-wise multiplication by -1
482 IMATH_HOSTDEVICE constexpr Matrix33 operator-() const IMATH_NOEXCEPT;
484 /// Component-wise multiplication by -1
485 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& negate() IMATH_NOEXCEPT;
487 /// Component-wise multiplication
488 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator*= (T a) IMATH_NOEXCEPT;
490 /// Component-wise multiplication
491 IMATH_HOSTDEVICE constexpr Matrix33 operator* (T a) const IMATH_NOEXCEPT;
493 /// Component-wise division
494 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator/= (T a) IMATH_NOEXCEPT;
496 /// Component-wise division
497 IMATH_HOSTDEVICE constexpr Matrix33 operator/ (T a) const IMATH_NOEXCEPT;
499 /// Matrix-matrix multiplication
500 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& operator*= (const Matrix33& v) IMATH_NOEXCEPT;
502 /// Matrix-matrix multiplication
503 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33 operator* (const Matrix33& v) const IMATH_NOEXCEPT;
505 /// Vector-matrix multiplication: a homogeneous transformation
506 /// by computing Vec3 (src.x, src.y, 1) * m and dividing by the
507 /// result's third element.
508 /// @param[in] src The input vector
509 /// @param[out] dst The output vector
510 template <class S> IMATH_HOSTDEVICE void multVecMatrix (const Vec2<S>& src, Vec2<S>& dst) const IMATH_NOEXCEPT;
512 /// Vector-matrix multiplication: multiply `src` by the upper left 2x2
513 /// submatrix, ignoring the rest of matrix.
514 /// @param[in] src The input vector
515 /// @param[out] dst The output vector
516 template <class S> IMATH_HOSTDEVICE void multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const IMATH_NOEXCEPT;
521 /// @name Maniplation
523 /// Set to the identity matrix
524 IMATH_HOSTDEVICE void makeIdentity() IMATH_NOEXCEPT;
527 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& transpose() IMATH_NOEXCEPT;
529 /// Return the transpose
530 IMATH_HOSTDEVICE constexpr Matrix33 transposed() const IMATH_NOEXCEPT;
532 /// Invert in place using the determinant.
533 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
534 /// @return const reference to this
535 IMATH_CONSTEXPR14 const Matrix33& invert (bool singExc);
537 /// Invert in place using the determinant.
538 /// @return const reference to this
539 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& invert() IMATH_NOEXCEPT;
541 /// Return the inverse using the determinant, leaving this unmodified.
542 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
543 IMATH_CONSTEXPR14 Matrix33<T> inverse (bool singExc) const;
545 /// Return the inverse using the determinant, leaving this unmodified.
546 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix33<T> inverse() const IMATH_NOEXCEPT;
548 /// Invert in place using the Gauss-Jordan method. Significantly slower
549 /// but more accurate than invert().
550 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
551 /// @return const reference to this
552 const Matrix33& gjInvert (bool singExc);
554 /// Invert in place using the Gauss-Jordan method. Significantly slower
555 /// but more accurate than invert().
556 /// @return const reference to this
557 IMATH_HOSTDEVICE const Matrix33& gjInvert() IMATH_NOEXCEPT;
559 /// Return the inverse using the Gauss-Jordan method, leaving this
560 /// unmodified. Significantly slower but more accurate than inverse().
561 Matrix33<T> gjInverse (bool singExc) const;
563 /// Return the inverse using the Gauss-Jordan method. Significantly slower,
564 /// leaving this unmodified. Slower but more accurate than inverse().
565 IMATH_HOSTDEVICE Matrix33<T> gjInverse() const IMATH_NOEXCEPT;
567 /// Calculate the matrix minor of the (r,c) element
568 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T minorOf (const int r, const int c) const IMATH_NOEXCEPT;
570 /// Build a minor using the specified rows and columns
572 constexpr T fastMinor (const int r0, const int r1, const int c0, const int c1) const IMATH_NOEXCEPT;
575 IMATH_HOSTDEVICE constexpr T determinant() const IMATH_NOEXCEPT;
578 IMATH_HOSTDEVICE constexpr T trace() const IMATH_NOEXCEPT;
580 /// Set matrix to rotation by r (in radians)
581 /// @return const referenced to this
582 template <class S> IMATH_HOSTDEVICE const Matrix33& setRotation (S r) IMATH_NOEXCEPT;
584 // Rotate the given matrix by r (in radians)
585 /// @return const referenced to this
586 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& rotate (S r) IMATH_NOEXCEPT;
588 /// Set matrix to scale by given uniform factor
589 /// @return const referenced to this
590 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setScale (T s) IMATH_NOEXCEPT;
592 /// Set matrix to scale by given vector
593 /// @return const referenced to this
595 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setScale (const Vec2<S>& s) IMATH_NOEXCEPT;
597 /// Scale the matrix by s
598 /// @return const referenced to this
599 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& scale (const Vec2<S>& s) IMATH_NOEXCEPT;
601 /// Set matrix to translation by given vector
602 /// @return const referenced to this
604 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setTranslation (const Vec2<S>& t) IMATH_NOEXCEPT;
606 /// Return the translation component
607 IMATH_HOSTDEVICE constexpr Vec2<T> translation() const IMATH_NOEXCEPT;
609 /// Translate the matrix by t
610 /// @return const referenced to this
612 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& translate (const Vec2<S>& t) IMATH_NOEXCEPT;
614 /// Set matrix to shear x for each y coord. by given factor xy
615 /// @return const referenced to this
616 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setShear (const S& h) IMATH_NOEXCEPT;
618 /// Set matrix to shear x for each y coord. by given factor h.x
619 /// and to shear y for each x coord. by given factor h.y
620 /// @return const referenced to this
622 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& setShear (const Vec2<S>& h) IMATH_NOEXCEPT;
624 /// Shear the matrix in x for each y coord. by given factor xy
625 /// @return const referenced to this
626 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& shear (const S& xy) IMATH_NOEXCEPT;
628 /// Shear the matrix in x for each y coord. by given factor xy
629 /// and shear y for each x coord. by given factor yx
630 /// @return const referenced to this
631 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix33& shear (const Vec2<S>& h) IMATH_NOEXCEPT;
636 /// @name Numeric Limits
638 /// Largest possible negative value
639 IMATH_HOSTDEVICE constexpr static T baseTypeLowest() IMATH_NOEXCEPT { return std::numeric_limits<T>::lowest(); }
641 /// Largest possible positive value
642 IMATH_HOSTDEVICE constexpr static T baseTypeMax() IMATH_NOEXCEPT { return std::numeric_limits<T>::max(); }
644 /// Smallest possible positive value
645 IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() IMATH_NOEXCEPT { return std::numeric_limits<T>::min(); }
647 /// Smallest possible e for which 1+e != 1
648 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() IMATH_NOEXCEPT { return std::numeric_limits<T>::epsilon(); }
652 /// Return the number of the row and column dimensions, i.e. 3.
653 IMATH_HOSTDEVICE constexpr static unsigned int dimensions() IMATH_NOEXCEPT { return 3; }
655 /// The base type: In templates that accept a parameter `V` (could be a Color4), you can refer to `T` as `V::BaseType`
658 /// The base vector type
659 typedef Vec3<T> BaseVecType;
663 /// 4x4 transformation matrix
666 template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Matrix44
671 /// @name Direct access to elements
679 IMATH_HOSTDEVICE T* operator[] (int i) IMATH_NOEXCEPT;
682 IMATH_HOSTDEVICE const T* operator[] (int i) const IMATH_NOEXCEPT;
685 /// @name Constructors and Assignment
688 IMATH_HOSTDEVICE constexpr Matrix44 (Uninitialized) IMATH_NOEXCEPT {}
690 /// Default constructor: initialize to identity
695 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44() IMATH_NOEXCEPT;
697 /// Initialize to scalar constant
702 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (T a) IMATH_NOEXCEPT;
704 /// Construct from 4x4 array
705 /// a[0][0] a[0][1] a[0][2] a[0][3]
706 /// a[1][0] a[1][1] a[1][2] a[1][3]
707 /// a[2][0] a[2][1] a[2][2] a[2][3]
708 /// a[3][0] a[3][1] a[3][2] a[3][3]
709 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (const T a[4][4]) IMATH_NOEXCEPT;
710 /// Construct from given scalar values
715 IMATH_HOSTDEVICE IMATH_CONSTEXPR14
716 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) IMATH_NOEXCEPT;
719 /// Construct from a 3x3 rotation matrix and a translation vector
724 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (Matrix33<T> r, Vec3<T> t) IMATH_NOEXCEPT;
727 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 (const Matrix44& v) IMATH_NOEXCEPT;
729 /// Construct from Matrix44 of another base type
730 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 explicit Matrix44 (const Matrix44<S>& v) IMATH_NOEXCEPT;
732 /// Assignment operator
733 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator= (const Matrix44& v) IMATH_NOEXCEPT;
735 /// Assignment from scalar
736 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator= (T a) IMATH_NOEXCEPT;
739 ~Matrix44() IMATH_NOEXCEPT = default;
743 #if IMATH_FOREIGN_VECTOR_INTEROP
745 /// @name Interoperability with other matrix types
747 /// Construction and assignment are allowed from other classes that
748 /// appear to be equivalent matrix types, provided that they support
749 /// double-subscript (i.e., `m[j][i]`) giving the same type as the
750 /// elements of this matrix, and their total size appears to be the
751 /// right number of matrix elements.
753 /// This functionality is disabled for gcc 4.x, which seems to have a
754 /// compiler bug that results in spurious errors. It can also be
755 /// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
756 /// including any Imath header files.
758 template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,4,4>::value)>
759 IMATH_HOSTDEVICE explicit Matrix44 (const M& m)
760 : Matrix44(T(m[0][0]), T(m[0][1]), T(m[0][2]), T(m[0][3]),
761 T(m[1][0]), T(m[1][1]), T(m[1][2]), T(m[1][3]),
762 T(m[2][0]), T(m[2][1]), T(m[2][2]), T(m[2][3]),
763 T(m[3][0]), T(m[3][1]), T(m[3][2]), T(m[3][3]))
766 /// Interoperability assignment from another type that behaves as if it
767 /// were an equivalent matrix.
768 template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,4,4>::value)>
769 IMATH_HOSTDEVICE const Matrix44& operator= (const M& m)
771 *this = Matrix44(T(m[0][0]), T(m[0][1]), T(m[0][2]), T(m[0][3]),
772 T(m[1][0]), T(m[1][1]), T(m[1][2]), T(m[1][3]),
773 T(m[2][0]), T(m[2][1]), T(m[2][2]), T(m[2][3]),
774 T(m[3][0]), T(m[3][1]), T(m[3][2]), T(m[3][3]));
781 /// @name Compatibility with Sb
783 /// Return a raw pointer to the array of values
784 IMATH_HOSTDEVICE T* getValue() IMATH_NOEXCEPT;
786 /// Return a raw pointer to the array of values
787 IMATH_HOSTDEVICE const T* getValue() const IMATH_NOEXCEPT;
789 /// Return the value in `v`
790 template <class S> IMATH_HOSTDEVICE void getValue (Matrix44<S>& v) const IMATH_NOEXCEPT;
793 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44& setValue (const Matrix44<S>& v) IMATH_NOEXCEPT;
797 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44& setTheMatrix (const Matrix44<S>& v) IMATH_NOEXCEPT;
802 /// @name Arithmetic and Comparison
805 IMATH_HOSTDEVICE constexpr bool operator== (const Matrix44& v) const IMATH_NOEXCEPT;
808 IMATH_HOSTDEVICE constexpr bool operator!= (const Matrix44& v) const IMATH_NOEXCEPT;
810 /// Compare two matrices and test if they are "approximately equal":
811 /// @return True if the coefficients of this and `m` are the same
812 /// with an absolute error of no more than e, i.e., for all i, j:
814 /// abs (this[i][j] - m[i][j]) <= e
815 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithAbsError (const Matrix44<T>& v, T e) const IMATH_NOEXCEPT;
817 /// Compare two matrices and test if they are "approximately equal":
818 /// @return True if the coefficients of this and m are the same with
819 /// a relative error of no more than e, i.e., for all i, j:
821 /// abs (this[i] - v[i][j]) <= e * abs (this[i][j])
822 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool equalWithRelError (const Matrix44<T>& v, T e) const IMATH_NOEXCEPT;
824 /// Component-wise addition
825 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator+= (const Matrix44& v) IMATH_NOEXCEPT;
827 /// Component-wise addition
828 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator+= (T a) IMATH_NOEXCEPT;
830 /// Component-wise addition
831 IMATH_HOSTDEVICE constexpr Matrix44 operator+ (const Matrix44& v) const IMATH_NOEXCEPT;
833 /// Component-wise subtraction
834 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator-= (const Matrix44& v) IMATH_NOEXCEPT;
836 /// Component-wise subtraction
837 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator-= (T a) IMATH_NOEXCEPT;
839 /// Component-wise subtraction
840 IMATH_HOSTDEVICE constexpr Matrix44 operator- (const Matrix44& v) const IMATH_NOEXCEPT;
842 /// Component-wise multiplication by -1
843 IMATH_HOSTDEVICE constexpr Matrix44 operator-() const IMATH_NOEXCEPT;
845 /// Component-wise multiplication by -1
846 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& negate() IMATH_NOEXCEPT;
848 /// Component-wise multiplication
849 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator*= (T a) IMATH_NOEXCEPT;
851 /// Component-wise multiplication
852 IMATH_HOSTDEVICE constexpr Matrix44 operator* (T a) const IMATH_NOEXCEPT;
854 /// Component-wise division
855 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator/= (T a) IMATH_NOEXCEPT;
857 /// Component-wise division
858 IMATH_HOSTDEVICE constexpr Matrix44 operator/ (T a) const IMATH_NOEXCEPT;
860 /// Matrix-matrix multiplication
861 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& operator*= (const Matrix44& v) IMATH_NOEXCEPT;
863 /// Matrix-matrix multiplication
864 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44 operator* (const Matrix44& v) const IMATH_NOEXCEPT;
866 /// Matrix-matrix multiplication: compute c = a * b
868 static void multiply (const Matrix44& a, // assumes that
869 const Matrix44& b, // &a != &c and
870 Matrix44& c) IMATH_NOEXCEPT; // &b != &c.
872 /// Matrix-matrix multiplication returning a result.
874 static IMATH_CONSTEXPR14 Matrix44 multiply (const Matrix44& a, const Matrix44& b) IMATH_NOEXCEPT;
876 /// Vector-matrix multiplication: a homogeneous transformation
877 /// by computing Vec3 (src.x, src.y, src.z, 1) * m and dividing by the
878 /// result's third element.
879 /// @param[in] src The input vector
880 /// @param[out] dst The output vector
881 template <class S> IMATH_HOSTDEVICE void multVecMatrix (const Vec3<S>& src, Vec3<S>& dst) const IMATH_NOEXCEPT;
883 /// Vector-matrix multiplication: multiply `src` by the upper left 2x2
884 /// submatrix, ignoring the rest of matrix.
885 /// @param[in] src The input vector
886 /// @param[out] dst The output vector
887 template <class S> IMATH_HOSTDEVICE void multDirMatrix (const Vec3<S>& src, Vec3<S>& dst) const IMATH_NOEXCEPT;
892 /// @name Maniplation
894 /// Set to the identity matrix
895 IMATH_HOSTDEVICE void makeIdentity() IMATH_NOEXCEPT;
898 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& transpose() IMATH_NOEXCEPT;
900 /// Return the transpose
901 IMATH_HOSTDEVICE constexpr Matrix44 transposed() const IMATH_NOEXCEPT;
903 /// Invert in place using the determinant.
904 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
905 /// @return const reference to this
906 IMATH_CONSTEXPR14 const Matrix44& invert (bool singExc);
908 /// Invert in place using the determinant.
909 /// @return const reference to this
910 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& invert() IMATH_NOEXCEPT;
912 /// Return the inverse using the determinant, leaving this unmodified.
913 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
914 IMATH_CONSTEXPR14 Matrix44<T> inverse (bool singExc) const;
916 /// Return the inverse using the determinant, leaving this unmodified.
917 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44<T> inverse() const IMATH_NOEXCEPT;
919 /// Invert in place using the Gauss-Jordan method. Significantly slower
920 /// but more accurate than invert().
921 /// @param singExc If true, throw an exception if the matrix cannot be inverted.
922 /// @return const reference to this
923 IMATH_CONSTEXPR14 const Matrix44& gjInvert (bool singExc);
925 /// Invert in place using the Gauss-Jordan method. Significantly slower
926 /// but more accurate than invert().
927 /// @return const reference to this
928 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& gjInvert() IMATH_NOEXCEPT;
930 /// Return the inverse using the Gauss-Jordan method, leaving this
931 /// unmodified. Significantly slower but more accurate than inverse().
932 Matrix44<T> gjInverse (bool singExc) const;
934 /// Return the inverse using the Gauss-Jordan method, leaving this
935 /// unmodified Significantly slower but more accurate than inverse().
936 IMATH_HOSTDEVICE Matrix44<T> gjInverse() const IMATH_NOEXCEPT;
938 /// Calculate the matrix minor of the (r,c) element
939 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T minorOf (const int r, const int c) const IMATH_NOEXCEPT;
941 /// Build a minor using the specified rows and columns
943 constexpr T fastMinor (const int r0,
948 const int c2) const IMATH_NOEXCEPT;
951 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T determinant() const IMATH_NOEXCEPT;
954 IMATH_HOSTDEVICE constexpr T trace() const IMATH_NOEXCEPT;
956 /// Set matrix to rotation by XYZ euler angles (in radians)
957 /// @return const referenced to this
958 template <class S> IMATH_HOSTDEVICE const Matrix44& setEulerAngles (const Vec3<S>& r) IMATH_NOEXCEPT;
960 /// Set matrix to rotation around given axis by given angle (in radians)
961 /// @return const referenced to this
963 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setAxisAngle (const Vec3<S>& ax, S ang) IMATH_NOEXCEPT;
965 /// Rotate the matrix by XYZ euler angles in r (in radians)
966 /// @return const referenced to this
967 template <class S> IMATH_HOSTDEVICE const Matrix44& rotate (const Vec3<S>& r) IMATH_NOEXCEPT;
969 /// Set matrix to scale by given uniform factor
970 /// @return const referenced to this
971 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setScale (T s) IMATH_NOEXCEPT;
973 /// Set matrix to scale by given vector
974 /// @return const referenced to this
976 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setScale (const Vec3<S>& s) IMATH_NOEXCEPT;
978 /// Scale the matrix by s
979 /// @return const referenced to this
980 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& scale (const Vec3<S>& s) IMATH_NOEXCEPT;
982 /// Set matrix to translation by given vector
983 /// @return const referenced to this
985 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setTranslation (const Vec3<S>& t) IMATH_NOEXCEPT;
987 /// Return translation component
988 IMATH_HOSTDEVICE constexpr const Vec3<T> translation() const IMATH_NOEXCEPT;
990 /// Translate the matrix by t
991 /// @return const referenced to this
993 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& translate (const Vec3<S>& t) IMATH_NOEXCEPT;
995 /// Set matrix to shear by given vector h. The resulting matrix
996 /// - will shear x for each y coord. by a factor of h[0] ;
997 /// - will shear x for each z coord. by a factor of h[1] ;
998 /// - will shear y for each z coord. by a factor of h[2] .
999 /// @return const referenced to this
1001 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setShear (const Vec3<S>& h) IMATH_NOEXCEPT;
1003 /// Set matrix to shear by given factors. The resulting matrix
1004 /// - will shear x for each y coord. by a factor of h.xy ;
1005 /// - will shear x for each z coord. by a factor of h.xz ;
1006 /// - will shear y for each z coord. by a factor of h.yz ;
1007 /// - will shear y for each x coord. by a factor of h.yx ;
1008 /// - will shear z for each x coord. by a factor of h.zx ;
1009 /// - will shear z for each y coord. by a factor of h.zy .
1010 /// @return const referenced to this
1012 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& setShear (const Shear6<S>& h) IMATH_NOEXCEPT;
1014 /// Shear the matrix by given vector. The composed matrix
1015 /// will be `shear` * `this`, where the shear matrix ...
1016 /// - will shear x for each y coord. by a factor of h[0] ;
1017 /// - will shear x for each z coord. by a factor of h[1] ;
1018 /// - will shear y for each z coord. by a factor of h[2] .
1019 /// @return const referenced to this
1020 template <class S> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& shear (const Vec3<S>& h) IMATH_NOEXCEPT;
1022 /// Shear the matrix by the given factors. The composed matrix
1023 /// will be `shear` * `this`, where the shear matrix ...
1024 /// - will shear x for each y coord. by a factor of h.xy ;
1025 /// - will shear x for each z coord. by a factor of h.xz ;
1026 /// - will shear y for each z coord. by a factor of h.yz ;
1027 /// - will shear y for each x coord. by a factor of h.yx ;
1028 /// - will shear z for each x coord. by a factor of h.zx ;
1029 /// - will shear z for each y coord. by a factor of h.zy .
1030 /// @return const referenced to this
1032 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Matrix44& shear (const Shear6<S>& h) IMATH_NOEXCEPT;
1037 /// @name Numeric Limits
1039 /// Largest possible negative value
1040 IMATH_HOSTDEVICE constexpr static T baseTypeLowest() IMATH_NOEXCEPT { return std::numeric_limits<T>::lowest(); }
1042 /// Largest possible positive value
1043 IMATH_HOSTDEVICE constexpr static T baseTypeMax() IMATH_NOEXCEPT { return std::numeric_limits<T>::max(); }
1045 /// Smallest possible positive value
1046 IMATH_HOSTDEVICE constexpr static T baseTypeSmallest() IMATH_NOEXCEPT { return std::numeric_limits<T>::min(); }
1048 /// Smallest possible e for which 1+e != 1
1049 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon() IMATH_NOEXCEPT { return std::numeric_limits<T>::epsilon(); }
1053 /// Return the number of the row and column dimensions, i.e. 4
1054 IMATH_HOSTDEVICE constexpr static unsigned int dimensions() IMATH_NOEXCEPT { return 4; }
1056 /// The base type: In templates that accept a parameter `V` (could be a Color4), you can refer to `T` as `V::BaseType`
1059 /// The base vector type
1060 typedef Vec4<T> BaseVecType;
1063 /// Stream output, as:
1066 template <class T> std::ostream& operator<< (std::ostream& s, const Matrix22<T>& m);
1068 /// Stream output, as:
1072 template <class T> std::ostream& operator<< (std::ostream& s, const Matrix33<T>& m);
1074 /// Stream output, as:
1076 /// (m00 m01 m02 m03
1079 /// m30 m31 m32 m33)
1080 template <class T> std::ostream& operator<< (std::ostream& s, const Matrix44<T>& m);
1082 //---------------------------------------------
1083 // Vector-times-matrix multiplication operators
1084 //---------------------------------------------
1086 /// Vector-matrix multiplication: v *= m
1087 template <class S, class T>
1088 IMATH_HOSTDEVICE inline const Vec2<S>& operator*= (Vec2<S>& v, const Matrix22<T>& m) IMATH_NOEXCEPT;
1090 /// Vector-matrix multiplication: r = v * m
1091 template <class S, class T>
1092 IMATH_HOSTDEVICE inline Vec2<S> operator* (const Vec2<S>& v, const Matrix22<T>& m) IMATH_NOEXCEPT;
1094 /// Vector-matrix multiplication: v *= m
1095 template <class S, class T>
1096 IMATH_HOSTDEVICE inline const Vec2<S>& operator*= (Vec2<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT;
1098 /// Vector-matrix multiplication: r = v * m
1099 template <class S, class T>
1100 IMATH_HOSTDEVICE inline Vec2<S> operator* (const Vec2<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT;
1102 /// Vector-matrix multiplication: v *= m
1103 template <class S, class T>
1104 IMATH_HOSTDEVICE inline const Vec3<S>& operator*= (Vec3<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT;
1106 /// Vector-matrix multiplication: r = v * m
1107 template <class S, class T>
1108 IMATH_HOSTDEVICE inline Vec3<S> operator* (const Vec3<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT;
1110 /// Vector-matrix multiplication: v *= m
1111 template <class S, class T>
1112 IMATH_HOSTDEVICE inline const Vec3<S>& operator*= (Vec3<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT;
1114 /// Vector-matrix multiplication: r = v * m
1115 template <class S, class T>
1116 IMATH_HOSTDEVICE inline Vec3<S> operator* (const Vec3<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT;
1118 /// Vector-matrix multiplication: v *= m
1119 template <class S, class T>
1120 IMATH_HOSTDEVICE inline const Vec4<S>& operator*= (Vec4<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT;
1122 /// Vector-matrix multiplication: r = v * m
1123 template <class S, class T>
1124 IMATH_HOSTDEVICE inline Vec4<S> operator* (const Vec4<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT;
1126 //-------------------------
1127 // Typedefs for convenience
1128 //-------------------------
1130 /// 2x2 matrix of float
1131 typedef Matrix22<float> M22f;
1133 /// 2x2 matrix of double
1134 typedef Matrix22<double> M22d;
1136 /// 3x3 matrix of float
1137 typedef Matrix33<float> M33f;
1139 /// 3x3 matrix of double
1140 typedef Matrix33<double> M33d;
1142 /// 4x4 matrix of float
1143 typedef Matrix44<float> M44f;
1145 /// 4x4 matrix of double
1146 typedef Matrix44<double> M44d;
1148 //---------------------------
1149 // Implementation of Matrix22
1150 //---------------------------
1153 IMATH_HOSTDEVICE inline T*
1154 Matrix22<T>::operator[] (int i) IMATH_NOEXCEPT
1160 IMATH_HOSTDEVICE inline const T*
1161 Matrix22<T>::operator[] (int i) const IMATH_NOEXCEPT
1166 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22() IMATH_NOEXCEPT
1174 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (T a) IMATH_NOEXCEPT
1183 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (
1184 const T a[2][2]) IMATH_NOEXCEPT
1186 // Function calls and aliasing issues can inhibit vectorization versus
1187 // straight assignment of data members, so instead of this:
1188 // memcpy (x, a, sizeof (x));
1197 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (
1198 T a, T b, T c, T d) IMATH_NOEXCEPT
1206 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (const Matrix22& v) IMATH_NOEXCEPT
1208 // Function calls and aliasing issues can inhibit vectorization versus
1209 // straight assignment of data members, so we don't do this:
1210 // memcpy (x, v.x, sizeof (x));
1212 x[0][0] = v.x[0][0];
1213 x[0][1] = v.x[0][1];
1214 x[1][0] = v.x[1][0];
1215 x[1][1] = v.x[1][1];
1220 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>::Matrix22 (const Matrix22<S>& v) IMATH_NOEXCEPT
1222 x[0][0] = T (v.x[0][0]);
1223 x[0][1] = T (v.x[0][1]);
1224 x[1][0] = T (v.x[1][0]);
1225 x[1][1] = T (v.x[1][1]);
1229 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1230 Matrix22<T>::operator= (const Matrix22& v) IMATH_NOEXCEPT
1232 // Function calls and aliasing issues can inhibit vectorization versus
1233 // straight assignment of data members, so we don't do this:
1234 // memcpy (x, v.x, sizeof (x));
1236 x[0][0] = v.x[0][0];
1237 x[0][1] = v.x[0][1];
1238 x[1][0] = v.x[1][0];
1239 x[1][1] = v.x[1][1];
1244 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1245 Matrix22<T>::operator= (T a) IMATH_NOEXCEPT
1255 IMATH_HOSTDEVICE inline T*
1256 Matrix22<T>::getValue () IMATH_NOEXCEPT
1258 return (T*) &x[0][0];
1262 IMATH_HOSTDEVICE inline const T*
1263 Matrix22<T>::getValue() const IMATH_NOEXCEPT
1265 return (const T*) &x[0][0];
1270 IMATH_HOSTDEVICE inline void
1271 Matrix22<T>::getValue (Matrix22<S>& v) const IMATH_NOEXCEPT
1273 v.x[0][0] = x[0][0];
1274 v.x[0][1] = x[0][1];
1275 v.x[1][0] = x[1][0];
1276 v.x[1][1] = x[1][1];
1281 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>&
1282 Matrix22<T>::setValue (const Matrix22<S>& v) IMATH_NOEXCEPT
1284 x[0][0] = v.x[0][0];
1285 x[0][1] = v.x[0][1];
1286 x[1][0] = v.x[1][0];
1287 x[1][1] = v.x[1][1];
1293 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>&
1294 Matrix22<T>::setTheMatrix (const Matrix22<S>& v) IMATH_NOEXCEPT
1296 x[0][0] = v.x[0][0];
1297 x[0][1] = v.x[0][1];
1298 x[1][0] = v.x[1][0];
1299 x[1][1] = v.x[1][1];
1304 IMATH_HOSTDEVICE inline void
1305 Matrix22<T>::makeIdentity() IMATH_NOEXCEPT
1314 IMATH_HOSTDEVICE constexpr inline bool
1315 Matrix22<T>::operator== (const Matrix22& v) const IMATH_NOEXCEPT
1317 return x[0][0] == v.x[0][0] && x[0][1] == v.x[0][1] && x[1][0] == v.x[1][0] &&
1318 x[1][1] == v.x[1][1];
1322 IMATH_HOSTDEVICE constexpr inline bool
1323 Matrix22<T>::operator!= (const Matrix22& v) const IMATH_NOEXCEPT
1325 return x[0][0] != v.x[0][0] || x[0][1] != v.x[0][1] || x[1][0] != v.x[1][0] ||
1326 x[1][1] != v.x[1][1];
1330 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1331 Matrix22<T>::equalWithAbsError (const Matrix22<T>& m, T e) const IMATH_NOEXCEPT
1333 for (int i = 0; i < 2; i++)
1334 for (int j = 0; j < 2; j++)
1335 if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this).x[i][j], m.x[i][j], e))
1342 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1343 Matrix22<T>::equalWithRelError (const Matrix22<T>& m, T e) const IMATH_NOEXCEPT
1345 for (int i = 0; i < 2; i++)
1346 for (int j = 0; j < 2; j++)
1347 if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this).x[i][j], m.x[i][j], e))
1354 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1355 Matrix22<T>::operator+= (const Matrix22<T>& v) IMATH_NOEXCEPT
1357 x[0][0] += v.x[0][0];
1358 x[0][1] += v.x[0][1];
1359 x[1][0] += v.x[1][0];
1360 x[1][1] += v.x[1][1];
1366 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1367 Matrix22<T>::operator+= (T a) IMATH_NOEXCEPT
1378 IMATH_HOSTDEVICE constexpr inline Matrix22<T>
1379 Matrix22<T>::operator+ (const Matrix22<T>& v) const IMATH_NOEXCEPT
1381 return Matrix22 (x[0][0] + v.x[0][0],
1382 x[0][1] + v.x[0][1],
1383 x[1][0] + v.x[1][0],
1384 x[1][1] + v.x[1][1]);
1388 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1389 Matrix22<T>::operator-= (const Matrix22<T>& v) IMATH_NOEXCEPT
1391 x[0][0] -= v.x[0][0];
1392 x[0][1] -= v.x[0][1];
1393 x[1][0] -= v.x[1][0];
1394 x[1][1] -= v.x[1][1];
1400 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1401 Matrix22<T>::operator-= (T a) IMATH_NOEXCEPT
1412 IMATH_HOSTDEVICE constexpr inline Matrix22<T>
1413 Matrix22<T>::operator- (const Matrix22<T>& v) const IMATH_NOEXCEPT
1415 return Matrix22 (x[0][0] - v.x[0][0],
1416 x[0][1] - v.x[0][1],
1417 x[1][0] - v.x[1][0],
1418 x[1][1] - v.x[1][1]);
1422 IMATH_HOSTDEVICE constexpr inline Matrix22<T>
1423 Matrix22<T>::operator-() const IMATH_NOEXCEPT
1425 return Matrix22 (-x[0][0], -x[0][1], -x[1][0], -x[1][1]);
1429 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1430 Matrix22<T>::negate() IMATH_NOEXCEPT
1441 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1442 Matrix22<T>::operator*= (T a) IMATH_NOEXCEPT
1453 IMATH_HOSTDEVICE constexpr inline Matrix22<T>
1454 Matrix22<T>::operator* (T a) const IMATH_NOEXCEPT
1456 return Matrix22 (x[0][0] * a, x[0][1] * a, x[1][0] * a, x[1][1] * a);
1459 /// Matrix-scalar multiplication
1461 IMATH_HOSTDEVICE inline Matrix22<T>
1462 operator* (T a, const Matrix22<T>& v) IMATH_NOEXCEPT
1468 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1469 Matrix22<T>::operator*= (const Matrix22<T>& v) IMATH_NOEXCEPT
1471 Matrix22 tmp (T (0));
1473 for (int i = 0; i < 2; i++)
1474 for (int j = 0; j < 2; j++)
1475 for (int k = 0; k < 2; k++)
1476 tmp.x[i][j] += x[i][k] * v.x[k][j];
1483 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>
1484 Matrix22<T>::operator* (const Matrix22<T>& v) const IMATH_NOEXCEPT
1486 Matrix22 tmp (T (0));
1488 for (int i = 0; i < 2; i++)
1489 for (int j = 0; j < 2; j++)
1490 for (int k = 0; k < 2; k++)
1491 tmp.x[i][j] += x[i][k] * v.x[k][j];
1498 IMATH_HOSTDEVICE inline void
1499 Matrix22<T>::multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const IMATH_NOEXCEPT
1503 a = src.x * x[0][0] + src.y * x[1][0];
1504 b = src.x * x[0][1] + src.y * x[1][1];
1511 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1512 Matrix22<T>::operator/= (T a) IMATH_NOEXCEPT
1523 IMATH_HOSTDEVICE constexpr inline Matrix22<T>
1524 Matrix22<T>::operator/ (T a) const IMATH_NOEXCEPT
1526 return Matrix22 (x[0][0] / a, x[0][1] / a, x[1][0] / a, x[1][1] / a);
1530 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1531 Matrix22<T>::transpose() IMATH_NOEXCEPT
1533 Matrix22 tmp (x[0][0], x[1][0], x[0][1], x[1][1]);
1539 IMATH_HOSTDEVICE constexpr inline Matrix22<T>
1540 Matrix22<T>::transposed() const IMATH_NOEXCEPT
1542 return Matrix22 (x[0][0], x[1][0], x[0][1], x[1][1]);
1546 IMATH_CONSTEXPR14 inline const Matrix22<T>&
1547 Matrix22<T>::invert (bool singExc)
1549 *this = inverse (singExc);
1554 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1555 Matrix22<T>::invert() IMATH_NOEXCEPT
1562 IMATH_CONSTEXPR14 inline Matrix22<T>
1563 Matrix22<T>::inverse (bool singExc) const
1565 Matrix22 s (x[1][1], -x[0][1], -x[1][0], x[0][0]);
1567 T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
1569 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
1571 for (int i = 0; i < 2; ++i)
1573 for (int j = 0; j < 2; ++j)
1581 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
1583 for (int i = 0; i < 2; ++i)
1585 for (int j = 0; j < 2; ++j)
1587 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
1594 throw std::invalid_argument ("Cannot invert "
1595 "singular matrix.");
1605 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix22<T>
1606 Matrix22<T>::inverse() const IMATH_NOEXCEPT
1608 Matrix22 s (x[1][1], -x[0][1], -x[1][0], x[0][0]);
1610 T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
1612 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
1614 for (int i = 0; i < 2; ++i)
1616 for (int j = 0; j < 2; ++j)
1624 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
1626 for (int i = 0; i < 2; ++i)
1628 for (int j = 0; j < 2; ++j)
1630 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
1645 IMATH_HOSTDEVICE constexpr inline T
1646 Matrix22<T>::determinant() const IMATH_NOEXCEPT
1648 return x[0][0] * x[1][1] - x[1][0] * x[0][1];
1652 IMATH_HOSTDEVICE constexpr inline T
1653 Matrix22<T>::trace () const IMATH_NOEXCEPT
1655 return x[0][0] + x[1][1];
1660 IMATH_HOSTDEVICE inline const Matrix22<T>&
1661 Matrix22<T>::setRotation (S r) IMATH_NOEXCEPT
1665 cos_r = cos ((T) r);
1666 sin_r = sin ((T) r);
1679 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1680 Matrix22<T>::rotate (S r) IMATH_NOEXCEPT
1682 *this *= Matrix22<T>().setRotation (r);
1687 IMATH_CONSTEXPR14 inline const Matrix22<T>&
1688 Matrix22<T>::setScale (T s) IMATH_NOEXCEPT
1691 // Set the matrix to:
1697 x[0][1] = static_cast<T> (0);
1698 x[1][0] = static_cast<T> (0);
1706 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1707 Matrix22<T>::setScale (const Vec2<S>& s) IMATH_NOEXCEPT
1710 // Set the matrix to:
1716 x[0][1] = static_cast<T> (0);
1717 x[1][0] = static_cast<T> (0);
1725 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix22<T>&
1726 Matrix22<T>::scale (const Vec2<S>& s) IMATH_NOEXCEPT
1737 //---------------------------
1738 // Implementation of Matrix33
1739 //---------------------------
1742 IMATH_HOSTDEVICE inline T*
1743 Matrix33<T>::operator[] (int i) IMATH_NOEXCEPT
1749 IMATH_HOSTDEVICE inline const T*
1750 Matrix33<T>::operator[] (int i) const IMATH_NOEXCEPT
1756 IMATH_HOSTDEVICE inline IMATH_CONSTEXPR14
1757 Matrix33<T>::Matrix33() IMATH_NOEXCEPT
1770 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (T a) IMATH_NOEXCEPT
1784 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (
1785 const T a[3][3]) IMATH_NOEXCEPT
1787 // Function calls and aliasing issues can inhibit vectorization versus
1788 // straight assignment of data members, so instead of this:
1789 // memcpy (x, a, sizeof (x));
1803 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i) IMATH_NOEXCEPT
1817 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (const Matrix33& v) IMATH_NOEXCEPT
1819 // Function calls and aliasing issues can inhibit vectorization versus
1820 // straight assignment of data members, so instead of this:
1821 // memcpy (x, v.x, sizeof (x));
1823 x[0][0] = v.x[0][0];
1824 x[0][1] = v.x[0][1];
1825 x[0][2] = v.x[0][2];
1826 x[1][0] = v.x[1][0];
1827 x[1][1] = v.x[1][1];
1828 x[1][2] = v.x[1][2];
1829 x[2][0] = v.x[2][0];
1830 x[2][1] = v.x[2][1];
1831 x[2][2] = v.x[2][2];
1836 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>::Matrix33 (const Matrix33<S>& v) IMATH_NOEXCEPT
1838 x[0][0] = T (v.x[0][0]);
1839 x[0][1] = T (v.x[0][1]);
1840 x[0][2] = T (v.x[0][2]);
1841 x[1][0] = T (v.x[1][0]);
1842 x[1][1] = T (v.x[1][1]);
1843 x[1][2] = T (v.x[1][2]);
1844 x[2][0] = T (v.x[2][0]);
1845 x[2][1] = T (v.x[2][1]);
1846 x[2][2] = T (v.x[2][2]);
1850 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
1851 Matrix33<T>::operator= (const Matrix33& v) IMATH_NOEXCEPT
1853 // Function calls and aliasing issues can inhibit vectorization versus
1854 // straight assignment of data members, so instead of this:
1855 // memcpy (x, v.x, sizeof (x));
1857 x[0][0] = v.x[0][0];
1858 x[0][1] = v.x[0][1];
1859 x[0][2] = v.x[0][2];
1860 x[1][0] = v.x[1][0];
1861 x[1][1] = v.x[1][1];
1862 x[1][2] = v.x[1][2];
1863 x[2][0] = v.x[2][0];
1864 x[2][1] = v.x[2][1];
1865 x[2][2] = v.x[2][2];
1870 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
1871 Matrix33<T>::operator= (T a) IMATH_NOEXCEPT
1886 IMATH_HOSTDEVICE inline T*
1887 Matrix33<T>::getValue () IMATH_NOEXCEPT
1889 return (T*) &x[0][0];
1893 IMATH_HOSTDEVICE inline const T*
1894 Matrix33<T>::getValue() const IMATH_NOEXCEPT
1896 return (const T*) &x[0][0];
1901 IMATH_HOSTDEVICE inline void
1902 Matrix33<T>::getValue (Matrix33<S>& v) const IMATH_NOEXCEPT
1904 v.x[0][0] = x[0][0];
1905 v.x[0][1] = x[0][1];
1906 v.x[0][2] = x[0][2];
1907 v.x[1][0] = x[1][0];
1908 v.x[1][1] = x[1][1];
1909 v.x[1][2] = x[1][2];
1910 v.x[2][0] = x[2][0];
1911 v.x[2][1] = x[2][1];
1912 v.x[2][2] = x[2][2];
1917 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>&
1918 Matrix33<T>::setValue (const Matrix33<S>& v) IMATH_NOEXCEPT
1920 x[0][0] = v.x[0][0];
1921 x[0][1] = v.x[0][1];
1922 x[0][2] = v.x[0][2];
1923 x[1][0] = v.x[1][0];
1924 x[1][1] = v.x[1][1];
1925 x[1][2] = v.x[1][2];
1926 x[2][0] = v.x[2][0];
1927 x[2][1] = v.x[2][1];
1928 x[2][2] = v.x[2][2];
1934 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>&
1935 Matrix33<T>::setTheMatrix (const Matrix33<S>& v) IMATH_NOEXCEPT
1937 x[0][0] = v.x[0][0];
1938 x[0][1] = v.x[0][1];
1939 x[0][2] = v.x[0][2];
1940 x[1][0] = v.x[1][0];
1941 x[1][1] = v.x[1][1];
1942 x[1][2] = v.x[1][2];
1943 x[2][0] = v.x[2][0];
1944 x[2][1] = v.x[2][1];
1945 x[2][2] = v.x[2][2];
1950 IMATH_HOSTDEVICE inline void
1951 Matrix33<T>::makeIdentity() IMATH_NOEXCEPT
1965 IMATH_HOSTDEVICE constexpr inline bool
1966 Matrix33<T>::operator== (const Matrix33& v) const IMATH_NOEXCEPT
1968 return x[0][0] == v.x[0][0] && x[0][1] == v.x[0][1] && x[0][2] == v.x[0][2] &&
1969 x[1][0] == v.x[1][0] && x[1][1] == v.x[1][1] && x[1][2] == v.x[1][2] &&
1970 x[2][0] == v.x[2][0] && x[2][1] == v.x[2][1] && x[2][2] == v.x[2][2];
1974 IMATH_HOSTDEVICE constexpr inline bool
1975 Matrix33<T>::operator!= (const Matrix33& v) const IMATH_NOEXCEPT
1977 return x[0][0] != v.x[0][0] || x[0][1] != v.x[0][1] || x[0][2] != v.x[0][2] ||
1978 x[1][0] != v.x[1][0] || x[1][1] != v.x[1][1] || x[1][2] != v.x[1][2] ||
1979 x[2][0] != v.x[2][0] || x[2][1] != v.x[2][1] || x[2][2] != v.x[2][2];
1983 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1984 Matrix33<T>::equalWithAbsError (const Matrix33<T>& m, T e) const IMATH_NOEXCEPT
1986 for (int i = 0; i < 3; i++)
1987 for (int j = 0; j < 3; j++)
1988 if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
1995 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
1996 Matrix33<T>::equalWithRelError (const Matrix33<T>& m, T e) const IMATH_NOEXCEPT
1998 for (int i = 0; i < 3; i++)
1999 for (int j = 0; j < 3; j++)
2000 if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
2007 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2008 Matrix33<T>::operator+= (const Matrix33<T>& v) IMATH_NOEXCEPT
2010 x[0][0] += v.x[0][0];
2011 x[0][1] += v.x[0][1];
2012 x[0][2] += v.x[0][2];
2013 x[1][0] += v.x[1][0];
2014 x[1][1] += v.x[1][1];
2015 x[1][2] += v.x[1][2];
2016 x[2][0] += v.x[2][0];
2017 x[2][1] += v.x[2][1];
2018 x[2][2] += v.x[2][2];
2024 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2025 Matrix33<T>::operator+= (T a) IMATH_NOEXCEPT
2041 IMATH_HOSTDEVICE constexpr inline Matrix33<T>
2042 Matrix33<T>::operator+ (const Matrix33<T>& v) const IMATH_NOEXCEPT
2044 return Matrix33 (x[0][0] + v.x[0][0],
2045 x[0][1] + v.x[0][1],
2046 x[0][2] + v.x[0][2],
2047 x[1][0] + v.x[1][0],
2048 x[1][1] + v.x[1][1],
2049 x[1][2] + v.x[1][2],
2050 x[2][0] + v.x[2][0],
2051 x[2][1] + v.x[2][1],
2052 x[2][2] + v.x[2][2]);
2056 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2057 Matrix33<T>::operator-= (const Matrix33<T>& v) IMATH_NOEXCEPT
2059 x[0][0] -= v.x[0][0];
2060 x[0][1] -= v.x[0][1];
2061 x[0][2] -= v.x[0][2];
2062 x[1][0] -= v.x[1][0];
2063 x[1][1] -= v.x[1][1];
2064 x[1][2] -= v.x[1][2];
2065 x[2][0] -= v.x[2][0];
2066 x[2][1] -= v.x[2][1];
2067 x[2][2] -= v.x[2][2];
2073 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2074 Matrix33<T>::operator-= (T a) IMATH_NOEXCEPT
2090 IMATH_HOSTDEVICE constexpr inline Matrix33<T>
2091 Matrix33<T>::operator- (const Matrix33<T>& v) const IMATH_NOEXCEPT
2093 return Matrix33 (x[0][0] - v.x[0][0],
2094 x[0][1] - v.x[0][1],
2095 x[0][2] - v.x[0][2],
2096 x[1][0] - v.x[1][0],
2097 x[1][1] - v.x[1][1],
2098 x[1][2] - v.x[1][2],
2099 x[2][0] - v.x[2][0],
2100 x[2][1] - v.x[2][1],
2101 x[2][2] - v.x[2][2]);
2105 IMATH_HOSTDEVICE constexpr inline Matrix33<T>
2106 Matrix33<T>::operator-() const IMATH_NOEXCEPT
2108 return Matrix33 (-x[0][0],
2120 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2121 Matrix33<T>::negate() IMATH_NOEXCEPT
2137 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2138 Matrix33<T>::operator*= (T a) IMATH_NOEXCEPT
2154 IMATH_HOSTDEVICE constexpr inline Matrix33<T>
2155 Matrix33<T>::operator* (T a) const IMATH_NOEXCEPT
2157 return Matrix33 (x[0][0] * a,
2168 /// Matrix-scalar multiplication
2170 IMATH_HOSTDEVICE inline Matrix33<T> constexpr
2171 operator* (T a, const Matrix33<T>& v) IMATH_NOEXCEPT
2177 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2178 Matrix33<T>::operator*= (const Matrix33<T>& v) IMATH_NOEXCEPT
2180 // Avoid initializing with 0 values before immediately overwriting them,
2181 // and unroll all loops for the best autovectorization.
2182 Matrix33 tmp(IMATH_INTERNAL_NAMESPACE::UNINITIALIZED);
2184 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];
2185 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];
2186 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];
2188 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];
2189 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];
2190 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];
2192 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];
2193 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];
2194 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];
2201 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>
2202 Matrix33<T>::operator* (const Matrix33<T>& v) const IMATH_NOEXCEPT
2204 // Avoid initializing with 0 values before immediately overwriting them,
2205 // and unroll all loops for the best autovectorization.
2206 Matrix33 tmp(IMATH_INTERNAL_NAMESPACE::UNINITIALIZED);
2208 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];
2209 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];
2210 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];
2212 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];
2213 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];
2214 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];
2216 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];
2217 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];
2218 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];
2225 IMATH_HOSTDEVICE inline void
2226 Matrix33<T>::multVecMatrix (const Vec2<S>& src, Vec2<S>& dst) const IMATH_NOEXCEPT
2230 a = src.x * x[0][0] + src.y * x[1][0] + x[2][0];
2231 b = src.x * x[0][1] + src.y * x[1][1] + x[2][1];
2232 w = src.x * x[0][2] + src.y * x[1][2] + x[2][2];
2240 IMATH_HOSTDEVICE inline void
2241 Matrix33<T>::multDirMatrix (const Vec2<S>& src, Vec2<S>& dst) const IMATH_NOEXCEPT
2245 a = src.x * x[0][0] + src.y * x[1][0];
2246 b = src.x * x[0][1] + src.y * x[1][1];
2253 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2254 Matrix33<T>::operator/= (T a) IMATH_NOEXCEPT
2270 IMATH_HOSTDEVICE constexpr inline Matrix33<T>
2271 Matrix33<T>::operator/ (T a) const IMATH_NOEXCEPT
2273 return Matrix33 (x[0][0] / a,
2285 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2286 Matrix33<T>::transpose() IMATH_NOEXCEPT
2288 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]);
2294 IMATH_HOSTDEVICE constexpr inline Matrix33<T>
2295 Matrix33<T>::transposed() const IMATH_NOEXCEPT
2297 return Matrix33 (x[0][0],
2309 const inline Matrix33<T>&
2310 Matrix33<T>::gjInvert (bool singExc)
2312 *this = gjInverse (singExc);
2317 IMATH_HOSTDEVICE const inline Matrix33<T>&
2318 Matrix33<T>::gjInvert() IMATH_NOEXCEPT
2320 *this = gjInverse();
2326 Matrix33<T>::gjInverse (bool singExc) const
2332 // Forward elimination
2334 for (i = 0; i < 2; i++)
2338 T pivotsize = t.x[i][i];
2341 pivotsize = -pivotsize;
2343 for (j = i + 1; j < 3; j++)
2350 if (tmp > pivotsize)
2360 throw std::invalid_argument ("Cannot invert singular matrix.");
2367 for (j = 0; j < 3; j++)
2372 t.x[i][j] = t.x[pivot][j];
2373 t.x[pivot][j] = tmp;
2376 s.x[i][j] = s.x[pivot][j];
2377 s.x[pivot][j] = tmp;
2381 for (j = i + 1; j < 3; j++)
2383 T f = t.x[j][i] / t.x[i][i];
2385 for (k = 0; k < 3; k++)
2387 t.x[j][k] -= f * t.x[i][k];
2388 s.x[j][k] -= f * s.x[i][k];
2393 // Backward substitution
2395 for (i = 2; i >= 0; --i)
2399 if ((f = t[i][i]) == 0)
2402 throw std::invalid_argument ("Cannot invert singular matrix.");
2407 for (j = 0; j < 3; j++)
2413 for (j = 0; j < i; j++)
2417 for (k = 0; k < 3; k++)
2419 t.x[j][k] -= f * t.x[i][k];
2420 s.x[j][k] -= f * s.x[i][k];
2429 IMATH_HOSTDEVICE inline Matrix33<T>
2430 Matrix33<T>::gjInverse() const IMATH_NOEXCEPT
2436 // Forward elimination
2438 for (i = 0; i < 2; i++)
2442 T pivotsize = t.x[i][i];
2445 pivotsize = -pivotsize;
2447 for (j = i + 1; j < 3; j++)
2454 if (tmp > pivotsize)
2468 for (j = 0; j < 3; j++)
2473 t.x[i][j] = t.x[pivot][j];
2474 t.x[pivot][j] = tmp;
2477 s.x[i][j] = s.x[pivot][j];
2478 s.x[pivot][j] = tmp;
2482 for (j = i + 1; j < 3; j++)
2484 T f = t.x[j][i] / t.x[i][i];
2486 for (k = 0; k < 3; k++)
2488 t.x[j][k] -= f * t.x[i][k];
2489 s.x[j][k] -= f * s.x[i][k];
2494 // Backward substitution
2496 for (i = 2; i >= 0; --i)
2500 if ((f = t.x[i][i]) == 0)
2505 for (j = 0; j < 3; j++)
2511 for (j = 0; j < i; j++)
2515 for (k = 0; k < 3; k++)
2517 t.x[j][k] -= f * t.x[i][k];
2518 s.x[j][k] -= f * s.x[i][k];
2527 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2528 Matrix33<T>::invert (bool singExc)
2530 *this = inverse (singExc);
2535 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2536 Matrix33<T>::invert() IMATH_NOEXCEPT
2543 IMATH_CONSTEXPR14 inline Matrix33<T>
2544 Matrix33<T>::inverse (bool singExc) const
2546 if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
2548 Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
2549 x[2][1] * x[0][2] - x[0][1] * x[2][2],
2550 x[0][1] * x[1][2] - x[1][1] * x[0][2],
2552 x[2][0] * x[1][2] - x[1][0] * x[2][2],
2553 x[0][0] * x[2][2] - x[2][0] * x[0][2],
2554 x[1][0] * x[0][2] - x[0][0] * x[1][2],
2556 x[1][0] * x[2][1] - x[2][0] * x[1][1],
2557 x[2][0] * x[0][1] - x[0][0] * x[2][1],
2558 x[0][0] * x[1][1] - x[1][0] * x[0][1]);
2560 T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
2562 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2564 for (int i = 0; i < 3; ++i)
2566 for (int j = 0; j < 3; ++j)
2574 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2576 for (int i = 0; i < 3; ++i)
2578 for (int j = 0; j < 3; ++j)
2580 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s.x[i][j]))
2587 throw std::invalid_argument ("Cannot invert "
2588 "singular matrix.");
2599 Matrix33 s (x[1][1],
2611 T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
2613 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2615 for (int i = 0; i < 2; ++i)
2617 for (int j = 0; j < 2; ++j)
2625 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2627 for (int i = 0; i < 2; ++i)
2629 for (int j = 0; j < 2; ++j)
2631 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s.x[i][j]))
2638 throw std::invalid_argument ("Cannot invert "
2639 "singular matrix.");
2646 s.x[2][0] = -x[2][0] * s.x[0][0] - x[2][1] * s.x[1][0];
2647 s.x[2][1] = -x[2][0] * s.x[0][1] - x[2][1] * s.x[1][1];
2654 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix33<T>
2655 Matrix33<T>::inverse () const IMATH_NOEXCEPT
2657 if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
2659 Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
2660 x[2][1] * x[0][2] - x[0][1] * x[2][2],
2661 x[0][1] * x[1][2] - x[1][1] * x[0][2],
2663 x[2][0] * x[1][2] - x[1][0] * x[2][2],
2664 x[0][0] * x[2][2] - x[2][0] * x[0][2],
2665 x[1][0] * x[0][2] - x[0][0] * x[1][2],
2667 x[1][0] * x[2][1] - x[2][0] * x[1][1],
2668 x[2][0] * x[0][1] - x[0][0] * x[2][1],
2669 x[0][0] * x[1][1] - x[1][0] * x[0][1]);
2671 T r = x[0][0] * s.x[0][0] + x[0][1] * s.x[1][0] + x[0][2] * s.x[2][0];
2673 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2675 for (int i = 0; i < 3; ++i)
2677 for (int j = 0; j < 3; ++j)
2685 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2687 for (int i = 0; i < 3; ++i)
2689 for (int j = 0; j < 3; ++j)
2691 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s.x[i][j]))
2707 Matrix33 s (x[1][1],
2719 T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
2721 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
2723 for (int i = 0; i < 2; ++i)
2725 for (int j = 0; j < 2; ++j)
2733 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
2735 for (int i = 0; i < 2; ++i)
2737 for (int j = 0; j < 2; ++j)
2739 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s.x[i][j]))
2751 s.x[2][0] = -x[2][0] * s.x[0][0] - x[2][1] * s.x[1][0];
2752 s.x[2][1] = -x[2][0] * s.x[0][1] - x[2][1] * s.x[1][1];
2759 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
2760 Matrix33<T>::minorOf (const int r, const int c) const IMATH_NOEXCEPT
2762 int r0 = 0 + (r < 1 ? 1 : 0);
2763 int r1 = 1 + (r < 2 ? 1 : 0);
2764 int c0 = 0 + (c < 1 ? 1 : 0);
2765 int c1 = 1 + (c < 2 ? 1 : 0);
2767 return x[r0][c0] * x[r1][c1] - x[r1][c0] * x[r0][c1];
2771 IMATH_HOSTDEVICE constexpr inline T
2772 Matrix33<T>::fastMinor (const int r0, const int r1, const int c0, const int c1) const IMATH_NOEXCEPT
2774 return x[r0][c0] * x[r1][c1] - x[r0][c1] * x[r1][c0];
2778 IMATH_HOSTDEVICE constexpr inline T
2779 Matrix33<T>::determinant() const IMATH_NOEXCEPT
2781 return x[0][0] * (x[1][1] * x[2][2] - x[1][2] * x[2][1]) +
2782 x[0][1] * (x[1][2] * x[2][0] - x[1][0] * x[2][2]) +
2783 x[0][2] * (x[1][0] * x[2][1] - x[1][1] * x[2][0]);
2787 IMATH_HOSTDEVICE constexpr inline T
2788 Matrix33<T>::trace () const IMATH_NOEXCEPT
2790 return x[0][0] + x[1][1] + x[2][2];
2795 IMATH_HOSTDEVICE inline const Matrix33<T>&
2796 Matrix33<T>::setRotation (S r) IMATH_NOEXCEPT
2800 cos_r = cos ((T) r);
2801 sin_r = sin ((T) r);
2820 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2821 Matrix33<T>::rotate (S r) IMATH_NOEXCEPT
2823 *this *= Matrix33<T>().setRotation (r);
2828 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2829 Matrix33<T>::setScale (T s) IMATH_NOEXCEPT
2832 // Set the matrix to a 2D homogeneous transform scale:
2852 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2853 Matrix33<T>::setScale (const Vec2<S>& s) IMATH_NOEXCEPT
2856 // Set the matrix to a 2D homogeneous transform scale:
2876 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2877 Matrix33<T>::scale (const Vec2<S>& s) IMATH_NOEXCEPT
2892 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2893 Matrix33<T>::setTranslation (const Vec2<S>& t) IMATH_NOEXCEPT
2911 IMATH_HOSTDEVICE constexpr inline Vec2<T>
2912 Matrix33<T>::translation() const IMATH_NOEXCEPT
2914 return Vec2<T> (x[2][0], x[2][1]);
2919 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2920 Matrix33<T>::translate (const Vec2<S>& t) IMATH_NOEXCEPT
2922 x[2][0] += t.x * x[0][0] + t.y * x[1][0];
2923 x[2][1] += t.x * x[0][1] + t.y * x[1][1];
2924 x[2][2] += t.x * x[0][2] + t.y * x[1][2];
2931 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2932 Matrix33<T>::setShear (const S& xy) IMATH_NOEXCEPT
2951 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2952 Matrix33<T>::setShear (const Vec2<S>& h) IMATH_NOEXCEPT
2971 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2972 Matrix33<T>::shear (const S& xy) IMATH_NOEXCEPT
2975 // In this case, we don't need a temp. copy of the matrix
2976 // because we never use a value on the RHS after we've
2977 // changed it on the LHS.
2980 x[1][0] += xy * x[0][0];
2981 x[1][1] += xy * x[0][1];
2982 x[1][2] += xy * x[0][2];
2989 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix33<T>&
2990 Matrix33<T>::shear (const Vec2<S>& h) IMATH_NOEXCEPT
2992 Matrix33<T> P (*this);
2994 x[0][0] = P.x[0][0] + h.y * P.x[1][0];
2995 x[0][1] = P.x[0][1] + h.y * P.x[1][1];
2996 x[0][2] = P.x[0][2] + h.y * P.x[1][2];
2998 x[1][0] = P.x[1][0] + h.x * P.x[0][0];
2999 x[1][1] = P.x[1][1] + h.x * P.x[0][1];
3000 x[1][2] = P.x[1][2] + h.x * P.x[0][2];
3005 //---------------------------
3006 // Implementation of Matrix44
3007 //---------------------------
3010 IMATH_HOSTDEVICE inline T*
3011 Matrix44<T>::operator[] (int i) IMATH_NOEXCEPT
3017 IMATH_HOSTDEVICE inline const T*
3018 Matrix44<T>::operator[] (int i) const IMATH_NOEXCEPT
3023 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44() IMATH_NOEXCEPT
3043 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (T a) IMATH_NOEXCEPT
3064 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (
3065 const T a[4][4]) IMATH_NOEXCEPT
3086 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<
3087 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) IMATH_NOEXCEPT
3107 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (Matrix33<T> r, Vec3<T> t) IMATH_NOEXCEPT
3109 x[0][0] = r.x[0][0];
3110 x[0][1] = r.x[0][1];
3111 x[0][2] = r.x[0][2];
3113 x[1][0] = r.x[1][0];
3114 x[1][1] = r.x[1][1];
3115 x[1][2] = r.x[1][2];
3117 x[2][0] = r.x[2][0];
3118 x[2][1] = r.x[2][1];
3119 x[2][2] = r.x[2][2];
3127 template <class T> IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (const Matrix44& v) IMATH_NOEXCEPT
3129 x[0][0] = v.x[0][0];
3130 x[0][1] = v.x[0][1];
3131 x[0][2] = v.x[0][2];
3132 x[0][3] = v.x[0][3];
3133 x[1][0] = v.x[1][0];
3134 x[1][1] = v.x[1][1];
3135 x[1][2] = v.x[1][2];
3136 x[1][3] = v.x[1][3];
3137 x[2][0] = v.x[2][0];
3138 x[2][1] = v.x[2][1];
3139 x[2][2] = v.x[2][2];
3140 x[2][3] = v.x[2][3];
3141 x[3][0] = v.x[3][0];
3142 x[3][1] = v.x[3][1];
3143 x[3][2] = v.x[3][2];
3144 x[3][3] = v.x[3][3];
3149 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>::Matrix44 (const Matrix44<S>& v) IMATH_NOEXCEPT
3151 x[0][0] = T (v.x[0][0]);
3152 x[0][1] = T (v.x[0][1]);
3153 x[0][2] = T (v.x[0][2]);
3154 x[0][3] = T (v.x[0][3]);
3155 x[1][0] = T (v.x[1][0]);
3156 x[1][1] = T (v.x[1][1]);
3157 x[1][2] = T (v.x[1][2]);
3158 x[1][3] = T (v.x[1][3]);
3159 x[2][0] = T (v.x[2][0]);
3160 x[2][1] = T (v.x[2][1]);
3161 x[2][2] = T (v.x[2][2]);
3162 x[2][3] = T (v.x[2][3]);
3163 x[3][0] = T (v.x[3][0]);
3164 x[3][1] = T (v.x[3][1]);
3165 x[3][2] = T (v.x[3][2]);
3166 x[3][3] = T (v.x[3][3]);
3170 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3171 Matrix44<T>::operator= (const Matrix44& v) IMATH_NOEXCEPT
3173 x[0][0] = v.x[0][0];
3174 x[0][1] = v.x[0][1];
3175 x[0][2] = v.x[0][2];
3176 x[0][3] = v.x[0][3];
3177 x[1][0] = v.x[1][0];
3178 x[1][1] = v.x[1][1];
3179 x[1][2] = v.x[1][2];
3180 x[1][3] = v.x[1][3];
3181 x[2][0] = v.x[2][0];
3182 x[2][1] = v.x[2][1];
3183 x[2][2] = v.x[2][2];
3184 x[2][3] = v.x[2][3];
3185 x[3][0] = v.x[3][0];
3186 x[3][1] = v.x[3][1];
3187 x[3][2] = v.x[3][2];
3188 x[3][3] = v.x[3][3];
3193 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3194 Matrix44<T>::operator= (T a) IMATH_NOEXCEPT
3216 IMATH_HOSTDEVICE inline T*
3217 Matrix44<T>::getValue () IMATH_NOEXCEPT
3219 return (T*) &x[0][0];
3223 IMATH_HOSTDEVICE inline const T*
3224 Matrix44<T>::getValue() const IMATH_NOEXCEPT
3226 return (const T*) &x[0][0];
3231 IMATH_HOSTDEVICE inline void
3232 Matrix44<T>::getValue (Matrix44<S>& v) const IMATH_NOEXCEPT
3234 v.x[0][0] = x[0][0];
3235 v.x[0][1] = x[0][1];
3236 v.x[0][2] = x[0][2];
3237 v.x[0][3] = x[0][3];
3238 v.x[1][0] = x[1][0];
3239 v.x[1][1] = x[1][1];
3240 v.x[1][2] = x[1][2];
3241 v.x[1][3] = x[1][3];
3242 v.x[2][0] = x[2][0];
3243 v.x[2][1] = x[2][1];
3244 v.x[2][2] = x[2][2];
3245 v.x[2][3] = x[2][3];
3246 v.x[3][0] = x[3][0];
3247 v.x[3][1] = x[3][1];
3248 v.x[3][2] = x[3][2];
3249 v.x[3][3] = x[3][3];
3254 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>&
3255 Matrix44<T>::setValue (const Matrix44<S>& v) IMATH_NOEXCEPT
3257 x[0][0] = T(v.x[0][0]);
3258 x[0][1] = T(v.x[0][1]);
3259 x[0][2] = T(v.x[0][2]);
3260 x[0][3] = T(v.x[0][3]);
3261 x[1][0] = T(v.x[1][0]);
3262 x[1][1] = T(v.x[1][1]);
3263 x[1][2] = T(v.x[1][2]);
3264 x[1][3] = T(v.x[1][3]);
3265 x[2][0] = T(v.x[2][0]);
3266 x[2][1] = T(v.x[2][1]);
3267 x[2][2] = T(v.x[2][2]);
3268 x[2][3] = T(v.x[2][3]);
3269 x[3][0] = T(v.x[3][0]);
3270 x[3][1] = T(v.x[3][1]);
3271 x[3][2] = T(v.x[3][2]);
3272 x[3][3] = T(v.x[3][3]);
3278 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>&
3279 Matrix44<T>::setTheMatrix (const Matrix44<S>& v) IMATH_NOEXCEPT
3281 x[0][0] = v.x[0][0];
3282 x[0][1] = v.x[0][1];
3283 x[0][2] = v.x[0][2];
3284 x[0][3] = v.x[0][3];
3285 x[1][0] = v.x[1][0];
3286 x[1][1] = v.x[1][1];
3287 x[1][2] = v.x[1][2];
3288 x[1][3] = v.x[1][3];
3289 x[2][0] = v.x[2][0];
3290 x[2][1] = v.x[2][1];
3291 x[2][2] = v.x[2][2];
3292 x[2][3] = v.x[2][3];
3293 x[3][0] = v.x[3][0];
3294 x[3][1] = v.x[3][1];
3295 x[3][2] = v.x[3][2];
3296 x[3][3] = v.x[3][3];
3301 IMATH_HOSTDEVICE inline void
3302 Matrix44<T>::makeIdentity() IMATH_NOEXCEPT
3323 IMATH_HOSTDEVICE constexpr inline bool
3324 Matrix44<T>::operator== (const Matrix44& v) const IMATH_NOEXCEPT
3326 return x[0][0] == v.x[0][0] && x[0][1] == v.x[0][1] && x[0][2] == v.x[0][2] &&
3327 x[0][3] == v.x[0][3] && x[1][0] == v.x[1][0] && x[1][1] == v.x[1][1] &&
3328 x[1][2] == v.x[1][2] && x[1][3] == v.x[1][3] && x[2][0] == v.x[2][0] &&
3329 x[2][1] == v.x[2][1] && x[2][2] == v.x[2][2] && x[2][3] == v.x[2][3] &&
3330 x[3][0] == v.x[3][0] && x[3][1] == v.x[3][1] && x[3][2] == v.x[3][2] &&
3331 x[3][3] == v.x[3][3];
3335 IMATH_HOSTDEVICE constexpr inline bool
3336 Matrix44<T>::operator!= (const Matrix44& v) const IMATH_NOEXCEPT
3338 return x[0][0] != v.x[0][0] || x[0][1] != v.x[0][1] || x[0][2] != v.x[0][2] ||
3339 x[0][3] != v.x[0][3] || x[1][0] != v.x[1][0] || x[1][1] != v.x[1][1] ||
3340 x[1][2] != v.x[1][2] || x[1][3] != v.x[1][3] || x[2][0] != v.x[2][0] ||
3341 x[2][1] != v.x[2][1] || x[2][2] != v.x[2][2] || x[2][3] != v.x[2][3] ||
3342 x[3][0] != v.x[3][0] || x[3][1] != v.x[3][1] || x[3][2] != v.x[3][2] ||
3343 x[3][3] != v.x[3][3];
3347 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
3348 Matrix44<T>::equalWithAbsError (const Matrix44<T>& m, T e) const IMATH_NOEXCEPT
3350 for (int i = 0; i < 4; i++)
3351 for (int j = 0; j < 4; j++)
3352 if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this).x[i][j], m.x[i][j], e))
3359 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline bool
3360 Matrix44<T>::equalWithRelError (const Matrix44<T>& m, T e) const IMATH_NOEXCEPT
3362 for (int i = 0; i < 4; i++)
3363 for (int j = 0; j < 4; j++)
3364 if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this).x[i][j], m.x[i][j], e))
3371 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3372 Matrix44<T>::operator+= (const Matrix44<T>& v) IMATH_NOEXCEPT
3374 x[0][0] += v.x[0][0];
3375 x[0][1] += v.x[0][1];
3376 x[0][2] += v.x[0][2];
3377 x[0][3] += v.x[0][3];
3378 x[1][0] += v.x[1][0];
3379 x[1][1] += v.x[1][1];
3380 x[1][2] += v.x[1][2];
3381 x[1][3] += v.x[1][3];
3382 x[2][0] += v.x[2][0];
3383 x[2][1] += v.x[2][1];
3384 x[2][2] += v.x[2][2];
3385 x[2][3] += v.x[2][3];
3386 x[3][0] += v.x[3][0];
3387 x[3][1] += v.x[3][1];
3388 x[3][2] += v.x[3][2];
3389 x[3][3] += v.x[3][3];
3395 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3396 Matrix44<T>::operator+= (T a) IMATH_NOEXCEPT
3419 IMATH_HOSTDEVICE constexpr inline Matrix44<T>
3420 Matrix44<T>::operator+ (const Matrix44<T>& v) const IMATH_NOEXCEPT
3422 return Matrix44 (x[0][0] + v.x[0][0],
3423 x[0][1] + v.x[0][1],
3424 x[0][2] + v.x[0][2],
3425 x[0][3] + v.x[0][3],
3426 x[1][0] + v.x[1][0],
3427 x[1][1] + v.x[1][1],
3428 x[1][2] + v.x[1][2],
3429 x[1][3] + v.x[1][3],
3430 x[2][0] + v.x[2][0],
3431 x[2][1] + v.x[2][1],
3432 x[2][2] + v.x[2][2],
3433 x[2][3] + v.x[2][3],
3434 x[3][0] + v.x[3][0],
3435 x[3][1] + v.x[3][1],
3436 x[3][2] + v.x[3][2],
3437 x[3][3] + v.x[3][3]);
3441 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3442 Matrix44<T>::operator-= (const Matrix44<T>& v) IMATH_NOEXCEPT
3444 x[0][0] -= v.x[0][0];
3445 x[0][1] -= v.x[0][1];
3446 x[0][2] -= v.x[0][2];
3447 x[0][3] -= v.x[0][3];
3448 x[1][0] -= v.x[1][0];
3449 x[1][1] -= v.x[1][1];
3450 x[1][2] -= v.x[1][2];
3451 x[1][3] -= v.x[1][3];
3452 x[2][0] -= v.x[2][0];
3453 x[2][1] -= v.x[2][1];
3454 x[2][2] -= v.x[2][2];
3455 x[2][3] -= v.x[2][3];
3456 x[3][0] -= v.x[3][0];
3457 x[3][1] -= v.x[3][1];
3458 x[3][2] -= v.x[3][2];
3459 x[3][3] -= v.x[3][3];
3465 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3466 Matrix44<T>::operator-= (T a) IMATH_NOEXCEPT
3489 IMATH_HOSTDEVICE constexpr inline Matrix44<T>
3490 Matrix44<T>::operator- (const Matrix44<T>& v) const IMATH_NOEXCEPT
3492 return Matrix44 (x[0][0] - v.x[0][0],
3493 x[0][1] - v.x[0][1],
3494 x[0][2] - v.x[0][2],
3495 x[0][3] - v.x[0][3],
3496 x[1][0] - v.x[1][0],
3497 x[1][1] - v.x[1][1],
3498 x[1][2] - v.x[1][2],
3499 x[1][3] - v.x[1][3],
3500 x[2][0] - v.x[2][0],
3501 x[2][1] - v.x[2][1],
3502 x[2][2] - v.x[2][2],
3503 x[2][3] - v.x[2][3],
3504 x[3][0] - v.x[3][0],
3505 x[3][1] - v.x[3][1],
3506 x[3][2] - v.x[3][2],
3507 x[3][3] - v.x[3][3]);
3511 IMATH_HOSTDEVICE constexpr inline Matrix44<T>
3512 Matrix44<T>::operator-() const IMATH_NOEXCEPT
3514 return Matrix44 (-x[0][0],
3533 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3534 Matrix44<T>::negate() IMATH_NOEXCEPT
3557 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3558 Matrix44<T>::operator*= (T a) IMATH_NOEXCEPT
3581 IMATH_HOSTDEVICE constexpr inline Matrix44<T>
3582 Matrix44<T>::operator* (T a) const IMATH_NOEXCEPT
3584 return Matrix44 (x[0][0] * a,
3602 /// Matrix-scalar multiplication
3604 IMATH_HOSTDEVICE inline Matrix44<T>
3605 operator* (T a, const Matrix44<T>& v) IMATH_NOEXCEPT
3612 IMATH_HOSTDEVICE inline IMATH_CONSTEXPR14 Matrix44<T>
3613 Matrix44<T>::multiply (const Matrix44 &a, const Matrix44 &b) IMATH_NOEXCEPT
3615 const auto a00 = a.x[0][0];
3616 const auto a01 = a.x[0][1];
3617 const auto a02 = a.x[0][2];
3618 const auto a03 = a.x[0][3];
3620 const auto c00 = a00 * b.x[0][0] + a01 * b.x[1][0] + a02 * b.x[2][0] + a03 * b.x[3][0];
3621 const auto c01 = a00 * b.x[0][1] + a01 * b.x[1][1] + a02 * b.x[2][1] + a03 * b.x[3][1];
3622 const auto c02 = a00 * b.x[0][2] + a01 * b.x[1][2] + a02 * b.x[2][2] + a03 * b.x[3][2];
3623 const auto c03 = a00 * b.x[0][3] + a01 * b.x[1][3] + a02 * b.x[2][3] + a03 * b.x[3][3];
3625 const auto a10 = a.x[1][0];
3626 const auto a11 = a.x[1][1];
3627 const auto a12 = a.x[1][2];
3628 const auto a13 = a.x[1][3];
3630 const auto c10 = a10 * b.x[0][0] + a11 * b.x[1][0] + a12 * b.x[2][0] + a13 * b.x[3][0];
3631 const auto c11 = a10 * b.x[0][1] + a11 * b.x[1][1] + a12 * b.x[2][1] + a13 * b.x[3][1];
3632 const auto c12 = a10 * b.x[0][2] + a11 * b.x[1][2] + a12 * b.x[2][2] + a13 * b.x[3][2];
3633 const auto c13 = a10 * b.x[0][3] + a11 * b.x[1][3] + a12 * b.x[2][3] + a13 * b.x[3][3];
3635 const auto a20 = a.x[2][0];
3636 const auto a21 = a.x[2][1];
3637 const auto a22 = a.x[2][2];
3638 const auto a23 = a.x[2][3];
3640 const auto c20 = a20 * b.x[0][0] + a21 * b.x[1][0] + a22 * b.x[2][0] + a23 * b.x[3][0];
3641 const auto c21 = a20 * b.x[0][1] + a21 * b.x[1][1] + a22 * b.x[2][1] + a23 * b.x[3][1];
3642 const auto c22 = a20 * b.x[0][2] + a21 * b.x[1][2] + a22 * b.x[2][2] + a23 * b.x[3][2];
3643 const auto c23 = a20 * b.x[0][3] + a21 * b.x[1][3] + a22 * b.x[2][3] + a23 * b.x[3][3];
3645 const auto a30 = a.x[3][0];
3646 const auto a31 = a.x[3][1];
3647 const auto a32 = a.x[3][2];
3648 const auto a33 = a.x[3][3];
3650 const auto c30 = a30 * b.x[0][0] + a31 * b.x[1][0] + a32 * b.x[2][0] + a33 * b.x[3][0];
3651 const auto c31 = a30 * b.x[0][1] + a31 * b.x[1][1] + a32 * b.x[2][1] + a33 * b.x[3][1];
3652 const auto c32 = a30 * b.x[0][2] + a31 * b.x[1][2] + a32 * b.x[2][2] + a33 * b.x[3][2];
3653 const auto c33 = a30 * b.x[0][3] + a31 * b.x[1][3] + a32 * b.x[2][3] + a33 * b.x[3][3];
3654 return Matrix44(c00, c01, c02, c03,
3657 c30, c31, c32, c33);
3662 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3663 Matrix44<T>::operator*= (const Matrix44<T>& v) IMATH_NOEXCEPT
3665 *this = multiply(*this, v);
3670 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>
3671 Matrix44<T>::operator* (const Matrix44<T>& v) const IMATH_NOEXCEPT
3673 return multiply(*this, v);
3677 IMATH_HOSTDEVICE inline void
3678 Matrix44<T>::multiply (const Matrix44<T>& a, const Matrix44<T>& b, Matrix44<T>& c) IMATH_NOEXCEPT
3685 IMATH_HOSTDEVICE inline void
3686 Matrix44<T>::multVecMatrix (const Vec3<S>& src, Vec3<S>& dst) const IMATH_NOEXCEPT
3690 a = src.x * x[0][0] + src.y * x[1][0] + src.z * x[2][0] + x[3][0];
3691 b = src.x * x[0][1] + src.y * x[1][1] + src.z * x[2][1] + x[3][1];
3692 c = src.x * x[0][2] + src.y * x[1][2] + src.z * x[2][2] + x[3][2];
3693 w = src.x * x[0][3] + src.y * x[1][3] + src.z * x[2][3] + x[3][3];
3702 IMATH_HOSTDEVICE inline void
3703 Matrix44<T>::multDirMatrix (const Vec3<S>& src, Vec3<S>& dst) const IMATH_NOEXCEPT
3707 a = src.x * x[0][0] + src.y * x[1][0] + src.z * x[2][0];
3708 b = src.x * x[0][1] + src.y * x[1][1] + src.z * x[2][1];
3709 c = src.x * x[0][2] + src.y * x[1][2] + src.z * x[2][2];
3717 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3718 Matrix44<T>::operator/= (T a) IMATH_NOEXCEPT
3741 IMATH_HOSTDEVICE constexpr inline Matrix44<T>
3742 Matrix44<T>::operator/ (T a) const IMATH_NOEXCEPT
3744 return Matrix44 (x[0][0] / a,
3763 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3764 Matrix44<T>::transpose() IMATH_NOEXCEPT
3766 Matrix44 tmp (x[0][0],
3787 IMATH_HOSTDEVICE constexpr inline Matrix44<T>
3788 Matrix44<T>::transposed() const IMATH_NOEXCEPT
3790 return Matrix44 (x[0][0],
3809 IMATH_CONSTEXPR14 inline const Matrix44<T>&
3810 Matrix44<T>::gjInvert (bool singExc)
3812 *this = gjInverse (singExc);
3817 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
3818 Matrix44<T>::gjInvert() IMATH_NOEXCEPT
3820 *this = gjInverse();
3826 Matrix44<T>::gjInverse (bool singExc) const
3832 // Forward elimination
3834 for (i = 0; i < 3; i++)
3838 T pivotsize = t.x[i][i];
3841 pivotsize = -pivotsize;
3843 for (j = i + 1; j < 4; j++)
3850 if (tmp > pivotsize)
3860 throw std::invalid_argument ("Cannot invert singular matrix.");
3867 for (j = 0; j < 4; j++)
3872 t.x[i][j] = t.x[pivot][j];
3873 t.x[pivot][j] = tmp;
3876 s.x[i][j] = s.x[pivot][j];
3877 s.x[pivot][j] = tmp;
3881 for (j = i + 1; j < 4; j++)
3883 T f = t.x[j][i] / t.x[i][i];
3885 for (k = 0; k < 4; k++)
3887 t.x[j][k] -= f * t.x[i][k];
3888 s.x[j][k] -= f * s.x[i][k];
3893 // Backward substitution
3895 for (i = 3; i >= 0; --i)
3899 if ((f = t.x[i][i]) == 0)
3902 throw std::invalid_argument ("Cannot invert singular matrix.");
3907 for (j = 0; j < 4; j++)
3913 for (j = 0; j < i; j++)
3917 for (k = 0; k < 4; k++)
3919 t.x[j][k] -= f * t.x[i][k];
3920 s.x[j][k] -= f * s.x[i][k];
3929 IMATH_HOSTDEVICE inline Matrix44<T>
3930 Matrix44<T>::gjInverse() const IMATH_NOEXCEPT
3936 // Forward elimination
3938 for (i = 0; i < 3; i++)
3942 T pivotsize = t.x[i][i];
3945 pivotsize = -pivotsize;
3947 for (j = i + 1; j < 4; j++)
3954 if (tmp > pivotsize)
3968 for (j = 0; j < 4; j++)
3973 t.x[i][j] = t.x[pivot][j];
3974 t.x[pivot][j] = tmp;
3977 s.x[i][j] = s.x[pivot][j];
3978 s.x[pivot][j] = tmp;
3982 for (j = i + 1; j < 4; j++)
3984 T f = t.x[j][i] / t.x[i][i];
3986 for (k = 0; k < 4; k++)
3988 t.x[j][k] -= f * t.x[i][k];
3989 s.x[j][k] -= f * s.x[i][k];
3994 // Backward substitution
3996 for (i = 3; i >= 0; --i)
4000 if ((f = t.x[i][i]) == 0)
4005 for (j = 0; j < 4; j++)
4011 for (j = 0; j < i; j++)
4015 for (k = 0; k < 4; k++)
4017 t.x[j][k] -= f * t.x[i][k];
4018 s.x[j][k] -= f * s.x[i][k];
4027 IMATH_CONSTEXPR14 inline const Matrix44<T>&
4028 Matrix44<T>::invert (bool singExc)
4030 *this = inverse (singExc);
4035 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4036 Matrix44<T>::invert() IMATH_NOEXCEPT
4043 IMATH_CONSTEXPR14 inline Matrix44<T>
4044 Matrix44<T>::inverse (bool singExc) const
4046 if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
4047 return gjInverse (singExc);
4049 Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
4050 x[2][1] * x[0][2] - x[0][1] * x[2][2],
4051 x[0][1] * x[1][2] - x[1][1] * x[0][2],
4054 x[2][0] * x[1][2] - x[1][0] * x[2][2],
4055 x[0][0] * x[2][2] - x[2][0] * x[0][2],
4056 x[1][0] * x[0][2] - x[0][0] * x[1][2],
4059 x[1][0] * x[2][1] - x[2][0] * x[1][1],
4060 x[2][0] * x[0][1] - x[0][0] * x[2][1],
4061 x[0][0] * x[1][1] - x[1][0] * x[0][1],
4069 T r = x[0][0] * s.x[0][0] + x[0][1] * s.x[1][0] + x[0][2] * s.x[2][0];
4071 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
4073 for (int i = 0; i < 3; ++i)
4075 for (int j = 0; j < 3; ++j)
4083 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
4085 for (int i = 0; i < 3; ++i)
4087 for (int j = 0; j < 3; ++j)
4089 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s.x[i][j]))
4096 throw std::invalid_argument ("Cannot invert singular matrix.");
4104 s.x[3][0] = -x[3][0] * s.x[0][0] - x[3][1] * s.x[1][0] - x[3][2] * s.x[2][0];
4105 s.x[3][1] = -x[3][0] * s.x[0][1] - x[3][1] * s.x[1][1] - x[3][2] * s.x[2][1];
4106 s.x[3][2] = -x[3][0] * s.x[0][2] - x[3][1] * s.x[1][2] - x[3][2] * s.x[2][2];
4112 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline Matrix44<T>
4113 Matrix44<T>::inverse() const IMATH_NOEXCEPT
4115 if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
4118 Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2],
4119 x[2][1] * x[0][2] - x[0][1] * x[2][2],
4120 x[0][1] * x[1][2] - x[1][1] * x[0][2],
4123 x[2][0] * x[1][2] - x[1][0] * x[2][2],
4124 x[0][0] * x[2][2] - x[2][0] * x[0][2],
4125 x[1][0] * x[0][2] - x[0][0] * x[1][2],
4128 x[1][0] * x[2][1] - x[2][0] * x[1][1],
4129 x[2][0] * x[0][1] - x[0][0] * x[2][1],
4130 x[0][0] * x[1][1] - x[1][0] * x[0][1],
4138 T r = x[0][0] * s.x[0][0] + x[0][1] * s.x[1][0] + x[0][2] * s.x[2][0];
4140 if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
4142 for (int i = 0; i < 3; ++i)
4144 for (int j = 0; j < 3; ++j)
4152 T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / std::numeric_limits<T>::min();
4154 for (int i = 0; i < 3; ++i)
4156 for (int j = 0; j < 3; ++j)
4158 if (mr > IMATH_INTERNAL_NAMESPACE::abs (s.x[i][j]))
4170 s.x[3][0] = -x[3][0] * s.x[0][0] - x[3][1] * s.x[1][0] - x[3][2] * s.x[2][0];
4171 s.x[3][1] = -x[3][0] * s.x[0][1] - x[3][1] * s.x[1][1] - x[3][2] * s.x[2][1];
4172 s.x[3][2] = -x[3][0] * s.x[0][2] - x[3][1] * s.x[1][2] - x[3][2] * s.x[2][2];
4178 IMATH_HOSTDEVICE constexpr inline T
4179 Matrix44<T>::fastMinor (const int r0,
4184 const int c2) const IMATH_NOEXCEPT
4186 return x[r0][c0] * (x[r1][c1] * x[r2][c2] - x[r1][c2] * x[r2][c1]) +
4187 x[r0][c1] * (x[r1][c2] * x[r2][c0] - x[r1][c0] * x[r2][c2]) +
4188 x[r0][c2] * (x[r1][c0] * x[r2][c1] - x[r1][c1] * x[r2][c0]);
4192 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
4193 Matrix44<T>::minorOf (const int r, const int c) const IMATH_NOEXCEPT
4195 int r0 = 0 + (r < 1 ? 1 : 0);
4196 int r1 = 1 + (r < 2 ? 1 : 0);
4197 int r2 = 2 + (r < 3 ? 1 : 0);
4198 int c0 = 0 + (c < 1 ? 1 : 0);
4199 int c1 = 1 + (c < 2 ? 1 : 0);
4200 int c2 = 2 + (c < 3 ? 1 : 0);
4202 Matrix33<T> working (x[r0][c0],
4212 return working.determinant();
4216 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T
4217 Matrix44<T>::determinant() const IMATH_NOEXCEPT
4222 sum -= x[0][3] * fastMinor (1, 2, 3, 0, 1, 2);
4224 sum += x[1][3] * fastMinor (0, 2, 3, 0, 1, 2);
4226 sum -= x[2][3] * fastMinor (0, 1, 3, 0, 1, 2);
4228 sum += x[3][3] * fastMinor (0, 1, 2, 0, 1, 2);
4234 IMATH_HOSTDEVICE constexpr inline T
4235 Matrix44<T>::trace () const IMATH_NOEXCEPT
4237 return x[0][0] + x[1][1] + x[2][2] + x[3][3];
4242 IMATH_HOSTDEVICE inline const Matrix44<T>&
4243 Matrix44<T>::setEulerAngles (const Vec3<S>& r) IMATH_NOEXCEPT
4245 S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
4247 cos_rz = cos ((T) r.z);
4248 cos_ry = cos ((T) r.y);
4249 cos_rx = cos ((T) r.x);
4251 sin_rz = sin ((T) r.z);
4252 sin_ry = sin ((T) r.y);
4253 sin_rx = sin ((T) r.x);
4255 x[0][0] = cos_rz * cos_ry;
4256 x[0][1] = sin_rz * cos_ry;
4260 x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
4261 x[1][1] = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
4262 x[1][2] = cos_ry * sin_rx;
4265 x[2][0] = sin_rz * sin_rx + cos_rz * sin_ry * cos_rx;
4266 x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx;
4267 x[2][2] = cos_ry * cos_rx;
4280 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4281 Matrix44<T>::setAxisAngle (const Vec3<S>& axis, S angle) IMATH_NOEXCEPT
4283 Vec3<S> unit (axis.normalized());
4284 S sine = std::sin (angle);
4285 S cosine = std::cos (angle);
4287 x[0][0] = unit.x * unit.x * (1 - cosine) + cosine;
4288 x[0][1] = unit.x * unit.y * (1 - cosine) + unit.z * sine;
4289 x[0][2] = unit.x * unit.z * (1 - cosine) - unit.y * sine;
4292 x[1][0] = unit.x * unit.y * (1 - cosine) - unit.z * sine;
4293 x[1][1] = unit.y * unit.y * (1 - cosine) + cosine;
4294 x[1][2] = unit.y * unit.z * (1 - cosine) + unit.x * sine;
4297 x[2][0] = unit.x * unit.z * (1 - cosine) + unit.y * sine;
4298 x[2][1] = unit.y * unit.z * (1 - cosine) - unit.x * sine;
4299 x[2][2] = unit.z * unit.z * (1 - cosine) + cosine;
4312 IMATH_HOSTDEVICE inline const Matrix44<T>&
4313 Matrix44<T>::rotate (const Vec3<S>& r) IMATH_NOEXCEPT
4315 S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
4320 cos_rz = cos ((S) r.z);
4321 cos_ry = cos ((S) r.y);
4322 cos_rx = cos ((S) r.x);
4324 sin_rz = sin ((S) r.z);
4325 sin_ry = sin ((S) r.y);
4326 sin_rx = sin ((S) r.x);
4328 m00 = cos_rz * cos_ry;
4329 m01 = sin_rz * cos_ry;
4331 m10 = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
4332 m11 = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
4333 m12 = cos_ry * sin_rx;
4334 m20 = -sin_rz * -sin_rx + cos_rz * sin_ry * cos_rx;
4335 m21 = cos_rz * -sin_rx + sin_rz * sin_ry * cos_rx;
4336 m22 = cos_ry * cos_rx;
4338 Matrix44<T> P (*this);
4340 x[0][0] = P.x[0][0] * m00 + P.x[1][0] * m01 + P.x[2][0] * m02;
4341 x[0][1] = P.x[0][1] * m00 + P.x[1][1] * m01 + P.x[2][1] * m02;
4342 x[0][2] = P.x[0][2] * m00 + P.x[1][2] * m01 + P.x[2][2] * m02;
4343 x[0][3] = P.x[0][3] * m00 + P.x[1][3] * m01 + P.x[2][3] * m02;
4345 x[1][0] = P.x[0][0] * m10 + P.x[1][0] * m11 + P.x[2][0] * m12;
4346 x[1][1] = P.x[0][1] * m10 + P.x[1][1] * m11 + P.x[2][1] * m12;
4347 x[1][2] = P.x[0][2] * m10 + P.x[1][2] * m11 + P.x[2][2] * m12;
4348 x[1][3] = P.x[0][3] * m10 + P.x[1][3] * m11 + P.x[2][3] * m12;
4350 x[2][0] = P.x[0][0] * m20 + P.x[1][0] * m21 + P.x[2][0] * m22;
4351 x[2][1] = P.x[0][1] * m20 + P.x[1][1] * m21 + P.x[2][1] * m22;
4352 x[2][2] = P.x[0][2] * m20 + P.x[1][2] * m21 + P.x[2][2] * m22;
4353 x[2][3] = P.x[0][3] * m20 + P.x[1][3] * m21 + P.x[2][3] * m22;
4359 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4360 Matrix44<T>::setScale (T s) IMATH_NOEXCEPT
4363 // Set the matrix to a 3D homogeneous transform scale:
4391 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4392 Matrix44<T>::setScale (const Vec3<S>& s) IMATH_NOEXCEPT
4395 // Set the matrix to a 3D homogeneous transform scale:
4423 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4424 Matrix44<T>::scale (const Vec3<S>& s) IMATH_NOEXCEPT
4446 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4447 Matrix44<T>::setTranslation (const Vec3<S>& t) IMATH_NOEXCEPT
4473 IMATH_HOSTDEVICE constexpr inline const Vec3<T>
4474 Matrix44<T>::translation() const IMATH_NOEXCEPT
4476 return Vec3<T> (x[3][0], x[3][1], x[3][2]);
4481 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4482 Matrix44<T>::translate (const Vec3<S>& t) IMATH_NOEXCEPT
4484 x[3][0] += t.x * x[0][0] + t.y * x[1][0] + t.z * x[2][0];
4485 x[3][1] += t.x * x[0][1] + t.y * x[1][1] + t.z * x[2][1];
4486 x[3][2] += t.x * x[0][2] + t.y * x[1][2] + t.z * x[2][2];
4487 x[3][3] += t.x * x[0][3] + t.y * x[1][3] + t.z * x[2][3];
4494 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4495 Matrix44<T>::setShear (const Vec3<S>& h) IMATH_NOEXCEPT
4522 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4523 Matrix44<T>::setShear (const Shear6<S>& h) IMATH_NOEXCEPT
4550 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4551 Matrix44<T>::shear (const Vec3<S>& h) IMATH_NOEXCEPT
4554 // In this case, we don't need a temp. copy of the matrix
4555 // because we never use a value on the RHS after we've
4556 // changed it on the LHS.
4559 for (int i = 0; i < 4; i++)
4561 x[2][i] += h.y * x[0][i] + h.z * x[1][i];
4562 x[1][i] += h.x * x[0][i];
4570 IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline const Matrix44<T>&
4571 Matrix44<T>::shear (const Shear6<S>& h) IMATH_NOEXCEPT
4573 Matrix44<T> P (*this);
4575 for (int i = 0; i < 4; i++)
4577 x[0][i] = P.x[0][i] + h.yx * P.x[1][i] + h.zx * P.x[2][i];
4578 x[1][i] = h.xy * P.x[0][i] + P.x[1][i] + h.zy * P.x[2][i];
4579 x[2][i] = h.xz * P.x[0][i] + h.yz * P.x[1][i] + P.x[2][i];
4585 //--------------------------------
4586 // Implementation of stream output
4587 //--------------------------------
4591 operator<< (std::ostream& s, const Matrix22<T>& m)
4593 std::ios_base::fmtflags oldFlags = s.flags();
4596 if (s.flags() & std::ios_base::fixed)
4598 s.setf (std::ios_base::showpoint);
4599 width = static_cast<int> (s.precision()) + 5;
4603 s.setf (std::ios_base::scientific);
4604 s.setf (std::ios_base::showpoint);
4605 width = static_cast<int> (s.precision()) + 8;
4608 s << "(" << std::setw (width) << m[0][0] << " " << std::setw (width) << m[0][1] << "\n"
4611 " " << std::setw (width) << m[1][0] << " " << std::setw (width) << m[1][1] << ")\n";
4619 operator<< (std::ostream& s, const Matrix33<T>& m)
4621 std::ios_base::fmtflags oldFlags = s.flags();
4624 if (s.flags() & std::ios_base::fixed)
4626 s.setf (std::ios_base::showpoint);
4627 width = static_cast<int> (s.precision()) + 5;
4631 s.setf (std::ios_base::scientific);
4632 s.setf (std::ios_base::showpoint);
4633 width = static_cast<int> (s.precision()) + 8;
4636 s << "(" << std::setw (width) << m[0][0] << " " << std::setw (width) << m[0][1] << " "
4637 << std::setw (width) << m[0][2] << "\n"
4640 " " << std::setw (width) << m[1][0] << " " << std::setw (width) << m[1][1] << " "
4641 << std::setw (width) << m[1][2] << "\n"
4644 " " << std::setw (width) << m[2][0] << " " << std::setw (width) << m[2][1] << " "
4645 << std::setw (width) << m[2][2] << ")\n";
4653 operator<< (std::ostream& s, const Matrix44<T>& m)
4655 std::ios_base::fmtflags oldFlags = s.flags();
4658 if (s.flags() & std::ios_base::fixed)
4660 s.setf (std::ios_base::showpoint);
4661 width = static_cast<int> (s.precision()) + 5;
4665 s.setf (std::ios_base::scientific);
4666 s.setf (std::ios_base::showpoint);
4667 width = static_cast<int> (s.precision()) + 8;
4670 s << "(" << std::setw (width) << m[0][0] << " " << std::setw (width) << m[0][1] << " "
4671 << std::setw (width) << m[0][2] << " " << std::setw (width) << m[0][3] << "\n"
4674 " " << std::setw (width) << m[1][0] << " " << std::setw (width) << m[1][1] << " "
4675 << std::setw (width) << m[1][2] << " " << std::setw (width) << m[1][3] << "\n"
4678 " " << std::setw (width) << m[2][0] << " " << std::setw (width) << m[2][1] << " "
4679 << std::setw (width) << m[2][2] << " " << std::setw (width) << m[2][3] << "\n"
4682 " " << std::setw (width) << m[3][0] << " " << std::setw (width) << m[3][1] << " "
4683 << std::setw (width) << m[3][2] << " " << std::setw (width) << m[3][3] << ")\n";
4689 //---------------------------------------------------------------
4690 // Implementation of vector-times-matrix multiplication operators
4691 //---------------------------------------------------------------
4693 template <class S, class T>
4694 IMATH_HOSTDEVICE inline const Vec2<S>&
4695 operator*= (Vec2<S>& v, const Matrix22<T>& m) IMATH_NOEXCEPT
4697 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0]);
4698 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1]);
4706 template <class S, class T>
4707 IMATH_HOSTDEVICE inline Vec2<S>
4708 operator* (const Vec2<S>& v, const Matrix22<T>& m) IMATH_NOEXCEPT
4710 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0]);
4711 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1]);
4713 return Vec2<S> (x, y);
4716 template <class S, class T>
4717 IMATH_HOSTDEVICE inline const Vec2<S>&
4718 operator*= (Vec2<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT
4720 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + m.x[2][0]);
4721 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + m.x[2][1]);
4722 S w = S (v.x * m.x[0][2] + v.y * m.x[1][2] + m.x[2][2]);
4730 template <class S, class T>
4731 IMATH_HOSTDEVICE inline Vec2<S>
4732 operator* (const Vec2<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT
4734 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + m.x[2][0]);
4735 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + m.x[2][1]);
4736 S w = S (v.x * m.x[0][2] + v.y * m.x[1][2] + m.x[2][2]);
4738 return Vec2<S> (x / w, y / w);
4741 template <class S, class T>
4742 IMATH_HOSTDEVICE inline const Vec3<S>&
4743 operator*= (Vec3<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT
4745 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + v.z * m.x[2][0]);
4746 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + v.z * m.x[2][1]);
4747 S z = S (v.x * m.x[0][2] + v.y * m.x[1][2] + v.z * m.x[2][2]);
4756 template <class S, class T>
4757 IMATH_HOSTDEVICE inline Vec3<S>
4758 operator* (const Vec3<S>& v, const Matrix33<T>& m) IMATH_NOEXCEPT
4760 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + v.z * m.x[2][0]);
4761 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + v.z * m.x[2][1]);
4762 S z = S (v.x * m.x[0][2] + v.y * m.x[1][2] + v.z * m.x[2][2]);
4764 return Vec3<S> (x, y, z);
4767 template <class S, class T>
4768 IMATH_HOSTDEVICE inline const Vec3<S>&
4769 operator*= (Vec3<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT
4771 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + v.z * m.x[2][0] + m.x[3][0]);
4772 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + v.z * m.x[2][1] + m.x[3][1]);
4773 S z = S (v.x * m.x[0][2] + v.y * m.x[1][2] + v.z * m.x[2][2] + m.x[3][2]);
4774 S w = S (v.x * m.x[0][3] + v.y * m.x[1][3] + v.z * m.x[2][3] + m.x[3][3]);
4783 template <class S, class T>
4784 IMATH_HOSTDEVICE inline Vec3<S>
4785 IMATH_HOSTDEVICE operator* (const Vec3<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT
4787 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + v.z * m.x[2][0] + m.x[3][0]);
4788 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + v.z * m.x[2][1] + m.x[3][1]);
4789 S z = S (v.x * m.x[0][2] + v.y * m.x[1][2] + v.z * m.x[2][2] + m.x[3][2]);
4790 S w = S (v.x * m.x[0][3] + v.y * m.x[1][3] + v.z * m.x[2][3] + m.x[3][3]);
4792 return Vec3<S> (x / w, y / w, z / w);
4795 template <class S, class T>
4796 IMATH_HOSTDEVICE inline const Vec4<S>&
4797 IMATH_HOSTDEVICE operator*= (Vec4<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT
4799 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + v.z * m.x[2][0] + v.w * m.x[3][0]);
4800 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + v.z * m.x[2][1] + v.w * m.x[3][1]);
4801 S z = S (v.x * m.x[0][2] + v.y * m.x[1][2] + v.z * m.x[2][2] + v.w * m.x[3][2]);
4802 S w = S (v.x * m.x[0][3] + v.y * m.x[1][3] + v.z * m.x[2][3] + v.w * m.x[3][3]);
4812 template <class S, class T>
4813 IMATH_HOSTDEVICE inline Vec4<S>
4814 IMATH_HOSTDEVICE operator* (const Vec4<S>& v, const Matrix44<T>& m) IMATH_NOEXCEPT
4816 S x = S (v.x * m.x[0][0] + v.y * m.x[1][0] + v.z * m.x[2][0] + v.w * m.x[3][0]);
4817 S y = S (v.x * m.x[0][1] + v.y * m.x[1][1] + v.z * m.x[2][1] + v.w * m.x[3][1]);
4818 S z = S (v.x * m.x[0][2] + v.y * m.x[1][2] + v.z * m.x[2][2] + v.w * m.x[3][2]);
4819 S w = S (v.x * m.x[0][3] + v.y * m.x[1][3] + v.z * m.x[2][3] + v.w * m.x[3][3]);
4821 return Vec4<S> (x, y, z, w);
4824 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
4826 #endif // INCLUDED_IMATHMATRIX_H