[Bf-blender-cvs] [0b50ea51ccd] master: Particles: simulate partial time steps on newly emitted particles

Jacques Lucke noreply at git.blender.org
Thu Jul 23 23:03:29 CEST 2020


Commit: 0b50ea51ccdf8ac5b7f1cecee027c1ddd1b9620f
Author: Jacques Lucke
Date:   Thu Jul 23 23:03:19 2020 +0200
Branches: master
https://developer.blender.org/rB0b50ea51ccdf8ac5b7f1cecee027c1ddd1b9620f

Particles: simulate partial time steps on newly emitted particles

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

M	source/blender/simulation/intern/simulation_solver.cc
M	source/blender/simulation/intern/simulation_solver_influences.hh

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

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 {



More information about the Bf-blender-cvs mailing list