[Bf-blender-cvs] [55616843375] functions: support emitting particles again

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


Commit: 5561684337521c1bd8005a848af6cd99e429ab93
Author: Jacques Lucke
Date:   Thu Jun 20 12:10:07 2019 +0200
Branches: functions
https://developer.blender.org/rB5561684337521c1bd8005a848af6cd99e429ab93

support emitting particles again

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

M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/core.hpp
M	source/blender/simulations/bparticles/simulate.cpp
A	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 3d2647ac0b7..1ff5457a381 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -53,6 +53,7 @@ void BParticles_state_free(BParticlesState state)
 
 class ModifierStepDescription : public StepDescription {
  public:
+  float m_duration;
   SmallVector<Emitter *> m_emitters;
   SmallVector<Force *> m_forces;
   SmallVector<Event *> m_events;
@@ -74,6 +75,11 @@ class ModifierStepDescription : public StepDescription {
   {
     return m_actions;
   }
+
+  float step_duration() override
+  {
+    return m_duration;
+  }
 };
 
 void BParticles_simulate_modifier(NodeParticlesModifierData *UNUSED(npmd),
@@ -84,6 +90,7 @@ void BParticles_simulate_modifier(NodeParticlesModifierData *UNUSED(npmd),
   ModifierStepDescription description;
   description.m_emitters.append(EMITTER_point({1, 1, 1}).release());
   description.m_forces.append(FORCE_directional({0, 0, -2}).release());
+  description.m_duration = 1.0f / 24.0f;
   simulate_step(state, description);
 }
 
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index 8504e9e7d33..b75aeeb98c2 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -129,6 +129,8 @@ class Emitter {
 
 class StepDescription {
  public:
+  virtual float step_duration() = 0;
+
   virtual ArrayRef<Emitter *> emitters() = 0;
   virtual ArrayRef<Force *> forces() = 0;
   virtual ArrayRef<Event *> events() = 0;
@@ -138,6 +140,7 @@ class StepDescription {
 class ParticlesState {
  public:
   ParticlesContainer *m_container;
+  float m_current_time = 0.0f;
 
   ParticlesState() = default;
 };
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 31ecd2d749b..2971261e121 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -1,9 +1,114 @@
 #include "simulate.hpp"
+#include "time_span.hpp"
+#include "BLI_lazy_init.hpp"
 
 namespace BParticles {
 
-void simulate_step(ParticlesState &UNUSED(state), StepDescription &UNUSED(description))
+/* Static Data
+ **************************************************/
+
+BLI_LAZY_INIT_STATIC(SmallVector<uint>, static_number_range_vector)
+{
+  return Range<uint>(0, 10000).to_small_vector();
+}
+
+static ArrayRef<uint> static_number_range_ref()
+{
+  return static_number_range_vector();
+}
+
+/* Step individual particles.
+ **********************************************/
+
+static void step_individual_particles(AttributeArrays attributes,
+                                      ArrayRef<uint> particle_indices,
+                                      ArrayRef<float> durations)
+{
+  auto positions = attributes.get_float3("Position");
+
+  for (uint i = 0; i < particle_indices.size(); i++) {
+    uint pindex = particle_indices[i];
+    positions[pindex].x += durations[i] * 2.0f;
+  }
+}
+
+/* Emit new particles from emitters.
+ **********************************************/
+
+static void emit_new_particles_from_emitter(ParticlesContainer &container,
+                                            Emitter &emitter,
+                                            TimeSpan time_span)
+{
+  SmallVector<EmitterTarget> targets;
+  SmallVector<ParticlesBlock *> blocks;
+
+  RequestEmitterTarget request_target = [&container, &targets, &blocks]() -> EmitterTarget & {
+    ParticlesBlock *block = container.new_block();
+    blocks.append(block);
+    targets.append(EmitterTarget{block->slice_all()});
+    return targets.last();
+  };
+
+  emitter.emit(EmitterHelper{request_target});
+
+  for (uint i = 0; i < targets.size(); i++) {
+    EmitterTarget &target = targets[i];
+    ParticlesBlock *block = blocks[i];
+    AttributeArrays emitted_attributes = target.attributes().take_front(target.emitted_amount());
+
+    emitted_attributes.get_byte("Kill State").fill(0);
+
+    auto birth_times = emitted_attributes.get_float("Birth Time");
+    for (float &birth_time : birth_times) {
+      float fac = (rand() % 1000) / 1000.0f;
+      birth_time = time_span.interpolate(fac);
+    }
+
+    SmallVector<float> initial_step_durations;
+    for (float birth_time : birth_times) {
+      initial_step_durations.append(time_span.end() - birth_time);
+    }
+
+    block->active_amount() += target.emitted_amount();
+    step_individual_particles(emitted_attributes,
+                              Range<uint>(0, emitted_attributes.size()).to_small_vector(),
+                              initial_step_durations);
+  }
+}
+
+static void emit_new_particles_from_emitters(ParticlesContainer &container,
+                                             ArrayRef<Emitter *> emitters,
+                                             TimeSpan time_span)
+{
+  for (Emitter *emitter : emitters) {
+    emit_new_particles_from_emitter(container, *emitter, time_span);
+  }
+}
+
+/* Main Entry Point
+ **************************************************/
+
+void simulate_step(ParticlesState &state, StepDescription &description)
 {
+  TimeSpan time_span{state.m_current_time, description.step_duration()};
+  state.m_current_time = time_span.end();
+
+  ParticlesContainer &particles = *state.m_container;
+
+  SmallVector<ParticlesBlock *> already_existing_blocks =
+      particles.active_blocks().to_small_vector();
+
+  SmallVector<float> durations_vector(particles.block_size());
+  durations_vector.fill(time_span.duration());
+  ArrayRef<float> durations = durations_vector;
+
+  for (ParticlesBlock *block : already_existing_blocks) {
+    step_individual_particles(block->slice_active(),
+                              static_number_range_ref().take_front(block->active_amount()),
+                              durations.take_front(block->active_amount()));
+  }
+
+  emit_new_particles_from_emitters(particles, description.emitters(), time_span);
 }
 
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/time_span.hpp b/source/blender/simulations/bparticles/time_span.hpp
new file mode 100644
index 00000000000..ec66ab2f3e3
--- /dev/null
+++ b/source/blender/simulations/bparticles/time_span.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+namespace BParticles {
+
+struct TimeSpan {
+ private:
+  float m_start, m_duration;
+
+ public:
+  TimeSpan(float start, float duration) : m_start(start), m_duration(duration)
+  {
+  }
+
+  float start() const
+  {
+    return m_start;
+  }
+
+  float duration() const
+  {
+    return m_duration;
+  }
+
+  float end() const
+  {
+    return m_start + m_duration;
+  }
+
+  float interpolate(float t) const
+  {
+    return m_start + t * m_duration;
+  }
+};
+
+}  // namespace BParticles



More information about the Bf-blender-cvs mailing list