GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
239 of 241, 0 excluded
99.2%
Functions:
45 of 45, 0 excluded
100.0%
Branches:
66 of 134, 0 excluded
49.3%

libs/base/src/eu/base/mat4.cc
Line Branch Exec Source
1 #include "eu/base/mat4.h"
2
3 #include "eu/base/quat.h"
4
5 namespace eu
6 {
7 [[nodiscard]]
8 m4
9 14 m4::from_col_major
10 (
11 float t00, float t01, float t02, float t03,
12 float t10, float t11, float t12, float t13,
13 float t20, float t21, float t22, float t23,
14 float t30, float t31, float t32, float t33
15 )
16 {
17 return
18 {
19 t00, t01, t02, t03,
20 t10, t11, t12, t13,
21 t20, t21, t22, t23,
22 t30, t31, t32, t33
23 14 };
24 }
25
26 [[nodiscard]]
27 m4
28 114 m4::from_major(const v4& major)
29 {
30 114 const float zero = 0;
31 return from_row_major
32 114 (
33 114 major.x, zero, zero, zero,
34 114 zero, major.y, zero, zero,
35 114 zero, zero, major.z, zero,
36 114 zero, zero, zero, major.w
37 114 );
38 }
39
40 171 [[nodiscard]] m4 m4::from_basis(const n3& a, const n3& b, const n3& c)
41 {
42 return from_row_major
43 171 (
44 171 a.x, b.x, c.x, 0,
45 171 a.y, b.y, c.y, 0,
46 171 a.z, b.z, c.z, 0,
47 0, 0, 0, 1
48 171 );
49 }
50
51 113 [[nodiscard]] m4 m4::from_scale(const v3& s)
52 {
53
2/4
✓ Branch 2 → 3 taken 113 times.
✗ Branch 2 → 7 not taken.
✓ Branch 3 → 4 taken 113 times.
✗ Branch 3 → 7 not taken.
113 return from_major({s, 1.0f});
54 }
55
56 [[nodiscard]]
57 m4
58 119 m4::from_translation(const v3& v)
59 {
60 119 const float one = 1;
61 119 const float z = 0;
62 return from_row_major
63 119 (
64 119 one, z, z, v.x,
65 119 z, one, z, v.y,
66 119 z, z, one, v.z,
67 z, z, z, one
68 119 );
69 }
70
71 v4
72 20 m4::get_transformed(const v4& p) const
73 {
74 20 return *this * p;
75 }
76
77 v3
78 19 m4::get_transformed_point(const v3& p) const
79 {
80
3/6
✓ Branch 2 → 3 taken 19 times.
✗ Branch 2 → 8 not taken.
✓ Branch 3 → 4 taken 19 times.
✗ Branch 3 → 8 not taken.
✓ Branch 4 → 5 taken 19 times.
✗ Branch 4 → 8 not taken.
19 return get_transformed(v4{p, 1.0f}).to_vec3_persp_div();
81 }
82
83 v3
84 1 m4::get_transformed_vec(const v3& p) const
85 {
86
3/6
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 8 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 8 not taken.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 8 not taken.
1 return get_transformed(v4{p, 0.0f}).to_vec3(0.0f);
87 }
88
89 n3
90 1 m4::get_transformed_vec(const n3& p) const
91 {
92
2/4
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 7 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 7 not taken.
1 return n3{ get_transformed_vec(static_cast<v3>(p))};
93 }
94
95 v3
96 59 m4::get_translation() const
97 {
98 59 return {get(0, 3), get(1, 3), get(2, 3)};
99 }
100
101 [[nodiscard]]
102 m4
103 2 m4::from_rot_x(const An& a)
104 {
105 2 const auto c = cos(a);
106 2 const auto s = sin(a);
107 return from_row_major
108 2 (
109 1, 0, 0, 0,
110 0, c, -s, 0,
111 0, s, c, 0,
112 0, 0, 0, 1
113 2 );
114 }
115
116 m4
117 1 m4::from_rot_y(const An& a)
118 {
119 1 const auto c = cos(a);
120 1 const auto s = sin(a);
121 return from_row_major
122 1 (
123 c, 0, s, 0,
124 0, 1, 0, 0,
125 -s, 0, c, 0,
126 0, 0, 0, 1
127 1 );
128 }
129
130 [[nodiscard]]
131 m4
132 1 m4::from_rot_z(const An& a)
133 {
134 1 const auto c = cos(a);
135 1 const auto s = sin(a);
136 return from_row_major
137 1 (
138 c, -s, 0, 0,
139 s, c, 0, 0,
140 0, 0, 1, 0,
141 0, 0, 0, 1
142 1 );
143 }
144
145 [[nodiscard]]
146 m4
147 7 m4::from(const AA& aa)
148 {
149 7 const float rcos = cos(aa.angle);
150 7 const float rsin = sin(aa.angle);
151
152 7 const auto u = aa.axis.x;
153 7 const auto v = aa.axis.y;
154 7 const auto w = aa.axis.z;
155
156 return m4::from_col_major
157 7 (
158 7 rcos + u * u * (1 - rcos),
159 7 w * rsin + v * u * (1 - rcos),
160 7 -v * rsin + w * u * (1 - rcos),
161 0,
162
163 7 -w * rsin + u * v * (1 - rcos),
164 7 rcos + v * v * (1 - rcos),
165 7 u * rsin + w * v * (1 - rcos),
166 0,
167
168 7 v * rsin + u * w * (1 - rcos),
169 7 -u * rsin + v * w * (1 - rcos),
170 7 rcos + w * w * (1 - rcos),
171 0,
172
173 0,
174 0,
175 0,
176 1
177 7 );
178 }
179
180
181 [[nodiscard]] std::optional<m4>
182 1 m4::from(const Q& q)
183 {
184
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 13 not taken.
1 const auto aa = AA::from(q);
185
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
1 if (!aa)
186 ✗ { return std::nullopt; }
187
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 12 not taken.
1 return m4::from(*aa);
188 }
189
190
191 v4
192 2 m4::get_major() const
193 {
194
1/2
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 10 not taken.
2 return {get(0, 0), get(1, 1), get(2, 2), get(3, 3)};
195 }
196
197 n3
198 9 get_axis(const m4& m, int col)
199 {
200
3/6
✓ Branch 2 → 3 taken 9 times.
✗ Branch 2 → 8 not taken.
✓ Branch 3 → 4 taken 9 times.
✗ Branch 3 → 8 not taken.
✓ Branch 4 → 5 taken 9 times.
✗ Branch 4 → 8 not taken.
9 return n3{m.get_column(col).to_vec3(0.0f)};
201 }
202
203 n3
204 3 m4::get_x_axis() const
205 {
206 3 return get_axis(*this, 0);
207 }
208
209 n3
210 3 m4::get_y_axis() const
211 {
212 3 return get_axis(*this, 1);
213 }
214
215 n3
216 3 m4::get_z_axis() const
217 {
218 3 return get_axis(*this, 2);
219 }
220
221 m4
222 2 m4::get_transposed() const
223 {
224 // https://www.j3d.org/matrix_faq/matrfaq_latest.html
225 return from_col_major
226 2 (
227 get(0, 0), get(0, 1), get(0, 2), get(0, 3),
228 get(1, 0), get(1, 1), get(1, 2), get(1, 3),
229 get(2, 0), get(2, 1), get(2, 2), get(2, 3),
230 get(3, 0), get(3, 1), get(3, 2), get(3, 3)
231 2 );
232 }
233
234 bool
235 2 m4::invert()
236 {
237 // from the glu source?
238 // https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
239
240 float inv[16];
241
242 2 float* m = data;
243
244 2 inv[0] =
245 2 m[5] * m[10] * m[15] - m[5] * m[11] * m[14] -
246 2 m[9] * m[6] * m[15] + m[9] * m[7] * m[14] +
247 2 m[13] * m[6] * m[11] - m[13] * m[7] * m[10]
248 ;
249
250 2 inv[4] =
251 2 -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] +
252 2 m[8] * m[6] * m[15] - m[8] * m[7] * m[14] -
253 2 m[12] * m[6] * m[11] + m[12] * m[7] * m[10]
254 ;
255
256 2 inv[8] =
257 2 m[4] * m[9] * m[15] - m[4] * m[11] * m[13] -
258 2 m[8] * m[5] * m[15] + m[8] * m[7] * m[13] +
259 2 m[12] * m[5] * m[11] - m[12] * m[7] * m[9]
260 ;
261
262 2 inv[12] =
263 2 -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] +
264 2 m[8] * m[5] * m[14] - m[8] * m[6] * m[13] -
265 2 m[12] * m[5] * m[10] + m[12] * m[6] * m[9]
266 ;
267
268 2 inv[1] =
269 2 -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] +
270 2 m[9] * m[2] * m[15] - m[9] * m[3] * m[14] -
271 2 m[13] * m[2] * m[11] + m[13] * m[3] * m[10]
272 ;
273
274 2 inv[5] =
275 2 m[0] * m[10] * m[15] - m[0] * m[11] * m[14] -
276 2 m[8] * m[2] * m[15] + m[8] * m[3] * m[14] +
277 2 m[12] * m[2] * m[11] - m[12] * m[3] * m[10]
278 ;
279
280 2 inv[9] =
281 2 -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] +
282 2 m[8] * m[1] * m[15] - m[8] * m[3] * m[13] -
283 2 m[12] * m[1] * m[11] + m[12] * m[3] * m[9]
284 ;
285
286 2 inv[13] =
287 2 m[0] * m[9] * m[14] - m[0] * m[10] * m[13] -
288 2 m[8] * m[1] * m[14] + m[8] * m[2] * m[13] +
289 2 m[12] * m[1] * m[10] - m[12] * m[2] * m[9]
290 ;
291
292 2 inv[2] =
293 2 m[1] * m[6] * m[15] - m[1] * m[7] * m[14] -
294 2 m[5] * m[2] * m[15] + m[5] * m[3] * m[14] +
295 2 m[13] * m[2] * m[7] - m[13] * m[3] * m[6]
296 ;
297
298 2 inv[6] =
299 2 -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] +
300 2 m[4] * m[2] * m[15] - m[4] * m[3] * m[14] -
301 2 m[12] * m[2] * m[7] + m[12] * m[3] * m[6]
302 ;
303
304 2 inv[10] =
305 2 m[0] * m[5] * m[15] - m[0] * m[7] * m[13] -
306 2 m[4] * m[1] * m[15] + m[4] * m[3] * m[13] +
307 2 m[12] * m[1] * m[7] - m[12] * m[3] * m[5]
308 ;
309
310 2 inv[14] =
311 2 -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] +
312 2 m[4] * m[1] * m[14] - m[4] * m[2] * m[13] -
313 2 m[12] * m[1] * m[6] + m[12] * m[2] * m[5]
314 ;
315
316 2 inv[3] =
317 2 -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] +
318 2 m[5] * m[2] * m[11] - m[5] * m[3] * m[10] -
319 2 m[9] * m[2] * m[7] + m[9] * m[3] * m[6]
320 ;
321
322 2 inv[7] =
323 2 m[0] * m[6] * m[11] - m[0] * m[7] * m[10] -
324 2 m[4] * m[2] * m[11] + m[4] * m[3] * m[10] +
325 2 m[8] * m[2] * m[7] - m[8] * m[3] * m[6]
326 ;
327
328 2 inv[11] =
329 2 -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] +
330 2 m[4] * m[1] * m[11] - m[4] * m[3] * m[9] -
331 2 m[8] * m[1] * m[7] + m[8] * m[3] * m[5]
332 ;
333
334 2 inv[15] =
335 2 m[0] * m[5] * m[10] - m[0] * m[6] * m[9] -
336 2 m[4] * m[1] * m[10] + m[4] * m[2] * m[9] +
337 2 m[8] * m[1] * m[6] - m[8] * m[2] * m[5]
338 ;
339
340 2 const auto inv_det =
341 2 m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] +
342 2 m[3] * inv[12];
343
344
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2 times.
2 if(inv_det == 0)
345 {
346 ✗ return false;
347 }
348
349 2 const auto det = 1.0f / inv_det;
350
351
2/2
✓ Branch 6 → 5 taken 32 times.
✓ Branch 6 → 7 taken 2 times.
34 for(int index = 0; index < 16; index += 1)
352 {
353 32 data[index] = inv[index] * det;
354 }
355
356 2 return true;
357 }
358
359 m4
360 1 m4::get_inverted() const
361 {
362 1 auto r = *this;
363 1 const auto was_inverted = r.invert();
364
1/6
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 10 taken 1 time.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 12 not taken.
1 ASSERT(was_inverted);
365 1 return r;
366 }
367
368 void
369 1 m4::operator+=(const m4& rhs)
370 {
371 #define OP(i) data[i] += rhs.data[i]
372 1 OP(0); OP(1); OP(2); OP(3);
373 1 OP(4); OP(5); OP(6); OP(7);
374 1 OP(8); OP(9); OP(10); OP(11);
375 1 OP(12); OP(13); OP(14); OP(15);
376 #undef OP
377 1 }
378
379 void
380 1 m4::operator-=(const m4& rhs)
381 {
382 #define OP(i) data[i] -= rhs.data[i]
383 1 OP(0); OP(1); OP(2); OP(3);
384 1 OP(4); OP(5); OP(6); OP(7);
385 1 OP(8); OP(9); OP(10); OP(11);
386 1 OP(12); OP(13); OP(14); OP(15);
387 #undef OP
388 1 }
389
390 [[nodiscard]]
391 m4
392 1 m4::create_ortho_lrud(float l, float r, float t, float b, float n, float f)
393 {
394 // http://www.songho.ca/opengl/gl_projectionmatrix.html
395 return from_row_major
396 1 (
397 1 2 / (r - l), 0, 0, -(r + l) / (r - l),
398 1 0, 2 / (t - b), 0, -(t + b) / (t - b),
399 1 0, 0, -2 / (f - n), -(f + n) / (f - n),
400 0, 0, 0, 1
401 1 );
402 }
403
404 [[nodiscard]]
405 m4
406 1 m4::create_perspective(const An& fov, float a, float near, float far)
407 {
408
2/4
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 7 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 7 not taken.
1 const float t = 1 / tan(fov / 2);
409 1 const float zm = far - near;
410 1 const float zp = far + near;
411 return from_row_major
412 1 (
413 t / a, 0, 0, 0,
414 0, t, 0, 0,
415 1 0, 0, -zp / zm, (-2 * far * near) / zm,
416 0, 0, -1, 0
417 1 );
418 }
419
420 m4
421 4 m4::get_translated(const v3& t) const
422 {
423
2/4
✓ Branch 2 → 3 taken 4 times.
✗ Branch 2 → 7 not taken.
✓ Branch 3 → 4 taken 4 times.
✗ Branch 3 → 7 not taken.
4 return *this * from_translation(t);
424 }
425
426 m4
427 4 m4::get_rotated(const AA& aa) const
428 {
429
2/4
✓ Branch 2 → 3 taken 4 times.
✗ Branch 2 → 7 not taken.
✓ Branch 3 → 4 taken 4 times.
✗ Branch 3 → 7 not taken.
4 return *this * from(aa);
430 }
431
432 const float*
433 1 m4::get_column_major_data_ptr() const
434 {
435 1 return data;
436 }
437
438 float*
439 1 m4::get_column_major_data_ptr()
440 {
441 1 return data;
442 }
443
444
445 float
446 17901 m4::get(int row, int col) const
447 {
448 17901 return data[col * 4 + row];
449 }
450
451 float
452 348 m4::get1(int row, int col) const
453 {
454 348 return data[(col-1) * 4 + (row-1)];
455 }
456
457 v4
458 3975 m4::get_column(int col) const
459 {
460 3975 const auto base = col * 4;
461 return
462 {
463 3975 data[base + 0],
464 3975 data[base + 1],
465 3975 data[base + 2],
466 3975 data[base + 3]
467
1/2
✓ Branch 2 → 3 taken 3975 times.
✗ Branch 2 → 6 not taken.
3975 };
468 }
469
470 v4
471 3872 m4::get_row(int r) const
472 {
473
1/2
✓ Branch 6 → 7 taken 3872 times.
✗ Branch 6 → 10 not taken.
3872 return {get(r, 0), get(r, 1), get(r, 2), get(r, 3)};
474 }
475
476
477 2 std::string string_from(const m4& m)
478 {
479
1/2
✓ Branch 2 → 3 taken 8 times.
✗ Branch 2 → 5 not taken.
8 const auto s = [](const v4& v) { return fmt::format("{} {} {} {}", v.x, v.y, v.z, v.w); };
480
9/18
✓ Branch 2 → 3 taken 2 times.
✗ Branch 2 → 32 not taken.
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 32 not taken.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 28 not taken.
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 28 not taken.
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 24 not taken.
✓ Branch 7 → 8 taken 2 times.
✗ Branch 7 → 24 not taken.
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 20 not taken.
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 20 not taken.
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 17 not taken.
2 return fmt::format("{}\n{}\n{}\n{}", s(m.get_row(0)), s(m.get_row(1)), s(m.get_row(2)), s(m.get_row(3)));
481 }
482
483
484 m4
485 1 operator+(const m4& lhs, const m4& rhs)
486 {
487 1 m4 t = lhs;
488 1 t += rhs;
489 1 return t;
490 }
491
492
493 m4
494 1 operator-(const m4& lhs, const m4& rhs)
495 {
496 1 m4 t = lhs;
497 1 t -= rhs;
498 1 return t;
499 }
500
501 float
502 3860 get_component_multiply_sum(const v4& lhs, const v4& rhs)
503 {
504 3860 const auto x = lhs.x * rhs.x;
505 3860 const auto y = lhs.y * rhs.y;
506 3860 const auto z = lhs.z * rhs.z;
507 3860 const auto w = lhs.w* rhs.w;
508 3860 return x + y + z + w;
509 }
510
511 236 m4 operator*(const m4& lhs, const m4& rhs)
512 {
513 3776 const auto op = [&lhs, &rhs](int r, int c) -> float
514 {
515
2/4
✓ Branch 2 → 3 taken 3776 times.
✗ Branch 2 → 8 not taken.
✓ Branch 3 → 4 taken 3776 times.
✗ Branch 3 → 7 not taken.
3776 return get_component_multiply_sum(lhs.get_row(r), rhs.get_column(c));
516 236 };
517 return m4::from_row_major
518
17/34
✓ Branch 2 → 3 taken 236 times.
✗ Branch 2 → 22 not taken.
✓ Branch 3 → 4 taken 236 times.
✗ Branch 3 → 22 not taken.
✓ Branch 4 → 5 taken 236 times.
✗ Branch 4 → 22 not taken.
✓ Branch 5 → 6 taken 236 times.
✗ Branch 5 → 22 not taken.
✓ Branch 6 → 7 taken 236 times.
✗ Branch 6 → 22 not taken.
✓ Branch 7 → 8 taken 236 times.
✗ Branch 7 → 22 not taken.
✓ Branch 8 → 9 taken 236 times.
✗ Branch 8 → 22 not taken.
✓ Branch 9 → 10 taken 236 times.
✗ Branch 9 → 22 not taken.
✓ Branch 10 → 11 taken 236 times.
✗ Branch 10 → 22 not taken.
✓ Branch 11 → 12 taken 236 times.
✗ Branch 11 → 22 not taken.
✓ Branch 12 → 13 taken 236 times.
✗ Branch 12 → 22 not taken.
✓ Branch 13 → 14 taken 236 times.
✗ Branch 13 → 22 not taken.
✓ Branch 14 → 15 taken 236 times.
✗ Branch 14 → 22 not taken.
✓ Branch 15 → 16 taken 236 times.
✗ Branch 15 → 22 not taken.
✓ Branch 16 → 17 taken 236 times.
✗ Branch 16 → 22 not taken.
✓ Branch 17 → 18 taken 236 times.
✗ Branch 17 → 22 not taken.
✓ Branch 18 → 19 taken 236 times.
✗ Branch 18 → 22 not taken.
236 (
519 op(0, 0), op(0, 1), op(0, 2), op(0, 3),
520 op(1, 0), op(1, 1), op(1, 2), op(1, 3),
521 op(2, 0), op(2, 1), op(2, 2), op(2, 3),
522 op(3, 0), op(3, 1), op(3, 2), op(3, 3)
523 472 );
524 }
525
526
527 21 v4 operator*(const m4& lhs, const v4& rhs)
528 {
529 84 const auto op = [&lhs, &rhs](int r) -> float
530 {
531
1/2
✓ Branch 2 → 3 taken 84 times.
✗ Branch 2 → 6 not taken.
84 return get_component_multiply_sum(lhs.get_row(r), rhs);
532 21 };
533
534
5/10
✓ Branch 2 → 3 taken 21 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 21 times.
✗ Branch 3 → 10 not taken.
✓ Branch 4 → 5 taken 21 times.
✗ Branch 4 → 10 not taken.
✓ Branch 5 → 6 taken 21 times.
✗ Branch 5 → 10 not taken.
✓ Branch 6 → 7 taken 21 times.
✗ Branch 6 → 10 not taken.
21 return {op(0), op(1), op(2), op(3)};
535 }
536
537
2/4
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 8 not taken.
1 ADD_CATCH_FORMATTER_IMPL(m4)
538 }
539