diff options
author | Jacques Lucke <mail@jlucke.com> | 2019-07-29 14:30:55 +0300 |
---|---|---|
committer | Jacques Lucke <mail@jlucke.com> | 2019-07-29 14:30:55 +0300 |
commit | f2d3539cb56bfd095b94ebb0966b72f39dfb85c1 (patch) | |
tree | f0998348acb9cc5ba81db2a035e18e7e4e0a71e4 /source/blender | |
parent | dbc453f414cc57f18e65ad623b2e525d397c2c70 (diff) |
new particle function input providers abstraction
Diffstat (limited to 'source/blender')
16 files changed, 176 insertions, 120 deletions
diff --git a/source/blender/simulations/bparticles/action_interface.cpp b/source/blender/simulations/bparticles/action_interface.cpp index 1e172d87aa5..07b57cb3483 100644 --- a/source/blender/simulations/bparticles/action_interface.cpp +++ b/source/blender/simulations/bparticles/action_interface.cpp @@ -2,6 +2,10 @@ namespace BParticles { +ActionContext::~ActionContext() +{ +} + Action::~Action() { } diff --git a/source/blender/simulations/bparticles/action_interface.hpp b/source/blender/simulations/bparticles/action_interface.hpp index 989b2eba555..2ea5b7da668 100644 --- a/source/blender/simulations/bparticles/action_interface.hpp +++ b/source/blender/simulations/bparticles/action_interface.hpp @@ -13,18 +13,7 @@ using FN::TupleCallBody; class ActionContext { public: - struct ContextArray { - void *buffer = nullptr; - uint stride = 0; - - ContextArray() = default; - template<typename T> - ContextArray(ArrayRef<T> array) : buffer((void *)array.begin()), stride(sizeof(T)) - { - } - }; - - virtual ContextArray get_context_array(StringRef name) = 0; + virtual ~ActionContext(); }; class ActionInterface { @@ -93,10 +82,6 @@ inline ActionInterface::ActionInterface(ParticleAllocator &particle_allocator, } class EmptyEventInfo : public ActionContext { - ContextArray get_context_array(StringRef UNUSED(name)) - { - return {}; - } }; inline void Action::execute_from_emitter(ParticleSets &particle_sets, diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp index 17d8cc3777e..1a633f1e643 100644 --- a/source/blender/simulations/bparticles/actions.cpp +++ b/source/blender/simulations/bparticles/actions.cpp @@ -15,7 +15,7 @@ void ChangeDirectionAction::execute(ActionInterface &interface) auto position_offsets = interface.attribute_offsets().try_get_float3("Position"); auto velocity_offsets = interface.attribute_offsets().try_get_float3("Velocity"); - auto inputs = m_compute_inputs.compute(interface); + auto inputs = m_compute_inputs->compute(interface); for (uint pindex : particles.pindices()) { float3 direction = inputs->get<float3>("Direction", 0, pindex); @@ -60,7 +60,7 @@ void ExplodeAction::execute(ActionInterface &interface) Vector<float3> new_velocities; Vector<float> new_birth_times; - auto inputs = m_compute_inputs.compute(interface); + auto inputs = m_compute_inputs->compute(interface); for (uint pindex : particles.pindices()) { uint parts_amount = std::max(0, inputs->get<int>("Amount", 0, pindex)); @@ -88,7 +88,7 @@ void ConditionAction::execute(ActionInterface &interface) { ParticleSet particles = interface.particles(); - auto inputs = m_compute_inputs.compute(interface); + auto inputs = m_compute_inputs->compute(interface); Vector<uint> true_pindices, false_pindices; for (uint pindex : particles.pindices()) { diff --git a/source/blender/simulations/bparticles/actions.hpp b/source/blender/simulations/bparticles/actions.hpp index 088ca8e1498..40656929120 100644 --- a/source/blender/simulations/bparticles/actions.hpp +++ b/source/blender/simulations/bparticles/actions.hpp @@ -15,11 +15,12 @@ class KillAction : public Action { class ChangeDirectionAction : public Action { private: - ParticleFunction m_compute_inputs; + std::unique_ptr<ParticleFunction> m_compute_inputs; std::unique_ptr<Action> m_post_action; public: - ChangeDirectionAction(ParticleFunction compute_inputs, std::unique_ptr<Action> post_action) + ChangeDirectionAction(std::unique_ptr<ParticleFunction> compute_inputs, + std::unique_ptr<Action> post_action) : m_compute_inputs(std::move(compute_inputs)), m_post_action(std::move(post_action)) { } @@ -30,12 +31,12 @@ class ChangeDirectionAction : public Action { class ExplodeAction : public Action { private: std::string m_new_particle_name; - ParticleFunction m_compute_inputs; + std::unique_ptr<ParticleFunction> m_compute_inputs; std::unique_ptr<Action> m_post_action; public: ExplodeAction(StringRef new_particle_name, - ParticleFunction compute_inputs, + std::unique_ptr<ParticleFunction> compute_inputs, std::unique_ptr<Action> post_action) : m_new_particle_name(new_particle_name.to_std_string()), m_compute_inputs(std::move(compute_inputs)), @@ -48,11 +49,11 @@ class ExplodeAction : public Action { class ConditionAction : public Action { private: - ParticleFunction m_compute_inputs; + std::unique_ptr<ParticleFunction> m_compute_inputs; std::unique_ptr<Action> m_true_action, m_false_action; public: - ConditionAction(ParticleFunction compute_inputs, + ConditionAction(std::unique_ptr<ParticleFunction> compute_inputs, std::unique_ptr<Action> true_action, std::unique_ptr<Action> false_action) : m_compute_inputs(std::move(compute_inputs)), diff --git a/source/blender/simulations/bparticles/events.cpp b/source/blender/simulations/bparticles/events.cpp index f1fa082c1df..30c6d9c83ef 100644 --- a/source/blender/simulations/bparticles/events.cpp +++ b/source/blender/simulations/bparticles/events.cpp @@ -18,7 +18,7 @@ void AgeReachedEvent::filter(EventFilterInterface &interface) float end_time = interface.end_time(); - auto inputs = m_compute_inputs.compute(interface); + auto inputs = m_compute_inputs->compute(interface); for (uint pindex : particles.pindices()) { if (was_activated_before[pindex]) { diff --git a/source/blender/simulations/bparticles/events.hpp b/source/blender/simulations/bparticles/events.hpp index b4a2ea659a5..58793741f59 100644 --- a/source/blender/simulations/bparticles/events.hpp +++ b/source/blender/simulations/bparticles/events.hpp @@ -19,12 +19,12 @@ using BLI::float4x4; class AgeReachedEvent : public Event { private: std::string m_identifier; - ParticleFunction m_compute_inputs; + std::unique_ptr<ParticleFunction> m_compute_inputs; std::unique_ptr<Action> m_action; public: AgeReachedEvent(StringRef identifier, - ParticleFunction compute_inputs, + std::unique_ptr<ParticleFunction> compute_inputs, std::unique_ptr<Action> action) : m_identifier(identifier.to_std_string()), m_compute_inputs(std::move(compute_inputs)), @@ -46,12 +46,9 @@ class CollisionEventInfo : public ActionContext { { } - ContextArray get_context_array(StringRef name) override + ArrayRef<float3> normals() { - if (name == "Normal") { - return m_normals; - } - return {}; + return m_normals; } }; diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp index f28fb478785..d5b8a9d3c9a 100644 --- a/source/blender/simulations/bparticles/forces.cpp +++ b/source/blender/simulations/bparticles/forces.cpp @@ -13,7 +13,7 @@ void GravityForce::add_force(ForceInterface &interface) ParticlesBlock &block = interface.block(); ArrayRef<float3> destination = interface.combined_destination(); - auto inputs = m_compute_inputs.compute(interface); + auto inputs = m_compute_inputs->compute(interface); for (uint pindex = 0; pindex < block.active_amount(); pindex++) { float3 acceleration = inputs->get<float3>("Direction", 0, pindex); @@ -28,7 +28,7 @@ void TurbulenceForce::add_force(ForceInterface &interface) auto positions = block.attributes().get_float3("Position"); - auto inputs = m_compute_inputs.compute(interface); + auto inputs = m_compute_inputs->compute(interface); for (uint pindex = 0; pindex < block.active_amount(); pindex++) { float3 pos = positions[pindex]; diff --git a/source/blender/simulations/bparticles/forces.hpp b/source/blender/simulations/bparticles/forces.hpp index 83807f26cee..1806713752d 100644 --- a/source/blender/simulations/bparticles/forces.hpp +++ b/source/blender/simulations/bparticles/forces.hpp @@ -14,10 +14,11 @@ class Force { class GravityForce : public Force { private: - ParticleFunction m_compute_inputs; + std::unique_ptr<ParticleFunction> m_compute_inputs; public: - GravityForce(ParticleFunction compute_inputs) : m_compute_inputs(std::move(compute_inputs)) + GravityForce(std::unique_ptr<ParticleFunction> compute_inputs) + : m_compute_inputs(std::move(compute_inputs)) { } @@ -26,10 +27,11 @@ class GravityForce : public Force { class TurbulenceForce : public Force { private: - ParticleFunction m_compute_inputs; + std::unique_ptr<ParticleFunction> m_compute_inputs; public: - TurbulenceForce(ParticleFunction compute_inputs) : m_compute_inputs(std::move(compute_inputs)) + TurbulenceForce(std::unique_ptr<ParticleFunction> compute_inputs) + : m_compute_inputs(std::move(compute_inputs)) { } diff --git a/source/blender/simulations/bparticles/inserters.cpp b/source/blender/simulations/bparticles/inserters.cpp index dc9d74b1773..8f8ffda95ee 100644 --- a/source/blender/simulations/bparticles/inserters.cpp +++ b/source/blender/simulations/bparticles/inserters.cpp @@ -50,20 +50,22 @@ using ActionFromNodeCallback = std::function<std::unique_ptr<Action>(BuildContext &ctx, VirtualSocket *start, VirtualSocket *trigger, - ParticleFunction compute_inputs_fn)>; + std::unique_ptr<ParticleFunction> compute_inputs_fn)>; -static std::unique_ptr<Action> BUILD_ACTION_kill(BuildContext &UNUSED(ctx), - VirtualSocket *UNUSED(start), - VirtualSocket *UNUSED(trigger), - ParticleFunction UNUSED(compute_inputs_fn)) +static std::unique_ptr<Action> BUILD_ACTION_kill( + BuildContext &UNUSED(ctx), + VirtualSocket *UNUSED(start), + VirtualSocket *UNUSED(trigger), + std::unique_ptr<ParticleFunction> UNUSED(compute_inputs_fn)) { return std::unique_ptr<Action>(new KillAction()); } -static std::unique_ptr<Action> BUILD_ACTION_change_direction(BuildContext &ctx, - VirtualSocket *start, - VirtualSocket *trigger, - ParticleFunction compute_inputs_fn) +static std::unique_ptr<Action> BUILD_ACTION_change_direction( + BuildContext &ctx, + VirtualSocket *start, + VirtualSocket *trigger, + std::unique_ptr<ParticleFunction> compute_inputs_fn) { VirtualNode *vnode = start->vnode(); auto post_action = build_action(ctx, vnode->output(0), trigger); @@ -72,10 +74,11 @@ static std::unique_ptr<Action> BUILD_ACTION_change_direction(BuildContext &ctx, new ChangeDirectionAction(std::move(compute_inputs_fn), std::move(post_action))); } -static std::unique_ptr<Action> BUILD_ACTION_explode(BuildContext &ctx, - VirtualSocket *start, - VirtualSocket *trigger, - ParticleFunction compute_inputs_fn) +static std::unique_ptr<Action> BUILD_ACTION_explode( + BuildContext &ctx, + VirtualSocket *start, + VirtualSocket *trigger, + std::unique_ptr<ParticleFunction> compute_inputs_fn) { VirtualNode *vnode = start->vnode(); @@ -94,10 +97,11 @@ static std::unique_ptr<Action> BUILD_ACTION_explode(BuildContext &ctx, } } -static std::unique_ptr<Action> BUILD_ACTION_condition(BuildContext &ctx, - VirtualSocket *start, - VirtualSocket *trigger, - ParticleFunction compute_inputs_fn) +static std::unique_ptr<Action> BUILD_ACTION_condition( + BuildContext &ctx, + VirtualSocket *start, + VirtualSocket *trigger, + std::unique_ptr<ParticleFunction> compute_inputs_fn) { VirtualNode *vnode = start->vnode(); auto true_action = build_action(ctx, vnode->output(0), trigger); @@ -144,8 +148,7 @@ static std::unique_ptr<Action> build_action(BuildContext &ctx, StringRef idname = start->vnode()->idname(); auto builders = get_action_builders(); - return builders.lookup(idname)( - ctx, start, trigger, ParticleFunction(fn_or_error.extract_value())); + return builders.lookup(idname)(ctx, start, trigger, fn_or_error.extract_value()); } static std::unique_ptr<Action> build_action_for_trigger(BuildContext &ctx, VirtualSocket *start) @@ -153,22 +156,26 @@ static std::unique_ptr<Action> build_action_for_trigger(BuildContext &ctx, Virtu return build_action(ctx, start, start); } -static std::unique_ptr<Force> BUILD_FORCE_gravity(BuildContext &UNUSED(ctx), - VirtualNode *UNUSED(vnode), - ParticleFunction compute_inputs_fn) +static std::unique_ptr<Force> BUILD_FORCE_gravity( + BuildContext &UNUSED(ctx), + VirtualNode *UNUSED(vnode), + std::unique_ptr<ParticleFunction> compute_inputs_fn) { return std::unique_ptr<Force>(new GravityForce(std::move(compute_inputs_fn))); } -static std::unique_ptr<Force> BUILD_FORCE_turbulence(BuildContext &UNUSED(ctx), - VirtualNode *UNUSED(vnode), - ParticleFunction compute_inputs_fn) +static std::unique_ptr<Force> BUILD_FORCE_turbulence( + BuildContext &UNUSED(ctx), + VirtualNode *UNUSED(vnode), + std::unique_ptr<ParticleFunction> compute_inputs_fn) { return std::unique_ptr<Force>(new TurbulenceForce(std::move(compute_inputs_fn))); } static std::unique_ptr<Event> BUILD_EVENT_mesh_collision( - BuildContext &ctx, VirtualNode *vnode, ParticleFunction UNUSED(compute_inputs_fn)) + BuildContext &ctx, + VirtualNode *vnode, + std::unique_ptr<ParticleFunction> UNUSED(compute_inputs_fn)) { PointerRNA rna = vnode->rna(); Object *object = (Object *)RNA_pointer_get(&rna, "object").id.data; @@ -180,26 +187,24 @@ static std::unique_ptr<Event> BUILD_EVENT_mesh_collision( return std::unique_ptr<Event>(new MeshCollisionEvent(vnode->name(), object, std::move(action))); } -static std::unique_ptr<Event> BUILD_EVENT_age_reached(BuildContext &ctx, - VirtualNode *vnode, - ParticleFunction compute_inputs_fn) +static std::unique_ptr<Event> BUILD_EVENT_age_reached( + BuildContext &ctx, VirtualNode *vnode, std::unique_ptr<ParticleFunction> compute_inputs_fn) { auto action = build_action_for_trigger(ctx, vnode->output(0)); return std::unique_ptr<Event>( new AgeReachedEvent(vnode->name(), std::move(compute_inputs_fn), std::move(action))); } -static std::unique_ptr<Event> BUILD_EVENT_close_by_points(BuildContext &ctx, - VirtualNode *vnode, - ParticleFunction compute_inputs) +static std::unique_ptr<Event> BUILD_EVENT_close_by_points( + BuildContext &ctx, VirtualNode *vnode, std::unique_ptr<ParticleFunction> compute_inputs) { - if (compute_inputs.parameter_depends_on_particle("Points", 0)) { + if (compute_inputs->parameter_depends_on_particle("Points", 0)) { return {}; } auto action = build_action_for_trigger(ctx, vnode->output(0)); - SharedFunction &fn = compute_inputs.function_no_deps(); + SharedFunction &fn = compute_inputs->function_no_deps(); BLI_assert(fn->input_amount() == 0); TupleCallBody &body = fn->body<TupleCallBody>(); FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); @@ -381,7 +386,7 @@ static std::unique_ptr<Emitter> BUILD_EMITTER_initial_grid(BuildContext &ctx, } static std::unique_ptr<OffsetHandler> BUILD_OFFSET_HANDLER_trails( - BuildContext &ctx, VirtualNode *vnode, ParticleFunction compute_inputs_fn) + BuildContext &ctx, VirtualNode *vnode, std::unique_ptr<ParticleFunction> compute_inputs_fn) { PointerRNA rna = vnode->rna(); char name[65]; diff --git a/source/blender/simulations/bparticles/inserters.hpp b/source/blender/simulations/bparticles/inserters.hpp index d7349382f55..16d58341109 100644 --- a/source/blender/simulations/bparticles/inserters.hpp +++ b/source/blender/simulations/bparticles/inserters.hpp @@ -37,16 +37,16 @@ struct BuildContext { }; using ForceFromNodeCallback = std::function<std::unique_ptr<Force>( - BuildContext &ctx, VirtualNode *vnode, ParticleFunction compute_inputs_fn)>; + BuildContext &ctx, VirtualNode *vnode, std::unique_ptr<ParticleFunction> compute_inputs_fn)>; using EventFromNodeCallback = std::function<std::unique_ptr<Event>( - BuildContext &ctx, VirtualNode *vnode, ParticleFunction compute_inputs_fn)>; + BuildContext &ctx, VirtualNode *vnode, std::unique_ptr<ParticleFunction> compute_inputs_fn)>; using EmitterFromNodeCallback = std::function<std::unique_ptr<Emitter>( BuildContext &ctx, VirtualNode *vnode, StringRef particle_type_name)>; using OffsetHandlerFromNodeCallback = std::function<std::unique_ptr<OffsetHandler>( - BuildContext &ctx, VirtualNode *vnode, ParticleFunction compute_inputs_fn)>; + BuildContext &ctx, VirtualNode *vnode, std::unique_ptr<ParticleFunction> compute_inputs_fn)>; StringMap<ForceFromNodeCallback> &get_force_builders(); StringMap<EventFromNodeCallback> &get_event_builders(); diff --git a/source/blender/simulations/bparticles/offset_handlers.cpp b/source/blender/simulations/bparticles/offset_handlers.cpp index c9aee57a7f1..697bd2aea68 100644 --- a/source/blender/simulations/bparticles/offset_handlers.cpp +++ b/source/blender/simulations/bparticles/offset_handlers.cpp @@ -8,7 +8,7 @@ void CreateTrailHandler::execute(OffsetHandlerInterface &interface) auto positions = particles.attributes().get_float3("Position"); auto position_offsets = interface.offsets().get_float3("Position"); - auto inputs = m_compute_inputs.compute(interface); + auto inputs = m_compute_inputs->compute(interface); Vector<float3> new_positions; Vector<float> new_birth_times; diff --git a/source/blender/simulations/bparticles/offset_handlers.hpp b/source/blender/simulations/bparticles/offset_handlers.hpp index 932bc9703b7..fb745255ffd 100644 --- a/source/blender/simulations/bparticles/offset_handlers.hpp +++ b/source/blender/simulations/bparticles/offset_handlers.hpp @@ -8,10 +8,11 @@ namespace BParticles { class CreateTrailHandler : public OffsetHandler { private: std::string m_particle_type_name; - ParticleFunction m_compute_inputs; + std::unique_ptr<ParticleFunction> m_compute_inputs; public: - CreateTrailHandler(StringRef particle_type_name, ParticleFunction compute_inputs) + CreateTrailHandler(StringRef particle_type_name, + std::unique_ptr<ParticleFunction> compute_inputs) : m_particle_type_name(particle_type_name.to_std_string()), m_compute_inputs(std::move(compute_inputs)) { diff --git a/source/blender/simulations/bparticles/particle_function.cpp b/source/blender/simulations/bparticles/particle_function.cpp index 98f664d6957..cf9ff7a1b96 100644 --- a/source/blender/simulations/bparticles/particle_function.cpp +++ b/source/blender/simulations/bparticles/particle_function.cpp @@ -2,11 +2,17 @@ namespace BParticles { +ParticleFunctionInputProvider::~ParticleFunctionInputProvider() +{ +} + ParticleFunction::ParticleFunction(SharedFunction fn_no_deps, SharedFunction fn_with_deps, + Vector<ParticleFunctionInputProvider *> input_providers, Vector<bool> parameter_depends_on_particle) : m_fn_no_deps(std::move(fn_no_deps)), m_fn_with_deps(std::move(fn_with_deps)), + m_input_providers(std::move(input_providers)), m_parameter_depends_on_particle(std::move(parameter_depends_on_particle)) { BLI_assert(m_fn_no_deps->output_amount() + m_fn_with_deps->output_amount() == @@ -27,6 +33,13 @@ ParticleFunction::ParticleFunction(SharedFunction fn_no_deps, } } +ParticleFunction::~ParticleFunction() +{ + for (auto *provider : m_input_providers) { + delete provider; + } +} + std::unique_ptr<ParticleFunctionResult> ParticleFunction::compute(ActionInterface &interface) { return this->compute(interface.array_allocator(), @@ -131,28 +144,13 @@ void ParticleFunction::init_with_deps(ParticleFunctionResult *result, Vector<uint> input_strides; for (uint i = 0; i < m_fn_with_deps->input_amount(); i++) { - StringRef input_name = m_fn_with_deps->input_name(i); - void *input_buffer = nullptr; - uint input_stride = 0; - if (input_name.startswith("Attribute")) { - StringRef attribute_name = input_name.drop_prefix("Attribute: "); - uint attribute_index = attributes.attribute_index(attribute_name); - input_buffer = attributes.get_ptr(attribute_index); - input_stride = attributes.attribute_stride(attribute_index); - } - else if (action_context != nullptr && input_name.startswith("Action Context")) { - StringRef context_name = input_name.drop_prefix("Action Context: "); - ActionContext::ContextArray array = action_context->get_context_array(context_name); - input_buffer = array.buffer; - input_stride = array.stride; - } - else { - BLI_assert(false); - } - BLI_assert(input_buffer != nullptr); + auto *provider = m_input_providers[i]; + auto array = provider->get(attributes, action_context); + BLI_assert(array.buffer != nullptr); + BLI_assert(array.stride > 0); - input_buffers.append(input_buffer); - input_strides.append(input_stride); + input_buffers.append(array.buffer); + input_strides.append(array.stride); } Vector<void *> output_buffers; diff --git a/source/blender/simulations/bparticles/particle_function.hpp b/source/blender/simulations/bparticles/particle_function.hpp index 636c9df0413..9ac8684c3f9 100644 --- a/source/blender/simulations/bparticles/particle_function.hpp +++ b/source/blender/simulations/bparticles/particle_function.hpp @@ -68,18 +68,44 @@ class ParticleFunctionResult { } }; +struct ParticleFunctionInputArray { + void *buffer = nullptr; + uint stride = 0; + + ParticleFunctionInputArray(void *buffer, uint stride) : buffer(buffer), stride(stride) + { + } + + template<typename T> + ParticleFunctionInputArray(ArrayRef<T> array) : buffer((void *)array.begin()), stride(sizeof(T)) + { + } +}; + +class ParticleFunctionInputProvider { + public: + virtual ~ParticleFunctionInputProvider(); + + virtual ParticleFunctionInputArray get(AttributeArrays attributes, + ActionContext *action_context) = 0; +}; + class ParticleFunction { private: SharedFunction m_fn_no_deps; SharedFunction m_fn_with_deps; + Vector<ParticleFunctionInputProvider *> m_input_providers; Vector<bool> m_parameter_depends_on_particle; Vector<uint> m_output_indices; public: ParticleFunction(SharedFunction fn_no_deps, SharedFunction fn_with_deps, + Vector<ParticleFunctionInputProvider *> input_providers, Vector<bool> parameter_depends_on_particle); + ~ParticleFunction(); + SharedFunction &function_no_deps() { return m_fn_no_deps; diff --git a/source/blender/simulations/bparticles/particle_function_builder.cpp b/source/blender/simulations/bparticles/particle_function_builder.cpp index 6345cbefe79..f682de9e810 100644 --- a/source/blender/simulations/bparticles/particle_function_builder.cpp +++ b/source/blender/simulations/bparticles/particle_function_builder.cpp @@ -1,5 +1,7 @@ #include "particle_function_builder.hpp" +#include "events.hpp" + namespace BParticles { using BKE::VirtualSocket; @@ -47,32 +49,63 @@ static SocketDependencies find_particle_dependencies(VTreeDataGraph &data_graph, return combined_dependencies; } -static SharedFunction create_function__with_deps(SharedDataFlowGraph &graph, - StringRef function_name, - ArrayRef<DFGraphSocket> sockets_to_compute, - SocketDependencies &dependencies) +class AttributeInputProvider : public ParticleFunctionInputProvider { + private: + std::string m_name; + + public: + AttributeInputProvider(StringRef name) : m_name(name.to_std_string()) + { + } + + ParticleFunctionInputArray get(AttributeArrays attributes, + ActionContext *UNUSED(action_context)) override + { + uint attribute_index = attributes.attribute_index(m_name); + uint stride = attributes.attribute_stride(attribute_index); + void *buffer = attributes.get_ptr(attribute_index); + return {buffer, stride}; + } +}; + +class CollisionNormalInputProvider : public ParticleFunctionInputProvider { + ParticleFunctionInputArray get(AttributeArrays UNUSED(attributes), + ActionContext *action_context) override + { + BLI_assert(action_context != nullptr); + CollisionEventInfo *collision_info = dynamic_cast<CollisionEventInfo *>(action_context); + BLI_assert(collision_info != nullptr); + return collision_info->normals(); + } +}; + +static SharedFunction create_function__with_deps( + SharedDataFlowGraph &graph, + StringRef function_name, + ArrayRef<DFGraphSocket> sockets_to_compute, + SocketDependencies &dependencies, + ArrayRef<ParticleFunctionInputProvider *> r_input_providers) { + uint input_amount = dependencies.sockets.size(); + BLI_assert(input_amount == r_input_providers.size()); + FunctionBuilder fn_builder; + fn_builder.add_inputs(graph, dependencies.sockets); fn_builder.add_outputs(graph, sockets_to_compute); - for (uint i = 0; i < dependencies.sockets.size(); i++) { + for (uint i = 0; i < input_amount; i++) { VirtualSocket *vsocket = dependencies.vsockets[i]; - DFGraphSocket socket = dependencies.sockets[i]; VirtualNode *vnode = vsocket->vnode(); - SharedType &type = graph->type_of_output(socket); - StringRef name_prefix; if (STREQ(vnode->idname(), "bp_ParticleInfoNode")) { - name_prefix = "Attribute: "; + r_input_providers[i] = new AttributeInputProvider(vsocket->name()); } else if (STREQ(vnode->idname(), "bp_CollisionInfoNode")) { - name_prefix = "Action Context: "; + r_input_providers[i] = new CollisionNormalInputProvider(); } else { BLI_assert(false); } - BLI_STRINGREF_STACK_COMBINE(name, name_prefix, vsocket->name()); - fn_builder.add_input(name, type); } SharedFunction fn = fn_builder.build(function_name); @@ -94,7 +127,7 @@ static SharedFunction create_function__without_deps(SharedDataFlowGraph &graph, return fn; } -static ValueOrError<ParticleFunction> create_particle_function_from_sockets( +static ValueOrError<std::unique_ptr<ParticleFunction>> create_particle_function_from_sockets( SharedDataFlowGraph &graph, StringRef name, ArrayRef<DFGraphSocket> sockets_to_compute, @@ -112,16 +145,20 @@ static ValueOrError<ParticleFunction> create_particle_function_from_sockets( } } + Vector<ParticleFunctionInputProvider *> input_providers(dependencies.sockets.size(), nullptr); + SharedFunction fn_without_deps = create_function__without_deps( graph, name, sockets_without_deps); SharedFunction fn_with_deps = create_function__with_deps( - graph, name, sockets_with_deps, dependencies); + graph, name, sockets_with_deps, dependencies, input_providers); - return ParticleFunction(fn_without_deps, fn_with_deps, depends_on_particle_flags); + ParticleFunction *particle_fn = new ParticleFunction( + fn_without_deps, fn_with_deps, input_providers, depends_on_particle_flags); + return std::unique_ptr<ParticleFunction>(particle_fn); } -ValueOrError<ParticleFunction> create_particle_function(VirtualNode *vnode, - VTreeDataGraph &data_graph) +ValueOrError<std::unique_ptr<ParticleFunction>> create_particle_function( + VirtualNode *vnode, VTreeDataGraph &data_graph) { Vector<DFGraphSocket> sockets_to_compute = find_input_data_sockets(vnode, data_graph); Vector<bool> depends_on_particle_flags(sockets_to_compute.size()); diff --git a/source/blender/simulations/bparticles/particle_function_builder.hpp b/source/blender/simulations/bparticles/particle_function_builder.hpp index c0a34c88062..7512346011c 100644 --- a/source/blender/simulations/bparticles/particle_function_builder.hpp +++ b/source/blender/simulations/bparticles/particle_function_builder.hpp @@ -14,7 +14,7 @@ using FN::DataFlowNodes::VTreeDataGraph; Vector<DFGraphSocket> find_input_data_sockets(VirtualNode *vnode, VTreeDataGraph &data_graph); -ValueOrError<ParticleFunction> create_particle_function(VirtualNode *vnode, - VTreeDataGraph &data_graph); +ValueOrError<std::unique_ptr<ParticleFunction>> create_particle_function( + VirtualNode *vnode, VTreeDataGraph &data_graph); } // namespace BParticles |