Coverage Report

Created: 2022-08-24 06:20

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