[Bf-blender-cvs] [278dc870c05] functions: allow event filters to add attributes to a particle type

Jacques Lucke noreply at git.blender.org
Fri Jul 5 17:38:38 CEST 2019


Commit: 278dc870c05d22c500cded6c3ba67cc2cbd883dc
Author: Jacques Lucke
Date:   Fri Jul 5 12:53:37 2019 +0200
Branches: functions
https://developer.blender.org/rB278dc870c05d22c500cded6c3ba67cc2cbd883dc

allow event filters to add attributes to a particle type

===================================================================

M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/events.cpp
M	source/blender/simulations/bparticles/events.hpp

===================================================================

diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index d19e3f1a49a..9cab561c421 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -65,6 +65,39 @@ void BParticles_state_free(BParticlesState state)
   delete unwrap(state);
 }
 
+class EventFilterWithAction : public Event {
+ private:
+  EventFilter *m_filter;
+  Action *m_action;
+
+ public:
+  EventFilterWithAction(EventFilter *filter, Action *action) : m_filter(filter), m_action(action)
+  {
+  }
+
+  ~EventFilterWithAction()
+  {
+    delete m_filter;
+    delete m_action;
+  }
+
+  void filter(EventFilterInterface &interface) override
+  {
+    m_filter->filter(interface);
+  }
+
+  void execute(EventExecuteInterface &interface) override
+  {
+    m_filter->triggered(interface);
+    m_action->execute(interface);
+  }
+
+  EventFilter *get_filter() const
+  {
+    return m_filter;
+  }
+};
+
 class EulerIntegrator : public Integrator {
  private:
   AttributesInfo m_offset_attributes_info;
@@ -163,6 +196,12 @@ class ModifierParticleType : public ParticleType {
   {
     interface.use(AttributeType::Float3, "Position");
     interface.use(AttributeType::Float3, "Velocity");
+
+    for (Event *event : m_events) {
+      EventFilterWithAction *event_action = dynamic_cast<EventFilterWithAction *>(event);
+      BLI_assert(event_action);
+      event_action->get_filter()->attributes(interface);
+    }
   }
 };
 
@@ -310,58 +349,6 @@ static void INSERT_EMITTER_point(bNode *emitter_node,
   }
 }
 
