MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
FieldOperator.hpp
Go to the documentation of this file.
1#pragma once
2
4
7
9
10/**
11 * @enum FieldTarget
12 * @brief Vertex attribute targets for Tendency field evaluation
13 */
14enum class FieldTarget : uint8_t {
16 COLOR,
17 NORMAL,
18 TANGENT,
19 SCALAR,
20 UV
21};
22
23/**
24 * @enum FieldMode
25 * @brief How fields are applied each frame
26 */
27enum class FieldMode : uint8_t {
30};
31
32/**
33 * @class FieldOperator
34 * @brief Pure field-driven vertex manipulation via Tendency evaluation
35 *
36 * No velocity, no mass, no integration. Each frame, evaluates bound
37 * Tendency fields at each vertex position and writes results into
38 * the targeted vertex attributes.
39 *
40 * ABSOLUTE mode: restores full reference vertex state before evaluation.
41 * Deterministic, stateless, frame-rate independent.
42 *
43 * ACCUMULATE mode: applies on top of current state. Produces drift
44 * and evolution, frame-rate dependent.
45 *
46 * Works with both PointVertex and LineVertex (identical 60-byte layout).
47 *
48 * Implemented targets:
49 * POSITION VectorField displacement added to position
50 * COLOR VectorField direct RGB assignment at position
51 * NORMAL VectorField direction assignment at position (auto-normalized)
52 * TANGENT VectorField direction assignment at position (auto-normalized)
53 * SCALAR SpatialField direct assignment (size/thickness)
54 * UV UVField direct assignment (UV coordinates)
55 *
56 * Usage with ParticleNetwork:
57 * @code
58 * auto field_op = particles->create_operator<FieldOperator>();
59 * field_op->bind(FieldTarget::POSITION, Kinesis::VectorField { ... });
60 * field_op->bind(FieldTarget::SCALAR, Kinesis::SpatialField { ... });
61 * @endcode
62 *
63 * Usage with PointCloudNetwork:
64 * @code
65 * auto field_op = cloud->create_operator<FieldOperator>();
66 * field_op->bind(FieldTarget::POSITION, Kinesis::VectorField { ... });
67 * @endcode
68 */
69class MAYAFLUX_API FieldOperator : public GraphicsOperator {
70public:
71 explicit FieldOperator(FieldMode mode = FieldMode::ABSOLUTE);
72
73 /**
74 * @brief Initialize from PointVertex data
75 * @param vertices Source vertices (positions stored as reference frame)
76 */
77 void initialize(const std::vector<PointVertex>& vertices);
78
79 /**
80 * @brief Initialize from LineVertex data
81 * @param vertices Source vertices (positions stored as reference frame)
82 */
83 void initialize(const std::vector<LineVertex>& vertices);
84
85 /**
86 * @brief Initialize from MeshVertex data
87 * @param vertices Source vertices (positions stored as reference frame)
88 */
89 void initialize(const std::vector<MeshVertex>& vertices);
90
91 void process(float dt) override;
92
93 // -----------------------------------------------------------------
94 // Field binding
95 // -----------------------------------------------------------------
96
97 /**
98 * @brief Bind a VectorField to a vec3 target
99 * @param target POSITION, COLOR, NORMAL, or TANGENT
100 * @param field VectorField: glm::vec3 -> glm::vec3
101 *
102 * POSITION fields are additive (displacement).
103 * COLOR fields are direct assignment (RGB).
104 * NORMAL fields are direct assignment (auto-normalized).
105 * TANGENT fields are direct assignment (auto-normalized).
106 */
107 void bind(FieldTarget target, Kinesis::VectorField field);
108
109 /**
110 * @brief Bind a SpatialField to a scalar target
111 * @param target SCALAR or UV
112 * @param field SpatialField: glm::vec3 -> float
113 */
115
116 /**
117 * @brief Bind a UVField to the UV target
118 * @param target Must be UV
119 * @param field UVField: glm::vec3 -> glm::vec2
120 *
121 * Multiple fields accumulate additively. Evaluation order matches
122 * bind order. Use ACCUMULATE mode for animated UV drift.
123 */
124 void bind(FieldTarget target, Kinesis::UVField field);
125
126 /**
127 * @brief Remove all fields bound to a target
128 * @param target Target to clear
129 */
130 void unbind(FieldTarget target);
131
132 /**
133 * @brief Remove all bound fields
134 */
135 void unbind_all();
136
137 /**
138 * @brief Set field application mode
139 * @param mode ABSOLUTE (reset each frame) or ACCUMULATE (stack displacements)
140 */
141 void set_mode(FieldMode mode) { m_mode = mode; }
142
143 /**
144 * @brief Get current field mode
145 */
146 [[nodiscard]] FieldMode get_mode() const { return m_mode; }
147
148 // -----------------------------------------------------------------
149 // GraphicsOperator interface
150 // -----------------------------------------------------------------
151
152 [[nodiscard]] std::span<const uint8_t> get_vertex_data() const override;
153 [[nodiscard]] std::span<const uint8_t> get_vertex_data_for_collection(uint32_t idx) const override;
154 [[nodiscard]] Kakshya::VertexLayout get_vertex_layout() const override;
155 [[nodiscard]] size_t get_vertex_count() const override;
156 [[nodiscard]] bool is_vertex_data_dirty() const override;
157 void mark_vertex_data_clean() override;
158 [[nodiscard]] std::vector<PointVertex> extract_point_vertices() const;
159 [[nodiscard]] std::vector<LineVertex> extract_line_vertices() const;
160 [[nodiscard]] std::vector<MeshVertex> extract_mesh_vertices() const;
161
162 void set_parameter(std::string_view param, double value) override;
163 [[nodiscard]] std::optional<double> query_state(std::string_view query) const override;
164 [[nodiscard]] std::string_view get_type_name() const override { return "Field"; }
165 [[nodiscard]] size_t get_point_count() const override;
166 [[nodiscard]] const char* get_vertex_type_name() const override;
167
168 void apply_one_to_one(
169 std::string_view param,
170 const std::shared_ptr<NodeNetwork>& source) override;
171
172protected:
173 void* get_data_at(size_t global_index) override;
174
175private:
176 /**
177 * @enum VertexType
178 * @brief Tracks which vertex type was used at initialization
179 */
180 enum class VertexType : uint8_t { NONE,
181 POINT,
182 LINE,
183 MESH
184 };
185
187 VertexType m_vertex_type { VertexType::NONE };
188 size_t m_count { 0 };
189
190 std::vector<uint8_t> m_reference_data;
191 std::vector<uint8_t> m_vertex_data;
192 bool m_dirty { false };
193
194 std::vector<Kinesis::VectorField> m_position_fields;
195 std::vector<Kinesis::VectorField> m_color_fields;
196 std::vector<Kinesis::VectorField> m_normal_fields;
197 std::vector<Kinesis::VectorField> m_tangent_fields;
198 std::vector<Kinesis::SpatialField> m_scalar_fields;
199 std::vector<Kinesis::UVField> m_uv_fields;
200
201 static constexpr size_t k_stride = 60;
202 static constexpr size_t k_position_offset = 0;
203 static constexpr size_t k_color_offset = 12;
204 static constexpr size_t k_scalar_offset = 24;
205 static constexpr size_t k_uv_offset = 28;
206 static constexpr size_t k_normal_offset = 36;
207 static constexpr size_t k_tangent_offset = 48;
208
209 glm::vec3& vec3_at(size_t i, size_t offset);
210 float& float_at(size_t i, size_t offset);
211 [[nodiscard]] glm::vec3 ref_position_at(size_t i) const;
212
213 void store_reference(const void* data, size_t count);
214};
215
216} // namespace MayaFlux::Nodes::Network
Eigen::Index count
std::vector< Kinesis::VectorField > m_position_fields
void set_mode(FieldMode mode)
Set field application mode.
std::vector< Kinesis::VectorField > m_tangent_fields
VertexType
Tracks which vertex type was used at initialization.
std::vector< Kinesis::SpatialField > m_scalar_fields
void bind(FieldTarget target, Kinesis::UVField field)
Bind a UVField to the UV target.
std::vector< Kinesis::VectorField > m_color_fields
std::vector< Kinesis::VectorField > m_normal_fields
std::string_view get_type_name() const override
Type name for introspection.
std::vector< Kinesis::UVField > m_uv_fields
void bind(FieldTarget target, Kinesis::SpatialField field)
Bind a SpatialField to a scalar target.
FieldMode get_mode() const
Get current field mode.
Pure field-driven vertex manipulation via Tendency evaluation.
Operator that produces GPU-renderable geometry.
void initialize()
Definition main.cpp:11
FieldMode
How fields are applied each frame.
FieldTarget
Vertex attribute targets for Tendency field evaluation.
Complete description of vertex data layout in a buffer.
Typed, composable, stateless callable from domain D to range R.
Definition Tendency.hpp:22