MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
AssemblyOperator.cpp
Go to the documentation of this file.
3
5
6std::shared_ptr<GpuSync::GeometryLeafNode> AssemblyOperator::add_geometry(
7 std::vector<glm::vec3> positions,
9{
10 auto node = std::make_shared<GpuSync::GeometryLeafNode>(std::move(positions));
11 node->set_primitive_topology(topology);
12 node->compute_frame();
13 m_items.push_back(node);
14 return node;
15}
16
17std::shared_ptr<GpuSync::GeometryLeafNode> AssemblyOperator::add_geometry(
18 std::vector<Kakshya::Vertex> vertices,
20{
21 auto node = std::make_shared<GpuSync::GeometryLeafNode>(std::move(vertices));
22 node->set_primitive_topology(topology);
23 node->compute_frame();
24 m_items.push_back(node);
25 return node;
26}
27
28std::shared_ptr<GpuSync::MeshWriterNode> AssemblyOperator::add_geometry(const Kakshya::MeshData& mesh)
29{
30 auto node = std::make_shared<GpuSync::MeshWriterNode>();
31 node->set_mesh(mesh);
32 node->compute_frame();
33 m_items.push_back(node);
34 return node;
35}
36
37void AssemblyOperator::add_geometry(std::shared_ptr<GpuSync::GeometryWriterNode> node)
38{
39 if (!node) {
41 "AssemblyOperator::add_geometry: null node ignored");
42 return;
43 }
44 node->compute_frame();
45 m_items.push_back(std::move(node));
46}
47
48bool AssemblyOperator::remove_geometry(const std::shared_ptr<GpuSync::GeometryWriterNode>& node)
49{
50 auto it = std::find(m_items.begin(), m_items.end(), node);
51 if (it == m_items.end()) {
52 return false;
53 }
54 m_items.erase(it);
55 return true;
56}
57
58void AssemblyOperator::process(float /*dt*/)
59{
60 for (auto& item : m_items) {
61 item->compute_frame();
62 }
63}
64
65std::span<const uint8_t> AssemblyOperator::get_vertex_data_for_collection(uint32_t idx) const
66{
67 if (idx >= m_items.size()) {
68 return {};
69 }
70 return m_items[idx]->get_vertex_data();
71}
72
73std::span<const uint8_t> AssemblyOperator::get_vertex_data() const
74{
76 for (const auto& item : m_items) {
77 auto span = item->get_vertex_data();
80 span.begin(), span.end());
81 }
82 return { m_vertex_data_aggregate.data(), m_vertex_data_aggregate.size() };
83}
84
86{
87 if (m_items.empty()) {
89 }
90
91 auto layout_opt = m_items[0]->get_vertex_layout();
92 if (!layout_opt) {
94 }
95
96 auto layout = *layout_opt;
97 layout.vertex_count = static_cast<uint32_t>(get_vertex_count());
98 return layout;
99}
100
102{
103 size_t total = 0;
104 for (const auto& item : m_items) {
105 total += item->get_vertex_count();
106 }
107 return total;
108}
109
111{
112 return std::ranges::any_of(
113 m_items,
114 [](const auto& item) { return item->needs_gpu_update(); });
115}
116
118{
119 for (auto& item : m_items) {
120 item->clear_gpu_update_flag();
121 }
122}
123
124std::vector<GraphicsOperator::DirtyVertexRange> AssemblyOperator::dirty_vertex_ranges() const
125{
126 std::vector<DirtyVertexRange> ranges;
127
128 uint32_t offset = 0;
129 uint32_t index = 0;
130 for (const auto& item : m_items) {
131 const auto count = static_cast<uint32_t>(item->get_vertex_count());
132 if (item->needs_gpu_update()) {
133 ranges.push_back(DirtyVertexRange {
135 .vertex_offset = offset,
136 .vertex_count = count });
137 }
138 offset += count;
139 ++index;
140 }
141
142 return ranges;
143}
144
146{
147 return get_vertex_count();
148}
149
150std::vector<uint32_t> AssemblyOperator::build_cluster_ids() const
151{
152 std::vector<uint32_t> ids(get_vertex_count(), 0U);
153
154 if (m_items.size() <= 1) {
155 return ids;
156 }
157
158 size_t offset = 0;
159 uint32_t cluster = 0;
160 for (const auto& item : m_items) {
161 const size_t count = item->get_vertex_count();
162 for (size_t i = 0; i < count && offset + i < ids.size(); ++i) {
163 ids[offset + i] = cluster;
164 }
165 offset += count;
166 ++cluster;
167 }
168
169 return ids;
170}
171
172std::optional<Portal::Graphics::PrimitiveTopology> AssemblyOperator::declared_topology() const
173{
174 if (m_items.empty()) {
175 return std::nullopt;
176 }
177 return m_items[0]->get_primitive_topology();
178}
179
180std::vector<DrawRun> AssemblyOperator::topology_runs() const
181{
182 std::vector<DrawRun> runs;
183 uint32_t offset = 0;
184
185 for (const auto& item : m_items) {
186 const auto count = static_cast<uint32_t>(item->get_vertex_count());
187 const auto topo = item->get_primitive_topology();
188
189 if (!runs.empty() && runs.back().topology == topo && is_concatenable_topology(topo)) {
190 runs.back().vertex_count += count;
191 } else {
192 runs.push_back(DrawRun { .topology = topo, .vertex_offset = offset, .vertex_count = count });
193 }
194
195 offset += count;
196 }
197
198 return runs;
199}
200
201void AssemblyOperator::set_parameter(std::string_view /*param*/, double /*value*/)
202{
203}
204
205std::optional<double> AssemblyOperator::query_state(std::string_view query) const
206{
207 if (query == "item_count") {
208 return static_cast<double>(m_items.size());
209 }
210 if (query == "vertex_count") {
211 return static_cast<double>(get_vertex_count());
212 }
213 return std::nullopt;
214}
215
216void* AssemblyOperator::get_data_at(size_t /*global_index*/)
217{
218 return nullptr;
219}
220
221} // namespace MayaFlux::Nodes::Network
#define MF_ERROR(comp, ctx,...)
uint32_t total
uint32_t index
Definition VKDevice.cpp:142
size_t count
float offset
bool is_vertex_data_dirty() const override
Check if geometry changed this frame.
size_t get_point_count() const override
Get source point count (before topology expansion)
std::vector< std::shared_ptr< GpuSync::GeometryWriterNode > > m_items
std::vector< uint32_t > build_cluster_ids() const override
One cluster id per item; coincides with get_vertex_count() since items carry no interpolation step of...
size_t get_vertex_count() const override
Get number of vertices (may differ from point count for topology/path)
std::optional< double > query_state(std::string_view query) const override
Query operator internal state.
void process(float dt) override
Process for one batch cycle.
std::vector< DrawRun > topology_runs() const override
Coalesces adjacent items sharing a concatenable topology into one run; strip/fan items are always rep...
std::vector< DirtyVertexRange > dirty_vertex_ranges() const override
One DirtyVertexRange per item that needs a GPU update, in add_geometry() order, matching get_vertex_d...
std::span< const uint8_t > get_vertex_data() const override
Get vertex data for GPU upload.
std::optional< Portal::Graphics::PrimitiveTopology > declared_topology() const override
Forwards to the first item's own get_primitive_topology().
void mark_vertex_data_clean() override
Clear dirty flag after GPU upload.
std::span< const uint8_t > get_vertex_data_for_collection(uint32_t idx) const override
Get vertex data for specific collection (if multiple)
void * get_data_at(size_t global_index) override
Get mutable access to point at global index.
Kakshya::VertexLayout get_vertex_layout() const override
The universal Kakshya::Vertex attribute layout, vertex_count 0 when there are no items yet.
std::shared_ptr< GpuSync::GeometryLeafNode > add_geometry(std::vector< glm::vec3 > positions, Portal::Graphics::PrimitiveTopology topology=Portal::Graphics::PrimitiveTopology::POINT_LIST)
Add an item from plain positions (color/scalar/normal/uv default).
void set_parameter(std::string_view param, double value) override
Set operator parameter.
bool remove_geometry(const std::shared_ptr< GpuSync::GeometryWriterNode > &node)
Remove an item by identity.
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
PrimitiveTopology
Vertex assembly primitive topology.
Owning CPU-side representation of a loaded or generated mesh.
Definition MeshData.hpp:33
static VertexLayout for_points(uint32_t stride=60)
Factory: layout for PointVertex (position, color, size, uv, normal, tangent)
Complete description of vertex data layout in a buffer.
Type-neutral vertex carrying the universal 60-byte attribute layout.
A contiguous span of vertex records that changed since the last mark_vertex_data_clean().
One contiguous span of vertices sharing a primitive topology.