[Bf-blender-cvs] [74fcb4d4c2f] master: Particles: initial particle birth action

Jacques Lucke noreply at git.blender.org
Fri Jul 24 13:39:45 CEST 2020


Commit: 74fcb4d4c2f3c72747119a672c7e322f6f910478
Author: Jacques Lucke
Date:   Fri Jul 24 13:37:55 2020 +0200
Branches: master
https://developer.blender.org/rB74fcb4d4c2f3c72747119a672c7e322f6f910478

Particles: initial particle birth action

A particle action is some function that is triggered by some event.
Right now, users cannot control this. There is just a
randomize-velocity on-birth action. So the direction of spawned
particles is slightly randomized now.

This also adds a new integer attribute called "Hash" which is
useful for a number of things. Mainly for generating random numbers
for a specific particle. The ID of a particle is not necessarily a good source
of randomness.

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

M	source/blender/simulation/intern/particle_allocator.cc
M	source/blender/simulation/intern/particle_allocator.hh
M	source/blender/simulation/intern/particle_function.cc
M	source/blender/simulation/intern/particle_mesh_emitter.cc
M	source/blender/simulation/intern/simulation_collect_influences.cc
M	source/blender/simulation/intern/simulation_solver.cc
M	source/blender/simulation/intern/simulation_solver_influences.hh

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

diff --git a/source/blender/simulation/intern/particle_allocator.cc b/source/blender/simulation/intern/particle_allocator.cc
index 5ff5909f506..e47a6354d81 100644
--- a/source/blender/simulation/intern/particle_allocator.cc
+++ b/source/blender/simulation/intern/particle_allocator.cc
@@ -16,6 +16,8 @@
 
 #include "particle_allocator.hh"
 
+#include "BLI_rand.hh"
+
 namespace blender::sim {
 
 AttributesAllocator::~AttributesAllocator()
@@ -67,6 +69,13 @@ fn::MutableAttributesRef ParticleAllocator::allocate(int size)
         ids[pindex] = start_id + pindex;
       }
     }
+    else if (name == "Hash") {
+      MutableSpan<int> hashes = attributes.get<int>("Hash");
+      RandomNumberGenerator rng(hash_seed_ ^ (uint32_t)next_id_);
+      for (int pindex : IndexRange(size)) {
+        hashes[pindex] = (int)rng.get_uint32();
+      }
+    }
     else {
       type.fill_uninitialized(info.default_of(i), attributes.get(i).data(), size);
     }
diff --git a/source/blender/simulation/intern/particle_allocator.hh b/source/blender/simulation/intern/particle_allocator.hh
index 1e7578a75ed..1c412508fe6 100644
--- a/source/blender/simulation/intern/particle_allocator.hh
+++ b/source/blender/simulation/intern/particle_allocator.hh
@@ -70,10 +70,11 @@ class ParticleAllocator : NonCopyable, NonMovable {
  private:
   AttributesAllocator attributes_allocator_;
   std::atomic<int> next_id_;
+  uint32_t hash_seed_;
 
  public:
-  ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id)
-      : attributes_allocator_(attributes_info), next_id_(next_id)
+  ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id, uint32_t hash_seed)
+      : attributes_allocator_(attributes_info), next_id_(next_id), hash_seed_(hash_seed)
   {
   }
 
diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc
index 935ef7983d9..1b259938e34 100644
--- a/source/blender/simulation/intern/particle_function.cc
+++ b/source/blender/simulation/intern/particle_function.cc
@@ -56,12 +56,11 @@ ParticleFunctionEvaluator::ParticleFunctionEvaluator(
     : particle_fn_(particle_fn),
       solve_context_(solve_context),
       particle_chunk_context_(particle_chunk_context),
-      mask_(particle_chunk_context_.index_mask()),
+      mask_(particle_chunk_context_.index_mask),
       outputs_(particle_fn_.output_types_.size(), nullptr)
 {
-  global_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map());
-  per_particle_context_.add_global_context("PersistentDataHandleMap",
-                                           &solve_context_.handle_map());
+  global_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map);
+  per_particle_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map);
 }
 
 ParticleFunctionEvaluator::~ParticleFunctionEvaluator()
