[Bf-blender-cvs] [0ae2a1d12af] master: Particles: improve emitter when object is animated

Jacques Lucke noreply at git.blender.org
Sat Jul 25 14:53:35 CEST 2020


Commit: 0ae2a1d12affc382d9fef8aff0703bea891fa0fb
Author: Jacques Lucke
Date:   Sat Jul 25 14:51:15 2020 +0200
Branches: master
https://developer.blender.org/rB0ae2a1d12affc382d9fef8aff0703bea891fa0fb

Particles: improve emitter when object is animated

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

M	source/blender/blenlib/BLI_float4x4.hh
M	source/blender/blenlib/BLI_multi_value_map.hh
M	source/blender/simulation/CMakeLists.txt
M	source/blender/simulation/intern/particle_mesh_emitter.cc
M	source/blender/simulation/intern/simulation_solver.cc
M	source/blender/simulation/intern/simulation_solver.hh
A	source/blender/simulation/intern/simulation_solver_influences.cc
M	source/blender/simulation/intern/simulation_solver_influences.hh
M	source/blender/simulation/intern/simulation_update.cc
M	source/blender/simulation/intern/time_interval.hh

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

diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh
index 5698d06f05d..b4f12f17cc2 100644
--- a/source/blender/blenlib/BLI_float4x4.hh
+++ b/source/blender/blenlib/BLI_float4x4.hh
@@ -93,6 +93,11 @@ struct float4x4 {
     return result;
   }
 
