[Bf-blender-cvs] [4c0e7a285a4] functions: initial particles container

Jacques Lucke noreply at git.blender.org
Fri Jun 7 17:18:54 CEST 2019


Commit: 4c0e7a285a4b639607ce8a8b021acb60b46fefaa
Author: Jacques Lucke
Date:   Fri Jun 7 17:18:18 2019 +0200
Branches: functions
https://developer.blender.org/rB4c0e7a285a4b639607ce8a8b021acb60b46fefaa

initial particles container

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

M	source/blender/simulations/CMakeLists.txt
A	source/blender/simulations/bparticles/particles_container.cpp
A	source/blender/simulations/bparticles/particles_container.hpp
M	source/blender/simulations/bparticles/playground_solver.cpp

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

diff --git a/source/blender/simulations/CMakeLists.txt b/source/blender/simulations/CMakeLists.txt
index f4c9c9c680c..d7e5e1b1d26 100644
--- a/source/blender/simulations/CMakeLists.txt
+++ b/source/blender/simulations/CMakeLists.txt
@@ -17,6 +17,8 @@ set(SRC
 
   bparticles/core.hpp
   bparticles/core.cpp
+  bparticles/particles_container.hpp
+  bparticles/particles_container.cpp
   bparticles/playground_solver.hpp
   bparticles/playground_solver.cpp
   bparticles/c_wrapper.cpp
diff --git a/source/blender/simulations/bparticles/particles_container.cpp b/source/blender/simulations/bparticles/particles_container.cpp
new file mode 100644
index 00000000000..effc3198a14
--- /dev/null
+++ b/source/blender/simulations/bparticles/particles_container.cpp
@@ -0,0 +1,70 @@
+#include "particles_container.hpp"
+
+namespace BParticles {
+
+ParticlesBlock::ParticlesBlock(ParticlesContainer &container,
+                               ArrayRef<float *> float_buffers,
+                               ArrayRef<Vec3 *> vec3_buffers,
+                               uint active_amount)
+    : m_container(container),
+      m_float_buffers(float_buffers.to_small_vector()),
+      m_vec3_buffers(vec3_buffers.to_small_vector()),
+      m_active_amount(active_amount)
+{
+  BLI_assert(m_float_buffers.size() == container.float_attribute_amount());
+  BLI_assert(m_vec3_buffers.size() == container.vec3_attribute_amount());
+}
+
+ParticlesContainer::ParticlesContainer(uint block_size,
+                                       const SmallVector<std::string> &float_attribute_names,
+                                       const SmallVector<std::string> &vec3_attribute_names)
+    : m_block_size(block_size),
+      m_float_attribute_names(float_attribute_names),
+      m_vec3_attribute_names(vec3_attribute_names)
+{
+  BLI_assert(
+      SmallSetVector<std::string>::Disjoint(m_float_attribute_names, m_vec3_attribute_names));
+}
+
+ParticlesContainer::~ParticlesContainer()
+{
+  while (m_blocks.size() > 0) {
+    ParticlesBlock *block = m_blocks.any();
+    block->clear();
+    this->release_block(block);
+  }
+}
+
+ParticlesBlock *ParticlesContainer::new_block()
+{
+  SmallVector<float *> float_buffers;
+  for (uint i = 0; i < m_float_attribute_names.size(); i++) {
+    float_buffers.append((float *)MEM_malloc_arrayN(m_block_size, sizeof(float), __func__));
+  }
+  SmallVector<Vec3 *> vec3_buffers;
+  for (uint i = 0; i < m_vec3_attribute_names.size(); i++) {
+    vec3_buffers.append((Vec3 *)MEM_malloc_arrayN(m_block_size, sizeof(Vec3), __func__));
+  }
+  ParticlesBlock *block = new ParticlesBlock(*this, float_buffers, vec3_buffers);
+  m_blocks.add_new(block);
+  return block;
+}
+
+void ParticlesContainer::release_block(ParticlesBlock *block)
+{
+  BLI_assert(block);
+  BLI_assert(block->active_amount() == 0);
+  BLI_assert(m_blocks.contains(block));
+  BLI_assert(&block->container() == this);
+
+  for (float *buffer : block->float_buffers()) {
+    MEM_freeN((void *)buffer);
+  }
+  for (Vec3 *buffer : block->vec3_buffers()) {
+    MEM_freeN((void *)buffer);
+  }
+  m_blocks.remove(block);
+  delete block;
+}
+
+}  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/particles_container.hpp b/source/blender/simulations/bparticles/particles_container.hpp
new file mode 100644
index 00000000000..0c9baadf3b6
--- /dev/null
+++ b/source/blender/simulations/bparticles/particles_container.hpp
@@ -0,0 +1,161 @@
+#pragma once
+
+#include "BLI_array_ref.hpp"
+#include "BLI_small_vector.hpp"
+#include "BLI_small_set_vector.hpp"
+#include "BLI_math.hpp"
+#include "BLI_string_ref.hpp"
+
+namespace BParticles {
+
+using BLI::ArrayRef;
+using BLI::SmallSet;
+using BLI::SmallSetVector;
+using BLI::SmallVector;
+using BLI::StringRef;
+using BLI::Vec3;
+
+class ParticlesContainer;
+class ParticlesBlock;
+
+class ParticlesContainer {
+ private:
+  uint m_block_size;
+  SmallSetVector<std::string> m_float_attribute_names;
+  SmallSetVector<std::string> m_vec3_attribute_names;
+  SmallSet<ParticlesBlock *> m_blocks;
+
+ public:
+  ParticlesContainer(uint block_size,
+                     const SmallVector<std::string> &float_attribute_names,
+                     const SmallVector<std::string> &vec3_attribute_names);
+
+  ~ParticlesContainer();
+
+  uint block_size() const;
+  uint float_attribute_amount() const;
+  uint vec3_attribute_amount() const;
+  uint float_buffer_index(StringRef name) const;
+  uint vec3_buffer_index(StringRef name) const;
+  const SmallSet<ParticlesBlock *> &active_blocks();
+
+  ParticlesBlock *new_block();
+  void release_block(ParticlesBlock *block);
+};
+
+class ParticlesBlock {
+  ParticlesContainer &m_container;
+  SmallVector<float *> m_float_buffers;
+  SmallVector<Vec3 *> m_vec3_buffers;
+  uint m_active_amount;
+
+ public:
+  ParticlesBlock(ParticlesContainer &container,
+                 ArrayRef<float *> float_buffers,
+                 ArrayRef<Vec3 *> vec3_buffers,
+                 uint active_amount = 0);
+
+  uint &active_amount();
+  bool is_full();
+  uint next_inactive_index();
+  uint size();
+
+  ParticlesContainer &container();
+
+  void clear();
+
+  ArrayRef<float *> float_buffers();
+  ArrayRef<Vec3 *> vec3_buffers();
+  float *float_buffer(StringRef name);
+  Vec3 *vec3_buffer(StringRef name);
+};
+
+/* Particles Container
+ ***********************************************/
+
+inline uint ParticlesContainer::block_size() const
+{
+  return m_block_size;
+}
+
+inline uint ParticlesContainer::float_attribute_amount() const
+{
+  return m_float_attribute_names.size();
+}
+
+inline uint ParticlesContainer::vec3_attribute_amount() const
+{
+  return m_vec3_attribute_names.size();
+}
+
+inline uint ParticlesContainer::float_buffer_index(StringRef name) const
+{
+  return m_float_attribute_names.index(name.to_std_string());
+}
+
+inline uint ParticlesContainer::vec3_buffer_index(StringRef name) const
+{
+  return m_vec3_attribute_names.index(name.to_std_string());
+}
+
+inline const SmallSet<ParticlesBlock *> &ParticlesContainer::active_blocks()
+{
+  return m_blocks;
+}
+
+/* Particles Block
+ ****************************************/
+
+inline uint &ParticlesBlock::active_amount()
+{
+  return m_active_amount;
+}
+
+inline bool ParticlesBlock::is_full()
+{
+  return m_active_amount == this->size();
+}
+
+inline uint ParticlesBlock::next_inactive_index()
+{
+  return m_active_amount;
+}
+
+inline uint ParticlesBlock::size()
+{
+  return m_container.block_size();
+}
+
+inline void ParticlesBlock::clear()
+{
+  m_active_amount = 0;
+}
+
+inline ParticlesContainer &ParticlesBlock::container()
+{
+  return m_container;
+}
+
+inline ArrayRef<float *> ParticlesBlock::float_buffers()
+{
+  return m_float_buffers;
+}
+
+inline ArrayRef<Vec3 *> ParticlesBlock::vec3_buffers()
+{
+  return m_vec3_buffers;
+}
+
+inline float *ParticlesBlock::float_buffer(StringRef name)
+{
+  uint index = m_container.float_buffer_index(name);
+  return m_float_buffers[index];
+}
+
+inline Vec3 *ParticlesBlock::vec3_buffer(StringRef name)
+{
+  uint index = m_container.vec3_buffer_index(name);
+  return m_vec3_buffers[index];
+}
+
+}  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/playground_solver.cpp b/source/blender/simulations/bparticles/playground_solver.cpp
index 774ba86b148..c21bcbcad37 100644
--- a/source/blender/simulations/bparticles/playground_solver.cpp
+++ b/source/blender/simulations/bparticles/playground_solver.cpp
@@ -1,5 +1,6 @@
 #include "BLI_small_vector.hpp"
 
+#include "particles_container.hpp"
 #include "playground_solver.hpp"
 
 namespace BParticles {
@@ -13,8 +14,12 @@ struct Vector {
 class SimpleSolver : public Solver {
 
   struct MyState : StateBase {
-    SmallVector<Vec3> positions;
-    SmallVector<Vec3> velocities;
+    ParticlesContainer *particles;
+
+    ~MyState()
+    {
+      delete particles;
+    }
   };
 
   Description &m_description;
@@ -26,23 +31,23 @@ class SimpleSolver : public Solver {
 
   StateBase *init() override
   {
-    return new MyState();
+    MyState *state = new MyState();
+    state->particles = new ParticlesContainer(50, {}, {"Position", "Velocity"});
+    return state;
   }
 
-  void step(WrappedState &wrapped_state) override
+  void step_block(ParticlesBlock *block)
   {
-    MyState &state = wrapped_state.state<MyState>();
-    uint last_particle_amount = state.positions.size();
-
-    for (uint i = 0; i < last_particle_amount; i++) {
-      Vec3 &position = state.positions[i];
-      Vec3 &velocity = state.velocities[i];
-      position.x += velocity.x;
-      position.y += velocity.y;
-      position.z += velocity.z;
+    uint active_amount = block->active_amount();
+
+    Vec3 *positions = block->vec3_buffer("Position");
+    Vec3 *velocities = block->vec3_buffer("Velocity");
+
+    for (uint i = 0; i < active_amount; i++) {
+      positions[i] += velocities[i];
     }
 
-    SmallVector<Vec3> combined_force(last_particle_amount);
+    SmallVector<Vec3> combined_force(active_amount);
     combined_force.fill({0, 0, 0});
 
     for (Force *force : m_description.forces()) {
@@ -50,28 +55,66 @@ class SimpleSolver : public Solver {
     }
 
     float time_step = 0.01f;
-    for (uint i = 0; i < last_particle_amount; i++) {
-      state.velocities[i] += combined_force[i] * time_step;
+    for (uint i = 0; i < active_amount; i++) {
+      velocities[i] += combined_force[i] * time_step;
+    }
+  }
+
+  void emit_new_particles(ParticlesContainer &particles)
+  {
+    ParticlesBlock *non_full_block = nullptr;
+    for (ParticlesBlock *block : particles.active_blocks()) {
+      if (!block->is_full()) {
+        non_full_block = block;
+        break;
+      }
+    }
+
+    if (non_full_block == nullptr) {
+      non_full_block = particles.new_block();
     }
 
-    for (uint i = 0; i < last_particle_amount; i++) {
-      state.positions[i] += state.velocities[i] * time_step;
+    uint index = non_full_block->next_inactive_index();
+    non_full_block->vec3_buffer("Position")[index] = {(float)(rand() % 100) / 100.0f, 0, 1};
+    non_full_block->vec3_buffer("Velocity")[index] = {0, 0.1, 0};
+    non_full_block->active_amount()++;
+  }
+
+  void step(WrappedState &wrapped_state

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list