GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 67, 0 excluded
0.0%
Functions:
0 of 17, 0 excluded
0.0%
Branches:
0 of 97, 0 excluded
0.0%

libs/core/src/eu/core/geom.extract.cc
Line Branch Exec Source
1 #include "eu/core/geom.h"
2
3 #include "eu/assert/assert.h"
4 #include "eu/base/cint.h"
5
6 #include "eu/core/geom.extract.h"
7 #include "eu/core/vertex_layout.h"
8
9 #include <numeric>
10
11 namespace eu::core
12 {
13
14 using ByteBuffer = std::vector<char>;
15
16 ✗ std::vector<u32> compile_indices(const Geom& geom)
17 {
18 ✗ std::vector<u32> indices;
19 ✗ const auto push = [&indices](const u32 i)
20 {
21 ✗ indices.emplace_back(i);
22 ✗ };
23 ✗ for (const auto& f: geom.faces)
24 {
25 ✗ push(f.a);
26 ✗ push(f.b);
27 ✗ push(f.c);
28 }
29 ✗ return indices;
30 ✗ }
31
32 ✗ void push_float(ByteBuffer* vv, float f)
33 {
34 // todo(Gustav): is this safe?
35 union
36 {
37 float f;
38 char bytes[4];
39 ✗ } convert {};
40
41 ✗ convert.f = f;
42 ✗ for (int byte_index = 0; byte_index < 4; byte_index += 1)
43 {
44 ✗ vv->emplace_back(convert.bytes[byte_index]);
45 }
46 ✗ }
47
48 ✗ void push2(ByteBuffer* vv, const v2& p)
49 {
50 ✗ push_float(vv, p.x);
51 ✗ push_float(vv, p.y);
52 ✗ }
53
54 ✗ void push3(ByteBuffer* vv, const v3& p)
55 {
56 ✗ push_float(vv, p.x);
57 ✗ push_float(vv, p.y);
58 ✗ push_float(vv, p.z);
59 ✗ }
60
61 ✗ void push4(ByteBuffer* vv, const v4& p)
62 {
63 ✗ push_float(vv, p.x);
64 ✗ push_float(vv, p.y);
65 ✗ push_float(vv, p.z);
66 ✗ push_float(vv, p.w);
67 ✗ }
68
69 struct BufferData
70 {
71 using PerVertex = void (*)(ByteBuffer*, const Vertex&);
72
73 std::vector<ExtractedAttribute> attributes;
74 std::vector<PerVertex> per_vertex;
75 };
76
77 ✗ ExtractedGeom extract_geom(const Geom& geom, const CompiledGeomVertexAttributes& layout)
78 {
79 ✗ const auto indices = compile_indices(geom);
80
81 ✗ const BufferData attribute_descriptions = [&]()
82 {
83 ✗ auto data = BufferData{};
84 ✗ data.attributes.reserve(layout.elements.size());
85 ✗ data.per_vertex.reserve(layout.elements.size());
86
87 ✗ for (const auto& element: layout.elements)
88 {
89 ✗ switch (element.type)
90 {
91 #define MAP(VT, PROP, COUNT) \
92 case VT: \
93 data.attributes.emplace_back(ExtractedAttribute{ExtractedAttributeType::Float, COUNT, sizeof(float) * (COUNT)}); \
94 data.per_vertex.emplace_back([](ByteBuffer* vertices, const Vertex& vertex) { push##COUNT(vertices, PROP); }); \
95 break
96 ✗ MAP(VertexType::position2xy, (v2{vertex.position.x, vertex.position.y}), 2);
97 ✗ MAP(VertexType::position2xz, (v2{vertex.position.x, vertex.position.z}), 2);
98 ✗ MAP(VertexType::position3, vertex.position, 3);
99 ✗ MAP(VertexType::normal3, vertex.normal, 3);
100 ✗ MAP(VertexType::color3, vertex.color, 3);
101 ✗ MAP(VertexType::color4, v4(vertex.color, 1.0f), 4);
102 ✗ MAP(VertexType::texture2, vertex.uv, 2);
103 #undef MAP
104 ✗ case VertexType::instance_transform:
105 ✗ DIE("can't use instance types for extraction");
106 ✗ break; // todo(Gustav): should something else be done here?
107 ✗ default: DIE("Invalid buffer type"); break;
108 }
109 }
110 ✗ return data;
111 ✗ }();
112
113 ✗ const std::size_t bytes_per_vertex = std::accumulate(
114 attribute_descriptions.attributes.begin(),
115 attribute_descriptions.attributes.end(),
116 static_cast<std::size_t>(0),
117 ✗ [](std::size_t s, const ExtractedAttribute& d) -> std::size_t { return s + d.size; }
118 ✗ );
119 ✗ const auto vertices = [&]()
120 {
121 ✗ auto verts = ByteBuffer{};
122 ✗ verts.reserve(geom.vertices.size() * bytes_per_vertex);
123 ✗ for (const auto& vertex: geom.vertices)
124 {
125 ✗ for (const auto& per_vertex: attribute_descriptions.per_vertex)
126 {
127 ✗ per_vertex(&verts, vertex);
128 }
129 }
130 ✗ return verts;
131 ✗ }();
132
133 ✗ const auto face_size = static_cast<i32>(geom.faces.size());
134
135 ✗ return {vertices, bytes_per_vertex, attribute_descriptions.attributes, indices, face_size};
136 ✗ }
137
138 } // namespace eu::core
139