[Bf-blender-cvs] [58452b095db] functions: initial test for spawning new particles in an action
Jacques Lucke
noreply at git.blender.org
Fri Jun 28 12:31:11 CEST 2019
Commit: 58452b095db403f34e1d3f09794dddcff81e39dd
Author: Jacques Lucke
Date: Fri Jun 28 11:32:08 2019 +0200
Branches: functions
https://developer.blender.org/rB58452b095db403f34e1d3f09794dddcff81e39dd
initial test for spawning new particles in an action
===================================================================
M source/blender/simulations/bparticles/actions.cpp
M source/blender/simulations/bparticles/actions.hpp
M source/blender/simulations/bparticles/c_wrapper.cpp
M source/blender/simulations/bparticles/core.cpp
M source/blender/simulations/bparticles/core.hpp
M source/blender/simulations/bparticles/simulate.cpp
===================================================================
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index aebfb128fc5..2c526a724d6 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -14,7 +14,7 @@ class KillAction : public Action {
}
};
-class MoveAction : public BParticles::Action {
+class MoveAction : public Action {
private:
float3 m_offset;
@@ -34,6 +34,28 @@ class MoveAction : public BParticles::Action {
}
};
+class SpawnAction : public Action {
+ void execute(ActionInterface &interface) override
+ {
+ ParticleSet &particles = interface.particles();
+
+ auto positions = particles.attributes().get_float3("Position");
+
+ SmallVector<float3> new_positions;
+ SmallVector<float3> new_velocities;
+
+ for (uint i : particles.range()) {
+ uint pindex = particles.get_particle_index(i);
+ new_positions.append(positions[pindex] + float3(20, 0, 0));
+ new_velocities.append(float3(1, 1, 10));
+ }
+
+ auto &target = interface.request_emit_target(0, particles.size());
+ target.set_float3("Position", new_positions);
+ target.set_float3("Velocity", new_velocities);
+ }
+};
+
std::unique_ptr<Action> ACTION_kill()
{
Action *action = new KillAction();
@@ -46,4 +68,10 @@ std::unique_ptr<Action> ACTION_move(float3 offset)
return std::unique_ptr<Action>(action);
}
+std::unique_ptr<Action> ACTION_spawn()
+{
+ Action *action = new SpawnAction();
+ return std::unique_ptr<Action>(action);
+}
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/actions.hpp b/source/blender/simulations/bparticles/actions.hpp
index e8edc9daa64..4e31d7c192e 100644
--- a/source/blender/simulations/bparticles/actions.hpp
+++ b/source/blender/simulations/bparticles/actions.hpp
@@ -6,5 +6,6 @@ namespace BParticles {
std::unique_ptr<Action> ACTION_kill();
std::unique_ptr<Action> ACTION_move(float3 offset);
+std::unique_ptr<Action> ACTION_spawn();
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index 81a03613fad..4350118f99f 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -157,7 +157,7 @@ void BParticles_simulate_modifier(NodeParticlesModifierData *npmd,
}
type0->m_forces.append(FORCE_directional({0, 0, -2}).release());
type0->m_events.append(EVENT_age_reached(3.0f).release());
- type0->m_actions.append(ACTION_move({0, 1, 0}).release());
+ type0->m_actions.append(ACTION_spawn().release());
auto *type1 = new ModifierParticleType();
description.m_types.add_new(1, type1);
diff --git a/source/blender/simulations/bparticles/core.cpp b/source/blender/simulations/bparticles/core.cpp
index e92bf67834e..1cb6f8533a2 100644
--- a/source/blender/simulations/bparticles/core.cpp
+++ b/source/blender/simulations/bparticles/core.cpp
@@ -63,6 +63,36 @@ ParticlesBlock &BlockAllocator::get_non_full_block(uint particle_type_id)
return block;
}
+void BlockAllocator::allocate_block_ranges(uint particle_type_id,
+ uint size,
+ SmallVector<ParticlesBlock *> &r_blocks,
+ SmallVector<Range<uint>> &r_ranges)
+{
+ uint remaining_size = size;
+ while (remaining_size > 0) {
+ ParticlesBlock &block = this->get_non_full_block(particle_type_id);
+
+ uint size_to_use = std::min(block.inactive_amount(), remaining_size);
+ Range<uint> range(block.active_amount(), block.active_amount() + size_to_use);
+ block.active_amount() += size_to_use;
+
+ r_blocks.append(&block);
+ r_ranges.append(range);
+
+ AttributeArrays attributes = block.slice(range);
+ for (uint i : attributes.info().attribute_indices()) {
+ attributes.init_default(i);
+ }
+
+ remaining_size -= size_to_use;
+ }
+}
+
+AttributesInfo &BlockAllocator::attributes_info(uint particle_type_id)
+{
+ return m_state.particle_container(particle_type_id).attributes_info();
+}
+
/* Emitter Interface
******************************************/
@@ -77,31 +107,34 @@ TimeSpanEmitTarget &EmitterInterface::request(uint particle_type_id, uint size)
{
SmallVector<ParticlesBlock *> blocks;
SmallVector<Range<uint>> ranges;
+ m_block_allocator.allocate_block_ranges(particle_type_id, size, blocks, ranges);
+ AttributesInfo &attributes_info = m_block_allocator.attributes_info(particle_type_id);
- uint remaining_size = size;
- while (remaining_size > 0) {
- ParticlesBlock &block = m_block_allocator.get_non_full_block(particle_type_id);
-
- uint size_to_use = std::min(block.inactive_amount(), remaining_size);
- Range<uint> range(block.active_amount(), block.active_amount() + size_to_use);
- block.active_amount() += size_to_use;
-
- blocks.append(&block);
- ranges.append(range);
+ auto *target = new TimeSpanEmitTarget(particle_type_id, attributes_info, blocks, ranges);
+ m_targets.append(target);
+ return *target;
+}
- AttributeArrays attributes = block.slice(range);
- for (uint i : attributes.info().attribute_indices()) {
- attributes.init_default(i);
- }
+/* Action Interface
+ **************************************/
- remaining_size -= size_to_use;
+ActionInterface::~ActionInterface()
+{
+ for (InstantEmitTarget *target : m_emit_targets) {
+ delete target;
}
+}
+
+InstantEmitTarget &ActionInterface::request_emit_target(uint particle_type_id, uint size)
+{
+ SmallVector<ParticlesBlock *> blocks;
+ SmallVector<Range<uint>> ranges;
+ m_block_allocator.allocate_block_ranges(particle_type_id, size, blocks, ranges);
+ AttributesInfo &attributes_info = m_block_allocator.attributes_info(particle_type_id);
- ParticlesContainer &container = m_block_allocator.particles_state().particle_container(
- particle_type_id);
- m_targets.append(
- new TimeSpanEmitTarget(particle_type_id, container.attributes_info(), blocks, ranges));
- return *m_targets.last();
+ auto *target = new InstantEmitTarget(particle_type_id, attributes_info, blocks, ranges);
+ m_emit_targets.append(target);
+ return *target;
}
/* EmitTarget
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index 5be647a6d3f..c419df320d3 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -74,6 +74,12 @@ class BlockAllocator {
BlockAllocator(ParticlesState &state);
ParticlesBlock &get_non_full_block(uint particle_type_id);
+ void allocate_block_ranges(uint particle_type_id,
+ uint size,
+ SmallVector<ParticlesBlock *> &r_blocks,
+ SmallVector<Range<uint>> &r_ranges);
+
+ AttributesInfo &attributes_info(uint particle_type_id);
ParticlesState &particles_state()
{
@@ -157,6 +163,17 @@ class EmitTargetBase {
void fill_elements(uint index, void *value);
};
+class InstantEmitTarget : public EmitTargetBase {
+ public:
+ InstantEmitTarget(uint particle_type_id,
+ AttributesInfo &attributes_info,
+ ArrayRef<ParticlesBlock *> blocks,
+ ArrayRef<Range<uint>> ranges)
+ : EmitTargetBase(particle_type_id, attributes_info, blocks, ranges)
+ {
+ }
+};
+
class TimeSpanEmitTarget : public EmitTargetBase {
private:
SmallVector<float> m_birth_moments;
@@ -328,6 +345,7 @@ class ActionInterface {
private:
ParticleSet m_particles;
BlockAllocator &m_block_allocator;
+ SmallVector<InstantEmitTarget *> m_emit_targets;
public:
ActionInterface(ParticleSet particles, BlockAllocator &block_allocator)
@@ -335,6 +353,8 @@ class ActionInterface {
{
}
+ ~ActionInterface();
+
BlockAllocator &block_allocator()
{
return m_block_allocator;
@@ -344,6 +364,13 @@ class ActionInterface {
{
return m_particles;
}
+
+ InstantEmitTarget &request_emit_target(uint particle_type_id, uint size);
+
+ ArrayRef<InstantEmitTarget *> emit_targets()
+ {
+ return m_emit_targets;
+ }
};
class Action {
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index ecb28062c6d..fd027b91b0d 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -130,6 +130,11 @@ BLI_NOINLINE static void run_actions(BlockAllocator &block_allocator,
ActionInterface interface(particles, block_allocator);
action->execute(interface);
+
+ for (InstantEmitTarget *target_ptr : interface.emit_targets()) {
+ InstantEmitTarget &target = *target_ptr;
+ target.fill_float("Birth Time", block_allocator.particles_state().m_current_time);
+ }
}
}
More information about the Bf-blender-cvs
mailing list