[Bf-blender-cvs] [24a02ee51b1] functions: initial action context chaining

Jacques Lucke noreply at git.blender.org
Tue Sep 3 16:23:21 CEST 2019


Commit: 24a02ee51b1a8b20e480dd30e83c9bdf059c64b4
Author: Jacques Lucke
Date:   Tue Sep 3 16:07:31 2019 +0200
Branches: functions
https://developer.blender.org/rB24a02ee51b1a8b20e480dd30e83c9bdf059c64b4

initial action context chaining

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

M	source/blender/simulations/bparticles/action_interface.hpp
M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/particle_function_input_providers.cpp

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

diff --git a/source/blender/simulations/bparticles/action_interface.hpp b/source/blender/simulations/bparticles/action_interface.hpp
index 5d35b39cf99..7e9d37e45cf 100644
--- a/source/blender/simulations/bparticles/action_interface.hpp
+++ b/source/blender/simulations/bparticles/action_interface.hpp
@@ -27,6 +27,34 @@ class EmitterActionContext {
   virtual void update(Range<uint> slice) = 0;
 };
 
+class SourceParticleActionContext : public ActionContext {
+ private:
+  ArrayRef<uint> m_all_source_indices;
+  ArrayRef<uint> m_current_source_indices;
+  ActionContext *m_source_context;
+
+ public:
+  SourceParticleActionContext(ArrayRef<uint> source_indices, ActionContext *source_context)
+      : m_all_source_indices(source_indices), m_source_context(source_context)
+  {
+  }
+
+  void update(Range<uint> slice)
+  {
+    m_current_source_indices = m_all_source_indices.slice(slice.start(), slice.size());
+  }
+
+  ArrayRef<uint> source_indices()
+  {
+    return m_current_source_indices;
+  }
+
+  ActionContext *source_context()
+  {
+    return m_source_context;
+  }
+};
+
 class ActionInterface {
  private:
   ParticleAllocator &m_particle_allocator;
@@ -71,7 +99,8 @@ class Action {
                           ActionContext *action_context = nullptr);
   void execute_for_subset(ArrayRef<uint> pindices, ActionInterface &action_interface);
   void execute_for_new_particles(AttributesRefGroup &new_particles,
-                                 ActionInterface &action_interface);
+                                 ActionInterface &action_interface,
+                                 SourceParticleActionContext *action_context);
   void execute_for_new_particles(AttributesRefGroup &new_particles,
                                  OffsetHandlerInterface &offset_handler_interface);
 };
@@ -169,16 +198,17 @@ inline void Action::execute_for_subset(ArrayRef<uint> pindices, ActionInterface
 }
 
 inline void Action::execute_for_new_particles(AttributesRefGroup &new_particles,
-                                              ActionInterface &action_interface)
+                                              ActionInterface &action_interface,
+                                              SourceParticleActionContext *action_context)
 {
   AttributesInfo info;
   std::array<void *, 0> buffers;
 
-  /* Use empty action context, until there a better solution is implemented. */
-  EmptyActionContext empty_context;
-
+  uint offset = 0;
   for (AttributesRef attributes : new_particles) {
     uint range_size = attributes.size();
+    action_context->update(Range<uint>(offset, offset + range_size));
+    offset += range_size;
 
     AttributesRef offsets(info, buffers, range_size);
     TemporaryArray<float> durations(range_size);
@@ -190,7 +220,7 @@ inline void Action::execute_for_new_particles(AttributesRefGroup &new_particles,
                                   offsets,
                                   attributes.get<float>("Birth Time"),
                                   durations,
-                                  empty_context);
+                                  *action_context);
     this->execute(new_interface);
   }
 }
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index 9ef4701d175..d0bf08042f0 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -1,4 +1,5 @@
 #include "actions.hpp"
+#include "action_contexts.hpp"
 
 #include "BLI_hash.h"
 
@@ -116,6 +117,7 @@ void ExplodeAction::execute(ActionInterface &interface)
   Vector<float3> new_positions;
   Vector<float3> new_velocities;
   Vector<float> new_birth_times;
+  Vector<uint> source_particles;
 
   auto inputs = m_compute_inputs->compute(interface);
 
@@ -123,6 +125,7 @@ void ExplodeAction::execute(ActionInterface &interface)
     uint parts_amount = std::max(0, inputs->get<int>("Amount", 0, pindex));
     float speed = inputs->get<float>("Speed", 1, pindex);
 
+    source_particles.append_n_times(pindex, parts_amount);
     new_positions.append_n_times(positions[pindex], parts_amount);
     new_birth_times.append_n_times(interface.current_times()[pindex], parts_amount);
 
@@ -138,7 +141,9 @@ void ExplodeAction::execute(ActionInterface &interface)
     new_particles.fill<float>("Size", 0.1f);
     new_particles.set<float>("Birth Time", new_birth_times);
 
-    m_on_birth_action->execute_for_new_particles(new_particles, interface);
+    SourceParticleActionContext source_context(source_particles, &interface.context());
+
+    m_on_birth_action->execute_for_new_particles(new_particles, interface, &source_context);
   }
 }
 
