Auto-create resource params in new graph nodes

This commit is contained in:
Marc Gilleron 2022-05-18 21:33:26 +01:00
parent df25723b20
commit 9588b73128
5 changed files with 67 additions and 20 deletions

View File

@ -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 &param = 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<Resource> 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;

View File

@ -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

View File

@ -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;
}

View File

@ -15,6 +15,7 @@
#include "../../util/noise/fast_noise_2.h"
#endif
#include <modules/noise/fastnoise_lite.h>
#include <modules/noise/noise.h>
#include <scene/resources/curve.h>
@ -216,6 +217,13 @@ inline Interval sdf_sphere_heightmap(Interval x, Interval y, Interval z, float r
return sd - m * h;
}
template <typename T>
Variant create_resource_to_variant() {
Ref<T> 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;
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> 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<FastNoiseLite>));
t.compile_func = [](CompileContext &ctx) {
Ref<Noise> 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<FastNoiseLite>));
t.compile_func = [](CompileContext &ctx) {
Ref<Noise> 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> 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<ZN_FastNoiseLite>));
t.compile_func = [](CompileContext &ctx) {
Ref<ZN_FastNoiseLite> 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<ZN_FastNoiseLite>));
t.compile_func = [](CompileContext &ctx) {
Ref<ZN_FastNoiseLite> 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<ZN_FastNoiseLiteGradient>));
t.compile_func = [](CompileContext &ctx) {
Ref<ZN_FastNoiseLiteGradient> 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<ZN_FastNoiseLiteGradient>));
t.compile_func = [](CompileContext &ctx) {
Ref<ZN_FastNoiseLiteGradient> 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<FastNoise2>));
t.compile_func = [](CompileContext &ctx) {
Ref<FastNoise2> 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<FastNoise2>));
t.compile_func = [](CompileContext &ctx) {
Ref<FastNoise2> noise = ctx.get_param(0);

View File

@ -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 {