[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