diff --git a/source/blender/simulations/bparticles/particle_function_input_providers.cpp b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
index b518c94c16d..9d0e19852f0 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.cpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
@@ -138,56 +138,110 @@ Optional<ParticleFunctionInputArray> SurfaceImageInputProvider::get(
 Optional<ParticleFunctionInputArray> VertexWeightInputProvider::get(
     InputProviderInterface &interface)
 {
-  auto *surface_info = dynamic_cast<MeshSurfaceActionContext *>(interface.action_context());
-  if (surface_info == nullptr) {
-    return {};
-  }
+  ActionContext *action_context = interface.action_context();
 
-  Object *object = surface_info->object();
-  Mesh *mesh = (Mesh *)object->data;
+  if (dynamic_cast<MeshSurfaceActionContext *>(action_context)) {
+    auto *surface_info = dynamic_cast<MeshSurfaceActionContext *>(action_context);
 
-  MDeformVert *vertex_weights = mesh->dvert;
-  int group_index = defgroup_name_index(object, m_group_name.data());
-  if (group_index == -1 || vertex_weights == nullptr) {
-    return {};
-  }
+    Object *object = surface_info->object();
+    Mesh *mesh = (Mesh *)object->data;
 
-  ArrayRef<float3> local_positions = surface_info->local_positions();
-  const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
+    MDeformVert *vertex_weights = mesh->dvert;
+    int group_index = defgroup_name_index(object, m_group_name.data());
+    if (group_index == -1 || vertex_weights == nullptr) {
+      return {};
+    }
 
-  float *weight_buffer = (float *)BLI_temporary_allocate(sizeof(float) *
-                                                         interface.attributes().size());
-  MutableArrayRef<float> weights(weight_buffer, interface.attributes().size());
+    ArrayRef<float3> local_positions = surface_info->local_positions();
+    const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
 
-  for (uint pindex : interface.pindices()) {
-    float3 local_position = local_positions[pindex];
-    uint triangle_index = surface_info->looptri_indices()[pindex];
-    const MLoopTri &triangle = triangles[triangle_index];
+    float *weight_buffer = (float *)BLI_temporary_allocate(sizeof(float) *
+                                                           interface.attributes().size());
+    MutableArrayRef<float> weights(weight_buffer, interface.attributes().size());
 
-    uint loop1 = triangle.tri[0];
-    uint loop2 = triangle.tri[1];
-    uint loop3 = triangle.tri[2];
+    for (uint pindex : interface.pindices()) {
+      float3 local_position = local_positions[pindex];
+      uint triangle_index = surface_info->looptri_indices()[pindex];
+      const MLoopTri &triangle = triangles[triangle_index];
 
-    uint vert1 = mesh->mloop[loop1].v;
-    uint vert2 = mesh->mloop[loop2].v;
-    uint vert3 = mesh->mloop[loop3].v;
+      uint loop1 = triangle.tri[0];
+      uint loop2 = triangle.tri[1];
+      uint loop3 = triangle.tri[2];
 
-    float3 v1 = mesh->mvert[vert1].co;
-    float3 v2 = mesh->mvert[vert2].co;
-    float3 v3 = mesh->mvert[vert3].co;
+      uint vert1 = mesh->mloop[loop1].v;
+      uint vert2 = mesh->mloop[loop2].v;
+      uint vert3 = mesh->mloop[loop3].v;
 
-    float3 bary_weights;
-    interp_weights_tri_v3(bary_weights, v1, v2, v3, local_position);
+      float3 v1 = mesh->mvert[vert1].co;
+      float3 v2 = mesh->mvert[vert2].co;
+      float3 v3 = mesh->mvert[vert3].co;
 
-    float3 corner_weights{defvert_find_weight(vertex_weights + vert1, group_index),
-                          defvert_find_weight(vertex_weights + vert2, group_index),
-                          defvert_find_weight(vertex_weights + vert3, group_index)};
+      float3 bary_weights;
+      interp_weights_tri_v3(bary_weights, v1, v2, v3, local_position);
 
-    float weight = float3::dot(bary_weights, corner_weights);
-    weights[pindex] = weight;
+      float3 corner_weights{defvert_find_weight(vertex_weights + vert1, group_index),
+                            defvert_find_weight(vertex_weights + vert2, group_index),
+                            defvert_find_weight(vertex_weights + vert3, group_index)};
+
+      float weight = float3::dot(bary_weights, corner_weights);
+      weights[pindex] = weight;
+    }
+
+    return ParticleFunctionInputArray(ArrayRef<float>(weights), true);
   }
+  else if (dynamic_cast<SourceParticleActionContext *>(action_context)) {
+    auto *source_info = dynamic_cast<SourceParticleActionContext *>(action_context);
+    auto *surface_info = dynamic_cast<MeshSurfaceActionContext *>(source_info->source_context());
+
+    Object *object = surface_info->object();
+    Mesh *mesh = (Mesh *)object->data;
+
+    MDeformVert *vertex_weights = mesh->dvert;
+    int group_index = defgroup_name_index(object, m_group_name.data());
+    if (group_index == -1 || vertex_weights == nullptr) {
+      return {};
+    }
+
+    const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
+
+    float *weight_buffer = (float *)BLI_temporary_allocate(sizeof(float) *
+                                                           interface.attributes().size());
+    MutableArrayRef<float> weights(weight_buffer, interface.attributes().size());
+
+    for (uint pindex : interface.pindices()) {
+      uint source_index = source_info->source_indices()[pindex];
+      float3 local_position = surface_info->local_positions()[source_index];
+    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list