[Bf-blender-cvs] [fce176dbd03] functions: fix mesh emitter action context

Jacques Lucke noreply at git.blender.org
Mon Sep 2 15:40:27 CEST 2019


Commit: fce176dbd036dc48871cd07daf976d3d96963c05
Author: Jacques Lucke
Date:   Mon Sep 2 15:40:13 2019 +0200
Branches: functions
https://developer.blender.org/rBfce176dbd036dc48871cd07daf976d3d96963c05

fix mesh emitter action context

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

M	source/blender/blenlib/BLI_array_ref.hpp
M	source/blender/blenlib/BLI_range.hpp
M	source/blender/simulations/bparticles/action_contexts.hpp
M	source/blender/simulations/bparticles/action_interface.hpp
M	source/blender/simulations/bparticles/emitters.cpp

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

diff --git a/source/blender/blenlib/BLI_array_ref.hpp b/source/blender/blenlib/BLI_array_ref.hpp
index 9b0424f72f1..cf1bafad8ff 100644
--- a/source/blender/blenlib/BLI_array_ref.hpp
+++ b/source/blender/blenlib/BLI_array_ref.hpp
@@ -82,7 +82,7 @@ template<typename T> class ArrayRef {
    */
   ArrayRef slice(uint start, uint length) const
   {
-    BLI_assert(start + length <= this->size());
+    BLI_assert(start + length <= this->size() || length == 0);
     return ArrayRef(m_start + start, length);
   }
 
diff --git a/source/blender/blenlib/BLI_range.hpp b/source/blender/blenlib/BLI_range.hpp
index 064444cfaa1..752311a213e 100644
--- a/source/blender/blenlib/BLI_range.hpp
+++ b/source/blender/blenlib/BLI_range.hpp
@@ -104,7 +104,7 @@ template<typename T> class Range {
   }
 
   /**
-   * Get the number of numbers in the range.
+   * Get the amount of numbers in the range.
    */
   uint size() const
   {
diff --git a/source/blender/simulations/bparticles/action_contexts.hpp b/source/blender/simulations/bparticles/action_contexts.hpp
index 318b0556113..3eacb245ba7 100644
--- a/source/blender/simulations/bparticles/action_contexts.hpp
+++ b/source/blender/simulations/bparticles/action_contexts.hpp
@@ -16,6 +16,77 @@ class MeshSurfaceActionContext : public ActionContext {
   virtual ArrayRef<uint> looptri_indices() const = 0;
 };
 
+class MeshEmitterContext : public MeshSurfaceActionContext, public EmitterActionContext {
+ private:
+  Object *m_object;
+  ArrayRef<float4x4> m_world_transforms;
+  ArrayRef<float3> m_local_positions;
+  ArrayRef<float3> m_local_normals;
+  ArrayRef<float3> m_world_normals;
+  ArrayRef<uint> m_looptri_indices;
+
+  ArrayRef<float4x4> m_all_world_transforms;
+  ArrayRef<float3> m_all_local_positions;
+  ArrayRef<float3> m_all_local_normals;
+  ArrayRef<float3> m_all_world_normals;
+  ArrayRef<uint> m_all_looptri_indices;
+
+ public:
+  MeshEmitterContext(Object *object,
+                     ArrayRef<float4x4> all_world_transforms,
+                     ArrayRef<float3> all_local_positions,
+                     ArrayRef<float3> all_local_normals,
+                     ArrayRef<float3> all_world_normals,
+                     ArrayRef<uint> all_looptri_indices)
+      : m_object(object),
+        m_all_world_transforms(all_world_transforms),
+        m_all_local_positions(all_local_positions),
+        m_all_local_normals(all_local_normals),
+        m_all_world_normals(all_world_normals),
+        m_all_looptri_indices(all_looptri_indices)
+  {
+  }
+
+  void update(Range<uint> slice) override
+  {
+    m_world_transforms = m_all_world_transforms.slice(slice.start(), slice.size());
+    m_local_positions = m_all_local_positions.slice(slice.start(), slice.size());
+    m_local_normals = m_all_local_normals.slice(slice.start(), slice.size());
+    m_world_normals = m_all_world_normals.slice(slice.start(), slice.size());
+    m_looptri_indices = m_all_looptri_indices.slice(slice.start(), slice.size());
+  }
+
+  const Object *object() const override
+  {
+    return m_object;
+  }
+
+  ArrayRef<float4x4> world_transforms() const override
+  {
+    return m_world_transforms;
+  }
+
+  ArrayRef<float3> local_positions() const override
+  {
+    return m_local_positions;
+  }
+
+  ArrayRef<float3> local_normals() const override
+  {
+    return m_local_normals;
+  }
+
+  ArrayRef<float3> world_normals() const override
+  {
+    return m_world_normals;
+  }
+
+  ArrayRef<uint> looptri_indices() const override
+  {
+    return m_looptri_indices;
+  }
+};
+
 class MeshCollisionContext : public MeshSurfaceActionContext {
  private:
   Object *m_object;
diff --git a/source/blender/simulations/bparticles/action_interface.hpp b/source/blender/simulations/bparticles/action_interface.hpp
index 98cc4f409ad..96f5782caea 100644
--- a/source/blender/simulations/bparticles/action_interface.hpp
+++ b/source/blender/simulations/bparticles/action_interface.hpp
@@ -19,6 +19,11 @@ class ActionContext {
   virtual ~ActionContext();
 };
 
+class EmitterActionContext {
+ public:
+  virtual void update(Range<uint> slice) = 0;
+};
+
 class ActionInterface {
  private:
   ParticleAllocator &m_particle_allocator;
@@ -55,7 +60,7 @@ class Action {
 
   void execute_from_emitter(ParticleSets &particle_sets,
                             EmitterInterface &emitter_interface,
-                            ActionContext *action_context = nullptr);
+                            EmitterActionContext *emitter_action_context = nullptr);
   void execute_from_event(EventExecuteInterface &event_interface,
                           ActionContext *action_context = nullptr);
   void execute_for_subset(ArrayRef<uint> pindices, ActionInterface &action_interface);
@@ -85,18 +90,29 @@ inline ActionInterface::ActionInterface(ParticleAllocator &particle_allocator,
 class EmptyActionContext : public ActionContext {
 };
 
+class EmptyEmitterActionContext : public EmitterActionContext {
+  void update(Range<uint> UNUSED(slice))
+  {
+  }
+};
+
 inline void Action::execute_from_emitter(ParticleSets &particle_sets,
                                          EmitterInterface &emitter_interface,
-                                         ActionContext *action_context)
+                                         EmitterActionContext *emitter_action_context)
 {
   AttributesInfo info;
   std::array<void *, 0> buffers;
 
-  EmptyActionContext empty_action_context;
-  ActionContext &used_action_context = (action_context == nullptr) ? empty_action_context :
-                                                                     *action_context;
+  EmptyEmitterActionContext empty_emitter_context;
+  EmitterActionContext &used_emitter_context = (emitter_action_context == nullptr) ?
+                                                   empty_emitter_context :
+                                                   *emitter_action_context;
 
+  uint offset = 0;
   for (ParticleSet particles : particle_sets.sets()) {
+    used_emitter_context.update(Range<uint>(offset, offset + particles.size()));
+    offset += particles.size();
+
     uint min_array_size = particles.attributes().size();
     AttributeArrays offsets(info, buffers, min_array_size);
     TemporaryArray<float> durations(min_array_size);
@@ -106,7 +122,7 @@ inline void Action::execute_from_emitter(ParticleSets &particle_sets,
                                      offsets,
                                      particles.attributes().get<float>("Birth Time"),
                                      durations,
-                                     used_action_context);
+                                     dynamic_cast<ActionContext &>(used_emitter_context));
     this->execute(action_interface);
   }
 }
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index 0da811e6dbf..d6e1fd90810 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -331,14 +331,14 @@ void SurfaceEmitter::emit(EmitterInterface &interface)
     new_particles.set<float>("Size", sizes);
     new_particles.set<float>("Birth Time", birth_times);
 
-    // MeshSurfaceActionContext action_context(m_object,
-    //                                         transforms_at_birth,
-    //                                         local_positions,
-    //                                         local_normals,
-    //                                         world_normals,
-    //                                         triangles_to_sample);
-
-    m_on_birth_action->execute_from_emitter(new_particles, interface);
+    MeshEmitterContext emitter_context(m_object,
+                                       transforms_at_birth,
+                                       local_positions,
+                                       local_normals,
+                                       world_normals,
+                                       triangles_to_sample);
+
+    m_on_birth_action->execute_from_emitter(new_particles, interface, &emitter_context);
   }
 }



More information about the Bf-blender-cvs mailing list