-class EventFilterWithAction : public Event {
- private:
-  EventFilter *m_filter;
-  Action *m_action;
-
- public:
-  EventFilterWithAction(EventFilter *filter, Action *action) : m_filter(filter), m_action(action)
-  {
-  }
-
-  ~EventFilterWithAction()
-  {
-    delete m_filter;
-    delete m_action;
-  }
-
-  void filter(EventFilterInterface &interface) override
-  {
-    m_filter->filter(interface);
-  }
-
-  void execute(EventExecuteInterface &interface) override
-  {
-    m_action->execute(interface);
-  }
-};
-
-class AgeReachedEventFilter : public EventFilter {
- private:
-  FN::SharedFunction m_compute_age_fn;
-
- public:
-  AgeReachedEventFilter(FN::SharedFunction compute_age_fn) : m_compute_age_fn(compute_age_fn)
-  {
-  }
-
-  void filter(EventFilterInterface &interface) override
-  {
-    auto *body = m_compute_age_fn->body<FN::TupleCallBody>();
-    FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out);
-
-    FN::ExecutionStack stack;
-    FN::ExecutionContext execution_context(stack);
-    body->call(fn_in, fn_out, execution_context);
-
-    float age = fn_out.get<float>(0);
-    EventFilter *filter = EVENT_age_reached(age);
-    filter->filter(interface);
-    delete filter;
-  }
-};
-
 static void INSERT_EVENT_age_reached(bNode *event_node,
                                      IndexedNodeTree &indexed_tree,
                                      FN::DataFlowNodes::GeneratedGraph &data_graph,
@@ -372,8 +359,8 @@ static void INSERT_EVENT_age_reached(bNode *event_node,
 
   FN::DFGraphSocket age_input_socket = data_graph.lookup_socket(event_input->next);
   FN::FunctionGraph function_graph(data_graph.graph(), {}, {age_input_socket});
-  FN::SharedFunction compute_age_function = function_graph.new_function("Compute Age");
-  FN::fgraph_add_TupleCallBody(compute_age_function, function_graph);
+  FN::SharedFunction compute_age_fn = function_graph.new_function("Compute Age");
+  FN::fgraph_add_TupleCallBody(compute_age_fn, function_graph);
 
   for (SocketWithNode linked : indexed_tree.linked(event_input)) {
     if (!is_particle_type_node(linked.node)) {
@@ -382,7 +369,7 @@ static void INSERT_EVENT_age_reached(bNode *event_node,
 
     bNode *type_node = linked.node;
 
-    EventFilter *event_filter = new AgeReachedEventFilter(compute_age_function);
+    EventFilter *event_filter = EVENT_age_reached(event_node->name, compute_age_fn);
     Action *action = build_action({(bNodeSocket *)event_node->outputs.first, event_node},
                                   indexed_tree,
                                   data_graph,
diff --git a/source/blender/simulations/bparticles/events.cpp b/source/blender/simulations/bparticles/events.cpp
index fce104ca43d..0ed2c9a3dca 100644
--- a/source/blender/simulations/bparticles/events.cpp
+++ b/source/blender/simulations/bparticles/events.cpp
@@ -12,33 +12,62 @@ EventFilter::~EventFilter()
 
 class AgeReachedEvent : public EventFilter {
  private:
-  float m_age;
+  std::string m_identifier;
+  SharedFunction m_compute_age_fn;
+  TupleCallBody *m_compute_age_body;
 
  public:
-  AgeReachedEvent(float age) : m_age(age)
+  AgeReachedEvent(StringRef identifier, SharedFunction &compute_age_fn)
+      : m_identifier(identifier.to_std_string()), m_compute_age_fn(compute_age_fn)
   {
+    m_compute_age_body = compute_age_fn->body<TupleCallBody>();
+  }
+
+  void attributes(TypeAttributeInterface &interface) override
+  {
+    interface.use(AttributeType::Byte, m_identifier);
   }
 
   void filter(EventFilterInterface &interface) override
   {
     ParticleSet particles = interface.particles();
     auto birth_times = particles.attributes().get_float("Birth Time");
+    auto was_activated_before = particles.attributes().get_byte(m_identifier);
+
     float end_time = interface.end_time();
 
+    FN_TUPLE_CALL_ALLOC_TUPLES(m_compute_age_body, fn_in, fn_out);
+    FN::ExecutionStack stack;
+    FN::ExecutionContext execution_context(stack);
+    m_compute_age_body->call(fn_in, fn_out, execution_context);
+    float trigger_age = fn_out.get<float>(0);
+
     for (uint i : particles.range()) {
       uint pindex = particles.get_particle_index(i);
-      TimeSpan time_span = interface.time_span(i);
+      if (was_activated_before[pindex]) {
+        continue;
+      }
 
       float birth_time = birth_times[pindex];
       float age_at_end = end_time - birth_time;
-      float age_at_start = age_at_end - time_span.duration();
 
-      if (age_at_end >= m_age && age_at_start < m_age) {
-        float time_factor = time_span.get_factor(birth_time + m_age);
+      if (age_at_end >= trigger_age) {
+        TimeSpan time_span = interface.time_span(i);
+        float time_factor = time_span.get_factor(birth_time + trigger_age);
         interface.trigger_particle(i, time_factor);
       }
     }
   }
+
+  void triggered(EventExecuteInterface &interface) override
+  {
+    ParticleSet particles = interface.particles();
+
+    auto was_activated_before = particles.attributes().get_byte(m_identifier);
+    for (uint pindex : particles.indices()) {
+      was_activated_before[pindex] = true;
+    }
+  }
 };
 
 class MeshBounceEvent : public Event {
@@ -145,9 +174,9 @@ class MeshBounceEvent : public Event {
   }
 };
 
-EventFilter *EVENT_age_reached(float age)
+EventFilter *EVENT_age_reached(StringRef identifier, SharedFunction &compute_age_fn)
 {
-  return new AgeReachedEvent(age);
+  return new AgeReachedEvent(identifier, compute_age_fn);
 }
 
 Event *EVENT_mesh_bounce(BVHTreeFromMesh *treedata, const float4x4 &transform)
diff --git a/source/blender/simulations/bparticles/events.hpp b/source/blender/simulations/bparticles/events.hpp
index 423ca3ba37b..08adc0bc7a1 100644
--- a/source/blender/simulations/bparticles/events.hpp
+++ b/source/blender/simulations/bparticles/events.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "core.hpp"
+#include "actions.hpp"
 
 struct BVHTreeFromMesh;
 
@@ -13,9 +14,17 @@ class EventFilter {
   virtual ~EventFilter() = 0;
 
   virtual void filter(EventFilterInterface &interface) = 0;
+
+  virtual void triggered(EventExecuteInterface &UNUSED(interface))
+  {
+  }
+
+  virtual void attributes(TypeAttributeInterface &UNUSED(interface))
+  {
+  }
 };
 
-EventFilter *EVENT_age_reached(float age);
+EventFilter *EVENT_age_reached(StringRef identifier, SharedFunction &compute_age_fn);
 Event *EVENT_mesh_bounce(struct BVHTreeFromMesh *treedata, const float4x4 &transform);
 
 }  // namespace BParticles



More information about the Bf-blender-cvs mailing list