@@ -117,7 +116,7 @@ void ParticleFunctionEvaluator::compute_globals()
 
   /* Add input parameters. */
   for (const ParticleFunctionInput *input : particle_fn_.global_inputs_) {
-    input->add_input(particle_chunk_context_.attributes(), params, resources_);
+    input->add_input(particle_chunk_context_.attributes, params, resources_);
   }
 
   /* Add output parameters. */
@@ -144,7 +143,7 @@ void ParticleFunctionEvaluator::compute_per_particle()
 
   /* Add input parameters. */
   for (const ParticleFunctionInput *input : particle_fn_.per_particle_inputs_) {
-    input->add_input(particle_chunk_context_.attributes(), params, resources_);
+    input->add_input(particle_chunk_context_.attributes, params, resources_);
   }
 
   /* Add output parameters. */
diff --git a/source/blender/simulation/intern/particle_mesh_emitter.cc b/source/blender/simulation/intern/particle_mesh_emitter.cc
index 15a6bffa884..81640695f92 100644
--- a/source/blender/simulation/intern/particle_mesh_emitter.cc
+++ b/source/blender/simulation/intern/particle_mesh_emitter.cc
@@ -291,7 +291,7 @@ static BLI_NOINLINE EmitterSettings compute_settings(const fn::MultiFunction &in
   EmitterSettings parameters;
 
   fn::MFContextBuilder mf_context;
-  mf_context.add_global_context("PersistentDataHandleMap", &context.solve_context().handle_map());
+  mf_context.add_global_context("PersistentDataHandleMap", &context.solve_context.handle_map);
 
   fn::MFParamsBuilder mf_params{inputs_fn, 1};
   bke::PersistentObjectHandle object_handle;
@@ -300,7 +300,7 @@ static BLI_NOINLINE EmitterSettings compute_settings(const fn::MultiFunction &in
 
   inputs_fn.call(IndexRange(1), mf_params, mf_context);
 
-  parameters.object = context.solve_context().handle_map().lookup(object_handle);
+  parameters.object = context.solve_context.handle_map.lookup(object_handle);
   return parameters;
 }
 
@@ -318,7 +318,7 @@ void ParticleMeshEmitter::emit(ParticleEmitterContext &context) const
   Vector<float> new_birth_times;
 
   if (!compute_new_particle_attributes(settings,
-                                       context.emit_interval(),
+                                       context.emit_interval,
                                        *state,
                                        new_positions,
                                        new_velocities,
diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc
index 7554f61404a..0fcaf78fe5b 100644
--- a/source/blender/simulation/intern/simulation_collect_influences.cc
+++ b/source/blender/simulation/intern/simulation_collect_influences.cc
@@ -26,6 +26,7 @@
 
 #include "DEG_depsgraph_query.h"
 
+#include "BLI_hash.h"
 #include "BLI_rand.hh"
 
 namespace blender::sim {
@@ -222,11 +223,11 @@ class ParticleFunctionForce : public ParticleForce {
 
   void add_force(ParticleForceContext &context) const override
   {
-    IndexMask mask = context.particle_chunk().index_mask();
-    MutableSpan<float3> r_combined_force = context.force_dst();
+    IndexMask mask = context.particle_chunk_context.index_mask;
+    MutableSpan<float3> r_combined_force = context.force_dst;
 
     ParticleFunctionEvaluator evaluator{
-        particle_fn_, context.solve_context(), context.particle_chunk()};
+        particle_fn_, context.solve_context, context.particle_chunk_context};
     evaluator.compute();
     fn::VSpan<float3> forces = evaluator.get<float3>(0, "Force");
 
@@ -341,6 +342,35 @@ static void collect_emitters(nodes::MFNetworkTreeMap &network_map,
   }
 }
 
+class RandomizeVelocityAction : public ParticleAction {
+ public:
+  void execute(ParticleActionContext &context) const override
+  {
+    MutableSpan<int> hashes = context.particle_chunk_context.attributes.get<int>("Hash");
+    MutableSpan<float3> velocities = context.particle_chunk_context.attributes.get<float3>(
+        "Velocity");
+    for (int i : context.particle_chunk_context.index_mask) {
+      const float x = BLI_hash_int_01((uint32_t)hashes[i] ^ 23423523u) - 0.5f;
+      const float y = BLI_hash_int_01((uint32_t)hashes[i] ^ 76463521u) - 0.5f;
+      const float z = BLI_hash_int_01((uint32_t)hashes[i] ^ 43523762u) - 0.5f;
+      float3 vector{x, y, z};
+      vector.normalize();
+      velocities[i] += vector * 0.3;
+    }
+  }
+};
+
+static void collect_birth_events(nodes::MFNetworkTreeMap &network_map,
+                                 ResourceCollector &resources,
+                                 SimulationInfluences &r_influences)
+{
+  RandomizeVelocityAction &action = resources.construct<RandomizeVelocityAction>(AT);
+  for (const nodes::DNode *dnode : get_particle_simulation_nodes(network_map.tree())) {
+    std::string particle_name = dnode_to_path(*dnode);
+    r_influences.particle_birth_actions.add_as(std::move(particle_name), &action);
+  }
+}
+
 static void prepare_particle_attribute_builders(nodes::MFNetworkTreeMap &network_map,
                                                 ResourceCollector &resources,
                                                 SimulationInfluences &r_influences)
@@ -353,6 +383,8 @@ static void prepare_particle_attribute_builders(nodes::MFNetworkTreeMap &network
     builder.add<int>("ID", 0);
     /* TODO: Use bool property, but need to add CD_PROP_BOOL first. */
     builder.add<int>("Dead", 0);
+    /* TODO: Use uint32_t, but we don't have a corresponding custom property type. */
+    builder.add<int>("Hash", 0);
     builder.add<float>("Birth Time", 0.0f);
     r_influences.particle_attributes_builder.add_new(std::move(name), &builder);
   }
@@ -381,6 +413,7 @@ void collect_simulation_influences(Simulation &simulation,
 
   collect_forces(network_map, resources, data_sources, r_influences);
   collect_emitters(network_map, resources, r_influences, r_required_states);
+  collect_birth_events(network_map, resources, r_influences);
 
   for (const nodes::DNode *dnode : get_particle_simulation_nodes(tree)) {
     r_required_states.add(dnode_to_path(*dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION);
diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc
index 5ab706dbb4b..a035a40f72f 100644
--- a/source/blender/simulation/intern/simulation_solver.cc
+++ b/source/blender/simulation/intern/simulation_solver.cc
@@ -34,7 +34,11 @@ ParticleEmitter::~ParticleEmitter()
 {
 }
 
-static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type)
+ParticleAction::~ParticleAction()
+{
+}
+
+static CustomDataType cpp_to_custom_data_type(const CPPType &type)
 {
   if (type.is<float3>()) {
     return CD_PROP_FLOAT3;
@@ -49,18 +53,18 @@ static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type)
   return CD_PROP_FLOAT;
 }
 
-static const fn::CPPType &custom_to_cpp_data_type(CustomDataType type)
+static const CPPType &custom_to_cpp_data_type(CustomDataType type)
 {
   switch (type) {
     case CD_PROP_FLOAT3:
-      return fn::CPPType::get<float3>();
+      return CPPType::get<float3>();
     case CD_PROP_FLOAT:
-      return fn::CPPType::get<float>();
+      return CPPType::get<float>();
     case CD_PROP_INT32:
-      return fn::CPPType::get<int32_t>();
+      return CPPType::get<int32_t>();
     default:
       BLI_assert(false);
-      re

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list