Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <mail@jlucke.com>2019-07-29 14:30:55 +0300
committerJacques Lucke <mail@jlucke.com>2019-07-29 14:30:55 +0300
commitf2d3539cb56bfd095b94ebb0966b72f39dfb85c1 (patch)
treef0998348acb9cc5ba81db2a035e18e7e4e0a71e4 /source/blender
parentdbc453f414cc57f18e65ad623b2e525d397c2c70 (diff)
new particle function input providers abstraction
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/simulations/bparticles/action_interface.cpp4
-rw-r--r--source/blender/simulations/bparticles/action_interface.hpp17
-rw-r--r--source/blender/simulations/bparticles/actions.cpp6
-rw-r--r--source/blender/simulations/bparticles/actions.hpp13
-rw-r--r--source/blender/simulations/bparticles/events.cpp2
-rw-r--r--source/blender/simulations/bparticles/events.hpp11
-rw-r--r--source/blender/simulations/bparticles/forces.cpp4
-rw-r--r--source/blender/simulations/bparticles/forces.hpp10
-rw-r--r--source/blender/simulations/bparticles/inserters.cpp75
-rw-r--r--source/blender/simulations/bparticles/inserters.hpp6
-rw-r--r--source/blender/simulations/bparticles/offset_handlers.cpp2
-rw-r--r--source/blender/simulations/bparticles/offset_handlers.hpp5
-rw-r--r--source/blender/simulations/bparticles/particle_function.cpp40
-rw-r--r--source/blender/simulations/bparticles/particle_function.hpp26
-rw-r--r--source/blender/simulations/bparticles/particle_function_builder.cpp71
-rw-r--r--source/blender/simulations/bparticles/particle_function_builder.hpp4
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