MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
PhysicsOperator.hpp
Go to the documentation of this file.
1#pragma once
4
6
8
9/**
10 * @enum PhysicsParameter
11 * @brief Identifiers for physics parameters that can be set via parameter mapping
12 */
26
27/**
28 * @struct PhysicsState
29 * @brief Physics-specific data parallel to PointVertex array
30 *
31 * Stored separately to avoid polluting vertex types with
32 * physics data. Indexed in parallel with PointCollectionNode's
33 * internal vertex array.
34 */
36 glm::vec3 velocity { 0.0F };
37 glm::vec3 force { 0.0F };
38 float mass { 1.0F };
39};
40
41/**
42 * @class PhysicsOperator
43 * @brief N-body physics simulation with point rendering
44 *
45 * Delegates rendering to PointCollectionNode. Physics state
46 * (velocity, force, mass) stored in parallel array. Each frame:
47 * 1. Apply forces
48 * 2. Integrate motion
49 * 3. Update PointCollectionNode vertices
50 * 4. PointCollectionNode handles GPU upload
51 */
52class MAYAFLUX_API PhysicsOperator : public GraphicsOperator {
53public:
55 std::shared_ptr<GpuSync::PointCollectionNode> collection;
56 std::vector<PhysicsState> physics_state;
57 };
58
59 /**
60 * @enum BoundsMode
61 * @brief How particles behave at spatial bounds
62 */
63 enum class BoundsMode : uint8_t {
64 NONE, ///< No bounds checking
65 BOUNCE, ///< Reflect off boundaries with damping
66 WRAP, ///< Teleport to opposite side
67 CLAMP ///< Stop at boundary
68 };
69
71
72 /**
73 * @brief Initialize with a single physics collection
74 * @param vertices PointVertex array with position, color, size
75 */
76 void initialize(const std::vector<PointVertex>& vertices);
77
78 /**
79 * @brief Initialize multiple physics collections
80 * @param collections Vector of PointVertex vectors (one per collection)
81 */
82 void initialize_collections(
83 const std::vector<std::vector<PointVertex>>& collections);
84
85 /**
86 * @brief Add a single physics collection
87 * @param vertices PointVertex array with position, color, size
88 * @param mass_multiplier Mass multiplier for all particles in this collection
89 */
90 void add_collection(
91 const std::vector<PointVertex>& vertices,
92 float mass_multiplier = 1.0F);
93
94 void process(float dt) override;
95
96 [[nodiscard]] std::span<const uint8_t> get_vertex_data_for_collection(uint32_t idx) const override;
97 [[nodiscard]] std::span<const uint8_t> get_vertex_data() const override;
98 [[nodiscard]] Kakshya::VertexLayout get_vertex_layout() const override;
99 [[nodiscard]] size_t get_vertex_count() const override;
100 [[nodiscard]] bool is_vertex_data_dirty() const override;
101 void mark_vertex_data_clean() override;
102
103 /**
104 * @brief Extract current vertex data as PointVertex array
105 * @return Vector of PointVertex with current positions, colors, sizes
106 */
107 [[nodiscard]] std::vector<PointVertex> extract_vertices() const;
108
109 void set_parameter(std::string_view param, double value) override;
110 [[nodiscard]] std::optional<double> query_state(std::string_view query) const override;
111 [[nodiscard]] std::string_view get_type_name() const override { return "Physics"; }
112 [[nodiscard]] size_t get_point_count() const override;
113
114 /**
115 * @brief Set the gravity vector.
116 * @param gravity Gravity vector.
117 */
118 void set_gravity(const glm::vec3& gravity) { m_gravity = gravity; }
119
120 /**
121 * @brief Set the drag coefficient.
122 * @param drag Drag value.
123 */
124 void set_drag(float drag) { m_drag = drag; }
125
126 /**
127 * @brief Set the interaction radius for physics calculations.
128 * @param radius Interaction radius.
129 */
130 void set_interaction_radius(float radius) { m_interaction_radius = radius; }
131
132 /**
133 * @brief Set the spring stiffness for interactions.
134 * @param stiffness Spring stiffness value.
135 */
136 void set_spring_stiffness(float stiffness) { m_spring_stiffness = stiffness; }
137
138 /**
139 * @brief Set the simulation bounds.
140 * @param min Minimum bounds.
141 * @param max Maximum bounds.
142 */
143 void set_bounds(const glm::vec3& min, const glm::vec3& max);
144
145 /**
146 * @brief Set the rendered point size.
147 * @param size Point size.
148 */
149 void set_point_size(float size) { m_point_size = size; }
150
151 /**
152 * @brief Set the current bounds mode.
153 * @param mode Bounds mode to set.
154 */
155 void set_bounds_mode(BoundsMode mode) { m_bounds_mode = mode; }
156
157 /**
158 * @brief Enable or disable spatial interactions between particles.
159 * @param enable True to enable, false to disable.
160 */
161 void enable_spatial_interactions(bool enable) { m_spatial_interactions_enabled = enable; }
162
163 /**
164 * @brief Set the strength of repulsion between particles when spatial interactions are enabled.
165 * @param strength Repulsion strength value.
166 */
167 void set_repulsion_strength(float strength) { m_repulsion_strength = strength; }
168
169 /**
170 * @brief Set the strength of attraction towards the attraction point.
171 * @param strength Attraction strength value.
172 */
173 void set_turbulence_strength(float strength) { m_turbulence_strength = strength; }
174
175 /**
176 * @brief Get velocity magnitude for specific particle
177 * @param global_index Particle index across all collections
178 */
179 [[nodiscard]] std::optional<double> get_particle_velocity(size_t global_index) const;
180
181 /**
182 * @brief Get the current gravity vector.
183 * @return Gravity vector.
184 */
185 [[nodiscard]] glm::vec3 get_gravity() const { return m_gravity; }
186
187 /**
188 * @brief Get the current drag coefficient.
189 * @return Drag value.
190 */
191 [[nodiscard]] float get_drag() const { return m_drag; }
192
193 /**
194 * @brief Get the current bounds mode.
195 * @return Current bounds mode.
196 */
197 [[nodiscard]] BoundsMode get_bounds_mode() const { return m_bounds_mode; }
198
199 /**
200 * @brief Check if spatial interactions between particles are enabled.
201 * @return True if enabled, false otherwise.
202 */
203 [[nodiscard]] bool spatial_interactions_enabled() const { return m_spatial_interactions_enabled; }
204
205 /**
206 * @brief Get the current repulsion strength for spatial interactions.
207 * @return Repulsion strength value.
208 */
209 [[nodiscard]] float get_repulsion_strength() const { return m_repulsion_strength; }
210
211 void set_attraction_point(const glm::vec3& point);
212
213 void clear_attraction_point() { m_has_attraction_point = false; }
214
215 [[nodiscard]] bool has_attraction_point() const { return m_has_attraction_point; }
216
217 [[nodiscard]] glm::vec3 get_attraction_point() const { return m_attraction_point; }
218
219 /**
220 * @brief Apply impulse to all particles
221 */
222 void apply_global_impulse(const glm::vec3& impulse);
223
224 /**
225 * @brief Apply impulse to specific particle
226 */
227 void apply_impulse(size_t index, const glm::vec3& impulse);
228
229 /**
230 * @brief Direct access to collections for advanced per-particle control
231 * @warning Only for ParticleNetwork's ONE_TO_ONE parameter mapping
232 */
233 std::vector<CollectionGroup>& get_collections() { return m_collections; }
234
235 /**
236 * @brief Apply ONE_TO_ONE parameter for physics-specific properties
237 *
238 * Supports:
239 * - "force_x/y/z": Per-particle force application
240 * - "mass": Per-particle mass
241 * - "color": Per-particle color (delegated to base)
242 * - "size": Per-particle size (delegated to base)
243 */
244 void apply_one_to_one(
245 std::string_view param,
246 const std::shared_ptr<NodeNetwork>& source) override;
247
248 const char* get_vertex_type_name() const override { return "PointVertex"; }
249
250protected:
251 void* get_data_at(size_t global_index) override;
252
253private:
254 std::vector<CollectionGroup> m_collections;
255 mutable std::vector<uint8_t> m_vertex_data_aggregate;
256
258
259 glm::vec3 m_gravity { 0.0F, -9.81F, 0.0F };
260 float m_drag { 0.01F };
261 float m_interaction_radius { 1.0F };
262 float m_spring_stiffness { 0.5F };
263 float m_point_size { 5.0F };
264 float m_turbulence_strength { 0.0F };
265 Kinesis::SamplerBounds m_bounds { .min = glm::vec3 { -10.0F }, .max = glm::vec3 { 10.0F } };
266 BoundsMode m_bounds_mode { BoundsMode::BOUNCE };
267 bool m_spatial_interactions_enabled {};
268 float m_repulsion_strength { 0.5F };
269
270 glm::vec3 m_attraction_point { 0.0F };
271 bool m_has_attraction_point { false };
272 float m_attraction_strength { 1.0F };
273
274 static std::optional<PhysicsParameter> string_to_parameter(std::string_view param);
275
276 void apply_forces();
277 void apply_spatial_interactions();
278 void apply_attraction_forces();
279 void apply_turbulence();
280 void integrate(float dt);
281 void handle_boundary_conditions();
282 void sync_to_point_collection();
283
284 void apply_per_particle_force(
285 std::string_view param,
286 const std::shared_ptr<NodeNetwork>& source);
287
288 void apply_per_particle_mass(
289 const std::shared_ptr<NodeNetwork>& source);
290};
291
292} // namespace MayaFlux::Nodes::Network
Unified generative infrastructure for stochastic and procedural algorithms.
Operator that produces GPU-renderable geometry.
void set_repulsion_strength(float strength)
Set the strength of repulsion between particles when spatial interactions are enabled.
std::vector< CollectionGroup > m_collections
glm::vec3 get_gravity() const
Get the current gravity vector.
void set_turbulence_strength(float strength)
Set the strength of attraction towards the attraction point.
Kinesis::Stochastic::Stochastic m_random_generator
float get_drag() const
Get the current drag coefficient.
BoundsMode
How particles behave at spatial bounds.
void set_interaction_radius(float radius)
Set the interaction radius for physics calculations.
void set_drag(float drag)
Set the drag coefficient.
std::vector< CollectionGroup > & get_collections()
Direct access to collections for advanced per-particle control.
void set_bounds_mode(BoundsMode mode)
Set the current bounds mode.
std::string_view get_type_name() const override
Type name for introspection.
void set_gravity(const glm::vec3 &gravity)
Set the gravity vector.
const char * get_vertex_type_name() const override
Get human-readable vertex type name (for validation/debugging)
void enable_spatial_interactions(bool enable)
Enable or disable spatial interactions between particles.
float get_repulsion_strength() const
Get the current repulsion strength for spatial interactions.
BoundsMode get_bounds_mode() const
Get the current bounds mode.
bool spatial_interactions_enabled() const
Check if spatial interactions between particles are enabled.
void set_point_size(float size)
Set the rendered point size.
void set_spring_stiffness(float stiffness)
Set the spring stiffness for interactions.
N-body physics simulation with point rendering.
void initialize()
Definition main.cpp:11
PhysicsParameter
Identifiers for physics parameters that can be set via parameter mapping.
Complete description of vertex data layout in a buffer.
Spatial domain for vertex generation.
std::shared_ptr< GpuSync::PointCollectionNode > collection
Physics-specific data parallel to PointVertex array.