From 9588b731280f6a9262084aa3bf1c90239ca84aaa Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Wed, 18 May 2022 21:33:26 +0100 Subject: [PATCH] Auto-create resource params in new graph nodes --- generators/graph/voxel_generator_graph.cpp | 30 ++++++++++++--- generators/graph/voxel_generator_graph.h | 4 +- generators/graph/voxel_graph_compiler.cpp | 3 +- generators/graph/voxel_graph_node_db.cpp | 44 ++++++++++++++++------ generators/graph/voxel_graph_node_db.h | 6 ++- 5 files changed, 67 insertions(+), 20 deletions(-) diff --git a/generators/graph/voxel_generator_graph.cpp b/generators/graph/voxel_generator_graph.cpp index 23e596f7..bde5014b 100644 --- a/generators/graph/voxel_generator_graph.cpp +++ b/generators/graph/voxel_generator_graph.cpp @@ -35,8 +35,8 @@ void VoxelGeneratorGraph::clear() { } } -ProgramGraph::Node *create_node_internal( - ProgramGraph &graph, VoxelGeneratorGraph::NodeTypeID type_id, Vector2 position, uint32_t id) { +ProgramGraph::Node *create_node_internal(ProgramGraph &graph, VoxelGeneratorGraph::NodeTypeID type_id, Vector2 position, + uint32_t id, bool create_default_instances) { const VoxelGraphNodeDB::NodeType &type = VoxelGraphNodeDB::get_singleton().get_type(type_id); ProgramGraph::Node *node = graph.create_node(type_id, id); @@ -48,8 +48,16 @@ ProgramGraph::Node *create_node_internal( node->params.resize(type.params.size()); for (size_t i = 0; i < type.params.size(); ++i) { - node->params[i] = type.params[i].default_value; + const VoxelGraphNodeDB::Param ¶m = type.params[i]; + + if (param.class_name.is_empty()) { + node->params[i] = param.default_value; + + } else if (param.default_value_func != nullptr && create_default_instances) { + node->params[i] = param.default_value_func(); + } } + for (size_t i = 0; i < type.inputs.size(); ++i) { node->default_inputs[i] = type.inputs[i].default_value; } @@ -59,8 +67,19 @@ ProgramGraph::Node *create_node_internal( uint32_t VoxelGeneratorGraph::create_node(NodeTypeID type_id, Vector2 position, uint32_t id) { ERR_FAIL_COND_V(!VoxelGraphNodeDB::get_singleton().is_valid_type_id(type_id), ProgramGraph::NULL_ID); - const ProgramGraph::Node *node = create_node_internal(_graph, type_id, position, id); + const ProgramGraph::Node *node = create_node_internal(_graph, type_id, position, id, true); ERR_FAIL_COND_V(node == nullptr, ProgramGraph::NULL_ID); + // Register resources if any were created by default + for (const Variant &v : node->params) { + if (!v.is_null()) { + Ref res = v; + if (res.is_valid()) { + register_subresource(**res); + } else { + ZN_PRINT_WARNING("Non-resource object found in node parameter"); + } + } + } return node->id; } @@ -1520,7 +1539,8 @@ static bool load_graph_from_variant_data(ProgramGraph &graph, Dictionary data) { const Vector2 gui_position = node_data["gui_position"]; VoxelGeneratorGraph::NodeTypeID type_id; ERR_FAIL_COND_V(!type_db.try_get_type_id_from_name(type_name, type_id), false); - ProgramGraph::Node *node = create_node_internal(graph, type_id, gui_position, id); + // Don't create default param values, they will be assigned from serialized data + ProgramGraph::Node *node = create_node_internal(graph, type_id, gui_position, id, false); ERR_FAIL_COND_V(node == nullptr, false); const Variant *param_key = nullptr; diff --git a/generators/graph/voxel_generator_graph.h b/generators/graph/voxel_generator_graph.h index d229922c..01f21a3d 100644 --- a/generators/graph/voxel_generator_graph.h +++ b/generators/graph/voxel_generator_graph.h @@ -300,8 +300,8 @@ private: static thread_local Cache _cache; }; -ProgramGraph::Node *create_node_internal( - ProgramGraph &graph, VoxelGeneratorGraph::NodeTypeID type_id, Vector2 position, uint32_t id); +ProgramGraph::Node *create_node_internal(ProgramGraph &graph, VoxelGeneratorGraph::NodeTypeID type_id, Vector2 position, + uint32_t id, bool create_default_instances); } // namespace zylann::voxel diff --git a/generators/graph/voxel_graph_compiler.cpp b/generators/graph/voxel_graph_compiler.cpp index 88eee3f1..21c4f2ff 100644 --- a/generators/graph/voxel_graph_compiler.cpp +++ b/generators/graph/voxel_graph_compiler.cpp @@ -49,7 +49,8 @@ static bool expand_input(ProgramGraph &graph, const ExpressionParser::Node &arg, static ProgramGraph::Node &create_node( ProgramGraph &graph, const VoxelGraphNodeDB &db, VoxelGeneratorGraph::NodeTypeID node_type_id) { - ProgramGraph::Node *node = create_node_internal(graph, node_type_id, Vector2(), ProgramGraph::NULL_ID); + // Not creating default sub-resources here, there are no use cases where we use such nodes. + ProgramGraph::Node *node = create_node_internal(graph, node_type_id, Vector2(), ProgramGraph::NULL_ID, false); CRASH_COND(node == nullptr); return *node; } diff --git a/generators/graph/voxel_graph_node_db.cpp b/generators/graph/voxel_graph_node_db.cpp index a7dd01ae..c243afca 100644 --- a/generators/graph/voxel_graph_node_db.cpp +++ b/generators/graph/voxel_graph_node_db.cpp @@ -15,6 +15,7 @@ #include "../../util/noise/fast_noise_2.h" #endif +#include #include #include @@ -216,6 +217,13 @@ inline Interval sdf_sphere_heightmap(Interval x, Interval y, Interval z, float r return sd - m * h; } +template +Variant create_resource_to_variant() { + Ref res; + res.instantiate(); + return Variant(res); +} + const VoxelGraphNodeDB &VoxelGraphNodeDB::get_singleton() { CRASH_COND(g_node_type_db == nullptr); return *g_node_type_db; @@ -984,7 +992,17 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.category = CATEGORY_CONVERT; t.inputs.push_back(Port("x")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("curve", Curve::get_class_static())); + t.params.push_back(Param("curve", Curve::get_class_static(), []() { + Ref curve; + curve.instantiate(); + // The default preset when creating a Curve isn't convenient. + // Let's use a linear preset. + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(1, 1)); + curve->set_point_right_mode(0, Curve::TANGENT_LINEAR); + curve->set_point_left_mode(1, Curve::TANGENT_LINEAR); + return Variant(curve); + })); t.compile_func = [](CompileContext &ctx) { Ref curve = ctx.get_param(0); if (curve.is_null()) { @@ -1036,7 +1054,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("x")); t.inputs.push_back(Port("y")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("noise", Noise::get_class_static())); + t.params.push_back(Param("noise", Noise::get_class_static(), &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); @@ -1082,7 +1100,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("y")); t.inputs.push_back(Port("z")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("noise", Noise::get_class_static())); + t.params.push_back(Param("noise", Noise::get_class_static(), &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); @@ -1127,7 +1145,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("x")); t.inputs.push_back(Port("y")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("image", Image::get_class_static())); + t.params.push_back(Param("image", Image::get_class_static(), nullptr)); t.compile_func = [](CompileContext &ctx) { Ref image = ctx.get_param(0); if (image.is_null()) { @@ -1590,7 +1608,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("y")); t.inputs.push_back(Port("z")); t.outputs.push_back(Port("sdf")); - t.params.push_back(Param("image", Image::get_class_static())); + t.params.push_back(Param("image", Image::get_class_static(), nullptr)); t.params.push_back(Param("radius", Variant::FLOAT, 10.f)); t.params.push_back(Param("factor", Variant::FLOAT, 1.f)); @@ -1718,7 +1736,8 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("x")); t.inputs.push_back(Port("y")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("noise", ZN_FastNoiseLite::get_class_static())); + t.params.push_back( + Param("noise", ZN_FastNoiseLite::get_class_static(), &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); @@ -1785,7 +1804,8 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("y")); t.inputs.push_back(Port("z")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("noise", ZN_FastNoiseLite::get_class_static())); + t.params.push_back( + Param("noise", ZN_FastNoiseLite::get_class_static(), &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); @@ -1854,7 +1874,8 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("y")); t.outputs.push_back(Port("out_x")); t.outputs.push_back(Port("out_y")); - t.params.push_back(Param("noise", ZN_FastNoiseLiteGradient::get_class_static())); + t.params.push_back(Param("noise", ZN_FastNoiseLiteGradient::get_class_static(), + &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); @@ -1908,7 +1929,8 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.outputs.push_back(Port("out_x")); t.outputs.push_back(Port("out_y")); t.outputs.push_back(Port("out_z")); - t.params.push_back(Param("noise", ZN_FastNoiseLiteGradient::get_class_static())); + t.params.push_back(Param("noise", ZN_FastNoiseLiteGradient::get_class_static(), + &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); @@ -1966,7 +1988,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("x")); t.inputs.push_back(Port("y")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("noise", FastNoise2::get_class_static())); + t.params.push_back(Param("noise", FastNoise2::get_class_static(), &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); @@ -2014,7 +2036,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { t.inputs.push_back(Port("y")); t.inputs.push_back(Port("z")); t.outputs.push_back(Port("out")); - t.params.push_back(Param("noise", FastNoise2::get_class_static())); + t.params.push_back(Param("noise", FastNoise2::get_class_static(), &create_resource_to_variant)); t.compile_func = [](CompileContext &ctx) { Ref noise = ctx.get_param(0); diff --git a/generators/graph/voxel_graph_node_db.h b/generators/graph/voxel_graph_node_db.h index 729d5e53..31871d42 100644 --- a/generators/graph/voxel_graph_node_db.h +++ b/generators/graph/voxel_graph_node_db.h @@ -21,9 +21,12 @@ public: Port(String p_name, float p_default_value) : name(p_name), default_value(p_default_value) {} }; + typedef Variant (*DefaultValueFactory)(); + struct Param { String name; Variant default_value; + DefaultValueFactory default_value_func; Variant::Type type; String class_name; uint32_t index = -1; @@ -34,7 +37,8 @@ public: Param(String p_name, Variant::Type p_type, Variant p_default_value = Variant()) : name(p_name), default_value(p_default_value), type(p_type) {} - Param(String p_name, String p_class_name) : name(p_name), type(Variant::OBJECT), class_name(p_class_name) {} + Param(String p_name, String p_class_name, DefaultValueFactory dvf) : + name(p_name), default_value_func(dvf), type(Variant::OBJECT), class_name(p_class_name) {} }; enum Category {