[Bf-blender-cvs] [e3d3d2eec70] functions: introduce concept of particle block slices

Jacques Lucke noreply at git.blender.org
Sat Jun 8 14:21:52 CEST 2019


Commit: e3d3d2eec701c24a755443e3bc51cab3e8e11635
Author: Jacques Lucke
Date:   Sat Jun 8 12:38:30 2019 +0200
Branches: functions
https://developer.blender.org/rBe3d3d2eec701c24a755443e3bc51cab3e8e11635

introduce concept of particle block slices

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

M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/core.hpp
M	source/blender/simulations/bparticles/particles_container.hpp
M	source/blender/simulations/bparticles/playground_solver.cpp

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

diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index a828a775612..2598d0056e4 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -14,6 +14,7 @@
   }
 
 using BParticles::Description;
+using BParticles::EmitterDestination;
 using BParticles::NamedBuffers;
 using BParticles::ParticlesBlock;
 using BParticles::Solver;
@@ -47,15 +48,15 @@ class TestForce : public BParticles::Force {
 
 class TestEmitter : public BParticles::Emitter {
  public:
-  void emit(std::function<ParticlesBlock *()> request_block) override
+  void emit(std::function<EmitterDestination &()> request_destination) override
   {
-    ParticlesBlock *block = request_block();
+    EmitterDestination &dst = request_destination();
+    BLI_assert(dst.size() > 0);
 
-    uint index = block->next_inactive_index();
-    block->vec3_buffer("Position")[index] = {(float)(rand() % 100) / 30.0f, 0, 1};
-    block->vec3_buffer("Velocity")[index] = {0, 0.1, 0};
-    block->float_buffer("Age")[index] = 0;
-    block->active_amount()++;
+    dst.vec3_buffer("Position")[0] = {(float)(rand() % 100) / 30.0f, 0, 1};
+    dst.vec3_buffer("Velocity")[0] = {0, 0.1, 0};
+    dst.float_buffer("Age")[0] = 0;
+    dst.initialized_n(1);
   }
 };
 
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index e76a8d9b03a..b22050c65ae 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -34,12 +34,47 @@ class Force {
   virtual void add_force(NamedBuffers &buffers, ArrayRef<Vec3> dst) = 0;
 };
 
-class ParticlesBlock;
+class EmitterDestination {
+ private:
+  NamedBuffers &m_buffers;
+  uint m_emitted_amount = 0;
+
+ public:
+  EmitterDestination(NamedBuffers &buffers) : m_buffers(buffers)
+  {
+  }
+
+  void initialized_n(uint n)
+  {
+    m_emitted_amount += n;
+    BLI_assert(m_emitted_amount <= m_buffers.size());
+  }
+
+  uint emitted_amount()
+  {
+    return m_emitted_amount;
+  }
+
+  ArrayRef<float> float_buffer(StringRef name)
+  {
+    return m_buffers.float_buffer(name);
+  }
+
+  ArrayRef<Vec3> vec3_buffer(StringRef name)
+  {
+    return m_buffers.vec3_buffer(name);
+  }
+
+  uint size()
+  {
+    return m_buffers.size();
+  }
+};
 
 class Emitter {
  public:
   virtual ~Emitter();
-  virtual void emit(std::function<ParticlesBlock *()> request_block) = 0;
+  virtual void emit(std::function<EmitterDestination &()> request_destination) = 0;
 };
 
 class Description {
diff --git a/source/blender/simulations/bparticles/particles_container.hpp b/source/blender/simulations/bparticles/particles_container.hpp
index 43c5e11a883..85b86727169 100644
--- a/source/blender/simulations/bparticles/particles_container.hpp
+++ b/source/blender/simulations/bparticles/particles_container.hpp
@@ -19,7 +19,7 @@ using BLI::Vec3;
 
 class ParticlesContainer;
 class ParticlesBlock;
-class BlockBuffersRef;
+class ParticlesBlockSlice;
 
 class ParticlesContainer {
  private:
@@ -46,6 +46,21 @@ class ParticlesContainer {
   void release_block(ParticlesBlock *block);
 };
 
+class ParticlesBlockSlice : public NamedBuffers {
+ private:
+  ParticlesBlock *m_block;
+  uint m_start;
+  uint m_length;
+
+ public:
+  ParticlesBlockSlice(ParticlesBlock *block, uint start, uint length);
+
+  ParticlesBlock *block();
+  uint size() override;
+  ArrayRef<float> float_buffer(StringRef name) override;
+  ArrayRef<Vec3> vec3_buffer(StringRef name) override;
+};
+
 class ParticlesBlock {
   ParticlesContainer &m_container;
   SmallVector<float *> m_float_buffers;
@@ -74,37 +89,16 @@ class ParticlesBlock {
   float *float_buffer(StringRef name);
   Vec3 *vec3_buffer(StringRef name);
 
+  ParticlesBlockSlice slice(uint start, uint length);
+  ParticlesBlockSlice slice_all();
+  ParticlesBlockSlice slice_active();
+
   void move(uint old_index, uint new_index);
 
   static void MoveUntilFull(ParticlesBlock *from, ParticlesBlock *to);
   static void Compress(ArrayRef<ParticlesBlock *> blocks);
 };
 
-class BlockBuffersRef : public NamedBuffers {
- private:
-  ParticlesBlock *m_block;
-
- public:
-  BlockBuffersRef(ParticlesBlock *block) : m_block(block)
-  {
-  }
-
-  uint size() override
-  {
-    return m_block->size();
-  }
-
-  ArrayRef<float> float_buffer(StringRef name) override
-  {
-    return ArrayRef<float>(m_block->float_buffer(name), m_block->active_amount());
-  }
-
-  ArrayRef<Vec3> vec3_buffer(StringRef name) override
-  {
-    return ArrayRef<Vec3>(m_block->vec3_buffer(name), m_block->active_amount());
-  }
-};
-
 /* Particles Container
  ***********************************************/
 
@@ -197,6 +191,21 @@ inline float *ParticlesBlock::float_buffer(StringRef name)
   return m_float_buffers[index];
 }
 
+inline ParticlesBlockSlice ParticlesBlock::slice(uint start, uint length)
+{
+  return ParticlesBlockSlice{this, start, length};
+}
+
+inline ParticlesBlockSlice ParticlesBlock::slice_all()
+{
+  return this->slice(0, this->size());
+}
+
+inline ParticlesBlockSlice ParticlesBlock::slice_active()
+{
+  return this->slice(0, m_active_amount);
+}
+
 inline Vec3 *ParticlesBlock::vec3_buffer(StringRef name)
 {
   uint index = m_container.vec3_buffer_index(name);
@@ -213,4 +222,33 @@ inline void ParticlesBlock::move(uint old_index, uint new_index)
   }
 }
 
+/* Particles Block Slice
+ ************************************************/
+
+inline ParticlesBlockSlice::ParticlesBlockSlice(ParticlesBlock *block, uint start, uint length)
+    : m_block(block), m_start(start), m_length(length)
+{
+  BLI_assert(start + length <= block->size());
+}
+
+inline ParticlesBlock *ParticlesBlockSlice::block()
+{
+  return m_block;
+}
+
+inline uint ParticlesBlockSlice::size()
+{
+  return m_length;
+}
+
+inline ArrayRef<float> ParticlesBlockSlice::float_buffer(StringRef name)
+{
+  return ArrayRef<float>(m_block->float_buffer(name) + m_start, m_length);
+}
+
+inline ArrayRef<Vec3> ParticlesBlockSlice::vec3_buffer(StringRef name)
+{
+  return ArrayRef<Vec3>(m_block->vec3_buffer(name) + m_start, m_length);
+}
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/playground_solver.cpp b/source/blender/simulations/bparticles/playground_solver.cpp
index ab7ec61b433..3c01d332a1d 100644
--- a/source/blender/simulations/bparticles/playground_solver.cpp
+++ b/source/blender/simulations/bparticles/playground_solver.cpp
@@ -5,12 +5,6 @@
 
 namespace BParticles {
 
-using BLI::SmallVector;
-
-struct Vector {
-  float x, y, z;
-};
-
 class SimpleSolver : public Solver {
 
   struct MyState : StateBase {
@@ -52,10 +46,10 @@ class SimpleSolver : public Solver {
     SmallVector<Vec3> combined_force(active_amount);
     combined_force.fill({0, 0, 0});
 
-    BlockBuffersRef buffers{block};
+    ParticlesBlockSlice slice = block->slice_active();
 
     for (Force *force : m_description.forces()) {
-      force->add_force(buffers, combined_force);
+      force->add_force(slice, combined_force);
     }
 
     float time_step = 0.01f;
@@ -92,12 +86,25 @@ class SimpleSolver : public Solver {
 
   void emit_new_particles(ParticlesContainer &particles)
   {
-    std::function<ParticlesBlock *()> request_non_full_block = [&particles]() -> ParticlesBlock * {
-      return particles.new_block();
+    SmallVector<ParticlesBlockSlice> block_slices;
+    SmallVector<EmitterDestination> destinations;
+    auto request_destination =
+        [&particles, &block_slices, &destinations]() -> EmitterDestination & {
+      ParticlesBlock *block = particles.new_block();
+      block_slices.append(block->slice_all());
+      destinations.append(EmitterDestination{block_slices.last()});
+      return destinations.last();
     };
 
     for (Emitter *emitter : m_description.emitters()) {
-      emitter->emit(request_non_full_block);
+      emitter->emit(request_destination);
+    }
+
+    for (uint i = 0; i < destinations.size(); i++) {
+      ParticlesBlockSlice &slice = block_slices[i];
+      EmitterDestination &dst = destinations[i];
+      ParticlesBlock *block = slice.block();
+      block->active_amount() += dst.emitted_amount();
     }
   }



More information about the Bf-blender-cvs mailing list