[Bf-blender-cvs] [01e97d117f3] functions: initial experimental Mesh Force node
Jacques Lucke
noreply at git.blender.org
Tue Sep 10 14:24:16 CEST 2019
Commit: 01e97d117f3f528ff1bd948fccab861e1a9c2485
Author: Jacques Lucke
Date: Tue Sep 10 14:23:52 2019 +0200
Branches: functions
https://developer.blender.org/rB01e97d117f3f528ff1bd948fccab861e1a9c2485
initial experimental Mesh Force node
===================================================================
M release/scripts/startup/nodes/bparticle_nodes/forces.py
M source/blender/blenlib/BLI_math.hpp
M source/blender/simulations/bparticles/forces.cpp
M source/blender/simulations/bparticles/forces.hpp
M source/blender/simulations/bparticles/node_frontend.cpp
===================================================================
diff --git a/release/scripts/startup/nodes/bparticle_nodes/forces.py b/release/scripts/startup/nodes/bparticle_nodes/forces.py
index 54bc6e497d0..411ee283b5a 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/forces.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/forces.py
@@ -3,6 +3,7 @@ from bpy.props import *
from .. base import BParticlesNode
from .. node_builder import NodeBuilder
+
class TurbulenceForceNode(bpy.types.Node, BParticlesNode):
bl_idname = "bp_TurbulenceForceNode"
bl_label = "Turbulence Force"
@@ -27,6 +28,16 @@ class DragForceNode(bpy.types.Node, BParticlesNode):
bl_label = "Drag Force"
def declaration(self, builder: NodeBuilder):
- builder.fixed_input("strength", "Strength", 'Float', default=1)
+ builder.fixed_input("strength", "Strength", "Float", default=1)
builder.fixed_input("falloff", "Falloff", "Falloff")
builder.particle_effector_output("force", "Force")
+
+
+class MeshForceNode(bpy.types.Node, BParticlesNode):
+ bl_idname = "bp_MeshForceNode"
+ bl_label = "Mesh Force"
+
+ def declaration(self, builder: NodeBuilder):
+ builder.fixed_input("object", "Object", "Object")
+ builder.fixed_input("strength", "Strength", "Float", default=1)
+ builder.particle_effector_output("force", "Force")
diff --git a/source/blender/blenlib/BLI_math.hpp b/source/blender/blenlib/BLI_math.hpp
index 335d494c994..3f4e8e8914c 100644
--- a/source/blender/blenlib/BLI_math.hpp
+++ b/source/blender/blenlib/BLI_math.hpp
@@ -150,6 +150,11 @@ struct float3 {
return len_v3(*this);
}
+ float length_squared() const
+ {
+ return len_squared_v3(*this);
+ }
+
void reflect(float3 normal)
{
*this = this->reflected(normal);
diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp
index eb9e0fe9e00..99b9fd84041 100644
--- a/source/blender/simulations/bparticles/forces.cpp
+++ b/source/blender/simulations/bparticles/forces.cpp
@@ -59,4 +59,38 @@ void DragForce::add_force(ForceInterface &interface)
}
}
+void MeshForce::add_force(ForceInterface &interface)
+{
+ MutableArrayRef<float3> destination = interface.combined_destination();
+ auto positions = interface.attributes().get<float3>("Position");
+
+ auto inputs = m_compute_inputs->compute(interface);
+
+ for (uint pindex : interface.pindices()) {
+ float3 position = positions[pindex];
+ float3 local_position = m_world_to_local.transform_position(position);
+
+ BVHTreeNearest nearest = {0};
+ nearest.dist_sq = 10000.0f;
+ nearest.index = -1;
+ BLI_bvhtree_find_nearest(m_bvhtree_data.tree,
+ local_position,
+ &nearest,
+ m_bvhtree_data.nearest_callback,
+ (void *)&m_bvhtree_data);
+
+ if (nearest.index == -1) {
+ continue;
+ }
+
+ float3 difference_local = float3(nearest.co) - local_position;
+ float3 difference = m_local_to_world.transform_direction(difference_local);
+ float distance_squared = difference.length_squared();
+ float factor = 1 / std::max(0.1f, distance_squared);
+
+ float strength = inputs->get<float>("Strength", 1, pindex);
+ destination[pindex] += difference * strength * factor;
+ }
+}
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/forces.hpp b/source/blender/simulations/bparticles/forces.hpp
index 88a04f47470..a1581f6b9ed 100644
--- a/source/blender/simulations/bparticles/forces.hpp
+++ b/source/blender/simulations/bparticles/forces.hpp
@@ -1,6 +1,12 @@
#pragma once
#include "BKE_falloff.hpp"
+#include "BKE_bvhutils.h"
+
+#include "BLI_kdopbvh.h"
+#include "BLI_kdtree.h"
+
+#include "DNA_object_types.h"
#include "actions.hpp"
#include "force_interface.hpp"
@@ -8,6 +14,7 @@
namespace BParticles {
using BKE::Falloff;
+using BLI::float4x4;
class Force {
public:
@@ -56,4 +63,26 @@ class DragForce : public Force {
void add_force(ForceInterface &interface) override;
};
+class MeshForce : public Force {
+ private:
+ std::unique_ptr<ParticleFunction> m_compute_inputs;
+ Object *m_object;
+ BVHTreeFromMesh m_bvhtree_data;
+ float4x4 m_local_to_world;
+ float4x4 m_world_to_local;
+
+ public:
+ MeshForce(std::unique_ptr<ParticleFunction> compute_inputs, Object *object)
+ : m_compute_inputs(std::move(compute_inputs)), 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);
+ }
+
+ void add_force(ForceInterface &interface) override;
+};
+
} // namespace BParticles
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index c965cd95265..ed39912ce12 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -571,6 +571,39 @@ static void PARSE_size_over_time(BehaviorCollector &collector,
}
}
+static void PARSE_mesh_force(BehaviorCollector &collector,
+ VTreeDataGraph &vtree_data_graph,
+ WorldTransition &UNUSED(world_transition),
+ VirtualNode *vnode)
+{
+
+ FunctionGraph fgraph(
+ vtree_data_graph.graph(), {}, {vtree_data_graph.lookup_socket(vnode->input(0, "Object"))});
+ auto fn = fgraph.new_function("Find Object");
+ FN::fgraph_add_TupleCallBody(fn, fgraph);
+ FN::TupleCallBody &body = fn->body<TupleCallBody>();
+
+ FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out);
+ body.call__setup_execution_context(fn_in, fn_out);
+
+ Object *object = fn_out.relocate_out<ObjectW>(0).ptr();
+ if (object == nullptr || object->type != OB_MESH) {
+ return;
+ }
+
+ Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Force"));
+ for (std::string &type_name : type_names) {
+ auto fn_or_error = create_particle_function(vnode, vtree_data_graph);
+ if (fn_or_error.is_error()) {
+ continue;
+ }
+ std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value();
+
+ Force *force = new MeshForce(std::move(compute_inputs), object);
+ collector.m_forces.add(type_name, force);
+ }
+}
+
BLI_LAZY_INIT_STATIC(StringMap<ParseNodeCallback>, get_node_parsers)
{
StringMap<ParseNodeCallback> map;
@@ -584,6 +617,7 @@ BLI_LAZY_INIT_STATIC(StringMap<ParseNodeCallback>, get_node_parsers)
map.add_new("bp_MeshCollisionEventNode", PARSE_mesh_collision);
map.add_new("bp_SizeOverTimeNode", PARSE_size_over_time);
map.add_new("bp_DragForceNode", PARSE_drag_force);
+ map.add_new("bp_MeshForceNode", PARSE_mesh_force);
return map;
}
More information about the Bf-blender-cvs
mailing list