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