[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