MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
ParticleNetwork.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "NodeNetwork.hpp"
4
6
8
9/**
10 * @class ParticleNetwork
11 * @brief Motion-focused point network with swappable operators
12 *
13 * Philosophy: ParticleNetwork is for MOTION. Operators define how
14 * points move (physics, flocking, fields). When you need connectivity
15 * visualization (topology, paths), use PointCloudNetwork instead.
16 *
17 * Supported operators (motion-based):
18 * - PhysicsOperator: Ballistic motion, gravity, springs, collisions
19 * - FieldOperator: Flow fields, attractors, force fields (future)
20 * - FlockingOperator: Boids, swarm intelligence (future)
21 *
22 * Unsupported operators (connectivity-based):
23 * - TopologyOperator: Technically works, but use PointCloudNetwork
24 * - PathOperator: Makes no semantic sense for particles
25 *
26 * PARAMETER MAPPING:
27 * ==================
28 * External nodes can control motion behavior:
29 *
30 * BROADCAST (one node → all particles):
31 * - "gravity_x/y/z": Gravity components
32 * - "drag": Air resistance coefficient
33 * - "turbulence": Chaos/noise strength
34 * - "interaction_radius": Spatial interaction distance
35 * - "spring_stiffness": Spring force strength
36 *
37 * USAGE:
38 * ======
39 * ```cpp
40 * auto particles = vega.ParticleNetwork(1000);
41 * auto physics = particles->create_operator<PhysicsOperator>();
42 * physics->set_gravity(glm::vec3(0, -9.81, 0));
43 * physics->set_interaction_radius(2.0F);
44 *
45 * // Audio-reactive turbulence
46 * auto chaos = vega.Random() | Audio;
47 * particles->map_parameter("turbulence", chaos, MappingMode::BROADCAST);
48 *
49 * // Runtime switch to field-driven motion
50 * auto field = particles->create_operator<FieldOperator>();
51 * field->add_attractor(glm::vec3(0, 0, 0), 5.0F);
52 * ```
53 */
54class MAYAFLUX_API ParticleNetwork : public NodeNetwork {
55public:
56 //-------------------------------------------------------------------------
57 // Construction
58 //-------------------------------------------------------------------------
59
60 /**
61 * @brief Create particle network with spatial bounds
62 * @param num_particles Number of particles
63 * @param bounds_min Minimum spatial extent
64 * @param bounds_max Maximum spatial extent
65 * @param init_mode Initialization distribution
66 */
68 size_t num_particles,
69 const glm::vec3& bounds_min = glm::vec3(-10.0F),
70 const glm::vec3& bounds_max = glm::vec3(10.0F),
71 Kinesis::SpatialDistribution init_mode = Kinesis::SpatialDistribution::RANDOM_VOLUME);
72
73 //-------------------------------------------------------------------------
74 // NodeNetwork Interface
75 //-------------------------------------------------------------------------
76
77 void initialize() override;
78 void reset() override;
79 void process_batch(unsigned int num_samples) override;
80
81 /**
82 * @brief Reinitialize particle network with new parameters
83 * @param num_particles Number of particles
84 * @param bounds_min Minimum spatial extent
85 * @param bounds_max Maximum spatial extent
86 * @param init_mode Initialization distribution
87 */
88 void reinitialize(
89 size_t num_particles,
90 const glm::vec3& bounds_min,
91 const glm::vec3& bounds_max,
93
94 /**
95 * @brief Get number of particles in network
96 *
97 * Returns total particle count across all internal collections.
98 * For ParticleNetwork, "nodes" ARE particles - each particle is
99 * a mappable entity for parameter control.
100 */
101 [[nodiscard]] size_t get_node_count() const override;
102
103 /**
104 * @brief Get point count (alias for get_node_count)
105 *
106 * Provided for clarity in graphics contexts. For ParticleNetwork,
107 * points and nodes are the same concept.
108 */
109 [[nodiscard]] size_t get_point_count() const { return get_node_count(); }
110
111 /**
112 * @brief Get output value for specific particle
113 * @param index Particle index (0 to get_node_count()-1)
114 *
115 * Returns per-particle output (e.g., velocity magnitude).
116 * Used for ONE_TO_ONE parameter mapping from this network
117 * to other networks.
118 */
119 [[nodiscard]] std::optional<double> get_node_output(size_t index) const override;
120
121 [[nodiscard]] std::unordered_map<std::string, std::string> get_metadata() const override;
122
123 //-------------------------------------------------------------------------
124 // Operator Management
125 //-------------------------------------------------------------------------
126
127 /**
128 * @brief Set active operator (runtime switching)
129 */
130 void set_operator(std::unique_ptr<NetworkOperator> op);
131
132 /**
133 * @brief Create and set operator in one call
134 */
135 template <typename OpType, typename... Args>
136 OpType* create_operator(Args&&... args)
137 {
138 auto op = std::make_unique<OpType>(std::forward<Args>(args)...);
139 auto* ptr = op.get();
140 set_operator(std::move(op));
141 return ptr;
142 }
143
144 /**
145 * @brief Get current operator with type-safe cast
146 */
147 template <typename OpType>
148 OpType* as_operator()
149 {
150 return dynamic_cast<OpType*>(m_operator.get());
151 }
152
153 template <typename OpType>
154 const OpType* as_operator() const
155 {
156 return dynamic_cast<const OpType*>(m_operator.get());
157 }
158
159 NetworkOperator* get_operator() override { return m_operator.get(); }
160 const NetworkOperator* get_operator() const override { return m_operator.get(); }
161 bool has_operator() const override { return m_operator != nullptr; }
162
163 //-------------------------------------------------------------------------
164 // Configuration
165 //-------------------------------------------------------------------------
166
167 void set_timestep(float dt) { m_timestep = dt; }
168 float get_timestep() const { return m_timestep; }
169
170 void set_bounds(const glm::vec3& min, const glm::vec3& max)
171 {
172 m_bounds = Kinesis::SamplerBounds(min, max);
173 }
174
175 Kinesis::SamplerBounds get_bounds() const { return m_bounds; }
176
177 void set_topology(Topology topology) override;
178
179 //-------------------------------------------------------------------------
180 // Parameter Mapping (Delegates to Operator)
181 //-------------------------------------------------------------------------
182
183 void map_parameter(
184 const std::string& param_name,
185 const std::shared_ptr<Node>& source,
186 MappingMode mode = MappingMode::BROADCAST) override;
187
188 void unmap_parameter(const std::string& param_name) override;
189
190private:
191 std::unique_ptr<NetworkOperator> m_operator;
193
195 // glm::vec3 m_bounds_min;
196 // glm::vec3 m_bounds_max;
199 float m_timestep { 0.016F };
200
201 void ensure_initialized();
202 std::vector<PointVertex> generate_initial_vertices();
203 PointVertex generate_single_vertex(Kinesis::SpatialDistribution mode, size_t index, size_t total);
204
205 //-------------------------------------------------------------------------
206 // Parameter Mapping Helpers
207 //-------------------------------------------------------------------------
208
209 /**
210 * @brief Update mapped parameters before physics step
211 */
212 void update_mapped_parameters();
213};
214
215} // namespace MayaFlux::Nodes::Network
Unified generative infrastructure for stochastic and procedural algorithms.
Domain-agnostic interpretive lens for network processing.
Abstract base class for structured collections of nodes with defined relationships.
size_t get_point_count() const
Get point count (alias for get_node_count)
Kinesis::Stochastic::Stochastic m_random_gen
Kinesis::SamplerBounds get_bounds() const
NetworkOperator * get_operator() override
OpType * create_operator(Args &&... args)
Create and set operator in one call.
OpType * as_operator()
Get current operator with type-safe cast.
const NetworkOperator * get_operator() const override
std::unique_ptr< NetworkOperator > m_operator
void set_bounds(const glm::vec3 &min, const glm::vec3 &max)
Motion-focused point network with swappable operators.
void initialize()
Definition main.cpp:11
SpatialDistribution
Spatial distribution mode for point cloud and particle generation.
Topology
Defines the structural relationships between nodes in the network.
MappingMode
Defines how nodes map to external entities (e.g., audio channels, graphics objects)
Spatial domain for vertex generation.