GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/math/Mat4.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 383 481 79.6%
Functions: 44 49 89.8%
Branches: 260 570 45.6%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #ifndef OPENVDB_MATH_MAT4_H_HAS_BEEN_INCLUDED
5 #define OPENVDB_MATH_MAT4_H_HAS_BEEN_INCLUDED
6
7 #include <openvdb/Exceptions.h>
8 #include <openvdb/Platform.h>
9 #include "Math.h"
10 #include "Mat3.h"
11 #include "Vec3.h"
12 #include "Vec4.h"
13 #include <algorithm> // for std::copy(), std::swap()
14 #include <cassert>
15 #include <iomanip>
16 #include <cmath>
17
18
19 namespace openvdb {
20 OPENVDB_USE_VERSION_NAMESPACE
21 namespace OPENVDB_VERSION_NAME {
22 namespace math {
23
24 template<typename T> class Vec4;
25
26
27 /// @class Mat4 Mat4.h
28 /// @brief 4x4 -matrix class.
29 template<typename T>
30 class Mat4: public Mat<4, T>
31 {
32 public:
33 /// Data type held by the matrix.
34 using value_type = T;
35 using ValueType = T;
36 using MyBase = Mat<4, T>;
37
38 /// Trivial constructor, the matrix is NOT initialized
39 #if OPENVDB_ABI_VERSION_NUMBER >= 8
40 /// @note destructor, copy constructor, assignment operator and
41 /// move constructor are left to be defined by the compiler (default)
42 Mat4() = default;
43 #else
44 Mat4() {}
45
46 /// Copy constructor
47 Mat4(const Mat<4, T> &m)
48 {
49 for (int i = 0; i < 4; ++i) {
50 for (int j = 0; j < 4; ++j) {
51 MyBase::mm[i*4 + j] = m[i][j];
52 }
53 }
54 }
55 #endif
56
57 /// Constructor given array of elements, the ordering is in row major form:
58 /** @verbatim
59 a[ 0] a[1] a[ 2] a[ 3]
60 a[ 4] a[5] a[ 6] a[ 7]
61 a[ 8] a[9] a[10] a[11]
62 a[12] a[13] a[14] a[15]
63 @endverbatim */
64 template<typename Source>
65 Mat4(Source *a)
66 {
67 for (int i = 0; i < 16; i++) {
68 MyBase::mm[i] = static_cast<T>(a[i]);
69 }
70 }
71
72 /// Constructor given array of elements, the ordering is in row major form:
73 /** @verbatim
74 a b c d
75 e f g h
76 i j k l
77 m n o p
78 @endverbatim */
79 template<typename Source>
80 743978 Mat4(Source a, Source b, Source c, Source d,
81 Source e, Source f, Source g, Source h,
82 Source i, Source j, Source k, Source l,
83 Source m, Source n, Source o, Source p)
84 {
85 743979 MyBase::mm[ 0] = static_cast<T>(a);
86 743979 MyBase::mm[ 1] = static_cast<T>(b);
87 743979 MyBase::mm[ 2] = static_cast<T>(c);
88 743979 MyBase::mm[ 3] = static_cast<T>(d);
89
90 743979 MyBase::mm[ 4] = static_cast<T>(e);
91 743979 MyBase::mm[ 5] = static_cast<T>(f);
92 743979 MyBase::mm[ 6] = static_cast<T>(g);
93 743979 MyBase::mm[ 7] = static_cast<T>(h);
94
95 743979 MyBase::mm[ 8] = static_cast<T>(i);
96 743979 MyBase::mm[ 9] = static_cast<T>(j);
97 743979 MyBase::mm[10] = static_cast<T>(k);
98 743979 MyBase::mm[11] = static_cast<T>(l);
99
100 743979 MyBase::mm[12] = static_cast<T>(m);
101 743979 MyBase::mm[13] = static_cast<T>(n);
102 743979 MyBase::mm[14] = static_cast<T>(o);
103
15/25
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 1 times.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 1 times.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
743970 MyBase::mm[15] = static_cast<T>(p);
104 }
105
106 /// Construct matrix from rows or columns vectors (defaults to rows
107 /// for historical reasons)
108 template<typename Source>
109 Mat4(const Vec4<Source> &v1, const Vec4<Source> &v2,
110 const Vec4<Source> &v3, const Vec4<Source> &v4, bool rows = true)
111 {
112 if (rows) {
113 this->setRows(v1, v2, v3, v4);
114 } else {
115 this->setColumns(v1, v2, v3, v4);
116 }
117 }
118
119 /// Conversion constructor
120 template<typename Source>
121 explicit Mat4(const Mat4<Source> &m)
122 {
123 const Source *src = m.asPointer();
124
125 for (int i=0; i<16; ++i) {
126 MyBase::mm[i] = static_cast<T>(src[i]);
127 }
128 }
129
130 /// Predefined constant for identity matrix
131 738714 static const Mat4<T>& identity() {
132
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 738712 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
738714 static const Mat4<T> sIdentity = Mat4<T>(
133 1, 0, 0, 0,
134 0, 1, 0, 0,
135 0, 0, 1, 0,
136 0, 0, 0, 1
137 );
138 738714 return sIdentity;
139 }
140
141 /// Predefined constant for zero matrix
142 7284032 static const Mat4<T>& zero() {
143
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3642179 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
7284032 static const Mat4<T> sZero = Mat4<T>(
144 0, 0, 0, 0,
145 0, 0, 0, 0,
146 0, 0, 0, 0,
147 0, 0, 0, 0
148 );
149 7284032 return sZero;
150 }
151
152 /// Set ith row to vector v
153 void setRow(int i, const Vec4<T> &v)
154 {
155 // assert(i>=0 && i<4);
156 int i4 = i * 4;
157 MyBase::mm[i4+0] = v[0];
158 MyBase::mm[i4+1] = v[1];
159 MyBase::mm[i4+2] = v[2];
160 MyBase::mm[i4+3] = v[3];
161 }
162
163 /// Get ith row, e.g. Vec4f v = m.row(1);
164 Vec4<T> row(int i) const
165 {
166 // assert(i>=0 && i<3);
167 return Vec4<T>((*this)(i,0), (*this)(i,1), (*this)(i,2), (*this)(i,3));
168 }
169
170 /// Set jth column to vector v
171 void setCol(int j, const Vec4<T>& v)
172 {
173 // assert(j>=0 && j<4);
174 MyBase::mm[ 0+j] = v[0];
175 MyBase::mm[ 4+j] = v[1];
176 MyBase::mm[ 8+j] = v[2];
177 MyBase::mm[12+j] = v[3];
178 }
179
180 /// Get jth column, e.g. Vec4f v = m.col(0);
181 Vec4<T> col(int j) const
182 {
183 // assert(j>=0 && j<4);
184 return Vec4<T>((*this)(0,j), (*this)(1,j), (*this)(2,j), (*this)(3,j));
185 }
186
187 /// Alternative indexed reference to the elements
188 /// Note that the indices are row first and column second.
189 /// e.g. m(0,0) = 1;
190 T& operator()(int i, int j)
191 {
192 // assert(i>=0 && i<4);
193 // assert(j>=0 && j<4);
194 return MyBase::mm[4*i+j];
195 }
196
197 /// Alternative indexed constant reference to the elements,
198 /// Note that the indices are row first and column second.
199 /// e.g. float f = m(1,0);
200 T operator()(int i, int j) const
201 {
202 // assert(i>=0 && i<4);
203 // assert(j>=0 && j<4);
204
18/96
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 663619 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 64 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 64 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 64 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 64 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 64 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 8 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 120 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 16 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 64 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 4 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
667515 return MyBase::mm[4*i+j];
205 }
206
207 /// Set the rows of this matrix to the vectors v1, v2, v3, v4
208 void setRows(const Vec4<T> &v1, const Vec4<T> &v2,
209 const Vec4<T> &v3, const Vec4<T> &v4)
210 {
211 MyBase::mm[ 0] = v1[0];
212 MyBase::mm[ 1] = v1[1];
213 MyBase::mm[ 2] = v1[2];
214 MyBase::mm[ 3] = v1[3];
215
216 MyBase::mm[ 4] = v2[0];
217 MyBase::mm[ 5] = v2[1];
218 MyBase::mm[ 6] = v2[2];
219 MyBase::mm[ 7] = v2[3];
220
221 MyBase::mm[ 8] = v3[0];
222 MyBase::mm[ 9] = v3[1];
223 MyBase::mm[10] = v3[2];
224 MyBase::mm[11] = v3[3];
225
226 MyBase::mm[12] = v4[0];
227 MyBase::mm[13] = v4[1];
228 MyBase::mm[14] = v4[2];
229 MyBase::mm[15] = v4[3];
230 }
231
232 /// Set the columns of this matrix to the vectors v1, v2, v3, v4
233 void setColumns(const Vec4<T> &v1, const Vec4<T> &v2,
234 const Vec4<T> &v3, const Vec4<T> &v4)
235 {
236 MyBase::mm[ 0] = v1[0];
237 MyBase::mm[ 1] = v2[0];
238 MyBase::mm[ 2] = v3[0];
239 MyBase::mm[ 3] = v4[0];
240
241 MyBase::mm[ 4] = v1[1];
242 MyBase::mm[ 5] = v2[1];
243 MyBase::mm[ 6] = v3[1];
244 MyBase::mm[ 7] = v4[1];
245
246 MyBase::mm[ 8] = v1[2];
247 MyBase::mm[ 9] = v2[2];
248 MyBase::mm[10] = v3[2];
249 MyBase::mm[11] = v4[2];
250
251 MyBase::mm[12] = v1[3];
252 MyBase::mm[13] = v2[3];
253 MyBase::mm[14] = v3[3];
254 MyBase::mm[15] = v4[3];
255 }
256
257 // Set this matrix to zero
258 void setZero()
259 {
260 MyBase::mm[ 0] = 0;
261 10 MyBase::mm[ 1] = 0;
262 10 MyBase::mm[ 2] = 0;
263 10 MyBase::mm[ 3] = 0;
264 10 MyBase::mm[ 4] = 0;
265 MyBase::mm[ 5] = 0;
266 10 MyBase::mm[ 6] = 0;
267 10 MyBase::mm[ 7] = 0;
268 10 MyBase::mm[ 8] = 0;
269 10 MyBase::mm[ 9] = 0;
270 MyBase::mm[10] = 0;
271 10 MyBase::mm[11] = 0;
272 10 MyBase::mm[12] = 0;
273 10 MyBase::mm[13] = 0;
274
10/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
10 MyBase::mm[14] = 0;
275 MyBase::mm[15] = 0;
276 }
277
278 /// Set this matrix to identity
279 void setIdentity()
280 {
281 406170 MyBase::mm[ 0] = 1;
282 406171 MyBase::mm[ 1] = 0;
283 406171 MyBase::mm[ 2] = 0;
284 406171 MyBase::mm[ 3] = 0;
285
286 406171 MyBase::mm[ 4] = 0;
287 406170 MyBase::mm[ 5] = 1;
288 406171 MyBase::mm[ 6] = 0;
289 406171 MyBase::mm[ 7] = 0;
290
291 406171 MyBase::mm[ 8] = 0;
292 406171 MyBase::mm[ 9] = 0;
293 406170 MyBase::mm[10] = 1;
294 406171 MyBase::mm[11] = 0;
295
296 406171 MyBase::mm[12] = 0;
297 406171 MyBase::mm[13] = 0;
298 406171 MyBase::mm[14] = 0;
299
2/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
406170 MyBase::mm[15] = 1;
300 }
301
302
303 /// Set upper left to a Mat3
304 void setMat3(const Mat3<T> &m)
305 {
306
4/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 3 times.
64 for (int i = 0; i < 3; i++)
307
4/4
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 27 times.
✓ Branch 3 taken 9 times.
192 for (int j=0; j < 3; j++)
308 144 MyBase::mm[i*4+j] = m[i][j];
309 }
310
311 Mat3<T> getMat3() const
312 {
313 Mat3<T> m;
314
315
8/12
✓ Branch 0 taken 1991460 times.
✓ Branch 1 taken 663820 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 303 times.
✓ Branch 9 taken 101 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2655712 for (int i = 0; i < 3; i++)
316
8/12
✓ Branch 0 taken 5974380 times.
✓ Branch 1 taken 1991460 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 909 times.
✓ Branch 9 taken 303 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
7967136 for (int j = 0; j < 3; j++)
317 5975352 m[i][j] = MyBase::mm[i*4+j];
318
319 return m;
320 }
321
322 /// Return the translation component
323 Vec3<T> getTranslation() const
324 {
325 663558 return Vec3<T>(MyBase::mm[12], MyBase::mm[13], MyBase::mm[14]);
326 }
327
328 void setTranslation(const Vec3<T> &t)
329 {
330 406093 MyBase::mm[12] = t[0];
331 406093 MyBase::mm[13] = t[1];
332
2/30
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 331776 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
331789 MyBase::mm[14] = t[2];
333 74304 }
334
335 /// Assignment operator
336 template<typename Source>
337 const Mat4& operator=(const Mat4<Source> &m)
338 {
339 const Source *src = m.asPointer();
340
341 // don't suppress warnings when assigning from different numerical types
342 std::copy(src, (src + this->numElements()), MyBase::mm);
343 return *this;
344 }
345
346 /// Return @c true if this matrix is equivalent to @a m within a tolerance of @a eps.
347 bool eq(const Mat4 &m, T eps=1.0e-8) const
348 {
349
95/100
✓ Branch 0 taken 3112 times.
✓ Branch 1 taken 144 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 80 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 32 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 38 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 32 times.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 16 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 16 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 16 times.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 16 times.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 16 times.
✓ Branch 21 taken 1 times.
✓ Branch 22 taken 16 times.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 16 times.
✓ Branch 25 taken 1 times.
✓ Branch 26 taken 1188880 times.
✓ Branch 27 taken 74305 times.
✓ Branch 28 taken 5308432 times.
✓ Branch 29 taken 331777 times.
✓ Branch 30 taken 16 times.
✓ Branch 31 taken 1 times.
✓ Branch 32 taken 16 times.
✓ Branch 33 taken 1 times.
✓ Branch 34 taken 16 times.
✓ Branch 35 taken 1 times.
✓ Branch 36 taken 16 times.
✓ Branch 37 taken 1 times.
✓ Branch 38 taken 16 times.
✓ Branch 39 taken 1 times.
✓ Branch 40 taken 16 times.
✓ Branch 41 taken 1 times.
✓ Branch 42 taken 16 times.
✓ Branch 43 taken 1 times.
✓ Branch 44 taken 16 times.
✓ Branch 45 taken 1 times.
✓ Branch 46 taken 16 times.
✓ Branch 47 taken 1 times.
✓ Branch 48 taken 16 times.
✓ Branch 49 taken 1 times.
✓ Branch 50 taken 16 times.
✓ Branch 51 taken 1 times.
✓ Branch 52 taken 16 times.
✓ Branch 53 taken 1 times.
✓ Branch 54 taken 16 times.
✓ Branch 55 taken 1 times.
✓ Branch 56 taken 16 times.
✓ Branch 57 taken 1 times.
✓ Branch 58 taken 16 times.
✓ Branch 59 taken 1 times.
✓ Branch 60 taken 16 times.
✓ Branch 61 taken 1 times.
✓ Branch 62 taken 16 times.
✓ Branch 63 taken 1 times.
✓ Branch 64 taken 16 times.
✓ Branch 65 taken 1 times.
✓ Branch 66 taken 16 times.
✓ Branch 67 taken 1 times.
✓ Branch 68 taken 16 times.
✓ Branch 69 taken 1 times.
✓ Branch 70 taken 16 times.
✓ Branch 71 taken 1 times.
✓ Branch 72 taken 16 times.
✓ Branch 73 taken 1 times.
✓ Branch 74 taken 16 times.
✓ Branch 75 taken 1 times.
✓ Branch 76 taken 16 times.
✓ Branch 77 taken 1 times.
✓ Branch 78 taken 16 times.
✓ Branch 79 taken 1 times.
✓ Branch 80 taken 16 times.
✓ Branch 81 taken 1 times.
✓ Branch 82 taken 16 times.
✓ Branch 83 taken 1 times.
✓ Branch 84 taken 16 times.
✓ Branch 85 taken 1 times.
✓ Branch 86 taken 16 times.
✓ Branch 87 taken 1 times.
✓ Branch 88 taken 16 times.
✓ Branch 89 taken 1 times.
✓ Branch 90 taken 16 times.
✓ Branch 91 taken 1 times.
✓ Branch 92 taken 16 times.
✓ Branch 93 taken 1 times.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
6907605 for (int i = 0; i < 16; i++) {
350
51/100
✓ Branch 0 taken 2890 times.
✓ Branch 1 taken 222 times.
✓ Branch 2 taken 92 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 37 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 16 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 16 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 16 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 16 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 16 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 16 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 16 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 1188880 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 5308432 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 16 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 16 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 16 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 16 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 16 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 16 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 16 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 16 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 16 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 16 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 16 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 16 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 16 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 16 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 16 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 16 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 16 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 16 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 16 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 16 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 16 times.
✗ Branch 71 not taken.
✓ Branch 72 taken 16 times.
✗ Branch 73 not taken.
✓ Branch 74 taken 16 times.
✗ Branch 75 not taken.
✓ Branch 76 taken 16 times.
✗ Branch 77 not taken.
✓ Branch 78 taken 16 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 16 times.
✗ Branch 81 not taken.
✓ Branch 82 taken 16 times.
✗ Branch 83 not taken.
✓ Branch 84 taken 16 times.
✗ Branch 85 not taken.
✓ Branch 86 taken 16 times.
✗ Branch 87 not taken.
✓ Branch 88 taken 16 times.
✗ Branch 89 not taken.
✓ Branch 90 taken 16 times.
✗ Branch 91 not taken.
✓ Branch 92 taken 16 times.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✓ Branch 95 taken 1 times.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
6501324 if (!isApproxEqual(MyBase::mm[i], m.mm[i], eps))
351 return false;
352 }
353 return true;
354 }
355
356 /// Negation operator, for e.g. m1 = -m2;
357 4 Mat4<T> operator-() const
358 {
359 return Mat4<T>(
360 4 -MyBase::mm[ 0], -MyBase::mm[ 1], -MyBase::mm[ 2], -MyBase::mm[ 3],
361 4 -MyBase::mm[ 4], -MyBase::mm[ 5], -MyBase::mm[ 6], -MyBase::mm[ 7],
362 4 -MyBase::mm[ 8], -MyBase::mm[ 9], -MyBase::mm[10], -MyBase::mm[11],
363 4 -MyBase::mm[12], -MyBase::mm[13], -MyBase::mm[14], -MyBase::mm[15]
364 4 );
365 } // trivial
366
367 /// Multiply each element of this matrix by @a scalar.
368 template <typename S>
369 const Mat4<T>& operator*=(S scalar)
370 {
371 MyBase::mm[ 0] *= scalar;
372 MyBase::mm[ 1] *= scalar;
373 MyBase::mm[ 2] *= scalar;
374 MyBase::mm[ 3] *= scalar;
375
376 MyBase::mm[ 4] *= scalar;
377 MyBase::mm[ 5] *= scalar;
378 MyBase::mm[ 6] *= scalar;
379 MyBase::mm[ 7] *= scalar;
380
381 MyBase::mm[ 8] *= scalar;
382 MyBase::mm[ 9] *= scalar;
383 MyBase::mm[10] *= scalar;
384 MyBase::mm[11] *= scalar;
385
386 MyBase::mm[12] *= scalar;
387 MyBase::mm[13] *= scalar;
388 MyBase::mm[14] *= scalar;
389 MyBase::mm[15] *= scalar;
390 return *this;
391 }
392
393 /// Add each element of the given matrix to the corresponding element of this matrix.
394 template <typename S>
395 24 const Mat4<T> &operator+=(const Mat4<S> &m1)
396 {
397 const S* s = m1.asPointer();
398
399 24 MyBase::mm[ 0] += s[ 0];
400 24 MyBase::mm[ 1] += s[ 1];
401 24 MyBase::mm[ 2] += s[ 2];
402 24 MyBase::mm[ 3] += s[ 3];
403
404 24 MyBase::mm[ 4] += s[ 4];
405 24 MyBase::mm[ 5] += s[ 5];
406 24 MyBase::mm[ 6] += s[ 6];
407 24 MyBase::mm[ 7] += s[ 7];
408
409 24 MyBase::mm[ 8] += s[ 8];
410 24 MyBase::mm[ 9] += s[ 9];
411 24 MyBase::mm[10] += s[10];
412 24 MyBase::mm[11] += s[11];
413
414 24 MyBase::mm[12] += s[12];
415 24 MyBase::mm[13] += s[13];
416 24 MyBase::mm[14] += s[14];
417 24 MyBase::mm[15] += s[15];
418
419 24 return *this;
420 }
421
422 /// Subtract each element of the given matrix from the corresponding element of this matrix.
423 template <typename S>
424 164074 const Mat4<T> &operator-=(const Mat4<S> &m1)
425 {
426 const S* s = m1.asPointer();
427
428 164074 MyBase::mm[ 0] -= s[ 0];
429 164074 MyBase::mm[ 1] -= s[ 1];
430 164074 MyBase::mm[ 2] -= s[ 2];
431 164074 MyBase::mm[ 3] -= s[ 3];
432
433 164074 MyBase::mm[ 4] -= s[ 4];
434 164074 MyBase::mm[ 5] -= s[ 5];
435 164074 MyBase::mm[ 6] -= s[ 6];
436 164074 MyBase::mm[ 7] -= s[ 7];
437
438 164074 MyBase::mm[ 8] -= s[ 8];
439 164074 MyBase::mm[ 9] -= s[ 9];
440 164074 MyBase::mm[10] -= s[10];
441 164074 MyBase::mm[11] -= s[11];
442
443 164074 MyBase::mm[12] -= s[12];
444 164074 MyBase::mm[13] -= s[13];
445 164074 MyBase::mm[14] -= s[14];
446 164074 MyBase::mm[15] -= s[15];
447
448 164074 return *this;
449 }
450
451 /// Multiply this matrix by the given matrix.
452 template <typename S>
453 1962135 const Mat4<T> &operator*=(const Mat4<S> &m1)
454 {
455 1962135 Mat4<T> m0(*this);
456
457 const T* s0 = m0.asPointer();
458 const S* s1 = m1.asPointer();
459
460
2/2
✓ Branch 0 taken 7848532 times.
✓ Branch 1 taken 1962133 times.
9810675 for (int i = 0; i < 4; i++) {
461 7848540 int i4 = 4 * i;
462 7848540 MyBase::mm[i4+0] = static_cast<T>(s0[i4+0] * s1[ 0] +
463 7848540 s0[i4+1] * s1[ 4] +
464 7848540 s0[i4+2] * s1[ 8] +
465 7848540 s0[i4+3] * s1[12]);
466
467 7848540 MyBase::mm[i4+1] = static_cast<T>(s0[i4+0] * s1[ 1] +
468 7848540 s0[i4+1] * s1[ 5] +
469 7848540 s0[i4+2] * s1[ 9] +
470 7848540 s0[i4+3] * s1[13]);
471
472 7848540 MyBase::mm[i4+2] = static_cast<T>(s0[i4+0] * s1[ 2] +
473 7848540 s0[i4+1] * s1[ 6] +
474 7848540 s0[i4+2] * s1[10] +
475 7848540 s0[i4+3] * s1[14]);
476
477 7848540 MyBase::mm[i4+3] = static_cast<T>(s0[i4+0] * s1[ 3] +
478 7848540 s0[i4+1] * s1[ 7] +
479 7848540 s0[i4+2] * s1[11] +
480 7848540 s0[i4+3] * s1[15]);
481 }
482 1962135 return *this;
483 }
484
485 /// @return transpose of this
486 Mat4 transpose() const
487 {
488 return Mat4<T>(
489 87 MyBase::mm[ 0], MyBase::mm[ 4], MyBase::mm[ 8], MyBase::mm[12],
490 87 MyBase::mm[ 1], MyBase::mm[ 5], MyBase::mm[ 9], MyBase::mm[13],
491 87 MyBase::mm[ 2], MyBase::mm[ 6], MyBase::mm[10], MyBase::mm[14],
492
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
87 MyBase::mm[ 3], MyBase::mm[ 7], MyBase::mm[11], MyBase::mm[15]
493 );
494 }
495
496
497 /// @return inverse of this
498 /// @throw ArithmeticError if singular
499 380 Mat4 inverse(T tolerance = 0) const
500 {
501 //
502 // inv [ A | b ] = [ E | f ] A: 3x3, b: 3x1, c': 1x3 d: 1x1
503 // [ c' | d ] [ g' | h ]
504 //
505 // If A is invertible use
506 //
507 // E = A^-1 + p*h*r
508 // p = A^-1 * b
509 // f = -p * h
510 // g' = -h * c'
511 // h = 1 / (d - c'*p)
512 // r' = c'*A^-1
513 //
514 // Otherwise use gauss-jordan elimination
515 //
516
517 //
518 // We create this alias to ourself so we can easily use own subscript
519 // operator.
520 const Mat4<T>& m(*this);
521
522 380 T m0011 = m[0][0] * m[1][1];
523 380 T m0012 = m[0][0] * m[1][2];
524 380 T m0110 = m[0][1] * m[1][0];
525 380 T m0210 = m[0][2] * m[1][0];
526 380 T m0120 = m[0][1] * m[2][0];
527 380 T m0220 = m[0][2] * m[2][0];
528
529 380 T detA = m0011 * m[2][2] - m0012 * m[2][1] - m0110 * m[2][2]
530
1/2
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
380 + m0210 * m[2][1] + m0120 * m[1][2] - m0220 * m[1][1];
531
532 bool hasPerspective =
533
1/2
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
380 (!isExactlyEqual(m[0][3], T(0.0)) ||
534
1/2
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
380 !isExactlyEqual(m[1][3], T(0.0)) ||
535
2/4
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 380 times.
760 !isExactlyEqual(m[2][3], T(0.0)) ||
536 !isExactlyEqual(m[3][3], T(1.0)));
537
538 T det;
539 if (hasPerspective) {
540 det = m[0][3] * det3(m, 1,2,3, 0,2,1)
541 + m[1][3] * det3(m, 2,0,3, 0,2,1)
542 + m[2][3] * det3(m, 3,0,1, 0,2,1)
543 + m[3][3] * detA;
544 } else {
545 380 det = detA * m[3][3];
546 }
547
548 Mat4<T> inv;
549 bool invertible;
550
551
1/2
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
380 if (isApproxEqual(det,T(0.0),tolerance)) {
552 invertible = false;
553
554
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
380 } else if (isApproxEqual(detA,T(0.0),T(1e-8))) {
555 // det is too small to rely on inversion by subblocks
556 invertible = m.invert(inv, tolerance);
557
558 } else {
559 invertible = true;
560 380 detA = 1.0 / detA;
561
562 //
563 // Calculate A^-1
564 //
565 380 inv[0][0] = detA * ( m[1][1] * m[2][2] - m[1][2] * m[2][1]);
566 380 inv[0][1] = detA * (-m[0][1] * m[2][2] + m[0][2] * m[2][1]);
567 380 inv[0][2] = detA * ( m[0][1] * m[1][2] - m[0][2] * m[1][1]);
568
569 380 inv[1][0] = detA * (-m[1][0] * m[2][2] + m[1][2] * m[2][0]);
570 380 inv[1][1] = detA * ( m[0][0] * m[2][2] - m0220);
571 380 inv[1][2] = detA * ( m0210 - m0012);
572
573 380 inv[2][0] = detA * ( m[1][0] * m[2][1] - m[1][1] * m[2][0]);
574 380 inv[2][1] = detA * ( m0120 - m[0][0] * m[2][1]);
575 380 inv[2][2] = detA * ( m0011 - m0110);
576
577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
380 if (hasPerspective) {
578 //
579 // Calculate r, p, and h
580 //
581 Vec3<T> r;
582 r[0] = m[3][0] * inv[0][0] + m[3][1] * inv[1][0]
583 + m[3][2] * inv[2][0];
584 r[1] = m[3][0] * inv[0][1] + m[3][1] * inv[1][1]
585 + m[3][2] * inv[2][1];
586 r[2] = m[3][0] * inv[0][2] + m[3][1] * inv[1][2]
587 + m[3][2] * inv[2][2];
588
589 Vec3<T> p;
590 p[0] = inv[0][0] * m[0][3] + inv[0][1] * m[1][3]
591 + inv[0][2] * m[2][3];
592 p[1] = inv[1][0] * m[0][3] + inv[1][1] * m[1][3]
593 + inv[1][2] * m[2][3];
594 p[2] = inv[2][0] * m[0][3] + inv[2][1] * m[1][3]
595 + inv[2][2] * m[2][3];
596
597 T h = m[3][3] - p.dot(Vec3<T>(m[3][0],m[3][1],m[3][2]));
598 if (isApproxEqual(h,T(0.0),tolerance)) {
599 invertible = false;
600
601 } else {
602 h = 1.0 / h;
603
604 //
605 // Calculate h, g, and f
606 //
607 inv[3][3] = h;
608 inv[3][0] = -h * r[0];
609 inv[3][1] = -h * r[1];
610 inv[3][2] = -h * r[2];
611
612 inv[0][3] = -h * p[0];
613 inv[1][3] = -h * p[1];
614 inv[2][3] = -h * p[2];
615
616 //
617 // Calculate E
618 //
619 p *= h;
620 inv[0][0] += p[0] * r[0];
621 inv[0][1] += p[0] * r[1];
622 inv[0][2] += p[0] * r[2];
623 inv[1][0] += p[1] * r[0];
624 inv[1][1] += p[1] * r[1];
625 inv[1][2] += p[1] * r[2];
626 inv[2][0] += p[2] * r[0];
627 inv[2][1] += p[2] * r[1];
628 inv[2][2] += p[2] * r[2];
629 }
630 } else {
631 // Equations are much simpler in the non-perspective case
632 380 inv[3][0] = - (m[3][0] * inv[0][0] + m[3][1] * inv[1][0]
633 380 + m[3][2] * inv[2][0]);
634 380 inv[3][1] = - (m[3][0] * inv[0][1] + m[3][1] * inv[1][1]
635 380 + m[3][2] * inv[2][1]);
636 380 inv[3][2] = - (m[3][0] * inv[0][2] + m[3][1] * inv[1][2]
637 380 + m[3][2] * inv[2][2]);
638 380 inv[0][3] = 0.0;
639 380 inv[1][3] = 0.0;
640 380 inv[2][3] = 0.0;
641 380 inv[3][3] = 1.0;
642 }
643 }
644
645 if (!invertible) OPENVDB_THROW(ArithmeticError, "Inversion of singular 4x4 matrix");
646 380 return inv;
647 }
648
649
650 /// Determinant of matrix
651 173 T det() const
652 {
653 const T *ap;
654 Mat3<T> submat;
655 T det;
656 T *sp;
657 int i, j, k, sign;
658
659 det = 0;
660 sign = 1;
661
2/2
✓ Branch 0 taken 356 times.
✓ Branch 1 taken 89 times.
865 for (i = 0; i < 4; i++) {
662 692 ap = &MyBase::mm[ 0];
663 sp = submat.asPointer();
664
2/2
✓ Branch 0 taken 1424 times.
✓ Branch 1 taken 356 times.
3460 for (j = 0; j < 4; j++) {
665
2/2
✓ Branch 0 taken 5696 times.
✓ Branch 1 taken 1424 times.
13840 for (k = 0; k < 4; k++) {
666
2/2
✓ Branch 0 taken 3204 times.
✓ Branch 1 taken 2492 times.
11072 if ((k != i) && (j != 0)) {
667 6228 *sp++ = *ap;
668 }
669 11072 ap++;
670 }
671 }
672
673 692 det += T(sign) * MyBase::mm[i] * submat.det();
674 692 sign = -sign;
675 }
676
677 173 return det;
678 }
679
680 /// Sets the matrix to a matrix that translates by v
681 static Mat4 translation(const Vec3d& v)
682 {
683 return Mat4(
684 T(1), T(0), T(0), T(0),
685 T(0), T(1), T(0), T(0),
686 T(0), T(0), T(1), T(0),
687 T(v.x()), T(v.y()),T(v.z()), T(1));
688 }
689
690 /// Sets the matrix to a matrix that translates by v
691 template <typename T0>
692 void setToTranslation(const Vec3<T0>& v)
693 {
694 MyBase::mm[ 0] = 1;
695 MyBase::mm[ 1] = 0;
696 MyBase::mm[ 2] = 0;
697 MyBase::mm[ 3] = 0;
698
699 MyBase::mm[ 4] = 0;
700 MyBase::mm[ 5] = 1;
701 MyBase::mm[ 6] = 0;
702 MyBase::mm[ 7] = 0;
703
704 MyBase::mm[ 8] = 0;
705 MyBase::mm[ 9] = 0;
706 MyBase::mm[10] = 1;
707 MyBase::mm[11] = 0;
708
709 MyBase::mm[12] = v.x();
710 MyBase::mm[13] = v.y();
711 MyBase::mm[14] = v.z();
712 MyBase::mm[15] = 1;
713 }
714
715 /// Left multiples by the specified translation, i.e. Trans * (*this)
716 template <typename T0>
717 743785 void preTranslate(const Vec3<T0>& tr)
718 {
719 Vec3<T> tmp(tr.x(), tr.y(), tr.z());
720 Mat4<T> Tr = Mat4<T>::translation(tmp);
721
722 743785 *this = Tr * (*this);
723
724 743785 }
725
726 /// Right multiplies by the specified translation matrix, i.e. (*this) * Trans
727 template <typename T0>
728 45 void postTranslate(const Vec3<T0>& tr)
729 {
730 Vec3<T> tmp(tr.x(), tr.y(), tr.z());
731 Mat4<T> Tr = Mat4<T>::translation(tmp);
732
733 45 *this = (*this) * Tr;
734
735 45 }
736
737
738 /// Sets the matrix to a matrix that scales by v
739 template <typename T0>
740 void setToScale(const Vec3<T0>& v)
741 {
742 this->setIdentity();
743 1 MyBase::mm[ 0] = v.x();
744 1 MyBase::mm[ 5] = v.y();
745 1 MyBase::mm[10] = v.z();
746 }
747
748 // Left multiples by the specified scale matrix, i.e. Sc * (*this)
749 template <typename T0>
750 149499 void preScale(const Vec3<T0>& v)
751 {
752 149499 MyBase::mm[ 0] *= v.x();
753 149499 MyBase::mm[ 1] *= v.x();
754 149499 MyBase::mm[ 2] *= v.x();
755 149499 MyBase::mm[ 3] *= v.x();
756
757 149499 MyBase::mm[ 4] *= v.y();
758 149499 MyBase::mm[ 5] *= v.y();
759 149499 MyBase::mm[ 6] *= v.y();
760 149499 MyBase::mm[ 7] *= v.y();
761
762 149499 MyBase::mm[ 8] *= v.z();
763 149499 MyBase::mm[ 9] *= v.z();
764 149499 MyBase::mm[10] *= v.z();
765 149499 MyBase::mm[11] *= v.z();
766 149499 }
767
768
769
770 // Right multiples by the specified scale matrix, i.e. (*this) * Sc
771 template <typename T0>
772 704 void postScale(const Vec3<T0>& v)
773 {
774
775 704 MyBase::mm[ 0] *= v.x();
776 704 MyBase::mm[ 1] *= v.y();
777 704 MyBase::mm[ 2] *= v.z();
778
779 704 MyBase::mm[ 4] *= v.x();
780 704 MyBase::mm[ 5] *= v.y();
781 704 MyBase::mm[ 6] *= v.z();
782
783 704 MyBase::mm[ 8] *= v.x();
784 704 MyBase::mm[ 9] *= v.y();
785 704 MyBase::mm[10] *= v.z();
786
787 704 MyBase::mm[12] *= v.x();
788 704 MyBase::mm[13] *= v.y();
789 704 MyBase::mm[14] *= v.z();
790
791 704 }
792
793
794 /// @brief Sets the matrix to a rotation about the given axis.
795 /// @param axis The axis (one of X, Y, Z) to rotate about.
796 /// @param angle The rotation angle, in radians.
797
0/3
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 void setToRotation(Axis axis, T angle) {*this = rotation<Mat4<T> >(axis, angle);}
798
799 /// @brief Sets the matrix to a rotation about an arbitrary axis
800 /// @param axis The axis of rotation (cannot be zero-length)
801 /// @param angle The rotation angle, in radians.
802 7 void setToRotation(const Vec3<T>& axis, T angle) {*this = rotation<Mat4<T> >(axis, angle);}
803
804 /// @brief Sets the matrix to a rotation that maps v1 onto v2 about the cross
805 /// product of v1 and v2.
806 14 void setToRotation(const Vec3<T>& v1, const Vec3<T>& v2) {*this = rotation<Mat4<T> >(v1, v2);}
807
808
809 /// @brief Left multiplies by a rotation clock-wiseabout the given axis into this matrix.
810 /// @param axis The axis (one of X, Y, Z) of rotation.
811 /// @param angle The clock-wise rotation angle, in radians.
812 446302 void preRotate(Axis axis, T angle)
813 {
814 446302 T c = static_cast<T>(cos(angle));
815 446302 T s = -static_cast<T>(sin(angle)); // the "-" makes it clockwise
816
817
3/4
✓ Branch 0 taken 148782 times.
✓ Branch 1 taken 148762 times.
✓ Branch 2 taken 148758 times.
✗ Branch 3 not taken.
446302 switch (axis) {
818 148782 case X_AXIS:
819 {
820 T a4, a5, a6, a7;
821
822 148782 a4 = c * MyBase::mm[ 4] - s * MyBase::mm[ 8];
823 148782 a5 = c * MyBase::mm[ 5] - s * MyBase::mm[ 9];
824 148782 a6 = c * MyBase::mm[ 6] - s * MyBase::mm[10];
825 148782 a7 = c * MyBase::mm[ 7] - s * MyBase::mm[11];
826
827
828 148782 MyBase::mm[ 8] = s * MyBase::mm[ 4] + c * MyBase::mm[ 8];
829 148782 MyBase::mm[ 9] = s * MyBase::mm[ 5] + c * MyBase::mm[ 9];
830 148782 MyBase::mm[10] = s * MyBase::mm[ 6] + c * MyBase::mm[10];
831 148782 MyBase::mm[11] = s * MyBase::mm[ 7] + c * MyBase::mm[11];
832
833 148782 MyBase::mm[ 4] = a4;
834 148782 MyBase::mm[ 5] = a5;
835 148782 MyBase::mm[ 6] = a6;
836 148782 MyBase::mm[ 7] = a7;
837 }
838 148782 break;
839
840 148762 case Y_AXIS:
841 {
842 T a0, a1, a2, a3;
843
844 148762 a0 = c * MyBase::mm[ 0] + s * MyBase::mm[ 8];
845 148762 a1 = c * MyBase::mm[ 1] + s * MyBase::mm[ 9];
846 148762 a2 = c * MyBase::mm[ 2] + s * MyBase::mm[10];
847 148762 a3 = c * MyBase::mm[ 3] + s * MyBase::mm[11];
848
849 148762 MyBase::mm[ 8] = -s * MyBase::mm[ 0] + c * MyBase::mm[ 8];
850 148762 MyBase::mm[ 9] = -s * MyBase::mm[ 1] + c * MyBase::mm[ 9];
851 148762 MyBase::mm[10] = -s * MyBase::mm[ 2] + c * MyBase::mm[10];
852 148762 MyBase::mm[11] = -s * MyBase::mm[ 3] + c * MyBase::mm[11];
853
854
855 148762 MyBase::mm[ 0] = a0;
856 148762 MyBase::mm[ 1] = a1;
857 148762 MyBase::mm[ 2] = a2;
858 148762 MyBase::mm[ 3] = a3;
859 }
860 148762 break;
861
862 148758 case Z_AXIS:
863 {
864 T a0, a1, a2, a3;
865
866 148758 a0 = c * MyBase::mm[ 0] - s * MyBase::mm[ 4];
867 148758 a1 = c * MyBase::mm[ 1] - s * MyBase::mm[ 5];
868 148758 a2 = c * MyBase::mm[ 2] - s * MyBase::mm[ 6];
869 148758 a3 = c * MyBase::mm[ 3] - s * MyBase::mm[ 7];
870
871 148758 MyBase::mm[ 4] = s * MyBase::mm[ 0] + c * MyBase::mm[ 4];
872 148758 MyBase::mm[ 5] = s * MyBase::mm[ 1] + c * MyBase::mm[ 5];
873 148758 MyBase::mm[ 6] = s * MyBase::mm[ 2] + c * MyBase::mm[ 6];
874 148758 MyBase::mm[ 7] = s * MyBase::mm[ 3] + c * MyBase::mm[ 7];
875
876 148758 MyBase::mm[ 0] = a0;
877 148758 MyBase::mm[ 1] = a1;
878 148758 MyBase::mm[ 2] = a2;
879 148758 MyBase::mm[ 3] = a3;
880 }
881 148758 break;
882
883 default:
884 assert(axis==X_AXIS || axis==Y_AXIS || axis==Z_AXIS);
885 }
886 446302 }
887
888
889 /// @brief Right multiplies by a rotation clock-wiseabout the given axis into this matrix.
890 /// @param axis The axis (one of X, Y, Z) of rotation.
891 /// @param angle The clock-wise rotation angle, in radians.
892 31 void postRotate(Axis axis, T angle)
893 {
894 31 T c = static_cast<T>(cos(angle));
895 31 T s = -static_cast<T>(sin(angle)); // the "-" makes it clockwise
896
897
898
899
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
31 switch (axis) {
900 24 case X_AXIS:
901 {
902 T a2, a6, a10, a14;
903
904 24 a2 = c * MyBase::mm[ 2] - s * MyBase::mm[ 1];
905 24 a6 = c * MyBase::mm[ 6] - s * MyBase::mm[ 5];
906 24 a10 = c * MyBase::mm[10] - s * MyBase::mm[ 9];
907 24 a14 = c * MyBase::mm[14] - s * MyBase::mm[13];
908
909
910 24 MyBase::mm[ 1] = c * MyBase::mm[ 1] + s * MyBase::mm[ 2];
911 24 MyBase::mm[ 5] = c * MyBase::mm[ 5] + s * MyBase::mm[ 6];
912 24 MyBase::mm[ 9] = c * MyBase::mm[ 9] + s * MyBase::mm[10];
913 24 MyBase::mm[13] = c * MyBase::mm[13] + s * MyBase::mm[14];
914
915 24 MyBase::mm[ 2] = a2;
916 24 MyBase::mm[ 6] = a6;
917 24 MyBase::mm[10] = a10;
918 24 MyBase::mm[14] = a14;
919 }
920 24 break;
921
922 5 case Y_AXIS:
923 {
924 T a2, a6, a10, a14;
925
926 5 a2 = c * MyBase::mm[ 2] + s * MyBase::mm[ 0];
927 5 a6 = c * MyBase::mm[ 6] + s * MyBase::mm[ 4];
928 5 a10 = c * MyBase::mm[10] + s * MyBase::mm[ 8];
929 5 a14 = c * MyBase::mm[14] + s * MyBase::mm[12];
930
931 5 MyBase::mm[ 0] = c * MyBase::mm[ 0] - s * MyBase::mm[ 2];
932 5 MyBase::mm[ 4] = c * MyBase::mm[ 4] - s * MyBase::mm[ 6];
933 5 MyBase::mm[ 8] = c * MyBase::mm[ 8] - s * MyBase::mm[10];
934 5 MyBase::mm[12] = c * MyBase::mm[12] - s * MyBase::mm[14];
935
936 5 MyBase::mm[ 2] = a2;
937 5 MyBase::mm[ 6] = a6;
938 5 MyBase::mm[10] = a10;
939 5 MyBase::mm[14] = a14;
940 }
941 5 break;
942
943 2 case Z_AXIS:
944 {
945 T a1, a5, a9, a13;
946
947 2 a1 = c * MyBase::mm[ 1] - s * MyBase::mm[ 0];
948 2 a5 = c * MyBase::mm[ 5] - s * MyBase::mm[ 4];
949 2 a9 = c * MyBase::mm[ 9] - s * MyBase::mm[ 8];
950 2 a13 = c * MyBase::mm[13] - s * MyBase::mm[12];
951
952 2 MyBase::mm[ 0] = c * MyBase::mm[ 0] + s * MyBase::mm[ 1];
953 2 MyBase::mm[ 4] = c * MyBase::mm[ 4] + s * MyBase::mm[ 5];
954 2 MyBase::mm[ 8] = c * MyBase::mm[ 8] + s * MyBase::mm[ 9];
955 2 MyBase::mm[12] = c * MyBase::mm[12] + s * MyBase::mm[13];
956
957 2 MyBase::mm[ 1] = a1;
958 2 MyBase::mm[ 5] = a5;
959 2 MyBase::mm[ 9] = a9;
960 2 MyBase::mm[13] = a13;
961
962 }
963 2 break;
964
965 default:
966 assert(axis==X_AXIS || axis==Y_AXIS || axis==Z_AXIS);
967 }
968 31 }
969
970 /// @brief Sets the matrix to a shear along axis0 by a fraction of axis1.
971 /// @param axis0 The fixed axis of the shear.
972 /// @param axis1 The shear axis.
973 /// @param shearby The shear factor.
974 void setToShear(Axis axis0, Axis axis1, T shearby)
975 {
976 2 *this = shear<Mat4<T> >(axis0, axis1, shearby);
977 }
978
979
980 /// @brief Left multiplies a shearing transformation into the matrix.
981 /// @see setToShear
982 7 void preShear(Axis axis0, Axis axis1, T shear)
983 {
984 7 int index0 = static_cast<int>(axis0);
985 7 int index1 = static_cast<int>(axis1);
986
987 // to row "index1" add a multiple of the index0 row
988 13 MyBase::mm[index1 * 4 + 0] += shear * MyBase::mm[index0 * 4 + 0];
989 13 MyBase::mm[index1 * 4 + 1] += shear * MyBase::mm[index0 * 4 + 1];
990 13 MyBase::mm[index1 * 4 + 2] += shear * MyBase::mm[index0 * 4 + 2];
991 12 MyBase::mm[index1 * 4 + 3] += shear * MyBase::mm[index0 * 4 + 3];
992 7 }
993
994
995 /// @brief Right multiplies a shearing transformation into the matrix.
996 /// @see setToShear
997 7 void postShear(Axis axis0, Axis axis1, T shear)
998 {
999 7 int index0 = static_cast<int>(axis0);
1000 7 int index1 = static_cast<int>(axis1);
1001
1002 // to collumn "index0" add a multiple of the index1 row
1003 12 MyBase::mm[index0 + 0] += shear * MyBase::mm[index1 + 0];
1004 12 MyBase::mm[index0 + 4] += shear * MyBase::mm[index1 + 4];
1005 12 MyBase::mm[index0 + 8] += shear * MyBase::mm[index1 + 8];
1006 11 MyBase::mm[index0 + 12] += shear * MyBase::mm[index1 + 12];
1007
1008 8 }
1009
1010 /// Transform a Vec4 by post-multiplication.
1011 template<typename T0>
1012 Vec4<T0> transform(const Vec4<T0> &v) const
1013 {
1014 return static_cast< Vec4<T0> >(v * *this);
1015 }
1016
1017 /// Transform a Vec3 by post-multiplication, without homogenous division.
1018 template<typename T0>
1019 1108081 Vec3<T0> transform(const Vec3<T0> &v) const
1020 {
1021 1108094 return static_cast< Vec3<T0> >(v * *this);
1022 }
1023
1024 /// Transform a Vec4 by pre-multiplication.
1025 template<typename T0>
1026 Vec4<T0> pretransform(const Vec4<T0> &v) const
1027 {
1028 return static_cast< Vec4<T0> >(*this * v);
1029 }
1030
1031 /// Transform a Vec3 by pre-multiplication, without homogenous division.
1032 template<typename T0>
1033 Vec3<T0> pretransform(const Vec3<T0> &v) const
1034 {
1035 return static_cast< Vec3<T0> >(*this * v);
1036 }
1037
1038 /// Transform a Vec3 by post-multiplication, doing homogenous divison.
1039 template<typename T0>
1040
1/2
✓ Branch 0 taken 55078 times.
✗ Branch 1 not taken.
55078 Vec3<T0> transformH(const Vec3<T0> &p) const
1041 {
1042 T0 w;
1043
1044 // w = p * (*this).col(3);
1045 55078 w = static_cast<T0>(p[0] * MyBase::mm[ 3] + p[1] * MyBase::mm[ 7]
1046
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
55078 + p[2] * MyBase::mm[11] + MyBase::mm[15]);
1047
1048
1/2
✓ Branch 0 taken 55078 times.
✗ Branch 1 not taken.
55078 if ( !isExactlyEqual(w , 0.0) ) {
1049 55078 return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 4] +
1050 55078 p[2] * MyBase::mm[ 8] + MyBase::mm[12]) / w),
1051 55078 static_cast<T0>((p[0] * MyBase::mm[ 1] + p[1] * MyBase::mm[ 5] +
1052 55078 p[2] * MyBase::mm[ 9] + MyBase::mm[13]) / w),
1053 55078 static_cast<T0>((p[0] * MyBase::mm[ 2] + p[1] * MyBase::mm[ 6] +
1054 55078 p[2] * MyBase::mm[10] + MyBase::mm[14]) / w));
1055 }
1056
1057 return Vec3<T0>(0, 0, 0);
1058 }
1059
1060 /// Transform a Vec3 by pre-multiplication, doing homogenous division.
1061 template<typename T0>
1062 Vec3<T0> pretransformH(const Vec3<T0> &p) const
1063 {
1064 T0 w;
1065
1066 // w = p * (*this).col(3);
1067 w = p[0] * MyBase::mm[12] + p[1] * MyBase::mm[13] + p[2] * MyBase::mm[14] + MyBase::mm[15];
1068
1069 if ( !isExactlyEqual(w , 0.0) ) {
1070 return Vec3<T0>(static_cast<T0>((p[0] * MyBase::mm[ 0] + p[1] * MyBase::mm[ 1] +
1071 p[2] * MyBase::mm[ 2] + MyBase::mm[ 3]) / w),
1072 static_cast<T0>((p[0] * MyBase::mm[ 4] + p[1] * MyBase::mm[ 5] +
1073 p[2] * MyBase::mm[ 6] + MyBase::mm[ 7]) / w),
1074 static_cast<T0>((p[0] * MyBase::mm[ 8] + p[1] * MyBase::mm[ 9] +
1075 p[2] * MyBase::mm[10] + MyBase::mm[11]) / w));
1076 }
1077
1078 return Vec3<T0>(0, 0, 0);
1079 }
1080
1081 /// Transform a Vec3 by post-multiplication, without translation.
1082 template<typename T0>
1083 112168 Vec3<T0> transform3x3(const Vec3<T0> &v) const
1084 {
1085 return Vec3<T0>(
1086 112168 static_cast<T0>(v[0] * MyBase::mm[ 0] + v[1] * MyBase::mm[ 4] + v[2] * MyBase::mm[ 8]),
1087 112168 static_cast<T0>(v[0] * MyBase::mm[ 1] + v[1] * MyBase::mm[ 5] + v[2] * MyBase::mm[ 9]),
1088 112168 static_cast<T0>(v[0] * MyBase::mm[ 2] + v[1] * MyBase::mm[ 6] + v[2] * MyBase::mm[10]));
1089 }
1090
1091
1092 private:
1093 bool invert(Mat4<T> &inverse, T tolerance) const;
1094
1095 T det2(const Mat4<T> &a, int i0, int i1, int j0, int j1) const {
1096 int i0row = i0 * 4;
1097 int i1row = i1 * 4;
1098 return a.mm[i0row+j0]*a.mm[i1row+j1] - a.mm[i0row+j1]*a.mm[i1row+j0];
1099 }
1100
1101 T det3(const Mat4<T> &a, int i0, int i1, int i2,
1102 int j0, int j1, int j2) const {
1103 int i0row = i0 * 4;
1104 return a.mm[i0row+j0]*det2(a, i1,i2, j1,j2) +
1105 a.mm[i0row+j1]*det2(a, i1,i2, j2,j0) +
1106 a.mm[i0row+j2]*det2(a, i1,i2, j0,j1);
1107 }
1108 }; // class Mat4
1109
1110
1111 /// @relates Mat4
1112 /// @brief Equality operator, does exact floating point comparisons
1113 template <typename T0, typename T1>
1114 83927889 bool operator==(const Mat4<T0> &m0, const Mat4<T1> &m1)
1115 {
1116 const T0 *t0 = m0.asPointer();
1117 const T1 *t1 = m1.asPointer();
1118
1119
4/4
✓ Branch 0 taken 670329300 times.
✓ Branch 1 taken 41889929 times.
✓ Branch 2 taken 670255280 times.
✓ Branch 3 taken 74020 times.
1424438305 for (int i=0; i<16; ++i) if (!isExactlyEqual(t0[i], t1[i])) return false;
1120 return true;
1121 }
1122
1123 /// @relates Mat4
1124 /// @brief Inequality operator, does exact floating point comparisons
1125 template <typename T0, typename T1>
1126 83927080 bool operator!=(const Mat4<T0> &m0, const Mat4<T1> &m1) { return !(m0 == m1); }
1127
1128 /// @relates Mat4
1129 /// @brief Multiply each element of the given matrix by @a scalar and return the result.
1130 template <typename S, typename T>
1131 Mat4<typename promote<S, T>::type> operator*(S scalar, const Mat4<T> &m)
1132 {
1133 return m*scalar;
1134 }
1135
1136 /// @relates Mat4
1137 /// @brief Multiply each element of the given matrix by @a scalar and return the result.
1138 template <typename S, typename T>
1139 Mat4<typename promote<S, T>::type> operator*(const Mat4<T> &m, S scalar)
1140 {
1141 Mat4<typename promote<S, T>::type> result(m);
1142 result *= scalar;
1143 return result;
1144 }
1145
1146 /// @relates Mat4
1147 /// @brief Multiply @a _m by @a _v and return the resulting vector.
1148 template<typename T, typename MT>
1149 inline Vec4<typename promote<T, MT>::type>
1150 296 operator*(const Mat4<MT> &_m,
1151 const Vec4<T> &_v)
1152 {
1153 MT const *m = _m.asPointer();
1154 return Vec4<typename promote<T, MT>::type>(
1155 296 _v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + _v[3]*m[3],
1156 296 _v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + _v[3]*m[7],
1157 296 _v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + _v[3]*m[11],
1158 296 _v[0]*m[12] + _v[1]*m[13] + _v[2]*m[14] + _v[3]*m[15]);
1159 }
1160
1161 /// @relates Mat4
1162 /// @brief Multiply @a _v by @a _m and return the resulting vector.
1163 template<typename T, typename MT>
1164 inline Vec4<typename promote<T, MT>::type>
1165 296 operator*(const Vec4<T> &_v,
1166 const Mat4<MT> &_m)
1167 {
1168 MT const *m = _m.asPointer();
1169 return Vec4<typename promote<T, MT>::type>(
1170 296 _v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + _v[3]*m[12],
1171 296 _v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + _v[3]*m[13],
1172 296 _v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + _v[3]*m[14],
1173 296 _v[0]*m[3] + _v[1]*m[7] + _v[2]*m[11] + _v[3]*m[15]);
1174 }
1175
1176 /// @relates Mat4
1177 /// @brief Multiply @a _m by @a _v and return the resulting vector.
1178 template<typename T, typename MT>
1179 inline Vec3<typename promote<T, MT>::type>
1180 592 operator*(const Mat4<MT> &_m, const Vec3<T> &_v)
1181 {
1182 MT const *m = _m.asPointer();
1183 return Vec3<typename promote<T, MT>::type>(
1184 592 _v[0]*m[0] + _v[1]*m[1] + _v[2]*m[2] + m[3],
1185 592 _v[0]*m[4] + _v[1]*m[5] + _v[2]*m[6] + m[7],
1186 592 _v[0]*m[8] + _v[1]*m[9] + _v[2]*m[10] + m[11]);
1187 }
1188
1189 /// @relates Mat4
1190 /// @brief Multiply @a _v by @a _m and return the resulting vector.
1191 template<typename T, typename MT>
1192 inline Vec3<typename promote<T, MT>::type>
1193 2646490322 operator*(const Vec3<T> &_v, const Mat4<MT> &_m)
1194 {
1195 MT const *m = _m.asPointer();
1196 return Vec3<typename promote<T, MT>::type>(
1197 2646490322 _v[0]*m[0] + _v[1]*m[4] + _v[2]*m[8] + m[12],
1198 2646490322 _v[0]*m[1] + _v[1]*m[5] + _v[2]*m[9] + m[13],
1199 2646490322 _v[0]*m[2] + _v[1]*m[6] + _v[2]*m[10] + m[14]);
1200 }
1201
1202 /// @relates Mat4
1203 /// @brief Add corresponding elements of @a m0 and @a m1 and return the result.
1204 template <typename T0, typename T1>
1205 Mat4<typename promote<T0, T1>::type>
1206 24 operator+(const Mat4<T0> &m0, const Mat4<T1> &m1)
1207 {
1208 24 Mat4<typename promote<T0, T1>::type> result(m0);
1209 24 result += m1;
1210 24 return result;
1211 }
1212
1213 /// @relates Mat4
1214 /// @brief Subtract corresponding elements of @a m0 and @a m1 and return the result.
1215 template <typename T0, typename T1>
1216 Mat4<typename promote<T0, T1>::type>
1217 164074 operator-(const Mat4<T0> &m0, const Mat4<T1> &m1)
1218 {
1219 164074 Mat4<typename promote<T0, T1>::type> result(m0);
1220 164074 result -= m1;
1221 164074 return result;
1222 }
1223
1224 /// @relates Mat4
1225 /// @brief Multiply @a m0 by @a m1 and return the resulting matrix.
1226 template <typename T0, typename T1>
1227 Mat4<typename promote<T0, T1>::type>
1228 1962135 operator*(const Mat4<T0> &m0, const Mat4<T1> &m1)
1229 {
1230 1962135 Mat4<typename promote<T0, T1>::type> result(m0);
1231 1962135 result *= m1;
1232 1962135 return result;
1233 }
1234
1235
1236 /// Transform a Vec3 by pre-multiplication, without translation.
1237 /// Presumes this matrix is inverse of coordinate transform
1238 /// Synonymous to "pretransform3x3"
1239 template<typename T0, typename T1>
1240 Vec3<T1> transformNormal(const Mat4<T0> &m, const Vec3<T1> &n)
1241 {
1242 return Vec3<T1>(
1243 static_cast<T1>(m[0][0]*n[0] + m[0][1]*n[1] + m[0][2]*n[2]),
1244 static_cast<T1>(m[1][0]*n[0] + m[1][1]*n[1] + m[1][2]*n[2]),
1245 static_cast<T1>(m[2][0]*n[0] + m[2][1]*n[1] + m[2][2]*n[2]));
1246 }
1247
1248
1249 /// Invert via gauss-jordan elimination. Modified from dreamworks internal mx library
1250 template<typename T>
1251 bool Mat4<T>::invert(Mat4<T> &inverse, T tolerance) const
1252 {
1253 Mat4<T> temp(*this);
1254 inverse.setIdentity();
1255
1256 // Forward elimination step
1257 double det = 1.0;
1258 for (int i = 0; i < 4; ++i) {
1259 int row = i;
1260 double max = fabs(temp[i][i]);
1261
1262 for (int k = i+1; k < 4; ++k) {
1263 if (fabs(temp[k][i]) > max) {
1264 row = k;
1265 max = fabs(temp[k][i]);
1266 }
1267 }
1268
1269 if (isExactlyEqual(max, 0.0)) return false;
1270
1271 // must move pivot to row i
1272 if (row != i) {
1273 det = -det;
1274 for (int k = 0; k < 4; ++k) {
1275 std::swap(temp[row][k], temp[i][k]);
1276 std::swap(inverse[row][k], inverse[i][k]);
1277 }
1278 }
1279
1280 double pivot = temp[i][i];
1281 det *= pivot;
1282
1283 // scale row i
1284 for (int k = 0; k < 4; ++k) {
1285 temp[i][k] /= pivot;
1286 inverse[i][k] /= pivot;
1287 }
1288
1289 // eliminate in rows below i
1290 for (int j = i+1; j < 4; ++j) {
1291 double t = temp[j][i];
1292 if (!isExactlyEqual(t, 0.0)) {
1293 // subtract scaled row i from row j
1294 for (int k = 0; k < 4; ++k) {
1295 temp[j][k] -= temp[i][k] * t;
1296 inverse[j][k] -= inverse[i][k] * t;
1297 }
1298 }
1299 }
1300 }
1301
1302 // Backward elimination step
1303 for (int i = 3; i > 0; --i) {
1304 for (int j = 0; j < i; ++j) {
1305 double t = temp[j][i];
1306
1307 if (!isExactlyEqual(t, 0.0)) {
1308 for (int k = 0; k < 4; ++k) {
1309 inverse[j][k] -= inverse[i][k]*t;
1310 }
1311 }
1312 }
1313 }
1314 return det*det >= tolerance*tolerance;
1315 }
1316
1317 template <typename T>
1318 inline bool isAffine(const Mat4<T>& m) {
1319 return (m.col(3) == Vec4<T>(0, 0, 0, 1));
1320 }
1321
1322 template <typename T>
1323 inline bool hasTranslation(const Mat4<T>& m) {
1324 return (m.row(3) != Vec4<T>(0, 0, 0, 1));
1325 }
1326
1327 template<typename T>
1328 inline Mat4<T>
1329 Abs(const Mat4<T>& m)
1330 {
1331 Mat4<T> out;
1332 const T* ip = m.asPointer();
1333 T* op = out.asPointer();
1334
4/4
✓ Branch 0 taken 656224 times.
✓ Branch 1 taken 41014 times.
✓ Branch 2 taken 656304 times.
✓ Branch 3 taken 41019 times.
1394561 for (unsigned i = 0; i < 16; ++i, ++op, ++ip) *op = math::Abs(*ip);
1335 return out;
1336 }
1337
1338 template<typename Type1, typename Type2>
1339 inline Mat4<Type1>
1340 cwiseAdd(const Mat4<Type1>& m, const Type2 s)
1341 {
1342 Mat4<Type1> out;
1343 const Type1* ip = m.asPointer();
1344 Type1* op = out.asPointer();
1345 for (unsigned i = 0; i < 16; ++i, ++op, ++ip) {
1346 OPENVDB_NO_TYPE_CONVERSION_WARNING_BEGIN
1347 *op = *ip + s;
1348 OPENVDB_NO_TYPE_CONVERSION_WARNING_END
1349 }
1350 return out;
1351 }
1352
1353 template<typename T>
1354 inline bool
1355 cwiseLessThan(const Mat4<T>& m0, const Mat4<T>& m1)
1356 {
1357 return cwiseLessThan<4, T>(m0, m1);
1358 }
1359
1360 template<typename T>
1361 inline bool
1362 cwiseGreaterThan(const Mat4<T>& m0, const Mat4<T>& m1)
1363 {
1364 return cwiseGreaterThan<4, T>(m0, m1);
1365 }
1366
1367 using Mat4s = Mat4<float>;
1368 using Mat4d = Mat4<double>;
1369 using Mat4f = Mat4d;
1370
1371 #if OPENVDB_ABI_VERSION_NUMBER >= 8
1372 OPENVDB_IS_POD(Mat4s)
1373 OPENVDB_IS_POD(Mat4d)
1374 #endif
1375
1376 } // namespace math
1377
1378
1379
0/25
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
1714017 template<> inline math::Mat4s zeroVal<math::Mat4s>() { return math::Mat4s::zero(); }
1380
0/25
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
1928135 template<> inline math::Mat4d zeroVal<math::Mat4d>() { return math::Mat4d::zero(); }
1381
1382 } // namespace OPENVDB_VERSION_NAME
1383 } // namespace openvdb
1384
1385 #endif // OPENVDB_UTIL_MAT4_H_HAS_BEEN_INCLUDED
1386