[Bf-blender-cvs] [49e5434e946] functions: initial collision event info

Jacques Lucke noreply at git.blender.org
Mon Jul 8 17:57:14 CEST 2019


Commit: 49e5434e946ce8572e810899fbf9bb31d3c0dbb5
Author: Jacques Lucke
Date:   Mon Jul 8 15:13:57 2019 +0200
Branches: functions
https://developer.blender.org/rB49e5434e946ce8572e810899fbf9bb31d3c0dbb5

initial collision event info

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

M	release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py
M	source/blender/blenlib/BLI_math.hpp
M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/core.hpp
M	source/blender/simulations/bparticles/events.cpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py b/release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py
index 2a6a5abbc78..6f56af7db69 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py
@@ -15,6 +15,7 @@ class MeshCollisionEventNode(bpy.types.Node, BParticlesNode):
     def declaration(self, builder : SocketBuilder):
         builder.event_input("event", "Event")
         builder.control_flow_output("on_event", "On event")
+        builder.fixed_output("normal", "EVENTNormal", "Vector")
 
     def draw(self, layout):
         layout.prop(self, "object", text="")
diff --git a/source/blender/blenlib/BLI_math.hpp b/source/blender/blenlib/BLI_math.hpp
index b98bd34a1b7..41d09dff541 100644
--- a/source/blender/blenlib/BLI_math.hpp
+++ b/source/blender/blenlib/BLI_math.hpp
@@ -101,6 +101,11 @@ struct float3 {
     return {a.x - b.x, a.y - b.y, a.z - b.z};
   }
 
+  friend float3 operator-(float3 a)
+  {
+    return {-a.x, -a.y, -a.z};
+  }
+
   void operator-=(float3 b)
   {
     this->x -= b.x;
diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index e59e342785a..064435ecae1 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -214,9 +214,10 @@ static bool is_particle_type_node(bNode *bnode)
   return STREQ(bnode->idname, "bp_ParticleTypeNode");
 }
 
-static bool is_particle_info_node(bNode *bnode)
+static bool is_particle_data_input(bNode *bnode)
 {
-  return STREQ(bnode->idname, "bp_ParticleInfoNode");
+  return STREQ(bnode->idname, "bp_ParticleInfoNode") ||
+         STREQ(bnode->idname, "bp_MeshCollisionEventNode");
 }
 
 static ArrayRef<bNode *> get_particle_type_nodes(IndexedNodeTree &indexed_tree)
