[Bf-blender-cvs] [1d69abe558a] functions: new Custom Force and Perlin Noise node
Jacques Lucke
noreply at git.blender.org
Tue Nov 12 14:30:04 CET 2019
Commit: 1d69abe558afe9a968553627e529a47b3fae3c0d
Author: Jacques Lucke
Date: Tue Nov 12 11:00:19 2019 +0100
Branches: functions
https://developer.blender.org/rB1d69abe558afe9a968553627e529a47b3fae3c0d
new Custom Force and Perlin Noise node
===================================================================
M release/scripts/startup/nodes/bparticle_nodes/forces.py
A release/scripts/startup/nodes/function_nodes/noise.py
M source/blender/functions/intern/multi_functions/mixed.cc
M source/blender/functions/intern/multi_functions/mixed.h
M source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
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 c6240c30ee3..2644fb014a6 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/forces.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/forces.py
@@ -4,6 +4,15 @@ from .. base import SimulationNode
from .. node_builder import NodeBuilder
+class AddForcesNode(bpy.types.Node, SimulationNode):
+ bl_idname = "fn_ForceNode"
+ bl_label = "Force"
+
+ def declaration(self, builder: NodeBuilder):
+ builder.fixed_input("force", "Force", "Vector")
+ builder.influences_output("force", "Force")
+
+
class TurbulenceForceNode(bpy.types.Node, SimulationNode):
bl_idname = "fn_TurbulenceForceNode"
bl_label = "Turbulence Force"
diff --git a/release/scripts/startup/nodes/function_nodes/noise.py b/release/scripts/startup/nodes/function_nodes/noise.py
new file mode 100644
index 00000000000..3706f548ec3
--- /dev/null
+++ b/release/scripts/startup/nodes/function_nodes/noise.py
@@ -0,0 +1,14 @@
+import bpy
+from bpy.props import *
+from .. base import FunctionNode
+from .. node_builder import NodeBuilder
+
+class PerlinNoiseNode(bpy.types.Node, FunctionNode):
+ bl_idname = "fn_PerlinNoiseNode"
+ bl_label = "Perlin Noise"
+
+ def declaration(self, builder: NodeBuilder):
+ builder.fixed_input("position", "Position", "Vector")
+ builder.fixed_input("amplitude", "Amplitude", "Float", default=1)
+ builder.fixed_input("scale", "Scale", "Float", default=1)
+ builder.fixed_output("noise", "Noise", "Float")
diff --git a/source/blender/functions/intern/multi_functions/mixed.cc b/source/blender/functions/intern/multi_functions/mixed.cc
index a01da4a439e..e977798d11e 100644
--- a/source/blender/functions/intern/multi_functions/mixed.cc
+++ b/source/blender/functions/intern/multi_functions/mixed.cc
@@ -8,6 +8,7 @@
#include "BLI_lazy_init_cxx.h"
#include "BLI_string_map.h"
#include "BLI_array_cxx.h"
+#include "BLI_noise.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
@@ -522,4 +523,30 @@ void MF_ContextCurrentFrame::call(const MFMask &mask, MFParams ¶ms, MFContex
}
}
+MF_PerlinNoise_3D_to_1D::MF_PerlinNoise_3D_to_1D()
+{
+ MFSignatureBuilder signature("Perlin Noise 3D to 1D");
+ signature.readonly_single_input<float3>("Position");
+ signature.readonly_single_input<float>("Amplitude");
+ signature.readonly_single_input<float>("Scale");
+ signature.single_output<float>("Noise");
+ this->set_signature(signature);
+}
+
+void MF_PerlinNoise_3D_to_1D::call(const MFMask &mask,
+ MFParams ¶ms,
+ MFContext &UNUSED(context)) const
+{
+ VirtualListRef<float3> positions = params.readonly_single_input<float3>(0, "Position");
+ VirtualListRef<float> amplitudes = params.readonly_single_input<float>(1, "Amplitude");
+ VirtualListRef<float> scales = params.readonly_single_input<float>(2, "Scale");
+ MutableArrayRef<float> r_noise = params.uninitialized_single_output<float>(3, "Noise");
+
+ for (uint i : mask.indices()) {
+ float3 pos = positions[i];
+ float noise = BLI_gNoise(scales[i], pos.x, pos.y, pos.z, false, 1);
+ r_noise[i] = noise * amplitudes[i];
+ }
+}
+
} // namespace FN
diff --git a/source/blender/functions/intern/multi_functions/mixed.h b/source/blender/functions/intern/multi_functions/mixed.h
index a026b5241c2..31f16372643 100644
--- a/source/blender/functions/intern/multi_functions/mixed.h
+++ b/source/blender/functions/intern/multi_functions/mixed.h
@@ -167,6 +167,12 @@ class MF_SwitchVector final : public MultiFunction {
void call(const MFMask &mask, MFParams ¶ms, MFContext &context) const override;
};
+class MF_PerlinNoise_3D_to_1D final : public MultiFunction {
+ public:
+ MF_PerlinNoise_3D_to_1D();
+ void call(const MFMask &mask, MFParams ¶ms, MFContext &context) const override;
+};
+
template<typename FromT, typename ToT, ToT (*Compute)(const FromT &)>
class MF_Mappping final : public MultiFunction {
public:
diff --git a/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc b/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
index 8d431c42d22..b767e0c56bd 100644
--- a/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
+++ b/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
@@ -445,6 +445,12 @@ static void INSERT_compare(VTreeMFNetworkBuilder &builder, const VNode &vnode)
insert_two_inputs_math_function<float, float, bool, less_than_func_cb>(builder, vnode);
}
+static void INSERT_perlin_noise(VTreeMFNetworkBuilder &builder, const VNode &vnode)
+{
+ const MultiFunction &fn = builder.construct_fn<MF_PerlinNoise_3D_to_1D>();
+ builder.add_function(fn, {0, 1, 2}, {3}, vnode);
+}
+
void add_vtree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
{
mappings.vnode_inserters.add_new("fn_CombineColorNode", INSERT_combine_color);
@@ -462,6 +468,7 @@ void add_vtree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
mappings.vnode_inserters.add_new("fn_FloatRangeNode", INSERT_float_range);
mappings.vnode_inserters.add_new("fn_TimeInfoNode", INSERT_time_info);
mappings.vnode_inserters.add_new("fn_CompareNode", INSERT_compare);
+ mappings.vnode_inserters.add_new("fn_PerlinNoiseNode", INSERT_perlin_noise);
mappings.vnode_inserters.add_new("fn_AddFloatsNode", INSERT_add_floats);
mappings.vnode_inserters.add_new("fn_MultiplyFloatsNode", INSERT_multiply_floats);
diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp
index 9533c7de5e7..8263f1eadf2 100644
--- a/source/blender/simulations/bparticles/forces.cpp
+++ b/source/blender/simulations/bparticles/forces.cpp
@@ -8,6 +8,17 @@ Force::~Force()
{
}
+void CustomForce::add_force(ForceInterface &interface)
+{
+ MutableArrayRef<float3> dst = interface.combined_destination();
+
+ auto inputs = m_inputs_fn->compute(interface);
+
+ for (uint pindex : interface.pindices()) {
+ dst[pindex] += inputs->get<float3>("Force", 0, pindex);
+ }
+}
+
void GravityForce::add_force(ForceInterface &interface)
{
MutableArrayRef<float3> destination = interface.combined_destination();
diff --git a/source/blender/simulations/bparticles/forces.hpp b/source/blender/simulations/bparticles/forces.hpp
index a62c372ef13..c5d06def35e 100644
--- a/source/blender/simulations/bparticles/forces.hpp
+++ b/source/blender/simulations/bparticles/forces.hpp
@@ -20,6 +20,18 @@ class Force {
virtual void add_force(ForceInterface &interface) = 0;
};
+class CustomForce : public Force {
+ private:
+ ParticleFunction *m_inputs_fn;
+
+ public:
+ CustomForce(ParticleFunction *inputs_fn) : m_inputs_fn(inputs_fn)
+ {
+ }
+
+ void add_force(ForceInterface &interface) override;
+};
+
class GravityForce : public Force {
private:
ParticleFunction *m_inputs_fn;
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 835ef7aef77..5d498d7f708 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -547,6 +547,25 @@ static void PARSE_gravity_force(InfluencesCollector &collector,
}
}
+static void PARSE_custom_force(InfluencesCollector &collector,
+ VTreeData &vtree_data,
+ WorldTransition &UNUSED(world_transition),
+ const VNode &vnode)
+{
+ ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode);
+ if (inputs_fn == nullptr) {
+ return;
+ }
+
+ ArrayRef<std::string> system_names = vtree_data.find_target_system_names(
+ vnode.output(0, "Force"));
+
+ for (const std::string &system_name : system_names) {
+ CustomForce *force = new CustomForce(inputs_fn);
+ collector.m_forces.add(system_name, force);
+ }
+}
+
static void PARSE_age_reached_event(InfluencesCollector &collector,
VTreeData &vtree_data,
WorldTransition &UNUSED(world_transition),
@@ -793,6 +812,7 @@ BLI_LAZY_INIT_STATIC(StringMap<ParseNodeCallback>, get_node_parsers)
map.add_new("fn_MeshForceNode", PARSE_mesh_force);
map.add_new("fn_CustomEventNode", PARSE_custom_event);
map.add_new("fn_AlwaysExecuteNode", PARSE_always_execute);
+ map.add_new("fn_ForceNode", PARSE_custom_force);
return map;
}
More information about the Bf-blender-cvs
mailing list