[Bf-blender-cvs] [5dada6b4658] functions: new birth time modes for custom emitter

Jacques Lucke noreply at git.blender.org
Tue Dec 10 23:21:06 CET 2019


Commit: 5dada6b4658f12cbbc192ef2e8fe9b9c44ba92b4
Author: Jacques Lucke
Date:   Tue Dec 10 23:20:50 2019 +0100
Branches: functions
https://developer.blender.org/rB5dada6b4658f12cbbc192ef2e8fe9b9c44ba92b4

new birth time modes for custom emitter

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

M	release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
M	source/blender/functions/FN_attributes_ref.h
M	source/blender/simulations/bparticles/emitters.cpp
M	source/blender/simulations/bparticles/emitters.hpp
M	source/blender/simulations/bparticles/node_frontend.cpp
M	source/blender/simulations/bparticles/time_span.hpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py b/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
index b89e219e695..5f475271107 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
@@ -27,6 +27,18 @@ class CustomEmitter(bpy.types.Node, SimulationNode):
         type=CustomEmitterAttribute,
     )
 
+    birth_time_mode: EnumProperty(
+        name="Birth Time Mode",
+        items=[
+            ("NONE", "None", "Manually specify birth times of every particle", "NONE", 0),
+            ("BEGIN", "Begin", "Spawn particles at the beginning of each time step", "NONE", 1),
+            ("END", "End", "Spawn particles at the end of each time step", "NONE", 2),
+            ("RANDOM", "Random", "Spawn particles at random moments in the time step", "NONE", 3),
+            ("LINEAR", "Linear", "Distribute particles linearly in each time step", "NONE", 4),
+        ],
+        default="END",
+    )
+
     def declaration(self, builder: NodeBuilder):
         for i, item in enumerate(self.attributes):
             builder.vectorized_input(
@@ -39,6 +51,7 @@ class CustomEmitter(bpy.types.Node, SimulationNode):
         builder.influences_output("emitter", "Emitter")
 
     def draw(self, layout):
+        layout.prop(self, "birth_time_mode", text="Birth")
         self.invoke_type_selection(layout, "add_attribute", "Add Attribute", mode="BASE")
 
     def draw_socket(self, layout, socket, text, decl, index_in_decl):
diff --git a/source/blender/functions/FN_attributes_ref.h b/source/blender/functions/FN_attributes_ref.h
index 9f7e5ccd785..8dafe39d0f4 100644
--- a/source/blender/functions/FN_attributes_ref.h
+++ b/source/blender/functions/FN_attributes_ref.h
@@ -392,6 +392,11 @@ class AttributesRefGroup {
     this->fill(m_info->index_of(name), type, value);
   }
 
+  uint total_size() const
+  {
+    return m_total_size;
+  }
+
   class Iterator {
    private:
     AttributesRefGroup *m_group;
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index b076e02d9c8..989deb44411 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -406,9 +406,35 @@ void CustomEmitter::emit(EmitterInterface &interface)
     particle_count = 1;
   }
 
+  TimeSpan time_span = interface.time_span();
+
   for (StringRef system_name : m_systems_to_emit) {
     auto new_particles = interface.particle_allocator().request(system_name, particle_count);
-    new_particles.fill<float>("Birth Time", interface.time_span().end());
+
+    switch (m_birth_time_mode) {
+      case BirthTimeModes::None:
+      case BirthTimeModes::End:
+        new_particles.fill<float>("Birth Time", time_span.end());
+        break;
+      case BirthTimeModes::Begin:
+        new_particles.fill<float>("Birth Time", time_span.start());
+        break;
+      case BirthTimeModes::Linear: {
+        TemporaryArray<float> birth_times(new_particles.total_size());
+        time_span.sample_linear(birth_times);
+        new_particles.set<float>("Birth Time", birth_times);
+        break;
+      }
+      case BirthTimeModes::Random: {
+        TemporaryArray<float> birth_times(new_particles.total_size());
+        for (uint i = 0; i < particle_count; i++) {
+          birth_times[i] = time_span.interpolate(random_float());
+        }
+        new_particles.set<float>("Birth Time", birth_times);
+        break;
+      }
+    }
+
     const AttributesInfo &info = new_particles.info();
 
     for (uint param_index : m_emitter_function.param_indices()) {
diff --git a/source/blender/simulations/bparticles/emitters.hpp b/source/blender/simulations/bparticles/emitters.hpp
index 33a8bc88e9d..e98b615fe04 100644
--- a/source/blender/simulations/bparticles/emitters.hpp
+++ b/source/blender/simulations/bparticles/emitters.hpp
@@ -96,22 +96,35 @@ class InitialGridEmitter : public Emitter {
   void emit(EmitterInterface &interface) override;
 };
 
+namespace BirthTimeModes {
+enum Enum {
+  None = 0,
+  Begin = 1,
+  End = 2,
+  Random = 3,
+  Linear = 4,
+};
+}
+
 class CustomEmitter : public Emitter {
  private:
   ArrayRef<std::string> m_systems_to_emit;
   const MultiFunction &m_emitter_function;
   Vector<std::string> m_attribute_names;
   Action &m_action;
+  BirthTimeModes::Enum m_birth_time_mode;
 
  public:
   CustomEmitter(ArrayRef<std::string> systems_to_emit,
                 const MultiFunction &emitter_function,
                 Vector<std::string> attribute_names,
-                Action &action)
+                Action &action,
+                BirthTimeModes::Enum birth_time_mode)
       : m_systems_to_emit(systems_to_emit),
         m_emitter_function(emitter_function),
         m_attribute_names(std::move(attribute_names)),
-        m_action(action)
+        m_action(action),
+        m_birth_time_mode(birth_time_mode)
   {
   }
 
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 0782c95b40e..eb50f3622d8 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -760,9 +760,11 @@ static void PARSE_custom_emitter(XNodeInfluencesBuilder &builder)
   }
 
   Action &action = builder.build_action_list("Execute on Birth");
+  BirthTimeModes::Enum birth_time_mode = (BirthTimeModes::Enum)RNA_enum_get(builder.node_rna(),
+                                                                            "birth_time_mode");
 
   Emitter &emitter = builder.construct<CustomEmitter>(
-      system_names, *emitter_function, std::move(attribute_names), action);
+      system_names, *emitter_function, std::move(attribute_names), action, birth_time_mode);
   builder.add_emitter(emitter);
 }
 
diff --git a/source/blender/simulations/bparticles/time_span.hpp b/source/blender/simulations/bparticles/time_span.hpp
index 75d77fa99c2..a8cabcafb72 100644
--- a/source/blender/simulations/bparticles/time_span.hpp
+++ b/source/blender/simulations/bparticles/time_span.hpp
@@ -60,6 +60,20 @@ struct TimeSpan {
     }
   }
 
+  void sample_linear(MutableArrayRef<float> r_results)
+  {
+    if (r_results.size() == 0) {
+      return;
+    }
+    if (r_results.size() == 1) {
+      r_results[0] = this->interpolate(0.5f);
+    }
+    for (uint i : r_results.index_iterator()) {
+      float factor = (i - 1) / (float)r_results.size();
+      r_results[i] = this->interpolate(factor);
+    }
+  }
+
   /**
    * The reverse of interpolate.
    * Asserts when the duration is 0.



More information about the Bf-blender-cvs mailing list