[Bf-blender-cvs] [fa79121db2a] functions: initial mesh collision event node

Jacques Lucke noreply at git.blender.org
Fri Jul 5 17:38:58 CEST 2019


Commit: fa79121db2a6116fabed60b4b6dee175d39381e8
Author: Jacques Lucke
Date:   Fri Jul 5 15:40:58 2019 +0200
Branches: functions
https://developer.blender.org/rBfa79121db2a6116fabed60b4b6dee175d39381e8

initial mesh collision event node

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

A	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/events.cpp
M	source/blender/simulations/bparticles/events.hpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py b/release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py
new file mode 100644
index 00000000000..2a6a5abbc78
--- /dev/null
+++ b/release/scripts/startup/nodes/bparticle_nodes/mesh_collision_event.py
@@ -0,0 +1,20 @@
+import bpy
+from bpy.props import *
+from .. base import BParticlesNode
+from .. socket_builder import SocketBuilder
+
+class MeshCollisionEventNode(bpy.types.Node, BParticlesNode):
+    bl_idname = "bp_MeshCollisionEventNode"
+    bl_label = "Mesh Collision Event"
+
+    object: PointerProperty(
+        name="Object",
+        type=bpy.types.Object,
+    )
+
+    def declaration(self, builder : SocketBuilder):
+        builder.event_input("event", "Event")
+        builder.control_flow_output("on_event", "On event")
+
+    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 38a9aed7b26..b98bd34a1b7 100644
--- a/source/blender/blenlib/BLI_math.hpp
+++ b/source/blender/blenlib/BLI_math.hpp
@@ -156,6 +156,8 @@ struct float3 {
 struct float4x4 {
   float values[4][4];
 
+  float4x4() = default;
+
   float4x4(float *matrix)
   {
     memcpy(values, matrix, sizeof(float) * 16);
diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index 1b346a6b0d5..e366b4fb5ab 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -399,14 +399,45 @@ static void INSERT_EVENT_age_reached(bNode *event_node,
       continue;
     }
 
+    EventFilter *event_filter = EVENT_age_reached(event_node->name, fn);
+    Action *action = build_action({(bNodeSocket *)event_node->outputs.first, event_node},
+                                  indexed_tree,
+                                  data_graph,
+                                  step_description);
+    Event *event = new EventFilterWithAction(event_filter, action);
+
     bNode *type_node = linked.node;
+    step_description.m_types.lookup_ref(type_node->name)->m_events.append(event);
+  }
+}
 
-    EventFilter *event_filter = EVENT_age_reached(event_node->name, fn);
+static void INSERT_EVENT_mesh_collision(bNode *event_node,
+                                        IndexedNodeTree &indexed_tree,
+                                        FN::DataFlowNodes::GeneratedGraph &data_graph,
+                                        ModifierStepDescription &step_description)
+{
+  BLI_assert(STREQ(event_node->idname, "bp_MeshCollisionEventNode"));
+  bSocketList node_inputs(event_node->inputs);
+
+  for (SocketWithNode linked : indexed_tree.linked(node_inputs.get(0))) {
+    if (!is_particle_type_node(linked.node)) {
+      continue;
+    }
+
+    PointerRNA rna = indexed_tree.get_rna(event_node);
+    Object *object = (Object *)RNA_pointer_get(&rna, "object").id.data;
+    if (object == nullptr || object->type != OB_MESH) {
+      continue;
+    }
+
+    EventFilter *event_filter = EVENT_mesh_collision(event_node->name, object);
     Action *action = build_action({(bNodeSocket *)event_node->outputs.first, event_node},
                                   indexed_tree,
                                   data_graph,
                                   step_description);
     Event *event = new EventFilterWithAction(event_filter, action);
+
+    bNode *type_node = linked.node;
     step_description.m_types.lookup_ref(type_node->name)->m_events.append(event);
   }
 }
@@ -421,6 +452,7 @@ static ModifierStepDescription *step_description_from_node_tree(bNodeTree *btree
 
   SmallMap<std::string, EventInserter> event_inserters;
   event_inserters.add_new("bp_AgeReachedEventNode", INSERT_EVENT_age_reached);
+  event_inserters.add_new("bp_MeshCollisionEventNode", INSERT_EVENT_mesh_collision);
 
   ModifierStepDescription *step_description = new ModifierStepDescription();
 
diff --git a/source/blender/simulations/bparticles/events.cpp b/source/blender/simulations/bparticles/events.cpp
index 34b501cad3c..3a49d98c208 100644
--- a/source/blender/simulations/bparticles/events.cpp
+++ b/source/blender/simulations/bparticles/events.cpp
@@ -4,6 +4,8 @@
 
 #include "BKE_bvhutils.h"
 
+#include "DNA_object_types.h"
+
 namespace BParticles {
 
 EventFilter::~EventFilter()
@@ -78,16 +80,14 @@ class AgeReachedEvent : public EventFilter {
   }
 };
 
-class MeshBounceEvent : public Event {
+class MeshCollisionEventFilter : public EventFilter {
  private:
-  BVHTreeFromMesh *m_treedata;
+  std::string m_identifier;
+  Object *m_object;
+  BVHTreeFromMesh m_bvhtree_data;
   float4x4 m_local_to_world;
   float4x4 m_world_to_local;
 
-  struct EventData {
-    float3 hit_normal;
-  };
-
   struct RayCastResult {
     bool success;
     int index;
@@ -96,16 +96,19 @@ class MeshBounceEvent : public Event {
   };
 
  public:
-  MeshBounceEvent(BVHTreeFromMesh *treedata, float4x4 transform)
-      : m_treedata(treedata),
-        m_local_to_world(transform),
-        m_world_to_local(transform.inverted__LocRotScale())
+  MeshCollisionEventFilter(StringRef identifier, Object *object)
+      : m_identifier(identifier.to_std_string()), m_object(object)
   {
+    BLI_assert(object->type == OB_MESH);
+    m_local_to_world = m_object->obmat;
+    m_world_to_local = m_local_to_world.inverted__LocRotScale();
+
+    BKE_bvhtree_from_mesh_get(&m_bvhtree_data, (Mesh *)object->data, BVHTREE_FROM_LOOPTRI, 2);
   }
 
-  uint storage_size() override
+  ~MeshCollisionEventFilter()
   {
-    return sizeof(EventData);
+    free_bvhtree_from_mesh(&m_bvhtree_data);
   }
 
   void filter(EventFilterInterface &interface) override
@@ -124,13 +127,7 @@ class MeshBounceEvent : public Event {
       auto result = this->ray_cast(ray_start, ray_direction, length);
       if (result.success) {
         float time_factor = result.distance / length;
-        auto &data = interface.trigger_particle<EventData>(i, time_factor);
-
-        float3 normal = result.normal;
-        if (float3::dot(normal, ray_direction) > 0) {
-          normal.invert();
-        }
-        data.hit_normal = m_local_to_world.transform_direction(normal).normalized();
+        interface.trigger_particle(i, time_factor);
       }
     }
   }
@@ -140,46 +137,16 @@ class MeshBounceEvent : public Event {
     BVHTreeRayHit hit;
     hit.dist = max_distance;
     hit.index = -1;
-    BLI_bvhtree_ray_cast(m_treedata->tree,
+    BLI_bvhtree_ray_cast(m_bvhtree_data.tree,
                          start,
                          normalized_direction,
                          0.0f,
                          &hit,
-                         m_treedata->raycast_callback,
-                         (void *)m_treedata);
+                         m_bvhtree_data.raycast_callback,
+                         (void *)&m_bvhtree_data);
 
     return {hit.index >= 0, hit.index, float3(hit.no), hit.dist};
   }
-
-  void execute(EventExecuteInterface &interface) override
-  {
-    ParticleSet &particles = interface.particles();
-
-    auto velocities = particles.attributes().get_float3("Velocity");
-    auto positions = particles.attributes().get_float3("Position");
-    auto position_offsets = interface.attribute_offsets().get_float3("Position");
-
-    for (uint pindex : particles.indices()) {
-      auto &data = interface.get_storage<EventData>(pindex);
-
-      /* Move particle back a little bit to avoid double collision. */
-      positions[pindex] += data.hit_normal * 0.001f;
-
-      velocities[pindex] = this->bounce_direction(velocities[pindex], data.hit_normal);
-      position_offsets[pindex] = this->bounce_direction(position_offsets[pindex], data.hit_normal);
-    }
-  }
-
-  float3 bounce_direction(float3 direction, float3 normal)
-  {
-    direction = direction.reflected(normal);
-
-    float normal_part = float3::dot(direction, normal);
-    float3 direction_normal = normal * normal_part;
-    float3 direction_tangent = direction - direction_normal;
-
-    return direction_normal * 0.5 + direction_tangent * 0.9;
-  }
 };
 
 EventFilter *EVENT_age_reached(StringRef identifier, SharedFunction &compute_age_fn)
@@ -187,9 +154,9 @@ EventFilter *EVENT_age_reached(StringRef identifier, SharedFunction &compute_age
   return new AgeReachedEvent(identifier, compute_age_fn);
 }
 
-Event *EVENT_mesh_bounce(BVHTreeFromMesh *treedata, const float4x4 &transform)
+EventFilter *EVENT_mesh_collision(StringRef identifier, Object *object)
 {
-  return new MeshBounceEvent(treedata, transform);
+  return new MeshCollisionEventFilter(identifier, object);
 }
 
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/events.hpp b/source/blender/simulations/bparticles/events.hpp
index 08adc0bc7a1..e4f84423ac5 100644
--- a/source/blender/simulations/bparticles/events.hpp
+++ b/source/blender/simulations/bparticles/events.hpp
@@ -3,7 +3,7 @@
 #include "core.hpp"
 #include "actions.hpp"
 
-struct BVHTreeFromMesh;
+struct Object;
 
 namespace BParticles {
 
@@ -24,7 +24,7 @@ class EventFilter {
   }
 };
 
+EventFilter *EVENT_mesh_collision(StringRef identifier, Object *object);
 EventFilter *EVENT_age_reached(StringRef identifier, SharedFunction &compute_age_fn);
-Event *EVENT_mesh_bounce(struct BVHTreeFromMesh *treedata, const float4x4 &transform);
 
 }  // namespace BParticles



More information about the Bf-blender-cvs mailing list