MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MeshFieldOperator.cpp
Go to the documentation of this file.
2
5
7
8// =============================================================================
9// Private helpers
10// =============================================================================
11
12std::shared_ptr<FieldOperator>
13MeshFieldOperator::get_or_create(MeshSlot& slot, uint32_t slot_index)
14{
15 auto it = m_field_ops.find(slot_index);
16 if (it != m_field_ops.end())
17 return it->second;
18
19 auto op = std::make_shared<FieldOperator>(FieldMode::ABSOLUTE);
20
21 if (slot.node) {
22 op->initialize(slot.node->get_mesh_vertices());
24 "MeshFieldOperator: initialised FieldOperator for slot {} ({} vertices)",
25 slot_index, slot.node->get_mesh_vertex_count());
26 } else {
28 "MeshFieldOperator: slot {} has no node at bind time -- "
29 "FieldOperator initialised with empty vertex data",
30 slot_index);
31 }
32
33 m_field_ops.emplace(slot_index, op);
34 return op;
35}
36
37// =============================================================================
38// Field binding
39// =============================================================================
40
42 uint32_t slot_index, FieldTarget target, Kinesis::VectorField field)
43{
44 if (!m_slots) {
46 "MeshFieldOperator::bind called before set_slots() -- "
47 "FieldOperator will be initialised lazily on first process()");
48 }
49
50 if (m_slots) {
51 if (slot_index >= m_slots->size()) {
53 "MeshFieldOperator::bind: slot_index {} out of range ({})",
54 slot_index, m_slots->size());
55 return;
56 }
57 auto op = get_or_create((*m_slots)[slot_index], slot_index);
58 op->bind(target, std::move(field));
59 } else {
60 auto& op = m_field_ops[slot_index];
61 if (!op)
62 op = std::make_shared<FieldOperator>(FieldMode::ABSOLUTE);
63 op->bind(target, std::move(field));
64 }
65}
66
68 uint32_t slot_index, FieldTarget target, Kinesis::SpatialField field)
69{
70 if (m_slots && slot_index < m_slots->size()) {
71 get_or_create((*m_slots)[slot_index], slot_index)->bind(target, std::move(field));
72 } else {
73 auto& op = m_field_ops[slot_index];
74 if (!op)
75 op = std::make_shared<FieldOperator>(FieldMode::ABSOLUTE);
76 op->bind(target, std::move(field));
77 }
78}
79
81 uint32_t slot_index, FieldTarget target, Kinesis::UVField field)
82{
83 if (m_slots && slot_index < m_slots->size()) {
84 get_or_create((*m_slots)[slot_index], slot_index)->bind(target, std::move(field));
85 } else {
86 auto& op = m_field_ops[slot_index];
87 if (!op)
88 op = std::make_shared<FieldOperator>(FieldMode::ABSOLUTE);
89 op->bind(target, std::move(field));
90 }
91}
92
93void MeshFieldOperator::unbind(uint32_t slot_index, FieldTarget target)
94{
95 auto it = m_field_ops.find(slot_index);
96 if (it != m_field_ops.end())
97 it->second->unbind(target);
98}
99
100void MeshFieldOperator::unbind_slot(uint32_t slot_index)
101{
102 m_field_ops.erase(slot_index);
103}
104
106{
107 m_field_ops.clear();
108}
109
110void MeshFieldOperator::set_mode(uint32_t slot_index, FieldMode mode)
111{
112 auto it = m_field_ops.find(slot_index);
113 if (it != m_field_ops.end())
114 it->second->set_mode(mode);
115}
116
117// =============================================================================
118// MeshOperator interface
119// =============================================================================
120
122{
123 auto it = m_field_ops.find(slot.index);
124 if (it == m_field_ops.end())
125 return;
126
127 auto& field_op = it->second;
128
129 if (field_op->get_vertex_count() == 0 && slot.node
130 && slot.node->get_mesh_vertex_count() > 0) {
131 field_op->initialize(slot.node->get_mesh_vertices());
133 "MeshFieldOperator: lazy-initialised slot {} ({} vertices)",
134 slot.index, slot.node->get_mesh_vertex_count());
135 }
136
137 field_op->process(dt);
138
139 if (field_op->is_vertex_data_dirty() && slot.node) {
140 slot.node->set_mesh_vertices(field_op->extract_mesh_vertices());
141 field_op->mark_vertex_data_clean();
142 }
143}
144
145} // namespace MayaFlux::Nodes::Network
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
Range size
std::unordered_map< uint32_t, std::shared_ptr< FieldOperator > > m_field_ops
void bind(uint32_t slot_index, FieldTarget target, Kinesis::VectorField field)
Bind a VectorField to a slot.
void set_mode(uint32_t slot_index, FieldMode mode)
Set the field application mode for a slot's FieldOperator.
std::shared_ptr< FieldOperator > get_or_create(MeshSlot &slot, uint32_t slot_index)
Return an existing FieldOperator for the slot, or create and initialise one from the slot's current v...
void unbind_slot(uint32_t slot_index)
Remove the entire FieldOperator for a slot.
void unbind(uint32_t slot_index, FieldTarget target)
Remove all fields bound to a target on a specific slot.
void process_slot(MeshSlot &slot, float dt) override
Run the slot's FieldOperator (if bound) and write results back to slot.node via set_mesh_vertices().
void unbind_all()
Remove all per-slot FieldOperators.
std::vector< MeshSlot > * m_slots
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
Tendency< glm::vec3, glm::vec2 > UVField
Definition Tendency.hpp:48
FieldMode
How fields are applied each frame.
FieldTarget
Vertex attribute targets for Tendency field evaluation.
Typed, composable, stateless callable from domain D to range R.
Definition Tendency.hpp:22
std::shared_ptr< GpuSync::MeshWriterNode > node
Geometry node for this slot.
Definition MeshSlot.hpp:39
uint32_t index
Position of this slot in MeshNetwork::m_slots. Stable after insertion.
Definition MeshSlot.hpp:33
Named, independently transformable mesh unit within a MeshNetwork.
Definition MeshSlot.hpp:31