Coverage Report

Created: 2024-07-27 06:04

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