MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NetworkGeometryProcessor.cpp
Go to the documentation of this file.
2
6
7namespace MayaFlux::Buffers {
8
14
16 const std::string& name,
17 const std::shared_ptr<Nodes::NodeNetwork>& network,
18 const std::shared_ptr<VKBuffer>& vertex_buffer)
19{
20 if (!network) {
21 error<std::invalid_argument>(
24 std::source_location::current(),
25 "Cannot bind null network '{}'", name);
26 }
27
28 if (!vertex_buffer) {
29 error<std::invalid_argument>(
32 std::source_location::current(),
33 "Cannot bind network '{}' to null vertex buffer", name);
34 }
35
36 std::shared_ptr<VKBuffer> staging = nullptr;
37 if (!vertex_buffer->is_host_visible()) {
38 staging = create_staging_buffer(vertex_buffer->get_size_bytes());
39
41 "Created staging buffer for device-local network geometry '{}' ({} bytes)",
42 name, vertex_buffer->get_size_bytes());
43 } else {
45 "No staging needed for host-visible network geometry '{}'", name);
46 }
47
49 .network = network,
50 .gpu_vertex_buffer = vertex_buffer,
51 .staging_buffer = staging
52 };
53
55 "Bound network '{}' ({} nodes, {} bytes buffer)",
56 name, network->get_node_count(), vertex_buffer->get_size_bytes());
57}
58
59void NetworkGeometryProcessor::unbind_network(const std::string& name)
60{
61 if (m_bindings.erase(name) == 0) {
63 "Attempted to unbind non-existent network '{}'", name);
64 } else {
66 "Unbound network '{}'", name);
67 }
68}
69
70bool NetworkGeometryProcessor::has_binding(const std::string& name) const
71{
72 return m_bindings.contains(name);
73}
74
75std::vector<std::string> NetworkGeometryProcessor::get_binding_names() const
76{
77 std::vector<std::string> names;
78 names.reserve(m_bindings.size());
79 for (const auto& [name, _] : m_bindings) {
80 names.push_back(name);
81 }
82 return names;
83}
84
86{
87 return m_bindings.size();
88}
89
90std::optional<NetworkGeometryProcessor::NetworkBinding>
91NetworkGeometryProcessor::get_binding(const std::string& name) const
92{
93 auto it = m_bindings.find(name);
94 if (it != m_bindings.end()) {
95 return it->second;
96 }
97 return std::nullopt;
98}
99
100void NetworkGeometryProcessor::processing_function(std::shared_ptr<Buffer> buffer)
101{
102 if (m_bindings.empty()) {
103 return;
104 }
105
106 auto vk_buffer = std::dynamic_pointer_cast<VKBuffer>(buffer);
107 if (!vk_buffer) {
109 "NetworkGeometryProcessor requires VKBuffer, got different buffer type");
110 return;
111 }
112
113 for (auto& [name, binding] : m_bindings) {
114 if (!binding.network || !binding.network->is_enabled()) {
116 "Network '{}' disabled, skipping upload", name);
117 continue;
118 }
119
120 std::vector<Nodes::GpuSync::PointVertex> vertices;
121
122 if (auto particle_net = std::dynamic_pointer_cast<Nodes::ParticleNetwork>(binding.network)) {
123 vertices = extract_particle_vertices(particle_net);
124 } else {
125 vertices = extract_network_vertices(binding.network);
126 }
127
128 if (vertices.empty()) {
129 binding.gpu_vertex_buffer->clear();
131 "Network '{}' has no vertices, cleared buffer", name);
132 continue;
133 }
134
135 size_t required_size = vertices.size() * sizeof(Nodes::GpuSync::PointVertex);
136 size_t available_size = binding.gpu_vertex_buffer->get_size_bytes();
137
138 if (required_size > available_size) {
139 auto new_size = static_cast<size_t>(required_size * 1.5F);
140
142 "Network '{}' growing: resizing GPU buffer from {} → {} bytes",
143 name, available_size, new_size);
144
145 binding.gpu_vertex_buffer->resize(new_size, false);
146 available_size = new_size;
147
148 if (binding.staging_buffer) {
149 binding.staging_buffer->resize(new_size, false);
151 "Resized staging buffer for '{}' to {} bytes", name, new_size);
152 }
153 }
154
155 size_t upload_size = std::min<size_t>(required_size, available_size);
156
158 vertices.data(),
159 upload_size,
160 binding.gpu_vertex_buffer,
161 binding.staging_buffer);
162
164 layout.vertex_count = static_cast<uint32_t>(vertices.size());
166
169 .offset_in_vertex = 0,
170 .name = "position" });
171
174 .offset_in_vertex = sizeof(glm::vec3),
175 .name = "color" });
176
179 .offset_in_vertex = sizeof(glm::vec3) + sizeof(glm::vec3),
180 .name = "size" });
181
182 binding.gpu_vertex_buffer->set_vertex_layout(layout);
183
185 "Uploaded {} vertices from network '{}' ({} bytes)",
186 vertices.size(), name, upload_size);
187 }
188}
189
190std::vector<Nodes::GpuSync::PointVertex>
192 const std::shared_ptr<Nodes::ParticleNetwork>& network)
193{
194 std::vector<Nodes::GpuSync::PointVertex> vertices;
195
196 const auto& particles = network->get_particles();
197 vertices.reserve(particles.size());
198
199 for (const auto& particle : particles) {
200 vertices.push_back({ .position = particle.point->get_position(),
201 .color = particle.point->get_color(),
202 .size = particle.point->get_size() });
203 }
204
205 return vertices;
206}
207
208std::vector<Nodes::GpuSync::PointVertex>
210 const std::shared_ptr<Nodes::NodeNetwork>& network)
211{
212 std::vector<Nodes::GpuSync::PointVertex> vertices;
213
214 // Generic fallback: attempt to extract from network metadata
215 // This is a placeholder - specific network types should be handled explicitly
216
218 "Generic network vertex extraction not yet implemented for this network type. "
219 "Returning empty vertex array.");
220
221 return vertices;
222}
223
224} // namespace MayaFlux::Buffers
#define MF_RT_WARN(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_RT_TRACE(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::unordered_map< std::string, NetworkBinding > m_bindings
void bind_network(const std::string &name, const std::shared_ptr< Nodes::NodeNetwork > &network, const std::shared_ptr< VKBuffer > &vertex_buffer)
Bind a network to a GPU vertex buffer.
void processing_function(std::shared_ptr< Buffer > buffer) override
BufferProcessor interface - aggregates and uploads network geometry.
std::vector< Nodes::GpuSync::PointVertex > extract_network_vertices(const std::shared_ptr< Nodes::NodeNetwork > &network)
Extract vertices from generic NodeNetwork (fallback)
void unbind_network(const std::string &name)
Remove a network binding.
bool has_binding(const std::string &name) const
Check if a binding exists.
std::vector< Nodes::GpuSync::PointVertex > extract_particle_vertices(const std::shared_ptr< Nodes::ParticleNetwork > &network)
Extract vertices from ParticleNetwork.
std::optional< NetworkBinding > get_binding(const std::string &name) const
Get a specific binding.
size_t get_binding_count() const
Get number of active bindings.
std::vector< std::string > get_binding_names() const
Get all binding names.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
std::shared_ptr< VKBuffer > create_staging_buffer(size_t size)
Create staging buffer for transfers.
void upload_to_gpu(const void *data, size_t size, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging)
Upload raw data to GPU buffer (auto-detects host-visible vs device-local)
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
@ UNKNOWN
Unknown or undefined modality.
Structure representing a network geometry binding.
DataModality component_modality
Semantic type of this attribute e.g., VERTEX_POSITIONS_3D → vec3, TEXTURE_COORDS_2D → vec2.
Semantic description of a single vertex attribute.
uint32_t stride_bytes
Total bytes per vertex (stride in Vulkan terms) e.g., 3 floats (position) + 3 floats (normal) = 24 by...
uint32_t vertex_count
Total number of vertices in this buffer.
std::vector< VertexAttributeLayout > attributes
All attributes that make up one vertex Ordered by shader location (0, 1, 2, ...)
Complete description of vertex data layout in a buffer.