[Bf-blender-cvs] [3b9e16a4f7b] master: Particles: initial support for the Time input node

Jacques Lucke noreply at git.blender.org
Tue Jul 28 12:11:41 CEST 2020


Commit: 3b9e16a4f7b8deca23ba8d2a02ef9182eb9d6bb4
Author: Jacques Lucke
Date:   Tue Jul 28 12:03:02 2020 +0200
Branches: master
https://developer.blender.org/rB3b9e16a4f7b8deca23ba8d2a02ef9182eb9d6bb4

Particles: initial support for the Time input node

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenlib/BLI_resource_collector.hh
M	source/blender/simulation/intern/particle_function.cc
M	source/blender/simulation/intern/particle_function.hh
M	source/blender/simulation/intern/simulation_collect_influences.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 2c9d7ae769a..7321f4f6345 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -487,7 +487,7 @@ simulation_node_categories = [
         NodeItem("SimulationNodeParticleSimulation"),
     ]),
     SimulationNodeCategory("SIM_INPUTS", "Input", items=[
-        not_implemented_node("SimulationNodeTime"),
+        NodeItem("SimulationNodeTime"),
         NodeItem("SimulationNodeParticleAttribute"),
         NodeItem("FunctionNodeGroupInstanceID"),
         NodeItem("ShaderNodeValue"),
diff --git a/source/blender/blenlib/BLI_resource_collector.hh b/source/blender/blenlib/BLI_resource_collector.hh
index 10d610da618..e1be87d8af2 100644
--- a/source/blender/blenlib/BLI_resource_collector.hh
+++ b/source/blender/blenlib/BLI_resource_collector.hh
@@ -79,6 +79,12 @@ class ResourceCollector : NonCopyable, NonMovable {
    */
   template<typename T> void add(destruct_ptr<T> resource, const char *name)
   {
+    /* There is no need to keep track of such types. */
+    if (std::is_trivially_destructible_v<T>) {
+      resource.release();
+      return;
+    }
+
     BLI_assert(resource.get() != nullptr);
     this->add(
         resource.release(),
diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc
index d1e9019a85a..035e6d50e21 100644
--- a/source/blender/simulation/intern/particle_function.cc
+++ b/source/blender/simulation/intern/particle_function.cc
@@ -116,8 +116,9 @@ void ParticleFunctionEvaluator::compute_globals()
   fn::MFParamsBuilder params(*particle_fn_.global_fn_, mask_.min_array_size());
 
   /* Add input parameters. */
+  ParticleFunctionInputContext input_context{solve_context_, particles_};
   for (const ParticleFunctionInput *input : particle_fn_.global_inputs_) {
-    input->add_input(particles_.attributes, params, resources_);
+    input->add_input(input_context, params, resources_);
   }
 
   /* Add output parameters. */
@@ -143,8 +144,9 @@ void ParticleFunctionEvaluator::compute_per_particle()
   fn::MFParamsBuilder params(*particle_fn_.per_particle_fn_, mask_.min_array_size());
 
   /* Add input parameters. */
+  ParticleFunctionInputContext input_context{solve_context_, particles_};
   for (const ParticleFunctionInput *input : particle_fn_.per_particle_inputs_) {
-    input->add_input(particles_.attributes, params, resources_);
+    input->add_input(input_context, params, resources_);
   }
 
   /* Add output parameters. */
diff --git a/source/blender/simulation/intern/particle_function.hh b/source/blender/simulation/intern/particle_function.hh
index abe0aae8522..c9b35640b47 100644
--- a/source/blender/simulation/intern/particle_function.hh
+++ b/source/blender/simulation/intern/particle_function.hh
@@ -26,10 +26,15 @@
 
 namespace blender::sim {
 
+struct ParticleFunctionInputContext {
+  const SimulationSolveContext &solve_context;
+  const ParticleChunkContext &particles;
+};
+
 class ParticleFunctionInput {
  public:
   virtual ~ParticleFunctionInput() = default;
-  virtual void add_input(fn::AttributesRef attributes,
+  virtual void add_input(ParticleFunctionInputContext &context,
                          fn::MFParamsBuilder &params,
                          ResourceCollector &resources) const = 0;
 };
diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc
index 40a29c95d25..4d339f9e323 100644
--- a/source/blender/simulation/intern/simulation_collect_influences.cc
+++ b/source/blender/simulation/intern/simulation_collect_influences.cc
@@ -28,12 +28,15 @@
 
 #include "BLI_hash.h"
 #include "BLI_rand.hh"
+#include "BLI_set.hh"
 
 namespace blender::sim {
 
 using fn::GVSpan;
 using fn::MFContextBuilder;
 using fn::MFDataType;
+using fn::MFDummyNode;
+using fn::MFFunctionNode;
 using fn::MFInputSocket;
 using fn::MFNetwork;
 using fn::MFNetworkEvaluator;
@@ -53,6 +56,8 @@ using nodes::NodeTreeRefMap;
 
 struct DummyDataSources {
   Map<const MFOutputSocket *, std::string> particle_attributes;
+  Set<const MFOutputSocket *> simulation_time;
+  Set<const MFOutputSocket *> scene_time;
 };
 
 extern "C" {
@@ -226,6 +231,47 @@ static void prepare_particle_attribute_nodes(CollectContext &context)
   }
 }
 
+static void prepare_time_input_nodes(CollectContext &context)
+{
+  Span<const DNode *> time_input_dnodes = nodes_by_type(context, "SimulationNodeTime");
+  Vector<const DNode *> simulation_time_inputs;
+  Vector<const DNode *> scene_time_inputs;
+  for (const DNode *dnode : time_input_dnodes) {
+    NodeSimInputTimeType type = (NodeSimInputTimeType)dnode->node_ref().bnode()->custom1;
+    switch (type) {
+      case NODE_SIM_INPUT_SIMULATION_TIME: {
+        simulation_time_inputs.append(dnode);
+        break;
+      }
+      case NODE_SIM_INPUT_SCENE_TIME: {
+        scene_time_inputs.append(dnode);
+        break;
+      }
+    }
+  }
+
+  if (simulation_time_inputs.size() > 0) {
+    MFOutputSocket &new_socket = context.network.add_input("Simulation Time",
+                                                           MFDataType::ForSingle<float>());
+    for (const DNode *dnode : simulation_time_inputs) {
+      MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+      context.network.relink(old_socket, new_socket);
+      context.network.remove(old_socket.node());
+    }
+    context.data_sources.simulation_time.add(&new_socket);
+  }
+  if (scene_time_inputs.size() > 0) {
+    MFOutputSocket &new_socket = context.network.add_input("Scene Time",
+                                                           MFDataType::ForSingle<float>());
+    for (const DNode *dnode : scene_time_inputs) {
+      MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+      context.network.relink(old_socket, new_socket);
+      context.network.remove(old_socket.node());
+    }
+    context.data_sources.scene_time.add(&new_socket);
+  }
+}
+
 class ParticleAttributeInput : public ParticleFunctionInput {
  private:
   std::string attribute_name_;
@@ -237,11 +283,12 @@ class ParticleAttributeInput : public ParticleFunctionInput {
   {
   }
 
-  void add_input(AttributesRef attributes,
+  void add_input(ParticleFunctionInputContext &context,
                  MFParamsBuilder &params,
                  ResourceCollector &UNUSED(resources)) const override
   {
-    std::optional<GSpan> span = attributes.try_get(attribute_name_, attribute_type_);
+    std::optional<GSpan> span = context.particles.attributes.try_get(attribute_name_,
+                                                                     attribute_type_);
     if (span.has_value()) {
       params.add_readonly_single_input(*span);
     }
@@ -251,6 +298,29 @@ class ParticleAttributeInput : public ParticleFunctionInput {
   }
 };
 
+class SceneTimeInput : public ParticleFunctionInput {
+  void add_input(ParticleFunctionInputContext &context,
+                 MFParamsBuilder &params,
+                 ResourceCollector &resources) const override
+  {
+    const float time = DEG_get_ctime(&context.solve_context.depsgraph);
+    float *time_ptr = &resources.construct<float>(AT, time);
+    params.add_readonly_single_input(time_ptr);
+  }
+};
+
+class SimulationTimeInput : public ParticleFunctionInput {
+  void add_input(ParticleFunctionInputContext &context,
+                 MFParamsBuilder &params,
+                 ResourceCollector &resources) const override
+  {
+    /* TODO: Vary this per particle. */
+    const float time = context.solve_context.solve_interval.stop();
+    float *time_ptr = &resources.construct<float>(AT, time);
+    params.add_readonly_single_input(time_ptr);
+  }
+};
+
 static const ParticleFunction *create_particle_function_for_inputs(
     CollectContext &context, Span<const MFInputSocket *> sockets_to_compute)
 {
@@ -264,13 +334,21 @@ static const ParticleFunction *create_particle_function_for_inputs(
 
   Vector<const ParticleFunctionInput *> per_particle_inputs;
   for (const MFOutputSocket *socket : dummy_deps) {
-    const std::string *attribute_name = context.data_sources.particle_attributes.lookup_ptr(
-        socket);
-    if (attribute_name == nullptr) {
-      return nullptr;
+    if (context.data_sources.particle_attributes.contains(socket)) {
+      const std::string *attribute_name = context.data_sources.particle_attributes.lookup_ptr(
+          socket);
+      if (attribute_name == nullptr) {
+        return nullptr;
+      }
+      per_particle_inputs.append(&context.resources.construct<ParticleAttributeInput>(
+          AT, *attribute_name, socket->data_type().single_type()));
+    }
+    else if (context.data_sources.scene_time.contains(socket)) {
+      per_particle_inputs.append(&context.resources.construct<SceneTimeInput>(AT));
+    }
+    else if (context.data_sources.simulation_time.contains(socket)) {
+      per_particle_inputs.append(&context.resources.construct<SimulationTimeInput>(AT));
     }
-    per_particle_inputs.append(&context.resources.construct<ParticleAttributeInput>(
-        AT, *attribute_name, socket->data_type().single_type()));
   }
 
   const MultiFunction &per_particle_fn = context.resources.construct<MFNetworkEvaluator>(
@@ -689,6 +767,7 @@ void collect_simulation_influences(Simulation &simulation,
   initialize_particle_attribute_builders(context);
 
   prepare_particle_attribute_nodes(context);
+  prepare_time_input_nodes(context);
 
   collect_forces(context);
   collect_emitters(context);



More information about the Bf-blender-cvs mailing list