MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MeshFieldOperator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "FieldOperator.hpp"
4#include "MeshOperator.hpp"
5
7
8/**
9 * @class MeshFieldOperator
10 * @brief Chain operator that applies Tendency field deformation to the
11 * vertex data of individual MeshNetwork slots.
12 *
13 * Holds one FieldOperator per bound slot, keyed by slot index.
14 * bind() creates or replaces the per-slot FieldOperator and initialises
15 * it from the slot's current MeshVertex array so the reference frame
16 * is always the geometry as it existed at bind time.
17 *
18 * process_slot() runs the slot's FieldOperator::process(dt) then writes
19 * the resulting MeshVertex array back via
20 * slot.node->set_mesh_vertices(). That call sets m_vertex_data_dirty on
21 * the MeshWriterNode, which any_slot_dirty() in MeshNetworkProcessor
22 * already checks.
23 *
24 * Slots without a bound FieldOperator are skipped entirely.
25 *
26 * This operator belongs in the OperatorChain, not as the primary operator.
27 * MeshTransformOperator runs first (as primary) to propagate world
28 * transforms; MeshFieldOperator runs after to deform vertex positions in
29 * local space.
30 *
31 * Usage:
32 * @code
33 * auto field_op = std::make_shared<MeshFieldOperator>();
34 * net->get_operator_chain()->emplace<MeshFieldOperator>();
35 *
36 * // Retrieve the typed pointer from the chain or hold it before emplacing.
37 * field_op->bind(torso_idx, FieldTarget::POSITION,
38 * Kinesis::make_radial_pull(glm::vec3(0), 4.0F));
39 * @endcode
40 */
41class MAYAFLUX_API MeshFieldOperator : public MeshOperator {
42public:
43 MeshFieldOperator() = default;
44 ~MeshFieldOperator() override = default;
45
46 // -------------------------------------------------------------------------
47 // Field binding
48 // -------------------------------------------------------------------------
49
50 /**
51 * @brief Bind a VectorField to a slot.
52 * @param slot_index Target slot index.
53 * @param target Vertex attribute to drive (POSITION, COLOR, NORMAL, TANGENT).
54 * @param field VectorField: glm::vec3 -> glm::vec3.
55 *
56 * Creates a FieldOperator for the slot if one does not yet exist.
57 * The FieldOperator is initialised from the slot's current vertex data.
58 * Subsequent binds on the same slot append fields to the existing operator.
59 */
60 void bind(uint32_t slot_index, FieldTarget target, Kinesis::VectorField field);
61
62 /**
63 * @brief Bind a SpatialField to a slot.
64 * @param slot_index Target slot index.
65 * @param target Vertex attribute to drive (SCALAR or UV).
66 * @param field SpatialField: glm::vec3 -> float.
67 */
68 void bind(uint32_t slot_index, FieldTarget target, Kinesis::SpatialField field);
69
70 /**
71 * @brief Bind a UVField to a slot.
72 * @param slot_index Target slot index.
73 * @param target Must be FieldTarget::UV.
74 * @param field UVField: glm::vec3 -> glm::vec2.
75 */
76 void bind(uint32_t slot_index, FieldTarget target, Kinesis::UVField field);
77
78 /**
79 * @brief Remove all fields bound to a target on a specific slot.
80 * @param slot_index Target slot index.
81 * @param target Target to clear.
82 */
83 void unbind(uint32_t slot_index, FieldTarget target);
84
85 /**
86 * @brief Remove the entire FieldOperator for a slot.
87 * @param slot_index Target slot index.
88 */
89 void unbind_slot(uint32_t slot_index);
90
91 /**
92 * @brief Remove all per-slot FieldOperators.
93 */
94 void unbind_all();
95
96 /**
97 * @brief Set the field application mode for a slot's FieldOperator.
98 * @param slot_index Target slot index. The FieldOperator must already exist.
99 * @param mode ABSOLUTE or ACCUMULATE.
100 */
101 void set_mode(uint32_t slot_index, FieldMode mode);
102
103 // -------------------------------------------------------------------------
104 // MeshOperator interface
105 // -------------------------------------------------------------------------
106
107 /**
108 * @brief Run the slot's FieldOperator (if bound) and write results back to
109 * slot.node via set_mesh_vertices().
110 */
111 void process_slot(MeshSlot& slot, float dt) override;
112
113 [[nodiscard]] std::string_view get_type_name() const override
114 {
115 return "MeshField";
116 }
117
118private:
119 std::unordered_map<uint32_t, std::shared_ptr<FieldOperator>> m_field_ops;
120
121 /**
122 * @brief Return an existing FieldOperator for the slot, or create and
123 * initialise one from the slot's current vertex data.
124 * @param slot Slot whose FieldOperator to retrieve or create.
125 * @param slot_index Slot index (key into m_field_ops).
126 * @return Pointer to the (possibly new) FieldOperator.
127 */
128 [[nodiscard]] std::shared_ptr<FieldOperator>
129 get_or_create(MeshSlot& slot, uint32_t slot_index);
130};
131
132} // namespace MayaFlux::Nodes::Network
void bind(uint32_t slot_index, FieldTarget target, Kinesis::SpatialField field)
Bind a SpatialField to a slot.
std::unordered_map< uint32_t, std::shared_ptr< FieldOperator > > m_field_ops
void bind(uint32_t slot_index, FieldTarget target, Kinesis::UVField field)
Bind a UVField to a slot.
std::string_view get_type_name() const override
Type name for introspection.
Chain operator that applies Tendency field deformation to the vertex data of individual MeshNetwork s...
Abstract base for operators that process MeshNetwork slots.
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
Named, independently transformable mesh unit within a MeshNetwork.
Definition MeshSlot.hpp:31