diff options
author | Jacques Lucke <jacques@blender.org> | 2021-08-19 19:07:36 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-08-19 19:07:36 +0300 |
commit | 95284d2f1edd65cd3ee279572ab80376d6d5fa9f (patch) | |
tree | 58f9488e2b34d195db8cd3415ff3076616689ef6 | |
parent | 7281f3eb564203f88fc895912e0a72454c973b43 (diff) |
bring back function nodes
18 files changed, 376 insertions, 26 deletions
diff --git a/source/blender/nodes/NOD_multi_function.hh b/source/blender/nodes/NOD_multi_function.hh index 93a5f683ca5..96118ef3f76 100644 --- a/source/blender/nodes/NOD_multi_function.hh +++ b/source/blender/nodes/NOD_multi_function.hh @@ -41,6 +41,8 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable { NodeMultiFunctionBuilder(ResourceScope &resource_scope, bNode &node, bNodeTree &tree); void set_matching_fn(const MultiFunction *fn); + void set_matching_fn(const MultiFunction &fn); + template<typename T, typename... Args> void construct_and_set_matching_fn(Args &&...args); bNode &node(); bNodeTree &tree(); @@ -84,6 +86,23 @@ inline ResourceScope &NodeMultiFunctionBuilder::resource_scope() return resource_scope_; } +inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction *fn) +{ + built_fn_ = fn; +} + +inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction &fn) +{ + this->set_matching_fn(&fn); +} + +template<typename T, typename... Args> +inline void NodeMultiFunctionBuilder::construct_and_set_matching_fn(Args &&...args) +{ + const T &fn = resource_scope_.construct<T>(__func__, std::forward<Args>(args)...); + this->set_matching_fn(&fn); +} + /* -------------------------------------------------------------------- * NodeMultiFunctions inline methods. */ diff --git a/source/blender/nodes/function/node_function_util.hh b/source/blender/nodes/function/node_function_util.hh index 98f0508f4bf..96a8f29c3e9 100644 --- a/source/blender/nodes/function/node_function_util.hh +++ b/source/blender/nodes/function/node_function_util.hh @@ -30,6 +30,7 @@ #include "BLT_translation.h" #include "NOD_function.h" +#include "NOD_multi_function.hh" #include "node_util.h" diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc index 3d36c57ae5d..fa0efa26d7b 100644 --- a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc +++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc @@ -58,7 +58,7 @@ static void node_boolean_math_label(bNodeTree *UNUSED(ntree), bNode *node, char BLI_strncpy(label, IFACE_(name), maxlen); } -static const blender::fn::MultiFunction &get_multi_function(bNode &bnode) +static const blender::fn::MultiFunction *get_multi_function(bNode &bnode) { static blender::fn::CustomMF_SI_SI_SO<bool, bool, bool> and_fn{ "And", [](bool a, bool b) { return a && b; }}; @@ -68,15 +68,22 @@ static const blender::fn::MultiFunction &get_multi_function(bNode &bnode) switch (bnode.custom1) { case NODE_BOOLEAN_MATH_AND: - return and_fn; + return &and_fn; case NODE_BOOLEAN_MATH_OR: - return or_fn; + return &or_fn; case NODE_BOOLEAN_MATH_NOT: - return not_fn; + return ¬_fn; } - BLI_assert(false); - return blender::fn::dummy_multi_function; + BLI_assert_unreachable(); + return nullptr; +} + +static void fn_node_boolean_math_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + const blender::fn::MultiFunction *fn = get_multi_function(builder.node()); + builder.set_matching_fn(fn); } void register_node_type_fn_boolean_math() @@ -88,5 +95,6 @@ void register_node_type_fn_boolean_math() node_type_label(&ntype, node_boolean_math_label); node_type_update(&ntype, node_boolean_math_update); ntype.draw_buttons = fn_node_boolean_math_layout; + ntype.build_multi_function = fn_node_boolean_math_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_float_compare.cc b/source/blender/nodes/function/nodes/node_fn_float_compare.cc index b733450d51f..53f505880af 100644 --- a/source/blender/nodes/function/nodes/node_fn_float_compare.cc +++ b/source/blender/nodes/function/nodes/node_fn_float_compare.cc @@ -64,7 +64,7 @@ static void node_float_compare_label(bNodeTree *UNUSED(ntree), BLI_strncpy(label, IFACE_(name), maxlen); } -static const blender::fn::MultiFunction &get_multi_function(bNode &node) +static const blender::fn::MultiFunction *get_multi_function(bNode &node) { static blender::fn::CustomMF_SI_SI_SO<float, float, bool> less_than_fn{ "Less Than", [](float a, float b) { return a < b; }}; @@ -81,21 +81,28 @@ static const blender::fn::MultiFunction &get_multi_function(bNode &node) switch (node.custom1) { case NODE_FLOAT_COMPARE_LESS_THAN: - return less_than_fn; + return &less_than_fn; case NODE_FLOAT_COMPARE_LESS_EQUAL: - return less_equal_fn; + return &less_equal_fn; case NODE_FLOAT_COMPARE_GREATER_THAN: - return greater_than_fn; + return &greater_than_fn; case NODE_FLOAT_COMPARE_GREATER_EQUAL: - return greater_equal_fn; + return &greater_equal_fn; case NODE_FLOAT_COMPARE_EQUAL: - return equal_fn; + return &equal_fn; case NODE_FLOAT_COMPARE_NOT_EQUAL: - return not_equal_fn; + return ¬_equal_fn; } - BLI_assert(false); - return blender::fn::dummy_multi_function; + BLI_assert_unreachable(); + return nullptr; +} + +static void fn_node_float_compare_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + const blender::fn::MultiFunction *fn = get_multi_function(builder.node()); + builder.set_matching_fn(fn); } void register_node_type_fn_float_compare() @@ -107,5 +114,6 @@ void register_node_type_fn_float_compare() node_type_label(&ntype, node_float_compare_label); node_type_update(&ntype, node_float_compare_update); ntype.draw_buttons = geo_node_float_compare_layout; + ntype.build_multi_function = fn_node_float_compare_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc index d24469e153f..34008ed2ef6 100644 --- a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc +++ b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc @@ -50,7 +50,7 @@ static void node_float_to_int_label(bNodeTree *UNUSED(ntree), bNode *node, char BLI_strncpy(label, IFACE_(name), maxlen); } -static const blender::fn::MultiFunction &get_multi_function(bNode &bnode) +static const blender::fn::MultiFunction *get_multi_function(bNode &bnode) { static blender::fn::CustomMF_SI_SO<float, int> round_fn{"Round", [](float a) { return (int)round(a); }}; @@ -63,17 +63,24 @@ static const blender::fn::MultiFunction &get_multi_function(bNode &bnode) switch (static_cast<FloatToIntRoundingMode>(bnode.custom1)) { case FN_NODE_FLOAT_TO_INT_ROUND: - return round_fn; + return &round_fn; case FN_NODE_FLOAT_TO_INT_FLOOR: - return floor_fn; + return &floor_fn; case FN_NODE_FLOAT_TO_INT_CEIL: - return ceil_fn; + return &ceil_fn; case FN_NODE_FLOAT_TO_INT_TRUNCATE: - return trunc_fn; + return &trunc_fn; } BLI_assert_unreachable(); - return blender::fn::dummy_multi_function; + return nullptr; +} + +static void fn_node_float_to_int_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + const blender::fn::MultiFunction *fn = get_multi_function(builder.node()); + builder.set_matching_fn(fn); } void register_node_type_fn_float_to_int() @@ -84,5 +91,6 @@ void register_node_type_fn_float_to_int() node_type_socket_templates(&ntype, fn_node_float_to_int_in, fn_node_float_to_int_out); node_type_label(&ntype, node_float_to_int_label); ntype.draw_buttons = fn_node_float_to_int_layout; + ntype.build_multi_function = fn_node_float_to_int_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_input_string.cc b/source/blender/nodes/function/nodes/node_fn_input_string.cc index 7200eca7cc2..e25ff31715a 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_string.cc @@ -60,6 +60,16 @@ static void fn_node_string_copy(bNodeTree *UNUSED(dest_ntree), dest_node->storage = destination_storage; } +static void fn_node_input_string_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + bNode &bnode = builder.node(); + NodeInputString *node_storage = static_cast<NodeInputString *>(bnode.storage); + std::string string = std::string((node_storage->string) ? node_storage->string : ""); + builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<std::string>>( + std::move(string)); +} + void register_node_type_fn_input_string() { static bNodeType ntype; @@ -69,5 +79,6 @@ void register_node_type_fn_input_string() node_type_init(&ntype, fn_node_input_string_init); node_type_storage(&ntype, "NodeInputString", fn_node_input_string_free, fn_node_string_copy); ntype.draw_buttons = fn_node_input_string_layout; + ntype.build_multi_function = fn_node_input_string_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_input_vector.cc b/source/blender/nodes/function/nodes/node_fn_input_vector.cc index 5367e22e22f..58a0e29fa05 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_vector.cc @@ -39,6 +39,15 @@ static void fn_node_input_vector_init(bNodeTree *UNUSED(ntree), bNode *node) node->storage = data; } +static void fn_node_vector_input_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + bNode &bnode = builder.node(); + NodeInputVector *node_storage = static_cast<NodeInputVector *>(bnode.storage); + blender::float3 vector(node_storage->vector); + builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<blender::float3>>(vector); +} + void register_node_type_fn_input_vector() { static bNodeType ntype; @@ -49,5 +58,6 @@ void register_node_type_fn_input_vector() node_type_storage( &ntype, "NodeInputVector", node_free_standard_storage, node_copy_standard_storage); ntype.draw_buttons = fn_node_input_vector_layout; + ntype.build_multi_function = fn_node_vector_input_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_random_float.cc b/source/blender/nodes/function/nodes/node_fn_random_float.cc index a9b4cd2c7f3..47ec9adf6bd 100644 --- a/source/blender/nodes/function/nodes/node_fn_random_float.cc +++ b/source/blender/nodes/function/nodes/node_fn_random_float.cc @@ -67,11 +67,19 @@ class RandomFloatFunction : public blender::fn::MultiFunction { } }; +static void fn_node_random_float_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + static RandomFloatFunction fn; + builder.set_matching_fn(fn); +} + void register_node_type_fn_random_float() { static bNodeType ntype; fn_node_type_base(&ntype, FN_NODE_RANDOM_FLOAT, "Random Float", 0, 0); node_type_socket_templates(&ntype, fn_node_random_float_in, fn_node_random_float_out); + ntype.build_multi_function = fn_node_random_float_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/intern/node_multi_function.cc b/source/blender/nodes/intern/node_multi_function.cc index 465b11684a5..c91899ed8c2 100644 --- a/source/blender/nodes/intern/node_multi_function.cc +++ b/source/blender/nodes/intern/node_multi_function.cc @@ -18,11 +18,6 @@ namespace blender::nodes { -void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction *fn) -{ - built_fn_ = fn; -} - NodeMultiFunctions::NodeMultiFunctions(const DerivedNodeTree &tree, ResourceScope &resource_scope) { for (const NodeTreeRef *tree_ref : tree.used_node_tree_refs()) { diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.cc b/source/blender/nodes/shader/nodes/node_shader_clamp.cc index 9fe9570b999..f105f8bcaf9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_clamp.cc +++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc @@ -51,6 +51,29 @@ static int gpu_shader_clamp(GPUMaterial *mat, GPU_stack_link(mat, node, "clamp_range", in, out); } +static void sh_node_clamp_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) +{ + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> minmax_fn{ + "Clamp (Min Max)", + [](float value, float min, float max) { return std::min(std::max(value, min), max); }}; + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> range_fn{ + "Clamp (Range)", [](float value, float a, float b) { + if (a < b) { + return clamp_f(value, a, b); + } + + return clamp_f(value, b, a); + }}; + + int clamp_type = builder.node().custom1; + if (clamp_type == NODE_CLAMP_MINMAX) { + builder.set_matching_fn(minmax_fn); + } + else { + builder.set_matching_fn(range_fn); + } +} + void register_node_type_sh_clamp(void) { static bNodeType ntype; @@ -59,6 +82,7 @@ void register_node_type_sh_clamp(void) node_type_socket_templates(&ntype, sh_node_clamp_in, sh_node_clamp_out); node_type_init(&ntype, node_shader_init_clamp); node_type_gpu(&ntype, gpu_shader_clamp); + ntype.build_multi_function = sh_node_clamp_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc index 3fdc26013f4..df075d6e973 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.cc +++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc @@ -143,6 +143,15 @@ class CurveVecFunction : public blender::fn::MultiFunction { } }; +static void sh_node_curve_vec_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + bNode &bnode = builder.node(); + CurveMapping *cumap = (CurveMapping *)bnode.storage; + BKE_curvemapping_init(cumap); + builder.construct_and_set_matching_fn<CurveVecFunction>(*cumap); +} + void register_node_type_sh_curve_vec(void) { static bNodeType ntype; @@ -154,6 +163,7 @@ void register_node_type_sh_curve_vec(void) node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); node_type_exec(&ntype, node_initexec_curves, nullptr, node_shader_exec_curve_vec); node_type_gpu(&ntype, gpu_shader_curve_vec); + ntype.build_multi_function = sh_node_curve_vec_build_multi_function; nodeRegisterType(&ntype); } @@ -308,6 +318,15 @@ class CurveRGBFunction : public blender::fn::MultiFunction { } }; +static void sh_node_curve_rgb_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + bNode &bnode = builder.node(); + CurveMapping *cumap = (CurveMapping *)bnode.storage; + BKE_curvemapping_init(cumap); + builder.construct_and_set_matching_fn<CurveRGBFunction>(*cumap); +} + void register_node_type_sh_curve_rgb(void) { static bNodeType ntype; @@ -319,6 +338,7 @@ void register_node_type_sh_curve_rgb(void) node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves); node_type_exec(&ntype, node_initexec_curves, nullptr, node_shader_exec_curve_rgb); node_type_gpu(&ntype, gpu_shader_curve_rgb); + ntype.build_multi_function = sh_node_curve_rgb_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc index d266716d790..e4739e2864d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc +++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc @@ -261,6 +261,51 @@ class MapRangeSmootherstepFunction : public blender::fn::MultiFunction { } }; +static void sh_node_map_range_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + bNode &bnode = builder.node(); + bool clamp = bnode.custom1 != 0; + int interpolation_type = bnode.custom2; + + switch (interpolation_type) { + case NODE_MAP_RANGE_LINEAR: { + if (clamp) { + static MapRangeFunction fn_with_clamp{true}; + builder.set_matching_fn(fn_with_clamp); + } + else { + static MapRangeFunction fn_without_clamp{false}; + builder.set_matching_fn(fn_without_clamp); + } + break; + } + case NODE_MAP_RANGE_STEPPED: { + if (clamp) { + static MapRangeSteppedFunction fn_stepped_with_clamp{true}; + builder.set_matching_fn(fn_stepped_with_clamp); + } + else { + static MapRangeSteppedFunction fn_stepped_without_clamp{false}; + builder.set_matching_fn(fn_stepped_without_clamp); + } + break; + } + case NODE_MAP_RANGE_SMOOTHSTEP: { + static MapRangeSmoothstepFunction smoothstep; + builder.set_matching_fn(smoothstep); + break; + } + case NODE_MAP_RANGE_SMOOTHERSTEP: { + static MapRangeSmootherstepFunction smootherstep; + builder.set_matching_fn(smootherstep); + break; + } + default: + break; + } +} + void register_node_type_sh_map_range(void) { static bNodeType ntype; @@ -270,6 +315,7 @@ void register_node_type_sh_map_range(void) node_type_init(&ntype, node_shader_init_map_range); node_type_update(&ntype, node_shader_update_map_range); node_type_gpu(&ntype, gpu_shader_map_range); + ntype.build_multi_function = sh_node_map_range_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc index 6e3c4f6a85a..8e20a922c92 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_math.cc @@ -69,6 +69,56 @@ static int gpu_shader_math(GPUMaterial *mat, return 0; } +static const blender::fn::MultiFunction *get_base_multi_function(bNode &node) +{ + const int mode = node.custom1; + const blender::fn::MultiFunction *base_fn = nullptr; + + blender::nodes::try_dispatch_float_math_fl_to_fl( + mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { + static blender::fn::CustomMF_SI_SO<float, float> fn{info.title_case_name, function}; + base_fn = &fn; + }); + if (base_fn != nullptr) { + return base_fn; + } + + blender::nodes::try_dispatch_float_math_fl_fl_to_fl( + mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { + static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{info.title_case_name, + function}; + base_fn = &fn; + }); + if (base_fn != nullptr) { + return base_fn; + } + + blender::nodes::try_dispatch_float_math_fl_fl_fl_to_fl( + mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> fn{ + info.title_case_name, function}; + base_fn = &fn; + }); + if (base_fn != nullptr) { + return base_fn; + } + + return nullptr; +} + +static void sh_node_math_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) +{ + const blender::fn::MultiFunction *base_function = get_base_multi_function(builder.node()); + + const bool clamp_output = builder.node().custom2 != 0; + if (clamp_output) { + /* TODO */ + } + else { + builder.set_matching_fn(base_function); + } +} + void register_node_type_sh_math(void) { static bNodeType ntype; @@ -78,6 +128,7 @@ void register_node_type_sh_math(void) node_type_label(&ntype, node_math_label); node_type_gpu(&ntype, gpu_shader_math); node_type_update(&ntype, node_math_update); + ntype.build_multi_function = sh_node_math_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc index 7983176bc5a..2779fc6bf68 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc @@ -96,6 +96,12 @@ class SeparateRGBFunction : public blender::fn::MultiFunction { } }; +static void sh_node_seprgb_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) +{ + static SeparateRGBFunction fn; + builder.set_matching_fn(fn); +} + void register_node_type_sh_seprgb(void) { static bNodeType ntype; @@ -104,6 +110,7 @@ void register_node_type_sh_seprgb(void) node_type_socket_templates(&ntype, sh_node_seprgb_in, sh_node_seprgb_out); node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_seprgb); node_type_gpu(&ntype, gpu_shader_seprgb); + ntype.build_multi_function = sh_node_seprgb_build_multi_function; nodeRegisterType(&ntype); } @@ -146,6 +153,14 @@ static int gpu_shader_combrgb(GPUMaterial *mat, return GPU_stack_link(mat, node, "combine_rgb", in, out); } +static void sh_node_combrgb_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) +{ + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, blender::ColorGeometry4f> fn{ + "Combine RGB", + [](float r, float g, float b) { return blender::ColorGeometry4f(r, g, b, 1.0f); }}; + builder.set_matching_fn(fn); +} + void register_node_type_sh_combrgb(void) { static bNodeType ntype; @@ -154,6 +169,7 @@ void register_node_type_sh_combrgb(void) node_type_socket_templates(&ntype, sh_node_combrgb_in, sh_node_combrgb_out); node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_combrgb); node_type_gpu(&ntype, gpu_shader_combrgb); + ntype.build_multi_function = sh_node_combrgb_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc index 1bc28dbe100..1fd794cdd0a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc @@ -81,6 +81,12 @@ class MF_SeparateXYZ : public blender::fn::MultiFunction { } }; +static void sh_node_sepxyz_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) +{ + static MF_SeparateXYZ separate_fn; + builder.set_matching_fn(separate_fn); +} + void register_node_type_sh_sepxyz(void) { static bNodeType ntype; @@ -88,6 +94,7 @@ void register_node_type_sh_sepxyz(void) sh_fn_node_type_base(&ntype, SH_NODE_SEPXYZ, "Separate XYZ", NODE_CLASS_CONVERTOR, 0); node_type_socket_templates(&ntype, sh_node_sepxyz_in, sh_node_sepxyz_out); node_type_gpu(&ntype, gpu_shader_sepxyz); + ntype.build_multi_function = sh_node_sepxyz_build_multi_function; nodeRegisterType(&ntype); } @@ -113,6 +120,13 @@ static int gpu_shader_combxyz(GPUMaterial *mat, return GPU_stack_link(mat, node, "combine_xyz", in, out); } +static void sh_node_combxyz_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) +{ + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, blender::float3> fn{ + "Combine Vector", [](float x, float y, float z) { return blender::float3(x, y, z); }}; + builder.set_matching_fn(fn); +} + void register_node_type_sh_combxyz(void) { static bNodeType ntype; @@ -120,6 +134,7 @@ void register_node_type_sh_combxyz(void) sh_fn_node_type_base(&ntype, SH_NODE_COMBXYZ, "Combine XYZ", NODE_CLASS_CONVERTOR, 0); node_type_socket_templates(&ntype, sh_node_combxyz_in, sh_node_combxyz_out); node_type_gpu(&ntype, gpu_shader_combxyz); + ntype.build_multi_function = sh_node_combxyz_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc index b5064bf9a09..1bc42ab0cc6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc @@ -163,6 +163,14 @@ class ColorBandFunction : public blender::fn::MultiFunction { } }; +static void sh_node_valtorgb_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + bNode &bnode = builder.node(); + const ColorBand *color_band = (const ColorBand *)bnode.storage; + builder.construct_and_set_matching_fn<ColorBandFunction>(*color_band); +} + void register_node_type_sh_valtorgb(void) { static bNodeType ntype; @@ -174,6 +182,7 @@ void register_node_type_sh_valtorgb(void) node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage); node_type_exec(&ntype, nullptr, nullptr, node_shader_exec_valtorgb); node_type_gpu(&ntype, gpu_shader_valtorgb); + ntype.build_multi_function = sh_node_valtorgb_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_value.cc b/source/blender/nodes/shader/nodes/node_shader_value.cc index fe97ccf1610..602d5a1cf56 100644 --- a/source/blender/nodes/shader/nodes/node_shader_value.cc +++ b/source/blender/nodes/shader/nodes/node_shader_value.cc @@ -39,6 +39,13 @@ static int gpu_shader_value(GPUMaterial *mat, return GPU_stack_link(mat, node, "set_value", in, out, link); } +static void sh_node_value_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder) +{ + const bNodeSocket *bsocket = (bNodeSocket *)builder.node().outputs.first; + const bNodeSocketValueFloat *value = (const bNodeSocketValueFloat *)bsocket->default_value; + builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<float>>(value->value); +} + void register_node_type_sh_value(void) { static bNodeType ntype; @@ -46,6 +53,7 @@ void register_node_type_sh_value(void) sh_fn_node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT, 0); node_type_socket_templates(&ntype, nullptr, sh_node_value_out); node_type_gpu(&ntype, gpu_shader_value); + ntype.build_multi_function = sh_node_value_build_multi_function; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index b5ffe6f2cb7..bc51b7e29ea 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -100,6 +100,98 @@ static float3 sh_node_vector_rotate_euler(const float3 vector, return result + center; } +static const blender::fn::MultiFunction *get_multi_function(bNode &node) +{ + bool invert = node.custom2; + const int mode = node.custom1; + + switch (mode) { + case NODE_VECTOR_ROTATE_TYPE_AXIS: { + if (invert) { + static blender::fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float3, float, float3> fn{ + "Rotate Axis", [](float3 in, float3 center, float3 axis, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, -angle); + }}; + return &fn; + } + static blender::fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float3, float, float3> fn{ + "Rotate Axis", [](float3 in, float3 center, float3 axis, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, angle); + }}; + return &fn; + } + case NODE_VECTOR_ROTATE_TYPE_AXIS_X: { + float3 axis = float3(1.0f, 0.0f, 0.0f); + if (invert) { + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ + "Rotate X-Axis", [=](float3 in, float3 center, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, -angle); + }}; + return &fn; + } + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ + "Rotate X-Axis", [=](float3 in, float3 center, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, angle); + }}; + return &fn; + } + case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: { + float3 axis = float3(0.0f, 1.0f, 0.0f); + if (invert) { + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ + "Rotate Y-Axis", [=](float3 in, float3 center, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, -angle); + }}; + return &fn; + } + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ + "Rotate Y-Axis", [=](float3 in, float3 center, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, angle); + }}; + return &fn; + } + case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: { + float3 axis = float3(0.0f, 0.0f, 1.0f); + if (invert) { + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ + "Rotate Z-Axis", [=](float3 in, float3 center, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, -angle); + }}; + return &fn; + } + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ + "Rotate Z-Axis", [=](float3 in, float3 center, float angle) { + return sh_node_vector_rotate_around_axis(in, center, axis, angle); + }}; + return &fn; + } + case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: { + if (invert) { + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3> fn{ + "Rotate Euler", [](float3 in, float3 center, float3 rotation) { + return sh_node_vector_rotate_euler(in, center, rotation, true); + }}; + return &fn; + } + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3> fn{ + "Rotate Euler", [](float3 in, float3 center, float3 rotation) { + return sh_node_vector_rotate_euler(in, center, rotation, false); + }}; + return &fn; + } + default: + BLI_assert_unreachable(); + return nullptr; + } +} + +static void sh_node_vector_rotate_build_multi_function( + blender::nodes::NodeMultiFunctionBuilder &builder) +{ + const blender::fn::MultiFunction *fn = get_multi_function(builder.node()); + builder.set_matching_fn(fn); +} + static void node_shader_update_vector_rotate(bNodeTree *UNUSED(ntree), bNode *node) { bNodeSocket *sock_rotation = nodeFindSocket(node, SOCK_IN, "Rotation"); @@ -118,6 +210,7 @@ void register_node_type_sh_vector_rotate(void) node_type_socket_templates(&ntype, sh_node_vector_rotate_in, sh_node_vector_rotate_out); node_type_gpu(&ntype, gpu_shader_vector_rotate); node_type_update(&ntype, node_shader_update_vector_rotate); + ntype.build_multi_function = sh_node_vector_rotate_build_multi_function; nodeRegisterType(&ntype); } |