23 bool has_field(
const std::shared_ptr<Buffers::VolumeGridBuffer>& volume,
const std::string&
name)
25 const auto names = volume->get_field_names();
26 return std::ranges::find(names,
name) != names.end();
36 const std::weak_ptr<Buffers::VolumeGridBuffer>& owner,
37 const std::shared_ptr<Buffers::VolumeGridBuffer>& volume)
39 const auto held = owner.lock();
40 return held && held != volume;
53 Buffers::ScalarRef resolve_scalar(
54 const std::shared_ptr<Buffers::VolumeGridBuffer>& volume,
55 Buffers::ScalarRef ref,
56 std::string_view fallback,
59 if (ref.name.empty()) {
60 if (fallback.empty()) {
63 ref.name = std::string(fallback);
66 if (owned_elsewhere(ref.owner, volume)) {
70 if (!has_field(volume, ref.name)) {
71 return single_slot ? volume->declare_scratch(ref.name) : volume->declare_scalar(ref.name);
86 Buffers::VectorRef resolve_vector(
87 const std::shared_ptr<Buffers::VolumeGridBuffer>& volume,
88 Buffers::VectorRef ref,
89 std::string_view fallback)
91 if (ref.name.empty()) {
92 if (fallback.empty()) {
95 ref.name = std::string(fallback);
98 if (owned_elsewhere(ref.owner, volume)) {
102 if (!has_field(volume, ref.name)) {
103 return volume->declare_vector(ref.name);
117 if (render.target_window) {
122 "evolve: RenderConfig::target_window is required, there is no default window");
145 const std::shared_ptr<Buffers::VolumeGridBuffer>& volume,
149 config.
pressure = resolve_scalar(volume, config.
pressure,
"pressure",
false);
153 config.
scratch = resolve_vector(volume, config.
scratch,
"scratch");
156 for (
auto& carried : config.
carried) {
157 carried.field = resolve_scalar(volume, carried.field, {},
false);
161 config.
buoyancy->temperature = resolve_scalar(volume, config.
buoyancy->temperature, {},
false);
162 config.
buoyancy->density = resolve_scalar(volume, config.
buoyancy->density, {},
false);
166 [[nodiscard]] std::shared_ptr<Buffers::RelaxationGridBuffer>
build_grid(
169 const std::vector<std::byte>& seed,
170 size_t seed_stride)
const
172 if (!has_target(render)) {
176 auto grid = std::make_shared<Buffers::RelaxationGridBuffer>(config);
179 if (seed_stride != grid->get_cell_stride_bytes()) {
181 "evolve: seed cell is {} bytes but the grid's cell format is {} bytes",
182 seed_stride, grid->get_cell_stride_bytes());
185 grid->seed_state(seed.data(), seed.size());
189 grid->setup_rendering(render);
194 const std::shared_ptr<Buffers::VolumeGridBuffer>& volume,
200 "evolve: null VolumeGridBuffer");
204 if (!has_target(render)) {
212 (void)volume->setup_flow(config);
213 volume->setup_rendering(render);
218 const std::shared_ptr<Nodes::Network::NodeNetwork>&
network,
225 "evolve: null NodeNetwork");
229 if (!has_target(render)) {
233 if (!
network->has_operator()) {
234 auto particles = std::dynamic_pointer_cast<Nodes::Network::ParticleNetwork>(
network);
235 if (particles && particles->default_operator_enabled()) {
243 "evolve: network has no primary GraphicsOperator to read a vertex layout from");
253 "evolve: network already carries a GpuFieldOperator, its SpatialFieldConfig is kept");
262 auto buffer = std::make_shared<Buffers::NetworkGeometryBuffer>(
network);
264 buffer->setup_rendering(render);
270 : m_impl(
std::make_unique<
Impl>())
280std::shared_ptr<Buffers::RelaxationGridBuffer>
Evolve::build_grid(
281 const Buffers::RelaxationGridBuffer::GridConfig& config,
283 const
std::vector<
std::
byte>& seed,
286 return m_impl->
build_grid(config, render, seed, seed_stride);
290 const std::shared_ptr<Buffers::VolumeGridBuffer>& volume,
294 return m_impl->build_flow(volume, flow, render);
298 const std::shared_ptr<Nodes::Network::NodeNetwork>&
network,
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
Core::GlobalNetworkConfig network
std::shared_ptr< NetworkGeometryBuffer > buffer
BufferProcessingChain * chain
bool build_field(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const Nodes::Network::SpatialFieldConfig &spatial, const FieldBinder &bind, const RenderConfig &render)
Create the field operator, bind, register the network and its buffer, and render.
bool build_flow(const std::shared_ptr< Buffers::VolumeGridBuffer > &volume, const Buffers::VolumeGridBuffer::FlowConfig &flow, const RenderConfig &render)
Resolve refs, register, build the flow stages and render a volume.
std::function< void(const std::shared_ptr< Nodes::Network::GpuFieldOperator > &)> FieldBinder
Callable that binds fields on the GpuFieldOperator before it is wired.
std::unique_ptr< Impl > m_impl
Buffers::VKBuffer::RenderConfig RenderConfig
Render target and pipeline overrides, shared by every family.
std::shared_ptr< Buffers::RelaxationGridBuffer > build_grid(const Buffers::RelaxationGridBuffer::GridConfig &config, const RenderConfig &render, const std::vector< std::byte > &seed, size_t seed_stride)
Construct, optionally seed, register and render a relaxation grid.
Sets a system going from a config: state that persists, a rule that advances it every cycle,...
Chain operator that declares Tendency field deformation as a compute shader rather than evaluating it...
Operator that produces GPU-renderable geometry.
N-body physics simulation with point rendering.
@ Init
Engine/subsystem initialization.
@ API
MayaFlux/API Wrapper and convenience functions.
@ VISUAL_RATE
Nodes that process at the visual frame rate.
void register_node_network(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const Nodes::ProcessingToken &token)
Registers a node network with the default engine's node graph manager.
void register_graphics_buffer(const std::shared_ptr< Buffers::VKBuffer > &buffer, Buffers::ProcessingToken token)
Registers a VKBuffer with the default engine's buffer manager.
Main namespace for the Maya Flux audio engine.
Arrangement of a relaxation grid: extent, the update rule, the emit stage that draws it,...
ScalarRef pressure
Required.
VectorRef velocity
Required.
VectorRef scratch
Required only when viscosity is above zero.
float viscosity
Zero omits the diffusion stage entirely.
std::optional< Buoyancy > buoyancy
std::vector< Carried > carried
ScalarRef divergence
Required. Single-slot is correct.
Parameters for the incompressible flow stage arrangement.
void resolve(const std::shared_ptr< Buffers::VolumeGridBuffer > &volume, Buffers::VolumeGridBuffer::FlowConfig &config) const
Fill unresolved refs of a flow config from the volume.
std::shared_ptr< Buffers::RelaxationGridBuffer > build_grid(const Buffers::RelaxationGridBuffer::GridConfig &config, const RenderConfig &render, const std::vector< std::byte > &seed, size_t seed_stride) const
bool build_field(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const Nodes::Network::SpatialFieldConfig &spatial, const FieldBinder &bind, const RenderConfig &render) const
bool build_flow(const std::shared_ptr< Buffers::VolumeGridBuffer > &volume, const Buffers::VolumeGridBuffer::FlowConfig &flow, const RenderConfig &render) const
Wiring sequences behind Evolve.
Declarative configuration for the GPU-side spatial-relational work a GpuFieldOperator can drive beyon...
Unified rendering configuration for graphics buffers.