+  float4x4 inverted_transposed_affine() const
+  {
+    return this->inverted_affine().transposed();
+  }
+
   struct float3x3_ref {
     const float4x4 &data;
 
diff --git a/source/blender/blenlib/BLI_multi_value_map.hh b/source/blender/blenlib/BLI_multi_value_map.hh
index ca7a369ed29..c20c4ef9677 100644
--- a/source/blender/blenlib/BLI_multi_value_map.hh
+++ b/source/blender/blenlib/BLI_multi_value_map.hh
@@ -22,7 +22,8 @@
  *
  * A `blender::MultiValueMap<Key, Value>` is an unordered associative container that stores
  * key-value pairs. It is different from `blender::Map` in that it can store multiple values for
- * the same key. The list of values that corresponds to a specific key can contain duplicates.
+ * the same key. The list of values that corresponds to a specific key can contain duplicates
+ * and their order is maintained.
  *
  * This data structure is different from a `std::multi_map`, because multi_map can store the same
  * key more than once and MultiValueMap can't.
diff --git a/source/blender/simulation/CMakeLists.txt b/source/blender/simulation/CMakeLists.txt
index 6466a6e67d4..cbc6ee65303 100644
--- a/source/blender/simulation/CMakeLists.txt
+++ b/source/blender/simulation/CMakeLists.txt
@@ -45,6 +45,7 @@ set(SRC
   intern/particle_function.cc
   intern/particle_mesh_emitter.cc
   intern/simulation_collect_influences.cc
+  intern/simulation_solver_influences.cc
   intern/simulation_solver.cc
   intern/simulation_update.cc
 
diff --git a/source/blender/simulation/intern/particle_mesh_emitter.cc b/source/blender/simulation/intern/particle_mesh_emitter.cc
index 81640695f92..c1482a29cb7 100644
--- a/source/blender/simulation/intern/particle_mesh_emitter.cc
+++ b/source/blender/simulation/intern/particle_mesh_emitter.cc
@@ -46,7 +46,7 @@ static BLI_NOINLINE void compute_birth_times(float rate,
     counter++;
     const float time_offset = counter * time_between_particles;
     const float birth_time = state.last_birth_time + time_offset;
-    if (birth_time > emit_interval.end()) {
+    if (birth_time > emit_interval.stop()) {
       break;
     }
     if (birth_time <= emit_interval.start()) {
@@ -217,8 +217,8 @@ static BLI_NOINLINE void sample_looptris(RandomNumberGenerator &rng,
   }
 }
 
-static BLI_NOINLINE bool compute_new_particle_attributes(EmitterSettings &settings,
-                                                         TimeInterval emit_interval,
+static BLI_NOINLINE bool compute_new_particle_attributes(ParticleEmitterContext &context,
+                                                         EmitterSettings &settings,
                                                          ParticleMeshEmitterSimulationState &state,
                                                          Vector<float3> &r_positions,
                                                          Vector<float3> &r_velocities,
@@ -238,19 +238,17 @@ static BLI_NOINLINE bool compute_new_particle_attributes(EmitterSettings &settin
     return false;
   }
 
-  const float4x4 local_to_world = settings.object->obmat;
-  float4x4 local_to_world_normal = local_to_world.inverted_affine().transposed();
-
-  const float start_time = emit_interval.start();
+  const float start_time = context.emit_interval.start();
   const uint32_t seed = DefaultHash<StringRef>{}(state.head.name);
   RandomNumberGenerator rng{(*(uint32_t *)&start_time) ^ seed};
 
-  compute_birth_times(settings.rate, emit_interval, state, r_birth_times);
+  compute_birth_times(settings.rate, context.emit_interval, state, r_birth_times);
   const int particle_amount = r_birth_times.size();
   if (particle_amount == 0) {
     return false;
   }
 
+  const float last_birth_time = r_birth_times.last();
   rng.shuffle(r_birth_times.as_mutable_span());
 
   Span<MLoopTri> triangles = get_mesh_triangles(mesh);
@@ -266,22 +264,36 @@ static BLI_NOINLINE bool compute_new_particle_attributes(EmitterSettings &settin
     return false;
   }
 
-  Array<float3> local_positions(particle_amount);
-  Array<float3> local_normals(particle_amount);
-  sample_looptris(rng, mesh, triangles, triangles_to_sample, local_positions, local_normals);
+  r_positions.resize(particle_amount);
+  r_velocities.resize(particle_amount);
+  sample_looptris(rng, mesh, triangles, triangles_to_sample, r_positions, r_velocities);
 
-  r_positions.reserve(particle_amount);
-  r_velocities.reserve(particle_amount);
-  for (int i : IndexRange(particle_amount)) {
-    float3 position = local_to_world * local_positions[i];
-    float3 normal = local_to_world_normal.ref_3x3() * local_normals[i];
-    normal.normalize();
+  if (context.solve_context.dependency_animations.is_object_transform_changing(*settings.object)) {
+    Array<float4x4> local_to_world_matrices(particle_amount);
+    context.solve_context.dependency_animations.get_object_transforms(
+        *settings.object, r_birth_times, local_to_world_matrices);
 
-    r_positions.append(position);
-    r_velocities.append(normal);
+    for (int i : IndexRange(particle_amount)) {
+      const float4x4 &position_to_world = local_to_world_matrices[i];
+      const float4x4 normal_to_world = position_to_world.inverted_transposed_affine();
+      r_positions[i] = position_to_world * r_positions[i];
+      r_velocities[i] = normal_to_world * r_velocities[i];
+    }
+  }
+  else {
+    const float4x4 position_to_world = settings.object->obmat;
+    const float4x4 normal_to_world = position_to_world.inverted_transposed_affine();
+    for (int i : IndexRange(particle_amount)) {
+      r_positions[i] = position_to_world * r_positions[i];
+      r_velocities[i] = normal_to_world * r_velocities[i];
+    }
+  }
+
+  for (int i : IndexRange(particle_amount)) {
+    r_velocities[i].normalize();
   }
 
-  state.last_birth_time = r_birth_times.last();
+  state.last_birth_time = last_birth_time;
   return true;
 }
 
@@ -317,12 +329,8 @@ void ParticleMeshEmitter::emit(ParticleEmitterContext &context) const
   Vector<float3> new_velocities;
   Vector<float> new_birth_times;
 
-  if (!compute_new_particle_attributes(settings,
-                                       context.emit_interval,
-                                       *state,
-                                       new_positions,
-                                       new_velocities,
-                                       new_birth_times)) {
+  if (!compute_new_particle_attributes(
+          context, settings, *state, new_positions, new_velocities, new_birth_times)) {
     return;
   }
 
diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc
index a035a40f72f..f650528edb6 100644
--- a/source/blender/simulation/intern/simulation_solver.cc
+++ b/source/blender/simulation/intern/simulation_solver.cc
@@ -26,18 +26,6 @@
 
 namespace blender::sim {
 
-ParticleForce::~ParticleForce()
-{
-}
-
-ParticleEmitter::~ParticleEmitter()
-{
-}
-
-ParticleAction::~ParticleAction()
-{
-}
-
 static CustomDataType cpp_to_custom_data_type(const CPPType &type)
 {
   if (type.is<float3>()) {
@@ -178,7 +166,7 @@ BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &sol
 
   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());
+      solve_context, state, attributes, remaining_durations, solve_context.solve_interval.stop());
 }
 
 BLI_NOINLINE static void run_emitters(SimulationSolveContext &solve_context,
@@ -273,6 +261,7 @@ void solve_simulation_time_step(Simulation &simulation,
                                 Depsgraph &depsgraph,
                                 const SimulationInfluences &influences,
                                 const bke::PersistentDataHandleMap &handle_map,
+                                const DependencyAnimations &dependency_animations,
                                 float time_step)
 {
   SimulationStateMap state_map;
@@ -285,7 +274,8 @@ void solve_simulation_time_step(Simulation &simulation,
                                        influences,
                                        TimeInterval(simulation.current_simulation_time, time_step),
                                        state_map,
-                                       handle_map};
+                                       handle_map,
+                                       dependency_animations};
 
   Span<ParticleSimulationState *> particle_simulation_states =
       state_map.lookup<ParticleSimulationState>();
@@ -335,7 +325,7 @@ void solve_simulation_time_step(Simulation &simulation,
     for (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();
+      const float end_time = solve_context.solve_interval.stop();
       for (int i : attributes.index_range()) {
         remaining_durations[i] = end_time - birth_times[i];
       }
@@ -345,7 +335,7 @@ void solve_simulation_time_step(Simulation &simulation,
     remove_dead_and_add_new_particles(*state, allocator);
   }
 
-  simulation.current_simulation_time = solve_context.solve_interval.end();
+  simulation.current_simulation_time = solve_context.solve_interval.stop();
 }
 
 }  // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver.hh b/source/blender/simulation/intern/simulation_solver.hh
index ccf4855a9a1..9d30ea87731 100644
--- a/source/blender/simulation/intern/simulation_solver.hh
+++ b/source/blender/simulation/intern/simulation_solver.hh
@@ -32,6 +32,7 @@ void solve_simulation_time_step(Simulation &simulation,
                                 Depsgraph &depsgraph,
                                 const SimulationInfluences &influences,
      

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list