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-18 13:08:36 +0300
committerJacques Lucke <mail@jlucke.com>2019-07-18 13:08:36 +0300
commit7aa22a24a7fea3766cab4e59f46bbca8064ded8d (patch)
tree06b302fda347a6dceba0a5df510340ae1ddea4bb /source/blender
parent4672d7aa83c5e6b2847c92d6c1be20e251bfa33a (diff)
initial forwarding listeners + particle trail node
Still looking for a better name instead of Forwarding Listeners
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/simulations/bparticles/core.cpp32
-rw-r--r--source/blender/simulations/bparticles/core.hpp77
-rw-r--r--source/blender/simulations/bparticles/forces.cpp18
-rw-r--r--source/blender/simulations/bparticles/forces.hpp13
-rw-r--r--source/blender/simulations/bparticles/inserters.cpp22
-rw-r--r--source/blender/simulations/bparticles/inserters.hpp5
-rw-r--r--source/blender/simulations/bparticles/node_frontend.cpp15
-rw-r--r--source/blender/simulations/bparticles/simulate.cpp77
-rw-r--r--source/blender/simulations/bparticles/step_description.hpp6
9 files changed, 251 insertions, 14 deletions
diff --git a/source/blender/simulations/bparticles/core.cpp b/source/blender/simulations/bparticles/core.cpp
index e04e0b1bf3b..de3626a44bd 100644
--- a/source/blender/simulations/bparticles/core.cpp
+++ b/source/blender/simulations/bparticles/core.cpp
@@ -14,10 +14,24 @@ Event::~Event()
{
}
+ForwardingListener::~ForwardingListener()
+{
+}
+
ParticleType::~ParticleType()
{
}
+ArrayRef<ForwardingListener *> ParticleType::forwarding_listeners()
+{
+ return {};
+}
+
+ArrayRef<Event *> ParticleType::events()
+{
+ return {};
+}
+
StepDescription::~StepDescription()
{
}
@@ -357,4 +371,22 @@ IntegratorInterface::IntegratorInterface(ParticlesBlock &block,
{
}
+/* ForwardingListenerInterface
+ ****************************************************/
+
+ForwardingListenerInterface::ForwardingListenerInterface(ParticleSet &particles,
+ ParticleAllocator &particle_allocator,
+ AttributeArrays offsets,
+ float step_end_time,
+ ArrayRef<float> durations,
+ ArrayRef<float> time_factors)
+ : m_particles(particles),
+ m_particle_allocator(particle_allocator),
+ m_offsets(offsets),
+ m_step_end_time(step_end_time),
+ m_durations(durations),
+ m_time_factors(time_factors)
+{
+}
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index 70aefdc2ebb..0b12545b1b7 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -25,6 +25,7 @@ class EventFilterInterface;
class EventExecuteInterface;
class EmitterInterface;
class IntegratorInterface;
+class ForwardingListenerInterface;
/* Main API for the particle simulation. These classes have to be subclassed to define how the
* particles should behave.
@@ -118,6 +119,13 @@ class Integrator {
virtual void integrate(IntegratorInterface &interface) = 0;
};
+class ForwardingListener {
+ public:
+ virtual ~ForwardingListener();
+
+ virtual void listen(ForwardingListenerInterface &interface) = 0;
+};
+
/**
* Describes how one type of particle behaves and which attributes it has.
*/
@@ -130,10 +138,12 @@ class ParticleType {
*/
virtual Integrator &integrator() = 0;
+ virtual ArrayRef<ForwardingListener *> forwarding_listeners();
+
/**
* Return the events that particles of this type can trigger.
*/
- virtual ArrayRef<Event *> events() = 0;
+ virtual ArrayRef<Event *> events();
/**
* Allows to define which attributes should exist for the type.
@@ -574,6 +584,32 @@ class IntegratorInterface {
AttributeArrays offset_targets();
};
+class ForwardingListenerInterface {
+ private:
+ ParticleSet m_particles;
+ ParticleAllocator &m_particle_allocator;
+ AttributeArrays m_offsets;
+ float m_step_end_time;
+ ArrayRef<float> m_durations;
+ ArrayRef<float> m_time_factors;
+
+ public:
+ ForwardingListenerInterface(ParticleSet &particles,
+ ParticleAllocator &particle_allocator,
+ AttributeArrays offsets,
+ float step_end_time,
+ ArrayRef<float> durations,
+ ArrayRef<float> time_factors);
+
+ ParticleSet &particles();
+ ParticleAllocator &particle_allocator();
+ AttributeArrays &offsets();
+ ArrayRef<float> time_factors();
+ float step_end_time();
+ ArrayRef<float> durations();
+ TimeSpan time_span(uint pindex);
+};
+
/* Event inline functions
********************************************/
@@ -862,4 +898,43 @@ inline AttributeArrays IntegratorInterface::offset_targets()
return m_offsets;
}
+/* ForwardingListenerInterface inline functions
+ **********************************************/
+
+inline ParticleSet &ForwardingListenerInterface::particles()
+{
+ return m_particles;
+}
+
+inline ParticleAllocator &ForwardingListenerInterface::particle_allocator()
+{
+ return m_particle_allocator;
+}
+
+inline AttributeArrays &ForwardingListenerInterface::offsets()
+{
+ return m_offsets;
+}
+
+inline ArrayRef<float> ForwardingListenerInterface::time_factors()
+{
+ return m_time_factors;
+}
+
+inline float ForwardingListenerInterface::step_end_time()
+{
+ return m_step_end_time;
+}
+
+inline ArrayRef<float> ForwardingListenerInterface::durations()
+{
+ return m_durations;
+}
+
+inline TimeSpan ForwardingListenerInterface::time_span(uint pindex)
+{
+ float duration = m_durations[pindex];
+ return TimeSpan(m_step_end_time - duration, duration);
+}
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp
index 28d00e9355d..7e39e512cd8 100644
--- a/source/blender/simulations/bparticles/forces.cpp
+++ b/source/blender/simulations/bparticles/forces.cpp
@@ -44,4 +44,22 @@ void TurbulenceForce::add_force(ParticlesBlock &block, ArrayRef<float3> r_force)
}
}
+void TrailListener::listen(ForwardingListenerInterface &interface)
+{
+ ParticleSet particles = interface.particles();
+ auto positions = particles.attributes().get_float3("Position");
+
+ SmallVector<float3> new_positions;
+ SmallVector<float> new_birth_times;
+ for (uint pindex : particles.pindices()) {
+ new_positions.append(positions[pindex]);
+ new_birth_times.append(interface.time_span(pindex).start());
+ }
+
+ auto new_particles = interface.particle_allocator().request(m_particle_type_name,
+ new_positions.size());
+ new_particles.set_float3("Position", new_positions);
+ new_particles.set_float("Birth Time", new_birth_times);
+}
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/forces.hpp b/source/blender/simulations/bparticles/forces.hpp
index 074bef42e71..f9c3b21ed5c 100644
--- a/source/blender/simulations/bparticles/forces.hpp
+++ b/source/blender/simulations/bparticles/forces.hpp
@@ -40,4 +40,17 @@ class TurbulenceForce : public Force {
void add_force(ParticlesBlock &block, ArrayRef<float3> r_force) override;
};
+class TrailListener : public ForwardingListener {
+ private:
+ std::string m_particle_type_name;
+
+ public:
+ TrailListener(StringRef particle_type_name)
+ : m_particle_type_name(particle_type_name.to_std_string())
+ {
+ }
+
+ void listen(ForwardingListenerInterface &interface) override;
+};
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/inserters.cpp b/source/blender/simulations/bparticles/inserters.cpp
index 3b30e5c2283..7ca19b297f7 100644
--- a/source/blender/simulations/bparticles/inserters.cpp
+++ b/source/blender/simulations/bparticles/inserters.cpp
@@ -397,6 +397,21 @@ static std::unique_ptr<Emitter> BUILD_EMITTER_initial_grid(BuildContext &ctx,
body->get_output<float>(fn_out, 4, "Size")));
}
+static std::unique_ptr<ForwardingListener> BUILD_FORWARDING_LISTENER_trails(BuildContext &ctx,
+ bNode *bnode)
+{
+ PointerRNA rna = ctx.indexed_tree.get_rna(bnode);
+ char name[65];
+ RNA_string_get(&rna, "particle_type_name", name);
+
+ if (ctx.step_description.m_types.contains(name)) {
+ return std::unique_ptr<ForwardingListener>(new TrailListener(name));
+ }
+ else {
+ return {};
+ }
+}
+
BLI_LAZY_INIT(StringMap<ForceFromNodeCallback>, get_force_builders)
{
StringMap<ForceFromNodeCallback> map;
@@ -424,4 +439,11 @@ BLI_LAZY_INIT(StringMap<EmitterFromNodeCallback>, get_emitter_builders)
return map;
}
+BLI_LAZY_INIT(StringMap<ForwardingListenerFromNodeCallback>, get_forwarding_listener_builders)
+{
+ StringMap<ForwardingListenerFromNodeCallback> map;
+ map.add_new("bp_ParticleTrailsNode", BUILD_FORWARDING_LISTENER_trails);
+ return map;
+}
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/inserters.hpp b/source/blender/simulations/bparticles/inserters.hpp
index 4e300513f3e..845a5a961e7 100644
--- a/source/blender/simulations/bparticles/inserters.hpp
+++ b/source/blender/simulations/bparticles/inserters.hpp
@@ -40,4 +40,9 @@ using EmitterFromNodeCallback = std::function<std::unique_ptr<Emitter>(
StringMap<EmitterFromNodeCallback> &get_emitter_builders();
+using ForwardingListenerFromNodeCallback =
+ std::function<std::unique_ptr<ForwardingListener>(BuildContext &ctx, bNode *bnode)>;
+
+StringMap<ForwardingListenerFromNodeCallback> &get_forwarding_listener_builders();
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 70aff0ce7a8..185c61cb535 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -60,6 +60,21 @@ std::unique_ptr<StepDescription> step_description_from_node_tree(IndexedNodeTree
}
}
+ for (auto item : get_forwarding_listener_builders().items()) {
+ for (bNode *bnode : indexed_tree.nodes_with_idname(item.key)) {
+ bNodeSocket *listener_output = bSocketList(bnode->outputs).get(0);
+ for (SocketWithNode linked : indexed_tree.linked(listener_output)) {
+ if (is_particle_type_node(linked.node)) {
+ auto listener = item.value(ctx, bnode);
+ if (listener) {
+ step_description->m_types.lookup_ref(linked.node->name)
+ ->m_forwarding_listeners.append(listener.release());
+ }
+ }
+ }
+ }
+ }
+
for (auto item : get_event_builders().items()) {
for (bNode *bnode : indexed_tree.nodes_with_idname(item.key)) {
bNodeSocket *event_input = bSocketList(bnode->inputs).get(0);
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 771f97d3d47..960b6c2be09 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -68,10 +68,24 @@ BLI_NOINLINE static void find_next_event_per_particle(ParticleSet particles,
}
BLI_NOINLINE static void forward_particles_to_next_event_or_end(
+ ParticleType &particle_type,
+ ParticleAllocator &particle_allocator,
ParticleSet particles,
AttributeArrays attribute_offsets,
+ float step_end_time,
+ ArrayRef<float> remaining_durations,
ArrayRef<float> time_factors_to_next_event)
{
+ ForwardingListenerInterface interface(particles,
+ particle_allocator,
+ attribute_offsets,
+ step_end_time,
+ remaining_durations,
+ time_factors_to_next_event);
+ for (ForwardingListener *listener : particle_type.forwarding_listeners()) {
+ listener->listen(interface);
+ }
+
for (uint attribute_index : attribute_offsets.info().float3_attributes()) {
StringRef name = attribute_offsets.info().name_of(attribute_index);
@@ -187,12 +201,14 @@ BLI_NOINLINE static void execute_events(ParticleAllocator &particle_allocator,
BLI_NOINLINE static void simulate_to_next_event(ArrayAllocator &array_allocator,
ParticleAllocator &particle_allocator,
ParticleSet particles,
+ ParticleType &particle_type,
AttributeArrays attribute_offsets,
ArrayRef<float> remaining_durations,
float end_time,
- ArrayRef<Event *> events,
VectorAdaptor<uint> &r_unfinished_pindices)
{
+ ArrayRef<Event *> events = particle_type.events();
+
ArrayAllocator::Array<int> next_event_indices(array_allocator);
ArrayAllocator::Array<float> time_factors_to_next_event(array_allocator);
ArrayAllocator::Vector<uint> pindices_with_event(array_allocator);
@@ -211,7 +227,13 @@ BLI_NOINLINE static void simulate_to_next_event(ArrayAllocator &array_allocator,
time_factors_to_next_event,
pindices_with_event);
- forward_particles_to_next_event_or_end(particles, attribute_offsets, time_factors_to_next_event);
+ forward_particles_to_next_event_or_end(particle_type,
+ particle_allocator,
+ particles,
+ attribute_offsets,
+ end_time,
+ remaining_durations,
+ time_factors_to_next_event);
update_remaining_attribute_offsets(
pindices_with_event, time_factors_to_next_event, attribute_offsets);
@@ -245,10 +267,10 @@ BLI_NOINLINE static void simulate_with_max_n_events(uint max_events,
ArrayAllocator &array_allocator,
ParticleAllocator &particle_allocator,
ParticlesBlock &block,
+ ParticleType &particle_type,
AttributeArrays attribute_offsets,
ArrayRef<float> remaining_durations,
float end_time,
- ArrayRef<Event *> events,
VectorAdaptor<uint> &r_unfinished_pindices)
{
BLI_assert(array_allocator.array_size() >= block.active_amount());
@@ -263,10 +285,10 @@ BLI_NOINLINE static void simulate_with_max_n_events(uint max_events,
simulate_to_next_event(array_allocator,
particle_allocator,
ParticleSet(block, Range<uint>(0, amount_left).as_array_ref()),
+ particle_type,
attribute_offsets,
remaining_durations,
end_time,
- events,
indices_output);
amount_left = indices_output.size();
}
@@ -278,10 +300,10 @@ BLI_NOINLINE static void simulate_with_max_n_events(uint max_events,
simulate_to_next_event(array_allocator,
particle_allocator,
ParticleSet(block, indices_input),
+ particle_type,
attribute_offsets,
remaining_durations,
end_time,
- events,
indices_output);
amount_left = indices_output.size();
std::swap(indices_A, indices_B);
@@ -320,9 +342,28 @@ BLI_NOINLINE static void add_float3_arrays(ArrayRef<float3> base, ArrayRef<float
}
}
-BLI_NOINLINE static void apply_remaining_offsets(ParticleSet particles,
- AttributeArrays attribute_offsets)
+BLI_NOINLINE static void apply_remaining_offsets(ParticleType &particle_type,
+ ArrayAllocator &array_allocator,
+ ParticleAllocator &particle_allocator,
+ ParticleSet particles,
+ AttributeArrays attribute_offsets,
+ ArrayRef<float> durations,
+ float step_end_time)
{
+ auto listeners = particle_type.forwarding_listeners();
+ if (listeners.size() > 0) {
+ ArrayAllocator::Array<float> time_factors(array_allocator);
+ for (uint pindex : particles.pindices()) {
+ time_factors[pindex] = 1.0f;
+ }
+
+ ForwardingListenerInterface interface(
+ particles, particle_allocator, attribute_offsets, step_end_time, durations, time_factors);
+ for (ForwardingListener *listener : particle_type.forwarding_listeners()) {
+ listener->listen(interface);
+ }
+ }
+
for (uint attribute_index : attribute_offsets.info().float3_attributes()) {
StringRef name = attribute_offsets.info().name_of(attribute_index);
@@ -359,11 +400,15 @@ BLI_NOINLINE static void simulate_block(ArrayAllocator &array_allocator,
IntegratorInterface interface(block, remaining_durations, array_allocator, attribute_offsets);
integrator.integrate(interface);
- ArrayRef<Event *> events = particle_type.events();
-
- if (events.size() == 0) {
+ if (particle_type.events().size() == 0) {
ParticleSet all_particles_in_block(block, block.active_range().as_array_ref());
- apply_remaining_offsets(all_particles_in_block, attribute_offsets);
+ apply_remaining_offsets(particle_type,
+ array_allocator,
+ particle_allocator,
+ all_particles_in_block,
+ attribute_offsets,
+ remaining_durations,
+ end_time);
}
else {
auto indices_array = array_allocator.allocate_scoped<uint>();
@@ -373,16 +418,22 @@ BLI_NOINLINE static void simulate_block(ArrayAllocator &array_allocator,
array_allocator,
particle_allocator,
block,
+ particle_type,
attribute_offsets,
remaining_durations,
end_time,
- events,
unfinished_pindices);
/* Not sure yet, if this really should be done. */
if (unfinished_pindices.size() > 0) {
ParticleSet remaining_particles(block, unfinished_pindices);
- apply_remaining_offsets(remaining_particles, attribute_offsets);
+ apply_remaining_offsets(particle_type,
+ array_allocator,
+ particle_allocator,
+ remaining_particles,
+ attribute_offsets,
+ remaining_durations,
+ end_time);
}
}
diff --git a/source/blender/simulations/bparticles/step_description.hpp b/source/blender/simulations/bparticles/step_description.hpp
index c262f5a3044..4799bef7497 100644
--- a/source/blender/simulations/bparticles/step_description.hpp
+++ b/source/blender/simulations/bparticles/step_description.hpp
@@ -7,6 +7,7 @@ namespace BParticles {
class ModifierParticleType : public ParticleType {
public:
SmallVector<Event *> m_events;
+ SmallVector<ForwardingListener *> m_forwarding_listeners;
Integrator *m_integrator;
~ModifierParticleType()
@@ -23,6 +24,11 @@ class ModifierParticleType : public ParticleType {
return m_events;
}
+ ArrayRef<ForwardingListener *> forwarding_listeners() override
+ {
+ return m_forwarding_listeners;
+ }
+
Integrator &integrator() override
{
return *m_integrator;