[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