[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