| 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 |
0/2
✗ Branch 18 → 4 not taken.
✗ Branch 18 → 19 not taken.
|
✗ |
for (const auto& f: geom.faces) |
| 24 |
|
|
{ |
| 25 |
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 21 not taken.
|
✗ |
push(f.a); |
| 26 |
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 21 not taken.
|
✗ |
push(f.b); |
| 27 |
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 21 not taken.
|
✗ |
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 |
0/2
✗ Branch 5 → 3 not taken.
✗ Branch 5 → 6 not taken.
|
✗ |
for (int byte_index = 0; byte_index < 4; byte_index += 1) |
| 43 |
|
|
{ |
| 44 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 7 not taken.
|
✗ |
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 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 44 not taken.
|
✗ |
const auto indices = compile_indices(geom); |
| 80 |
|
|
|
| 81 |
|
✗ |
const BufferData attribute_descriptions = [&]() |
| 82 |
|
|
{ |
| 83 |
|
✗ |
auto data = BufferData{}; |
| 84 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 73 not taken.
|
✗ |
data.attributes.reserve(layout.elements.size()); |
| 85 |
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 73 not taken.
|
✗ |
data.per_vertex.reserve(layout.elements.size()); |
| 86 |
|
|
|
| 87 |
0/2
✗ Branch 49 → 8 not taken.
✗ Branch 49 → 50 not taken.
|
✗ |
for (const auto& element: layout.elements) |
| 88 |
|
|
{ |
| 89 |
0/9
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 14 not taken.
✗ Branch 10 → 17 not taken.
✗ Branch 10 → 20 not taken.
✗ Branch 10 → 23 not taken.
✗ Branch 10 → 26 not taken.
✗ Branch 10 → 29 not taken.
✗ Branch 10 → 32 not taken.
✗ Branch 10 → 36 not taken.
|
✗ |
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 |
0/6
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 52 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 53 not taken.
|
✗ |
MAP(VertexType::position2xy, (v2{vertex.position.x, vertex.position.y}), 2); |
| 97 |
0/6
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 54 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 55 not taken.
|
✗ |
MAP(VertexType::position2xz, (v2{vertex.position.x, vertex.position.z}), 2); |
| 98 |
0/4
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 56 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 57 not taken.
|
✗ |
MAP(VertexType::position3, vertex.position, 3); |
| 99 |
0/4
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 58 not taken.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 59 not taken.
|
✗ |
MAP(VertexType::normal3, vertex.normal, 3); |
| 100 |
0/4
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 60 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 61 not taken.
|
✗ |
MAP(VertexType::color3, vertex.color, 3); |
| 101 |
0/8
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 62 not taken.
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 63 not taken.
|
✗ |
MAP(VertexType::color4, v4(vertex.color, 1.0f), 4); |
| 102 |
0/4
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 64 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 65 not taken.
|
✗ |
MAP(VertexType::texture2, vertex.uv, 2); |
| 103 |
|
|
#undef MAP |
| 104 |
|
✗ |
case VertexType::instance_transform: |
| 105 |
0/2
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 66 not taken.
|
✗ |
DIE("can't use instance types for extraction"); |
| 106 |
|
✗ |
break; // todo(Gustav): should something else be done here? |
| 107 |
0/2
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 69 not taken.
|
✗ |
default: DIE("Invalid buffer type"); break; |
| 108 |
|
|
} |
| 109 |
|
|
} |
| 110 |
|
✗ |
return data; |
| 111 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 27 not taken.
|
✗ |
}(); |
| 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 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 37 not taken.
|
✗ |
verts.reserve(geom.vertices.size() * bytes_per_vertex); |
| 123 |
0/2
✗ Branch 32 → 6 not taken.
✗ Branch 32 → 33 not taken.
|
✗ |
for (const auto& vertex: geom.vertices) |
| 124 |
|
|
{ |
| 125 |
0/2
✗ Branch 22 → 10 not taken.
✗ Branch 22 → 23 not taken.
|
✗ |
for (const auto& per_vertex: attribute_descriptions.per_vertex) |
| 126 |
|
|
{ |
| 127 |
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 35 not taken.
|
✗ |
per_vertex(&verts, vertex); |
| 128 |
|
|
} |
| 129 |
|
|
} |
| 130 |
|
✗ |
return verts; |
| 131 |
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 28 not taken.
|
✗ |
}(); |
| 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 |
0/16
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 38 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 32 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 29 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 17 not taken.
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 31 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 34 not taken.
|
✗ |
} |
| 137 |
|
|
|
| 138 |
|
|
} // namespace eu::core |
| 139 |
|
|
|