@@ -238,7 +239,7 @@ static SmallVector<bNodeSocket *> find_input_sockets(IndexedNodeTree &indexed_tr
       BLI_assert(linked.size() <= 1);
       if (linked.size() == 1) {
         SocketWithNode origin = linked[0];
-        if (is_particle_info_node(origin.node)) {
+        if (is_particle_data_input(origin.node)) {
           found_inputs.add(origin.socket);
         }
         else {
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index 104945be238..fa01336cce0 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -462,6 +462,8 @@ class EventStorage {
 
   void *operator[](uint index);
   template<typename T> T &get(uint index);
+
+  uint max_element_size() const;
 };
 
 /**
@@ -846,6 +848,11 @@ template<typename T> inline T &EventStorage::get(uint index)
   return *(T *)(*this)[index];
 }
 
+inline uint EventStorage::max_element_size() const
+{
+  return m_stride;
+}
+
 /* EventFilterInterface inline functions
  **********************************************/
 
@@ -887,7 +894,9 @@ inline void EventFilterInterface::trigger_particle(uint index, float time_factor
 template<typename T>
 inline T &EventFilterInterface::trigger_particle(uint index, float time_factor)
 {
-  BLI_assert(sizeof(T) <= sizeof(m_dummy_event_storage));
+  BLI_STATIC_ASSERT(std::is_trivial<T>::value, "");
+  BLI_assert(sizeof(T) <= m_event_storage.max_element_size());
+  BLI_assert(sizeof(m_dummy_event_storage) >= m_event_storage.max_element_size());
   if (time_factor <= m_known_min_time_factors[index]) {
     this->trigger_particle(index, time_factor);
     return m_event_storage.get<T>(m_particles.get_particle_index(index));
@@ -939,6 +948,8 @@ inline float EventExecuteInterface::remaining_time_in_step(uint index)
 
 template<typename T> inline T &EventExecuteInterface::get_storage(uint pindex)
 {
+  BLI_STATIC_ASSERT(std::is_trivial<T>::value, "");
+  BLI_assert(sizeof(T) <= m_event_storage.max_element_size());
   return m_event_storage.get<T>(pindex);
 }
 
diff --git a/source/blender/simulations/bparticles/events.cpp b/source/blender/simulations/bparticles/events.cpp
index 3a8112a4223..9806cfcd943 100644
--- a/source/blender/simulations/bparticles/events.cpp
+++ b/source/blender/simulations/bparticles/events.cpp
@@ -91,6 +91,21 @@ class AgeReachedEvent : public Event {
   }
 };
 
+class CollisionEventInfo : public EventInfo {
+ private:
+  ArrayRef<float3> m_normals;
+
+ public:
+  CollisionEventInfo(ArrayRef<float3> normals) : m_normals(normals)
+  {
+  }
+
+  void *get_info_array(StringRef UNUSED(name)) override
+  {
+    return (void *)m_normals.begin();
+  }
+};
+
 class MeshCollisionEventFilter : public Event {
  private:
   std::string m_identifier;
@@ -107,6 +122,10 @@ class MeshCollisionEventFilter : public Event {
     float distance;
   };
 
+  struct EventStorage {
+    float3 normal;
+  };
+
  public:
   MeshCollisionEventFilter(StringRef identifier, Object *object, std::unique_ptr<Action> action)
       : m_identifier(identifier.to_std_string()), m_object(object), m_action(std::move(action))
@@ -123,10 +142,21 @@ class MeshCollisionEventFilter : public Event {
     free_bvhtree_from_mesh(&m_bvhtree_data);
   }
 
+  void attributes(TypeAttributeInterface &interface) override
+  {
+    interface.use(AttributeType::Float, m_identifier);
+  }
+
+  uint storage_size() override
+  {
+    return sizeof(EventStorage);
+  }
+
   void filter(EventFilterInterface &interface) override
   {
     ParticleSet &particles = interface.particles();
     auto positions = particles.attributes().get_float3("Position");
+    auto last_collision_times = particles.attributes().get_float(m_identifier);
     auto position_offsets = interface.attribute_offsets().get_float3("Position");
 
     for (uint i : particles.range()) {
@@ -139,7 +169,15 @@ class MeshCollisionEventFilter : public Event {
       auto result = this->ray_cast(ray_start, ray_direction, length);
       if (result.success) {
         float time_factor = result.distance / length;
-        interface.trigger_particle(i, time_factor);
+        float time = interface.time_span(i).interpolate(time_factor);
+        if (std::abs(last_collision_times[pindex] - time) < 0.0001f) {
+          continue;
+        }
+        auto &storage = interface.trigger_particle<EventStorage>(i, time_factor);
+        if (float3::dot(result.normal, ray_direction) > 0) {
+          result.normal = -result.normal;
+        }
+        storage.normal = m_local_to_world.transform_direction(result.normal).normalized();
       }
     }
   }
@@ -162,7 +200,18 @@ class MeshCollisionEventFilter : public Event {
 
   void execute(EventExecuteInterface &interface) override
   {
-    EmptyEventInfo event_info;
+    ParticleSet &particles = interface.particles();
+    SmallVector<float3> normals(particles.block().active_amount());
+    auto last_collision_times = particles.attributes().get_float(m_identifier);
+
+    for (uint i : particles.range()) {
+      uint pindex = particles.get_particle_index(i);
+      auto storage = interface.get_storage<EventStorage>(pindex);
+      normals[pindex] = storage.normal;
+      last_collision_times[pindex] = interface.current_times()[i];
+    }
+
+    CollisionEventInfo event_info(normals);
     m_action->execute(interface, event_info);
   }
 };



More information about the Bf-blender-cvs mailing list