[Bf-blender-cvs] [b65783941cf] functions: separate integrator from simulation

Jacques Lucke noreply at git.blender.org
Sat Jun 29 16:25:45 CEST 2019


Commit: b65783941cfd5d0fdf0f28036d1404cfbb189c0e
Author: Jacques Lucke
Date:   Sat Jun 29 13:44:00 2019 +0200
Branches: functions
https://developer.blender.org/rBb65783941cfd5d0fdf0f28036d1404cfbb189c0e

separate integrator from simulation

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

M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/core.cpp
M	source/blender/simulations/bparticles/core.hpp
M	source/blender/simulations/bparticles/events.cpp
M	source/blender/simulations/bparticles/forces.cpp
M	source/blender/simulations/bparticles/simulate.cpp

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

diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index 54958b7b7da..d26d46f25ff 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -54,17 +54,69 @@ void BParticles_state_free(BParticlesState state)
   delete unwrap(state);
 }
 
-class ModifierParticleType : public ParticleType {
+class EulerIntegrator : public Integrator {
+ private:
+  AttributesInfo m_integrated_attributes_info;
+
  public:
   SmallVector<Force *> m_forces;
-  SmallVector<Event *> m_events;
-  SmallVector<Action *> m_actions;
 
-  ~ModifierParticleType()
+  EulerIntegrator() : m_integrated_attributes_info({}, {}, {"Position", "Velocity"})
+  {
+  }
+
+  ~EulerIntegrator()
   {
     for (Force *force : m_forces) {
       delete force;
     }
+  }
+
+  AttributesInfo &integrated_attributes_info() override
+  {
+    return m_integrated_attributes_info;
+  }
+
+  void integrate(ParticlesBlock &block,
+                 ArrayRef<float> durations,
+                 AttributeArrays r_values) override
+  {
+    uint amount = block.active_amount();
+    BLI_assert(amount == r_values.size());
+
+    SmallVector<float3> combined_force(amount);
+    combined_force.fill({0, 0, 0});
+
+    for (Force *force : m_forces) {
+      force->add_force(block, combined_force);
+    }
+
+    auto last_velocities = block.slice_active().get_float3("Velocity");
+
+    auto position_offsets = r_values.get_float3("Position");
+    auto velocity_offsets = r_values.get_float3("Velocity");
+
+    for (uint pindex = 0; pindex < amount; pindex++) {
+      float mass = 1.0f;
+      float duration = durations[pindex];
+
+      velocity_offsets[pindex] = duration * combined_force[pindex] / mass;
+      position_offsets[pindex] = duration *
+                                 (last_velocities[pindex] + velocity_offsets[pindex] * 0.5f);
+    }
+  }
+};
+
+class ModifierParticleType : public ParticleType {
+ public:
+  SmallVector<Event *> m_events;
+  SmallVector<Action *> m_actions;
+  EulerIntegrator *m_integrator;
+
+  ~ModifierParticleType()
+  {
+    delete m_integrator;
+
     for (Event *event : m_events) {
       delete event;
     }
@@ -73,10 +125,6 @@ class ModifierParticleType : public ParticleType {
     }
   }
 
-  ArrayRef<Force *> forces() override
-  {
-    return m_forces;
-  }
   ArrayRef<Event *> events() override
   {
     return m_events;
@@ -85,6 +133,11 @@ class ModifierParticleType : public ParticleType {
   {
     return m_actions;
   }
+
+  Integrator &integrator() override
+  {
+    return *m_integrator;
+  }
 };
 
 class ModifierStepDescription : public StepDescription {
@@ -150,13 +203,15 @@ void BParticles_simulate_modifier(NodeParticlesModifierData *npmd,
     type0->m_events.append(
         EVENT_mesh_collection(&treedata, npmd->collision_object->obmat).release());
     type0->m_actions.append(ACTION_explode().release());
-    type0->m_forces.append(FORCE_directional({0, 0, -2}).release());
   }
+  type0->m_integrator = new EulerIntegrator();
+  type0->m_integrator->m_forces.append(FORCE_directional({0, 0, -2}).release());
 
   auto *type1 = new ModifierParticleType();
   description.m_types.add_new(1, type1);
   type1->m_events.append(EVENT_age_reached(0.3f).release());
   type1->m_actions.append(ACTION_kill().release());
+  type1->m_integrator = new EulerIntegrator();
 
   simulate_step(state, description);
 
diff --git a/source/blender/simulations/bparticles/core.cpp b/source/blender/simulations/bparticles/core.cpp
index 669f67e1f2c..b9f08ad883e 100644
--- a/source/blender/simulations/bparticles/core.cpp
+++ b/source/blender/simulations/bparticles/core.cpp
@@ -10,6 +10,10 @@ Emitter::~Emitter()
 {
 }
 
+Integrator::~Integrator()
+{
+}
+
 Action::~Action()
 {
 }
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index 814bd75b77b..6549a3363ea 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -265,18 +265,13 @@ struct ParticleSet {
 class Force {
  public:
   virtual ~Force();
-  virtual void add_force(ParticleSet particles, ArrayRef<float3> dst) = 0;
-};
-
-struct IdealOffsets {
-  ArrayRef<float3> position_offsets;
-  ArrayRef<float3> velocity_offsets;
+  virtual void add_force(ParticlesBlock &block, ArrayRef<float3> r_force) = 0;
 };
 
 class EventInterface {
  private:
   ParticleSet m_particles;
-  IdealOffsets &m_ideal_offsets;
+  AttributeArrays &m_integrated_attributes;
   ArrayRef<float> m_durations;
   float m_end_time;
 
@@ -285,13 +280,13 @@ class EventInterface {
 
  public:
   EventInterface(ParticleSet particles,
-                 IdealOffsets &ideal_offsets,
+                 AttributeArrays &integrated_attributes,
                  ArrayRef<float> durations,
                  float end_time,
                  SmallVector<uint> &r_filtered_indices,
                  SmallVector<float> &r_filtered_time_factors)
       : m_particles(particles),
-        m_ideal_offsets(ideal_offsets),
+        m_integrated_attributes(integrated_attributes),
         m_durations(durations),
         m_end_time(end_time),
         m_filtered_indices(r_filtered_indices),
@@ -315,9 +310,9 @@ class EventInterface {
     return TimeSpan(m_end_time - duration, duration);
   }
 
-  IdealOffsets &ideal_offsets()
+  AttributeArrays integrated_attributes()
   {
-    return m_ideal_offsets;
+    return m_integrated_attributes;
   }
 
   float end_time()
@@ -404,13 +399,24 @@ class Emitter {
   virtual void emit(EmitterInterface &interface) = 0;
 };
 
+class Integrator {
+ public:
+  virtual ~Integrator();
+
+  virtual AttributesInfo &integrated_attributes_info() = 0;
+
+  virtual void integrate(ParticlesBlock &block,
+                         ArrayRef<float> durations,
+                         AttributeArrays r_values) = 0;
+};
+
 class ParticleType {
  public:
   virtual ~ParticleType();
 
-  virtual ArrayRef<Force *> forces() = 0;
   virtual ArrayRef<Event *> events() = 0;
   virtual ArrayRef<Action *> action_per_event() = 0;
+  virtual Integrator &integrator() = 0;
 };
 
 class StepDescription {
diff --git a/source/blender/simulations/bparticles/events.cpp b/source/blender/simulations/bparticles/events.cpp
index de9084c6ee3..ca531adad28 100644
--- a/source/blender/simulations/bparticles/events.cpp
+++ b/source/blender/simulations/bparticles/events.cpp
@@ -49,7 +49,7 @@ class MeshCollisionEvent : public Event {
   {
     ParticleSet &particles = interface.particles();
     auto positions = particles.attributes().get_float3("Position");
-    auto position_offsets = interface.ideal_offsets().position_offsets;
+    auto position_offsets = interface.integrated_attributes().get_float3("Position");
 
     for (uint i : particles.range()) {
       uint pindex = particles.get_particle_index(i);
diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp
index 9ff3f1c8318..81d86a39592 100644
--- a/source/blender/simulations/bparticles/forces.cpp
+++ b/source/blender/simulations/bparticles/forces.cpp
@@ -13,10 +13,10 @@ class DirectionalForce : public Force {
   {
   }
 
-  void add_force(ParticleSet particles, ArrayRef<float3> dst) override
+  void add_force(ParticlesBlock &block, ArrayRef<float3> r_force) override
   {
-    for (uint i : particles.range()) {
-      dst[i] += m_force;
+    for (uint i = 0; i < block.active_amount(); i++) {
+      r_force[i] += m_force;
     }
   };
 };
@@ -30,15 +30,14 @@ class TurbulenceForce : public BParticles::Force {
   {
   }
 
-  void add_force(ParticleSet particles, ArrayRef<float3> dst) override
+  void add_force(ParticlesBlock &block, ArrayRef<float3> r_force) override
   {
-    auto positions = particles.attributes().get_float3("Position");
-    for (uint i : particles.indices()) {
-      uint pindex = particles.get_particle_index(i);
+    auto positions = block.slice_active().get_float3("Position");
 
+    for (uint pindex = 0; pindex < block.active_amount(); pindex++) {
       float3 pos = positions[pindex];
       float value = BLI_hnoise(0.5f, pos.x, pos.y, pos.z);
-      dst[i].z += value * m_strength;
+      r_force[pindex].z += value * m_strength;
     }
   }
 };
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 8a6939da144..eee4d59f46e 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -33,7 +33,7 @@ static ArrayRef<uint> static_number_range_ref(Range<uint> range)
  **************************************************/
 
 BLI_NOINLINE static void find_next_event_per_particle(ParticleSet particles,
-                                                      IdealOffsets &ideal_offsets,
+                                                      AttributeArrays &integrated_attributes,
                                                       ArrayRef<float> durations,
                                                       float end_time,
                                                       ArrayRef<Event *> events,
@@ -50,8 +50,12 @@ BLI_NOINLINE static void find_next_event_per_particle(ParticleSet particles,
     SmallVector<float> triggered_time_factors;
 
     Event *event = events[event_index];
-    EventInterface interface(
-        particles, ideal_offsets, durations, end_time, triggered_indices, triggered_time_factors);
+    EventInterface interface(particles,
+                             integrated_attributes,
+                             durations,
+                             end_time,
+                             triggered_indices,
+                             triggered_time_factors);
     event->filter(interface);
 
     for (uint i = 0; i < triggered_indices.size(); i++) {
@@ -78,29 +82,37 @@ BLI_NOINLINE static void find_next_event_per_particle(ParticleSet particles,
 }
 
 BLI_NOINLINE static void forward_particles_to_next_event_or_end(
-    ParticleSet particles, IdealOffsets &ideal_offsets, ArrayRef<float> time_factors_to_next_event)
+    ParticleSet particles,
+    AttributeArrays integ

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list