25 std::shared_ptr<GpuSync::MeshWriterNode> node,
26 std::optional<uint32_t> parent)
29 error<std::invalid_argument>(
31 std::source_location::current(),
32 "MeshNetwork::add_slot: null MeshWriterNode for slot '{}'", name);
35 if (parent.has_value() && parent.value() >=
m_slots.size()) {
36 error<std::out_of_range>(
38 std::source_location::current(),
39 "MeshNetwork::add_slot: parent index {} out of range (slot count: {})",
40 parent.value(),
m_slots.size());
43 const auto idx =
static_cast<uint32_t
>(
m_slots.size());
47 slot.
name = std::move(name);
48 slot.
node = std::move(node);
52 if (parent.has_value()) {
53 m_slots[parent.value()].child_indices.push_back(idx);
56 m_slots.push_back(std::move(slot));
60 "MeshNetwork: added slot '{}' at index {} (parent: {})",
62 parent.has_value() ? std::to_string(parent.value()) :
"none");
79 auto it = std::ranges::find_if(
m_slots,
81 return it !=
m_slots.end() ? &*it :
nullptr;
86 auto it = std::ranges::find_if(
m_slots,
88 return it !=
m_slots.end() ? &*it :
nullptr;
93 for (uint32_t i = 0; i < static_cast<uint32_t>(
m_slots.size()); ++i) {
112 for (
unsigned int frame = 0; frame < num_samples; ++frame) {
116 m_operator->process(
static_cast<float>(frame));
123 if (
auto* mesh_op =
dynamic_cast<MeshOperator*
>(op.get()))
125 op->process(
static_cast<float>(frame));
130 for (
const auto& slot :
m_slots) {
132 slot.node->compute_frame();
139 slot.local_transform = glm::mat4(1.0F);
140 slot.world_transform = glm::mat4(1.0F);
149 return static_cast<double>(index);
155 meta[
"slot_count"] = std::to_string(
m_slots.size());
171 "MeshNetwork::set_operator: null operator ignored");
190 std::vector<uint32_t> in_degree(
m_slots.size(), 0);
191 for (
const auto& slot :
m_slots) {
192 if (slot.parent_index.has_value())
193 ++in_degree[slot.parent_index.value()];
197 std::vector<uint32_t> queue;
198 for (uint32_t i = 0; i < static_cast<uint32_t>(
m_slots.size()); ++i) {
199 if (!
m_slots[i].parent_index.has_value())
206 while (!queue.empty()) {
207 uint32_t idx = queue.front();
208 queue.erase(queue.begin());
211 for (uint32_t child :
m_slots[idx].child_indices)
212 queue.push_back(child);
217 "MeshNetwork: slot DAG contains a cycle — sort is incomplete");
223 "MeshNetwork: rebuilt slot sort order ({} slots)",
m_sorted_indices.size());
230 if (slot.parent_index.has_value()) {
232 =
m_slots[slot.parent_index.value()].world_transform
233 * slot.local_transform;
235 slot.world_transform = slot.local_transform;
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::vector< MeshSlot > m_slots
MeshSlot & get_slot(uint32_t index)
Return the slot at the given index.
void propagate_world_transforms()
std::vector< uint32_t > m_sorted_indices
Processing order: indices into m_slots, parents before children.
bool m_sort_dirty
Set when add_slot() changes the DAG and a re-sort is needed.
void set_operator(std::shared_ptr< NetworkOperator > op)
Replace the primary operator.
std::unordered_map< std::string, std::string > get_metadata() const override
Get network metadata for debugging/visualization.
uint32_t add_slot(std::string name, std::shared_ptr< GpuSync::MeshWriterNode > node, std::optional< uint32_t > parent=std::nullopt)
Add a slot to the network.
std::shared_ptr< NetworkOperator > m_operator
void process_batch(unsigned int num_samples) override
Process the network for the given number of samples.
void ensure_sorted()
Ensure the slot processing order is up to date.
std::optional< uint32_t > find_slot_index(std::string_view name) const
Find the index of a slot by name.
MeshSlot * find_slot(std::string_view name)
Find a slot by name.
std::optional< double > get_node_output(size_t index) const override
Get output of specific internal node (for ONE_TO_ONE mapping)
void reset() override
Reset network to initial state.
Abstract base for operators that process MeshNetwork slots.
virtual void set_topology(Topology topology)
Set the network's topology.
bool is_enabled() const
Check if network is enabled.
std::shared_ptr< OperatorChain > m_operator_chain
virtual std::unordered_map< std::string, std::string > get_metadata() const
Get network metadata for debugging/visualization.
void set_output_mode(OutputMode mode)
Set the network's output routing mode.
@ Init
Engine/subsystem initialization.
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
@ CUSTOM
User-defined arbitrary topology.
@ GRAPHICS_BIND
State available for visualization (read-only)
std::string name
Logical name. Used for lookup and logging only.
bool dirty
Set when local_transform or slot config changes since last upload.
std::shared_ptr< GpuSync::MeshWriterNode > node
Geometry node for this slot.
uint32_t index
Position of this slot in MeshNetwork::m_slots. Stable after insertion.
std::optional< uint32_t > parent_index
Index of the parent slot, or nullopt for a root slot.
Named, independently transformable mesh unit within a MeshNetwork.