[Bf-blender-cvs] [dd47cbf3b7c] functions: use constant velocity integrator when there are no forces

Jacques Lucke noreply at git.blender.org
Sat Jul 20 13:44:29 CEST 2019


Commit: dd47cbf3b7cdebc645f4df15ef921b0f333179c3
Author: Jacques Lucke
Date:   Sat Jul 20 13:40:00 2019 +0200
Branches: functions
https://developer.blender.org/rBdd47cbf3b7cdebc645f4df15ef921b0f333179c3

use constant velocity integrator when there are no forces

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

M	source/blender/simulations/bparticles/integrator.cpp
M	source/blender/simulations/bparticles/integrator.hpp
M	source/blender/simulations/bparticles/node_frontend.cpp

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

diff --git a/source/blender/simulations/bparticles/integrator.cpp b/source/blender/simulations/bparticles/integrator.cpp
index 1b885052211..e67ae383c77 100644
--- a/source/blender/simulations/bparticles/integrator.cpp
+++ b/source/blender/simulations/bparticles/integrator.cpp
@@ -2,7 +2,31 @@
 
 namespace BParticles {
 
-EulerIntegrator::EulerIntegrator()
+ConstantVelocityIntegrator::ConstantVelocityIntegrator()
+{
+  AttributesDeclaration builder;
+  builder.add_float3("Position", {0, 0, 0});
+  m_offset_attributes_info = AttributesInfo(builder);
+}
+
+AttributesInfo &ConstantVelocityIntegrator::offset_attributes_info()
+{
+  return m_offset_attributes_info;
+}
+
+void ConstantVelocityIntegrator::integrate(IntegratorInterface &interface)
+{
+  ParticlesBlock &block = interface.block();
+  auto velocities = block.attributes().get_float3("Velocity");
+  auto position_offsets = interface.offsets().get_float3("Position");
+  auto durations = interface.durations();
+
+  for (uint pindex = 0; pindex < block.active_amount(); pindex++) {
+    position_offsets[pindex] = velocities[pindex] * durations[pindex];
+  }
+}
+
+EulerIntegrator::EulerIntegrator(ArrayRef<Force *> forces) : m_forces(forces)
 {
   AttributesDeclaration builder;
   builder.add_float3("Position", {0, 0, 0});
diff --git a/source/blender/simulations/bparticles/integrator.hpp b/source/blender/simulations/bparticles/integrator.hpp
index c3a21b3c91c..4321d0366c7 100644
--- a/source/blender/simulations/bparticles/integrator.hpp
+++ b/source/blender/simulations/bparticles/integrator.hpp
@@ -5,23 +5,28 @@
 
 namespace BParticles {
 
+class ConstantVelocityIntegrator : public Integrator {
+  AttributesInfo m_offset_attributes_info;
+
+ public:
+  ConstantVelocityIntegrator();
+
+  AttributesInfo &offset_attributes_info() override;
+  void integrate(IntegratorInterface &interface) override;
+};
+
 class EulerIntegrator : public Integrator {
  private:
   AttributesInfo m_offset_attributes_info;
   SmallVector<Force *> m_forces;
 
  public:
-  EulerIntegrator();
+  EulerIntegrator(ArrayRef<Force *> forces);
   ~EulerIntegrator();
 
   AttributesInfo &offset_attributes_info() override;
   void integrate(IntegratorInterface &interface) override;
 
-  void add_force(std::unique_ptr<Force> force)
-  {
-    m_forces.append(force.release());
-  }
-
  private:
   void compute_combined_force(ParticlesBlock &block, ArrayRef<float3> r_force);
 
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index aeb7c8cb2e9..67380bfffd9 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -1,4 +1,5 @@
 #include "BLI_timeit.hpp"
+#include "BLI_small_multimap.hpp"
 
 #include "node_frontend.hpp"
 #include "inserters.hpp"
@@ -6,6 +7,8 @@
 
 namespace BParticles {
 
+using BLI::SmallMultiMap;
+
 static bool is_particle_type_node(bNode *bnode)
 {
   return STREQ(bnode->idname, "bp_ParticleTypeNode");
@@ -27,6 +30,11 @@ static bNodeSocket *find_emitter_output(bNode *bnode)
   return nullptr;
 }
 
+static ArrayRef<bNode *> get_type_nodes(IndexedNodeTree &indexed_tree)
+{
+  return indexed_tree.nodes_with_idname("bp_ParticleTypeNode");
+}
+
 std::unique_ptr<StepDescription> step_description_from_node_tree(IndexedNodeTree &indexed_tree,
                                                                  WorldState &world_state,
                                                                  float time_step)
@@ -34,13 +42,9 @@ std::unique_ptr<StepDescription> step_description_from_node_tree(IndexedNodeTree
   SCOPED_TIMER(__func__);
 
   StepDescriptionBuilder step_builder;
-  StringMap<EulerIntegrator *> euler_integrators;
 
-  for (bNode *particle_type_node : indexed_tree.nodes_with_idname("bp_ParticleTypeNode")) {
+  for (bNode *particle_type_node : get_type_nodes(indexed_tree)) {
     auto &type_builder = step_builder.add_type(particle_type_node->name);
-    EulerIntegrator *integrator = new EulerIntegrator();
-    euler_integrators.add_new(particle_type_node->name, integrator);
-    type_builder.set_integrator(integrator);
     auto &attributes = type_builder.attributes();
     attributes.add_float3("Position", {0, 0, 0});
     attributes.add_float3("Velocity", {0, 0, 0});
@@ -52,6 +56,7 @@ std::unique_ptr<StepDescription> step_description_from_node_tree(IndexedNodeTree
 
   BuildContext ctx = {indexed_tree, data_graph, step_builder, world_state};
 
+  SmallMultiMap<std::string, Force *> forces;
   for (auto item : get_force_builders().items()) {
     for (bNode *bnode : indexed_tree.nodes_with_idname(item.key)) {
       bNodeSocket *force_output = bSocketList(bnode->outputs).get(0);
@@ -59,7 +64,7 @@ std::unique_ptr<StepDescription> step_description_from_node_tree(IndexedNodeTree
         if (is_particle_type_node(linked.node)) {
           auto force = item.value(ctx, bnode);
           if (force) {
-            euler_integrators.lookup(linked.node->name)->add_force(std::move(force));
+            forces.add(linked.node->name, force.release());
           }
         }
       }
@@ -108,6 +113,18 @@ std::unique_ptr<StepDescription> step_description_from_node_tree(IndexedNodeTree
     }
   }
 
+  for (bNode *bnode : get_type_nodes(indexed_tree)) {
+    std::string name = bnode->name;
+    ParticleTypeBuilder &type_builder = step_builder.get_type(name);
+    ArrayRef<Force *> forces_on_type = forces.lookup_default(name);
+    if (forces_on_type.size() == 0) {
+      type_builder.set_integrator(new ConstantVelocityIntegrator());
+    }
+    else {
+      type_builder.set_integrator(new EulerIntegrator(forces_on_type));
+    }
+  }
+
   return step_builder.build(time_step);
 }



More information about the Bf-blender-cvs mailing list