chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
45 / 78
57.7%
Branches:
33 / 83
39.8%
Functions:
6 / 7, 1 excl
85.7%

scene/tables/tangents.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #pragma once
3
4 #include <compare>
5 #include <cstdint>
6 #include <map>
7 #include <optional>
8 #include <span>
9 #include <unordered_map>
10 #include <vector>
11
12 #include "chrono_batch_render/device/buffer.h"
13 #include "chrono_batch_render/device/commands.h"
14 #include "chrono_batch_render/device/program.h"
15 #include "chrono_batch_render/device/ref.h"
16 #include "chrono_batch_render/scene/records/meshes.h"
17 #include "chrono_batch_render/scene/records/tangents.h"
18 #include "chrono_batch_render/scene/tables/meshes.h"
19 #include "chrono_batch_render/scene/tables/storage.h"
20 #include "chrono_batch_render/scene/tables/table.h"
21 #include "chrono_batch_render/stage/schema/schema.h"
22 #include "chrono_batch_render/stage/structure/structure.h"
23
24 namespace chrono::batch_render {
25
26 struct TangentMesh {
27 std::vector<Float3> points;
28 std::vector<int32_t> indices;
29 std::vector<int32_t> counts;
30 std::vector<Float3> normals;
31 std::vector<Float2> st;
32 };
33
34 std::vector<Float4> MikkTangents(const TangentMesh& mesh);
35
36 std::vector<Float3> SmoothCornerNormals(std::span<const Float3> points,
37 std::span<const int32_t> indices,
38 std::span<const int32_t> counts);
39
40 std::vector<Float3> FacetedCornerNormals(std::span<const Float3> points,
41 std::span<const int32_t> indices,
42 std::span<const int32_t> counts);
43
44 template <class T>
45 std::optional<std::vector<T>>
46 34 CornerValues(std::span<const T> values, std::span<const int32_t> valueIndices,
47 Interpolation interpolation, std::span<const int32_t> indices,
48 std::span<const int32_t> counts) {
49 34 std::vector<T> corners(indices.size());
50 34 uint32_t corner = 0;
51
2/4
std::optional<std::vector<chrono::batch_render::Float2, std::allocator<chrono::batch_render::Float2> > > chrono::batch_render::CornerValues<chrono::batch_render::Float2>(std::span<chrono::batch_render::Float2 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 34 times.
std::optional<std::vector<chrono::batch_render::Float3, std::allocator<chrono::batch_render::Float3> > > chrono::batch_render::CornerValues<chrono::batch_render::Float3>(std::span<chrono::batch_render::Float3 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
98 for (uint32_t face = 0; face < counts.size(); ++face) {
52
3/8
std::optional<std::vector<chrono::batch_render::Float2, std::allocator<chrono::batch_render::Float2> > > chrono::batch_render::CornerValues<chrono::batch_render::Float2>(std::span<chrono::batch_render::Float2 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 256 times.
✗ Branch 3 not taken.
std::optional<std::vector<chrono::batch_render::Float3, std::allocator<chrono::batch_render::Float3> > > chrono::batch_render::CornerValues<chrono::batch_render::Float3>(std::span<chrono::batch_render::Float3 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
320 for (int32_t k = 0; k < counts[face] && corner < indices.size(); ++k, ++corner) {
53 256 uint32_t at = corner;
54
2/8
std::optional<std::vector<chrono::batch_render::Float2, std::allocator<chrono::batch_render::Float2> > > chrono::batch_render::CornerValues<chrono::batch_render::Float2>(std::span<chrono::batch_render::Float2 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 200 times.
✗ Branch 3 not taken.
std::optional<std::vector<chrono::batch_render::Float3, std::allocator<chrono::batch_render::Float3> > > chrono::batch_render::CornerValues<chrono::batch_render::Float3>(std::span<chrono::batch_render::Float3 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
256 switch (interpolation) {
55 case Interpolation::Constant:
56 at = 0;
57 break;
58 ✗ case Interpolation::Uniform:
59 ✗ at = face;
60 ✗ break;
61 56 case Interpolation::FaceVarying:
62 56 at = corner;
63 56 break;
64 200 default:
65 200 at = uint32_t(indices[corner]);
66 200 break;
67 }
68
1/4
std::optional<std::vector<chrono::batch_render::Float2, std::allocator<chrono::batch_render::Float2> > > chrono::batch_render::CornerValues<chrono::batch_render::Float2>(std::span<chrono::batch_render::Float2 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✓ Branch 1 taken 256 times.
std::optional<std::vector<chrono::batch_render::Float3, std::allocator<chrono::batch_render::Float3> > > chrono::batch_render::CornerValues<chrono::batch_render::Float3>(std::span<chrono::batch_render::Float3 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
256 if (!valueIndices.empty()) {
69
0/4
std::optional<std::vector<chrono::batch_render::Float2, std::allocator<chrono::batch_render::Float2> > > chrono::batch_render::CornerValues<chrono::batch_render::Float2>(std::span<chrono::batch_render::Float2 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
std::optional<std::vector<chrono::batch_render::Float3, std::allocator<chrono::batch_render::Float3> > > chrono::batch_render::CornerValues<chrono::batch_render::Float3>(std::span<chrono::batch_render::Float3 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (at >= valueIndices.size()) {
70 ✗ return std::nullopt;
71 }
72 ✗ at = uint32_t(valueIndices[at]);
73 }
74
1/4
std::optional<std::vector<chrono::batch_render::Float2, std::allocator<chrono::batch_render::Float2> > > chrono::batch_render::CornerValues<chrono::batch_render::Float2>(std::span<chrono::batch_render::Float2 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✓ Branch 1 taken 256 times.
std::optional<std::vector<chrono::batch_render::Float3, std::allocator<chrono::batch_render::Float3> > > chrono::batch_render::CornerValues<chrono::batch_render::Float3>(std::span<chrono::batch_render::Float3 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
256 if (at >= values.size()) {
75 ✗ return std::nullopt;
76 }
77 256 corners[corner] = values[at];
78 }
79 }
80 34 return corners;
81 34 }
82
83 360 struct TangentStats {
84 uint32_t meshes = 0;
85 uint32_t sets = 0;
86 uint32_t computed = 0;
87 uint32_t deformed = 0;
88 };
89
90 class TangentTable : public RenderTable {
91 public:
92 360 TangentTable(Structure& structure, const MeshTable& geometry)
93
1/1
✓ Branch 1 taken 360 times.
360 : m_structure(structure), m_geometry(geometry) {}
94
95 940 std::string_view Name() const override {
96 940 return "tangents";
97 }
98
99 std::span<const ColumnRef> Inputs() const override;
100
101 4562 std::span<const TableId> TableInputs() const override {
102 4562 static constexpr TableId kTables[] = {TableId::Meshes, TableId::MeshPoints};
103 4562 return kTables;
104 }
105
106 360 std::span<const TableId> TableOutputs() const override {
107 360 static constexpr TableId kTables[] = {TableId::Tangents};
108 360 return kTables;
109 }
110
111 void Describe(RenderTables& tables) const override;
112 void Hold(std::vector<Ref<const RefCounted>>& held) const override;
113
114 16 const TangentRecord& Record(uint32_t meshRow) const {
115
4/7
chrono::batch_render::TangentTable::TangentTable(chrono::batch_render::Structure&, chrono::batch_render::MeshTable const&):
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
std::optional<std::vector<chrono::batch_render::Float2, std::allocator<chrono::batch_render::Float2> > > chrono::batch_render::CornerValues<chrono::batch_render::Float2>(std::span<chrono::batch_render::Float2 const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>, chrono::batch_render::Interpolation, std::span<int const, 18446744073709551615ul>, std::span<int const, 18446744073709551615ul>):
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
17 return m_records.Row(meshRow);
116 }
117
118 void Prepare() override;
119 void Run(const ChangeSet& changes, TableVersions& versions) override;
120
121 const TangentStats& Stats() const {
122
1/1
✓ Branch 1 taken 1 time.
1 return m_stats;
123 }
124
125 private:
126 struct Key {
127 289 uint64_t points = 0;
128 238 uint64_t indices = 0;
129 238 uint64_t counts = 0;
130 238 uint64_t primvars = 0;
131 238 uint64_t normals = 0;
132 238 uint32_t interpolation = 0;
133 238 uint32_t scheme = 0;
134
135
18/42
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 51 times.
✓ Branch 5 taken 238 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 238 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 238 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 238 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 238 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 238 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 238 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 238 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 238 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 238 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 238 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 238 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✓ Branch 41 taken 238 times.
289 auto operator<=>(const Key&) const = default;
136 };
137
138 struct Deform {
139 Ref<device::Buffer> st;
140 Ref<device::Buffer> normals;
141 Ref<device::Buffer> triangles;
142 Ref<device::Buffer> starts;
143 Ref<device::Buffer> corners;
144 Ref<device::Buffer> groups;
145 Ref<device::Buffer> results;
146 uint32_t groupCount = 0;
147 uint32_t cornerCount = 0;
148 bool faceted = false;
149 };
150
151 75 struct Set {
152 ArrayRef tangents;
153 uint32_t words = 0;
154 uint32_t users = 0;
155 std::optional<Deform> deform;
156 };
157
158 81 struct Mesh {
159 uint32_t generation = 0;
160 uint32_t pointsRow = kNoRow;
161 uint32_t meshRow = kNoRow;
162 uint32_t gprimRow = kNoRow;
163 uint32_t interpolation = 0;
164 uint32_t scheme = 0;
165 std::optional<Key> key;
166 Set* set = nullptr;
167 };
168
169 360 struct Cells {
170 std::vector<uint32_t> interpolation;
171 std::vector<uint32_t> scheme;
172 };
173
174 Key KeyFor(const Mesh& mesh) const;
175 void Compute(const Mesh& mesh, const Key& key, Set& set);
176 void Recompute(const Mesh& mesh, const Key& key, Set& set, device::CommandEncoder& encoder);
177 void Forget(uint32_t prim);
178 void Place(uint32_t prim, const Cells& cells);
179 void CacheCells(Mesh& mesh, const Cells& cells) const;
180 void Release(Mesh& mesh);
181 void Prune();
182 void Link(uint32_t prim, const Mesh& mesh);
183 void Process(const ChangeSet& changes);
184
185 Structure& m_structure;
186 const MeshTable& m_geometry;
187 RecordTable<TangentRecord> m_records{"tangent records"};
188 std::vector<uint32_t> m_relinked;
189 std::unordered_map<uint32_t, Mesh> m_meshes;
190 std::unordered_map<uint32_t, uint32_t> m_byPointsRow;
191 std::unordered_map<uint32_t, uint32_t> m_byMeshRow;
192 std::unordered_map<uint32_t, uint32_t> m_byGprimRow;
193 std::map<Key, Set> m_sets;
194 bool m_stale = false;
195 device::Program& Kernels();
196
197 Ref<device::Program> m_program;
198 uint64_t m_seen = 0;
199 Cells m_cells;
200 TangentStats m_stats;
201 };
202
203 }
204