diff options
Diffstat (limited to 'source/blender/nodes/function/nodes/node_fn_random_value.cc')
-rw-r--r-- | source/blender/nodes/function/nodes/node_fn_random_value.cc | 141 |
1 files changed, 100 insertions, 41 deletions
diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc index 53ca77aab0c..ceea6246cb0 100644 --- a/source/blender/nodes/function/nodes/node_fn_random_value.cc +++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc @@ -19,36 +19,41 @@ #include "node_function_util.hh" +#include "NOD_socket_search_link.hh" + #include "UI_interface.h" #include "UI_resources.h" -namespace blender::nodes { +namespace blender::nodes::node_fn_random_value_cc { + +NODE_STORAGE_FUNCS(NodeRandomValue) static void fn_node_random_value_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Vector>("Min").supports_field(); - b.add_input<decl::Vector>("Max").default_value({1.0f, 1.0f, 1.0f}).supports_field(); - b.add_input<decl::Float>("Min", "Min_001").supports_field(); - b.add_input<decl::Float>("Max", "Max_001").default_value(1.0f).supports_field(); - b.add_input<decl::Int>("Min", "Min_002").min(-100000).max(100000).supports_field(); - b.add_input<decl::Int>("Max", "Max_002") + b.add_input<decl::Vector>(N_("Min")).supports_field(); + b.add_input<decl::Vector>(N_("Max")).default_value({1.0f, 1.0f, 1.0f}).supports_field(); + b.add_input<decl::Float>(N_("Min"), "Min_001").supports_field(); + b.add_input<decl::Float>(N_("Max"), "Max_001").default_value(1.0f).supports_field(); + b.add_input<decl::Int>(N_("Min"), "Min_002").min(-100000).max(100000).supports_field(); + b.add_input<decl::Int>(N_("Max"), "Max_002") .default_value(100) .min(-100000) .max(100000) .supports_field(); - b.add_input<decl::Float>("Probability") + b.add_input<decl::Float>(N_("Probability")) .min(0.0f) .max(1.0f) .default_value(0.5f) .subtype(PROP_FACTOR) - .supports_field(); - b.add_input<decl::Int>("ID").implicit_field(); - b.add_input<decl::Int>("Seed").default_value(0).min(-10000).max(10000).supports_field(); - - b.add_output<decl::Vector>("Value").dependent_field(); - b.add_output<decl::Float>("Value", "Value_001").dependent_field(); - b.add_output<decl::Int>("Value", "Value_002").dependent_field(); - b.add_output<decl::Bool>("Value", "Value_003").dependent_field(); + .supports_field() + .make_available([](bNode &node) { node_storage(node).data_type = CD_PROP_BOOL; }); + b.add_input<decl::Int>(N_("ID")).implicit_field(); + b.add_input<decl::Int>(N_("Seed")).default_value(0).min(-10000).max(10000).supports_field(); + + b.add_output<decl::Vector>(N_("Value")).dependent_field(); + b.add_output<decl::Float>(N_("Value"), "Value_001").dependent_field(); + b.add_output<decl::Int>(N_("Value"), "Value_002").dependent_field(); + b.add_output<decl::Bool>(N_("Value"), "Value_003").dependent_field(); } static void fn_node_random_value_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -58,14 +63,14 @@ static void fn_node_random_value_layout(uiLayout *layout, bContext *UNUSED(C), P static void fn_node_random_value_init(bNodeTree *UNUSED(tree), bNode *node) { - NodeRandomValue *data = (NodeRandomValue *)MEM_callocN(sizeof(NodeRandomValue), __func__); + NodeRandomValue *data = MEM_cnew<NodeRandomValue>(__func__); data->data_type = CD_PROP_FLOAT; node->storage = data; } -static void fn_node_random_value_update(bNodeTree *UNUSED(ntree), bNode *node) +static void fn_node_random_value_update(bNodeTree *ntree, bNode *node) { - const NodeRandomValue &storage = *(const NodeRandomValue *)node->storage; + const NodeRandomValue &storage = node_storage(*node); const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); bNodeSocket *sock_min_vector = (bNodeSocket *)node->inputs.first; @@ -81,18 +86,66 @@ static void fn_node_random_value_update(bNodeTree *UNUSED(ntree), bNode *node) bNodeSocket *sock_out_int = sock_out_float->next; bNodeSocket *sock_out_bool = sock_out_int->next; - nodeSetSocketAvailability(sock_min_vector, data_type == CD_PROP_FLOAT3); - nodeSetSocketAvailability(sock_max_vector, data_type == CD_PROP_FLOAT3); - nodeSetSocketAvailability(sock_min_float, data_type == CD_PROP_FLOAT); - nodeSetSocketAvailability(sock_max_float, data_type == CD_PROP_FLOAT); - nodeSetSocketAvailability(sock_min_int, data_type == CD_PROP_INT32); - nodeSetSocketAvailability(sock_max_int, data_type == CD_PROP_INT32); - nodeSetSocketAvailability(sock_probability, data_type == CD_PROP_BOOL); - - nodeSetSocketAvailability(sock_out_vector, data_type == CD_PROP_FLOAT3); - nodeSetSocketAvailability(sock_out_float, data_type == CD_PROP_FLOAT); - nodeSetSocketAvailability(sock_out_int, data_type == CD_PROP_INT32); - nodeSetSocketAvailability(sock_out_bool, data_type == CD_PROP_BOOL); + nodeSetSocketAvailability(ntree, sock_min_vector, data_type == CD_PROP_FLOAT3); + nodeSetSocketAvailability(ntree, sock_max_vector, data_type == CD_PROP_FLOAT3); + nodeSetSocketAvailability(ntree, sock_min_float, data_type == CD_PROP_FLOAT); + nodeSetSocketAvailability(ntree, sock_max_float, data_type == CD_PROP_FLOAT); + nodeSetSocketAvailability(ntree, sock_min_int, data_type == CD_PROP_INT32); + nodeSetSocketAvailability(ntree, sock_max_int, data_type == CD_PROP_INT32); + nodeSetSocketAvailability(ntree, sock_probability, data_type == CD_PROP_BOOL); + + nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3); + nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT); + nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32); + nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL); +} + +static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket) +{ + switch (socket.type) { + case SOCK_FLOAT: + return CD_PROP_FLOAT; + case SOCK_BOOLEAN: + return CD_PROP_BOOL; + case SOCK_INT: + return CD_PROP_INT32; + case SOCK_VECTOR: + case SOCK_RGBA: + return CD_PROP_FLOAT3; + default: + return {}; + } +} + +static void fn_node_random_value_gather_link_search(GatherLinkSearchOpParams ¶ms) +{ + const NodeDeclaration &declaration = *params.node_type().fixed_declaration; + const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket()); + if (!type) { + return; + } + if (params.in_out() == SOCK_IN) { + if (ELEM(*type, CD_PROP_INT32, CD_PROP_FLOAT3, CD_PROP_FLOAT)) { + params.add_item(IFACE_("Min"), [type](LinkSearchOpParams ¶ms) { + bNode &node = params.add_node("FunctionNodeRandomValue"); + node_storage(node).data_type = *type; + params.update_and_connect_available_socket(node, "Min"); + }); + params.add_item(IFACE_("Max"), [type](LinkSearchOpParams ¶ms) { + bNode &node = params.add_node("FunctionNodeRandomValue"); + node_storage(node).data_type = *type; + params.update_and_connect_available_socket(node, "Max"); + }); + } + search_link_ops_for_declarations(params, declaration.inputs().take_back(3)); + } + else { + params.add_item(IFACE_("Value"), [type](LinkSearchOpParams ¶ms) { + bNode &node = params.add_node("FunctionNodeRandomValue"); + node_storage(node).data_type = *type; + params.update_and_connect_available_socket(node, "Value"); + }); + } } class RandomVectorFunction : public fn::MultiFunction { @@ -203,14 +256,16 @@ class RandomIntFunction : public fn::MultiFunction { const VArray<int> &seeds = params.readonly_single_input<int>(3, "Seed"); MutableSpan<int> values = params.uninitialized_single_output<int>(4, "Value"); + /* Add one to the maximum and use floor to produce an even + * distribution for the first and last values (See T93591). */ for (int64_t i : mask) { const float min_value = min_values[i]; - const float max_value = max_values[i]; + const float max_value = max_values[i] + 1.0f; const int seed = seeds[i]; const int id = ids[i]; const float value = noise::hash_to_float(id, seed); - values[i] = round_fl_to_int(value * (max_value - min_value) + min_value); + values[i] = floor(value * (max_value - min_value) + min_value); } } }; @@ -251,7 +306,7 @@ class RandomBoolFunction : public fn::MultiFunction { static void fn_node_random_value_build_multi_function(NodeMultiFunctionBuilder &builder) { - const NodeRandomValue &storage = *(const NodeRandomValue *)builder.node().storage; + const NodeRandomValue &storage = node_storage(builder.node()); const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type); switch (data_type) { @@ -282,17 +337,21 @@ static void fn_node_random_value_build_multi_function(NodeMultiFunctionBuilder & } } -} // namespace blender::nodes +} // namespace blender::nodes::node_fn_random_value_cc void register_node_type_fn_random_value() { + namespace file_ns = blender::nodes::node_fn_random_value_cc; + static bNodeType ntype; - fn_node_type_base(&ntype, FN_NODE_RANDOM_VALUE, "Random Value", NODE_CLASS_CONVERTER, 0); - node_type_init(&ntype, blender::nodes::fn_node_random_value_init); - node_type_update(&ntype, blender::nodes::fn_node_random_value_update); - ntype.draw_buttons = blender::nodes::fn_node_random_value_layout; - ntype.declare = blender::nodes::fn_node_random_value_declare; - ntype.build_multi_function = blender::nodes::fn_node_random_value_build_multi_function; + + fn_node_type_base(&ntype, FN_NODE_RANDOM_VALUE, "Random Value", NODE_CLASS_CONVERTER); + node_type_init(&ntype, file_ns::fn_node_random_value_init); + node_type_update(&ntype, file_ns::fn_node_random_value_update); + ntype.draw_buttons = file_ns::fn_node_random_value_layout; + ntype.declare = file_ns::fn_node_random_value_declare; + ntype.build_multi_function = file_ns::fn_node_random_value_build_multi_function; + ntype.gather_link_search_ops = file_ns::fn_node_random_value_gather_link_search; node_type_storage( &ntype, "NodeRandomValue", node_free_standard_storage, node_copy_standard_storage); nodeRegisterType(&ntype); |