[Bf-blender-cvs] [0886cdb1fed] functions: support killing particles again

Jacques Lucke noreply at git.blender.org
Thu Jun 20 15:51:22 CEST 2019


Commit: 0886cdb1fedc310590c18e213c105a2f87b71f25
Author: Jacques Lucke
Date:   Thu Jun 20 14:23:39 2019 +0200
Branches: functions
https://developer.blender.org/rB0886cdb1fedc310590c18e213c105a2f87b71f25

support killing particles again

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

M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/core.hpp
M	source/blender/simulations/bparticles/simulate.cpp
M	source/blender/simulations/bparticles/time_span.hpp

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

diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index 9e4e0b27975..b76a18674eb 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -51,6 +51,49 @@ void BParticles_state_free(BParticlesState state)
   delete unwrap(state);
 }
 
+class AgeReachedEvent : public Event {
+ private:
+  float m_age;
+
+ public:
+  AgeReachedEvent(float age) : m_age(age)
+  {
+  }
+
+  void filter(AttributeArrays attributes,
+              ArrayRef<uint> particle_indices,
+              IdealOffsets &ideal_offsets,
+              ArrayRef<float> durations,
+              float end_time,
+              SmallVector<uint> &r_filtered_indices,
+              SmallVector<float> &r_time_factors) override
+  {
+    auto birth_times = attributes.get_float("Birth Time");
+
+    for (uint i = 0; i < particle_indices.size(); i++) {
+      uint pindex = particle_indices[i];
+      float duration = durations[i];
+      float birth_time = birth_times[i];
+      float age = end_time - birth_time;
+      if (age >= m_age && age - duration < m_age) {
+        r_filtered_indices.append(i);
+        r_time_factors.append(
+            TimeSpan(end_time - duration, duration).get_factor(birth_time + m_age));
+      }
+    }
+  }
+};
+
+class KillAction : public Action {
+  void execute(AttributeArrays attributes, ArrayRef<uint> particle_indices) override
+  {
+    auto kill_states = attributes.get_byte("Kill State");
+    for (uint pindex : particle_indices) {
+      kill_states[pindex] = 1;
+    }
+  }
+};
+
 class ModifierStepParticleInfluences : public ParticleInfluences {
  public:
   SmallVector<Force *> m_forces;
@@ -122,6 +165,8 @@ void BParticles_simulate_modifier(NodeParticlesModifierData *UNUSED(npmd),
   description.m_duration = 1.0f / 24.0f;
   description.m_emitters.append(EMITTER_point({1, 1, 1}).release());
   description.m_influences.m_forces.append(FORCE_directional({0, 0, -2}).release());
+  description.m_influences.m_events.append(new AgeReachedEvent(3));
+  description.m_influences.m_actions.append(new KillAction());
   simulate_step(state, description);
 
   std::cout << "Active Blocks: " << state.m_container->active_blocks().size() << "\n";
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index d80b71462d5..ffa3f9719d6 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -12,6 +12,7 @@
 
 #include "attributes.hpp"
 #include "particles_container.hpp"
+#include "time_span.hpp"
 
 namespace BParticles {
 
@@ -28,7 +29,7 @@ class Force {
  public:
   virtual ~Force();
   virtual void add_force(AttributeArrays attributes,
-                         ArrayRef<uint> indices_mask,
+                         ArrayRef<uint> particle_indices,
                          ArrayRef<float3> dst) = 0;
 };
 
@@ -42,8 +43,10 @@ class Event {
   virtual ~Event();
 
   virtual void filter(AttributeArrays attributes,
-                      ArrayRef<uint> indices_mask,
-                      IdealOffsets &next_movement,
+                      ArrayRef<uint> particle_indices,
+                      IdealOffsets &ideal_offsets,
+                      ArrayRef<float> durations,
+                      float end_time,
                       SmallVector<uint> &r_filtered_indices,
                       SmallVector<float> &r_time_factors) = 0;
 };
@@ -52,7 +55,7 @@ class Action {
  public:
   virtual ~Action();
 
-  virtual void execute(AttributeArrays attributes, ArrayRef<uint> indices_mask) = 0;
+  virtual void execute(AttributeArrays attributes, ArrayRef<uint> particle_indices) = 0;
 };
 
 class EmitterTarget {
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 8a4ddecccbf..507eb7fb5ba 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -24,6 +24,7 @@ static void find_next_event_per_particle(AttributeArrays attributes,
                                          ArrayRef<uint> particle_indices,
                                          IdealOffsets &ideal_offsets,
                                          ArrayRef<float> durations,
+                                         float end_time,
                                          ArrayRef<Event *> events,
                                          ArrayRef<int> r_next_event_indices,
                                          ArrayRef<float> r_time_factors_to_next_event)
@@ -36,8 +37,13 @@ static void find_next_event_per_particle(AttributeArrays attributes,
     SmallVector<float> triggered_time_factors;
 
     Event *event = events[event_index];
-    event->filter(
-        attributes, particle_indices, ideal_offsets, triggered_indices, triggered_time_factors);
+    event->filter(attributes,
+                  particle_indices,
+                  ideal_offsets,
+                  durations,
+                  end_time,
+                  triggered_indices,
+                  triggered_time_factors);
 
     for (uint i = 0; i < triggered_indices.size(); i++) {
       uint index = triggered_indices[i];
@@ -157,6 +163,7 @@ static void compute_ideal_attribute_offsets(AttributeArrays attributes,
 static void simulate_to_next_event(AttributeArrays attributes,
                                    ArrayRef<uint> particle_indices,
                                    ArrayRef<float> durations,
+                                   float end_time,
                                    ParticleInfluences &influences,
                                    SmallVector<uint> &r_unfinished_particle_indices,
                                    SmallVector<float> &r_remaining_durations)
@@ -175,6 +182,7 @@ static void simulate_to_next_event(AttributeArrays attributes,
                                particle_indices,
                                ideal_offsets,
                                durations,
+                               end_time,
                                influences.events(),
                                next_event_indices,
                                time_factors_to_next_event);
@@ -219,6 +227,7 @@ static void simulate_ignoring_events(AttributeArrays attributes,
 static void step_individual_particles(AttributeArrays attributes,
                                       ArrayRef<uint> particle_indices,
                                       ArrayRef<float> durations,
+                                      float end_time,
                                       ParticleInfluences &influences)
 {
   SmallVector<uint> unfinished_particle_indices;
@@ -226,6 +235,7 @@ static void step_individual_particles(AttributeArrays attributes,
   simulate_to_next_event(attributes,
                          particle_indices,
                          durations,
+                         end_time,
                          influences,
                          unfinished_particle_indices,
                          remaining_durations);
@@ -235,6 +245,32 @@ static void step_individual_particles(AttributeArrays attributes,
       attributes, unfinished_particle_indices, remaining_durations, influences);
 }
 
+/* Delete particles.
+ **********************************************/
+
+static void delete_tagged_particles_and_reorder(ParticlesBlock &block)
+{
+  auto kill_states = block.slice_active().get_byte("Kill State");
+
+  uint index = 0;
+  while (index < block.active_amount()) {
+    if (kill_states[index] == 1) {
+      block.move(block.active_amount() - 1, index);
+      block.active_amount() -= 1;
+    }
+    else {
+      index++;
+    }
+  }
+}
+
+static void delete_tagged_particles(ArrayRef<ParticlesBlock *> blocks)
+{
+  for (ParticlesBlock *block : blocks) {
+    delete_tagged_particles_and_reorder(*block);
+  }
+}
+
 /* Emit new particles from emitters.
  **********************************************/
 
@@ -277,6 +313,7 @@ static void emit_new_particles_from_emitter(ParticlesContainer &container,
     step_individual_particles(emitted_attributes,
                               Range<uint>(0, emitted_attributes.size()).to_small_vector(),
                               initial_step_durations,
+                              time_span.end(),
                               influences);
   }
 }
@@ -327,12 +364,14 @@ void simulate_step(ParticlesState &state, StepDescription &description)
     step_individual_particles(block->slice_active(),
                               static_number_range_ref().take_front(block->active_amount()),
                               durations.take_front(block->active_amount()),
+                              time_span.end(),
                               description.influences());
   }
 
   emit_new_particles_from_emitters(
       particles, description.emitters(), description.influences(), time_span);
 
+  delete_tagged_particles(particles.active_blocks().to_small_vector());
   compress_all_blocks(particles);
 }
 
diff --git a/source/blender/simulations/bparticles/time_span.hpp b/source/blender/simulations/bparticles/time_span.hpp
index ec66ab2f3e3..e5c6d90a6d4 100644
--- a/source/blender/simulations/bparticles/time_span.hpp
+++ b/source/blender/simulations/bparticles/time_span.hpp
@@ -30,6 +30,12 @@ struct TimeSpan {
   {
     return m_start + t * m_duration;
   }
+
+  float get_factor(float time) const
+  {
+    BLI_assert(m_duration > 0.0f);
+    return (time - m_start) / m_duration;
+  }
 };
 
 }  // namespace BParticles



More information about the Bf-blender-cvs mailing list