| 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 |
|
|
|