Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-07-24 00:03:19 +0300
committerJacques Lucke <jacques@blender.org>2020-07-24 00:03:19 +0300
commit0b50ea51ccdf8ac5b7f1cecee027c1ddd1b9620f (patch)
tree4abdcafe13cb598009a84e51807476ccb461cf0d /source/blender/simulation
parentf359672c3589c5c474abe1de78fcf39dd59e3532 (diff)
Particles: simulate partial time steps on newly emitted particles
Diffstat (limited to 'source/blender/simulation')
-rw-r--r--source/blender/simulation/intern/simulation_solver.cc61
-rw-r--r--source/blender/simulation/intern/simulation_solver_influences.hh10
2 files changed, 51 insertions, 20 deletions
diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc
index 2bd9e72eeac..1ed60022e2d 100644
--- a/source/blender/simulation/intern/simulation_solver.cc
+++ b/source/blender/simulation/intern/simulation_solver.cc
@@ -129,35 +129,32 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At
}
}
-BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context,
- ParticleSimulationState &state,
- const fn::AttributesInfo &attributes_info)
+BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ fn::MutableAttributesRef attributes,
+ MutableSpan<float> remaining_durations,
+ float end_time)
{
- CustomDataAttributesRef custom_data_attributes{
- state.attributes, state.tot_particles, attributes_info};
- fn::MutableAttributesRef attributes = custom_data_attributes;
+ int particle_amount = attributes.size();
+ Array<float3> force_vectors{particle_amount, {0, 0, 0}};
+ Span<const ParticleForce *> forces = solve_context.influences().get_particle_forces(
+ state.head.name);
- Array<float3> force_vectors{state.tot_particles, {0, 0, 0}};
- const Vector<const ParticleForce *> *forces =
- solve_context.influences().particle_forces.lookup_ptr(state.head.name);
+ ParticleChunkContext particle_chunk_context{IndexMask(particle_amount), attributes};
+ ParticleForceContext particle_force_context{
+ solve_context, particle_chunk_context, force_vectors};
- if (forces != nullptr) {
- ParticleChunkContext particle_chunk_context{IndexMask(state.tot_particles), attributes};
- ParticleForceContext particle_force_context{
- solve_context, particle_chunk_context, force_vectors};
-
- for (const ParticleForce *force : *forces) {
- force->add_force(particle_force_context);
- }
+ for (const ParticleForce *force : forces) {
+ force->add_force(particle_force_context);
}
MutableSpan<float3> positions = attributes.get<float3>("Position");
MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
MutableSpan<float> birth_times = attributes.get<float>("Birth Time");
MutableSpan<int> dead_states = attributes.get<int>("Dead");
- float end_time = solve_context.solve_interval().end();
- float time_step = solve_context.solve_interval().duration();
- for (int i : positions.index_range()) {
+
+ for (int i : IndexRange(particle_amount)) {
+ const float time_step = remaining_durations[i];
velocities[i] += force_vectors[i] * time_step;
positions[i] += velocities[i] * time_step;
@@ -167,6 +164,19 @@ BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &sol
}
}
+BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ const fn::AttributesInfo &attributes_info)
+{
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, attributes_info};
+ fn::MutableAttributesRef attributes = custom_data_attributes;
+
+ Array<float> remaining_durations(state.tot_particles, solve_context.solve_interval().duration());
+ simulate_particle_chunk(
+ solve_context, state, attributes, remaining_durations, solve_context.solve_interval().end());
+}
+
BLI_NOINLINE static void run_emitters(SimulationSolveContext &solve_context,
ParticleAllocators &particle_allocators)
{
@@ -301,6 +311,17 @@ void solve_simulation_time_step(Simulation &simulation,
for (ParticleSimulationState *state : particle_simulation_states) {
ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name);
+
+ for (fn::MutableAttributesRef attributes : allocator.get_allocations()) {
+ Array<float> remaining_durations(attributes.size());
+ Span<float> birth_times = attributes.get<float>("Birth Time");
+ const float end_time = solve_context.solve_interval().end();
+ for (int i : attributes.index_range()) {
+ remaining_durations[i] = end_time - birth_times[i];
+ }
+ simulate_particle_chunk(solve_context, *state, attributes, remaining_durations, end_time);
+ }
+
remove_dead_and_add_new_particles(*state, allocator);
}
diff --git a/source/blender/simulation/intern/simulation_solver_influences.hh b/source/blender/simulation/intern/simulation_solver_influences.hh
index 8d5e171bea0..0eb4dfbaf69 100644
--- a/source/blender/simulation/intern/simulation_solver_influences.hh
+++ b/source/blender/simulation/intern/simulation_solver_influences.hh
@@ -48,9 +48,19 @@ class ParticleForce {
};
struct SimulationInfluences {
+ /* TODO: Use a special type for a map that contains vectors. */
Map<std::string, Vector<const ParticleForce *>> particle_forces;
Map<std::string, fn::AttributesInfoBuilder *> particle_attributes_builder;
Vector<const ParticleEmitter *> particle_emitters;
+
+ Span<const ParticleForce *> get_particle_forces(StringRef particle_name) const
+ {
+ const Vector<const ParticleForce *> *forces = particle_forces.lookup_ptr(particle_name);
+ if (forces == nullptr) {
+ return {};
+ }
+ return *forces;
+ }
};
class SimulationStateMap {