Namespaced VoxelGraphNodeDB

master
Marc Gilleron 2022-01-03 03:55:44 +00:00
parent 8777bb2bf1
commit e68f59643b
7 changed files with 133 additions and 123 deletions

View File

@ -214,9 +214,9 @@ VoxelGraphEditor::VoxelGraphEditor() {
add_child(vbox_container);
_context_menu = memnew(PopupMenu);
FixedArray<PopupMenu *, VoxelGraphNodeDB::CATEGORY_COUNT> category_menus;
FixedArray<PopupMenu *, zylann::voxel::VoxelGraphNodeDB::CATEGORY_COUNT> category_menus;
for (unsigned int i = 0; i < category_menus.size(); ++i) {
String name = VoxelGraphNodeDB::get_category_name(VoxelGraphNodeDB::Category(i));
String name = zylann::voxel::VoxelGraphNodeDB::get_category_name(zylann::voxel::VoxelGraphNodeDB::Category(i));
PopupMenu *menu = memnew(PopupMenu);
menu->set_name(name);
menu->connect("id_pressed", callable_mp(this, &VoxelGraphEditor::_on_context_menu_id_pressed));
@ -224,8 +224,9 @@ VoxelGraphEditor::VoxelGraphEditor() {
_context_menu->add_submenu_item(name, name, i);
category_menus[i] = menu;
}
for (int i = 0; i < VoxelGraphNodeDB::get_singleton()->get_type_count(); ++i) {
const VoxelGraphNodeDB::NodeType &node_type = VoxelGraphNodeDB::get_singleton()->get_type(i);
for (int i = 0; i < zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type_count(); ++i) {
const zylann::voxel::VoxelGraphNodeDB::NodeType &node_type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(i);
PopupMenu *menu = category_menus[node_type.category];
menu->add_item(node_type.name, i);
}
@ -374,7 +375,8 @@ void VoxelGraphEditor::create_node_gui(uint32_t node_id) {
CRASH_COND(_graph.is_null());
const VoxelGeneratorGraph &graph = **_graph;
const uint32_t node_type_id = graph.get_node_type_id(node_id);
const VoxelGraphNodeDB::NodeType &node_type = VoxelGraphNodeDB::get_singleton()->get_type(node_type_id);
const zylann::voxel::VoxelGraphNodeDB::NodeType &node_type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(node_type_id);
const String ui_node_name = node_to_gui_name(node_id);
ERR_FAIL_COND(_graph_edit->has_node(ui_node_name));
@ -393,7 +395,7 @@ void VoxelGraphEditor::create_node_gui(uint32_t node_id) {
// We artificially hide output ports if the node is an output.
// These nodes have an output for implementation reasons, some outputs can process the data like any other node.
const bool hide_outputs = node_type.category == VoxelGraphNodeDB::CATEGORY_OUTPUT;
const bool hide_outputs = node_type.category == zylann::voxel::VoxelGraphNodeDB::CATEGORY_OUTPUT;
const unsigned int row_count = max(node_type.inputs.size(), hide_outputs ? 0 : node_type.outputs.size());
const Color port_color(0.4, 0.4, 1.0);
@ -593,7 +595,8 @@ void VoxelGraphEditor::_on_graph_edit_delete_nodes_request() {
*_graph, "create_node", node_type_id, _graph->get_node_gui_position(node_id), node_id);
// Params undo
const size_t param_count = VoxelGraphNodeDB::get_singleton()->get_type(node_type_id).params.size();
const size_t param_count =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(node_type_id).params.size();
for (size_t j = 0; j < param_count; ++j) {
Variant param_value = _graph->get_node_param(node_id, j);
_undo_redo->add_undo_method(*_graph, "set_node_param", node_id, SIZE_T_TO_VARIANT(j), param_value);
@ -930,7 +933,7 @@ void VoxelGraphEditor::_on_graph_node_name_changed(int node_id) {
StringName node_name = _graph->get_node_name(node_id);
const uint32_t node_type_id = _graph->get_node_type_id(node_id);
String node_type_name = VoxelGraphNodeDB::get_singleton()->get_type(node_type_id).name;
String node_type_name = zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(node_type_id).name;
const String ui_node_name = node_to_gui_name(node_id);
VoxelGraphEditorNode *node_view = Object::cast_to<VoxelGraphEditorNode>(_graph_edit->get_node(ui_node_name));

View File

@ -24,14 +24,15 @@ void VoxelGraphNodeInspectorWrapper::_get_property_list(List<PropertyInfo> *p_li
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_EDITOR));
const uint32_t node_type_id = graph->get_node_type_id(_node_id);
const VoxelGraphNodeDB::NodeType &node_type = VoxelGraphNodeDB::get_singleton()->get_type(node_type_id);
const zylann::voxel::VoxelGraphNodeDB::NodeType &node_type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(node_type_id);
// Params
p_list->push_back(PropertyInfo(Variant::NIL, "Params", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
for (size_t i = 0; i < node_type.params.size(); ++i) {
const VoxelGraphNodeDB::Param &param = node_type.params[i];
const zylann::voxel::VoxelGraphNodeDB::Param &param = node_type.params[i];
PropertyInfo pi;
pi.name = param.name;
pi.type = param.type;
@ -53,7 +54,7 @@ void VoxelGraphNodeInspectorWrapper::_get_property_list(List<PropertyInfo> *p_li
PropertyInfo(Variant::NIL, "Input Defaults", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
for (size_t i = 0; i < node_type.inputs.size(); ++i) {
const VoxelGraphNodeDB::Port &port = node_type.inputs[i];
const zylann::voxel::VoxelGraphNodeDB::Port &port = node_type.inputs[i];
PropertyInfo pi;
pi.name = port.name;
pi.type = port.default_value.get_type();
@ -81,8 +82,10 @@ bool VoxelGraphNodeInspectorWrapper::_set(const StringName &p_name, const Varian
const uint32_t node_type_id = graph->get_node_type_id(_node_id);
const zylann::voxel::VoxelGraphNodeDB *db = zylann::voxel::VoxelGraphNodeDB::get_singleton();
uint32_t index;
if (VoxelGraphNodeDB::get_singleton()->try_get_param_index_from_name(node_type_id, p_name, index)) {
if (db->try_get_param_index_from_name(node_type_id, p_name, index)) {
Variant previous_value = graph->get_node_param(_node_id, index);
ur->create_action("Set VoxelGeneratorGraph node parameter");
ur->add_do_method(graph.ptr(), "set_node_param", _node_id, index, p_value);
@ -91,7 +94,7 @@ bool VoxelGraphNodeInspectorWrapper::_set(const StringName &p_name, const Varian
ur->add_undo_method(this, "notify_property_list_changed");
ur->commit_action();
} else if (VoxelGraphNodeDB::get_singleton()->try_get_input_index_from_name(node_type_id, p_name, index)) {
} else if (db->try_get_input_index_from_name(node_type_id, p_name, index)) {
Variant previous_value = graph->get_node_default_input(_node_id, index);
ur->create_action("Set VoxelGeneratorGraph node default input");
ur->add_do_method(graph.ptr(), "set_node_default_input", _node_id, index, p_value);
@ -119,11 +122,13 @@ bool VoxelGraphNodeInspectorWrapper::_get(const StringName &p_name, Variant &r_r
const uint32_t node_type_id = graph->get_node_type_id(_node_id);
const zylann::voxel::VoxelGraphNodeDB *db = zylann::voxel::VoxelGraphNodeDB::get_singleton();
uint32_t index;
if (VoxelGraphNodeDB::get_singleton()->try_get_param_index_from_name(node_type_id, p_name, index)) {
if (db->try_get_param_index_from_name(node_type_id, p_name, index)) {
r_ret = graph->get_node_param(_node_id, index);
} else if (VoxelGraphNodeDB::get_singleton()->try_get_input_index_from_name(node_type_id, p_name, index)) {
} else if (db->try_get_input_index_from_name(node_type_id, p_name, index)) {
r_ret = graph->get_node_default_input(_node_id, index);
} else {

View File

@ -27,7 +27,8 @@ void VoxelGeneratorGraph::clear() {
static ProgramGraph::Node *create_node_internal(
ProgramGraph &graph, VoxelGeneratorGraph::NodeTypeID type_id, Vector2 position, uint32_t id) {
const VoxelGraphNodeDB::NodeType &type = VoxelGraphNodeDB::get_singleton()->get_type(type_id);
const zylann::voxel::VoxelGraphNodeDB::NodeType &type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(type_id);
ProgramGraph::Node *node = graph.create_node(type_id, id);
ERR_FAIL_COND_V(node == nullptr, nullptr);
@ -48,7 +49,8 @@ static 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);
ERR_FAIL_COND_V(
!zylann::voxel::VoxelGraphNodeDB::get_singleton()->is_valid_type_id(type_id), ProgramGraph::NULL_ID);
const ProgramGraph::Node *node = create_node_internal(_graph, type_id, position, id);
ERR_FAIL_COND_V(node == nullptr, ProgramGraph::NULL_ID);
return node->id;
@ -1154,7 +1156,8 @@ static Dictionary get_graph_as_variant_data(const ProgramGraph &graph) {
Dictionary node_data;
const VoxelGraphNodeDB::NodeType &type = VoxelGraphNodeDB::get_singleton()->get_type(node->type_id);
const zylann::voxel::VoxelGraphNodeDB::NodeType &type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(node->type_id);
node_data["type"] = type.name;
node_data["gui_position"] = node->gui_position;
@ -1163,13 +1166,13 @@ static Dictionary get_graph_as_variant_data(const ProgramGraph &graph) {
}
for (size_t j = 0; j < type.params.size(); ++j) {
const VoxelGraphNodeDB::Param &param = type.params[j];
const zylann::voxel::VoxelGraphNodeDB::Param &param = type.params[j];
node_data[param.name] = node->params[j];
}
for (size_t j = 0; j < type.inputs.size(); ++j) {
if (node->inputs[j].connections.size() == 0) {
const VoxelGraphNodeDB::Port &port = type.inputs[j];
const zylann::voxel::VoxelGraphNodeDB::Port &port = type.inputs[j];
node_data[port.name] = node->default_inputs[j];
}
}
@ -1214,7 +1217,7 @@ static bool var_to_id(Variant v, uint32_t &out_id, uint32_t min = 0) {
static bool load_graph_from_variant_data(ProgramGraph &graph, Dictionary data) {
Dictionary nodes_data = data["nodes"];
Array connections_data = data["connections"];
const VoxelGraphNodeDB &type_db = *VoxelGraphNodeDB::get_singleton();
const zylann::voxel::VoxelGraphNodeDB &type_db = *zylann::voxel::VoxelGraphNodeDB::get_singleton();
const Variant *id_key = nullptr;
while ((id_key = nodes_data.next(id_key))) {
@ -1459,12 +1462,12 @@ void VoxelGeneratorGraph::debug_load_waves_preset() {
// Binding land
int VoxelGeneratorGraph::_b_get_node_type_count() const {
return VoxelGraphNodeDB::get_singleton()->get_type_count();
return zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type_count();
}
Dictionary VoxelGeneratorGraph::_b_get_node_type_info(int type_id) const {
ERR_FAIL_COND_V(!VoxelGraphNodeDB::get_singleton()->is_valid_type_id(type_id), Dictionary());
return VoxelGraphNodeDB::get_singleton()->get_type_info_dict(type_id);
ERR_FAIL_COND_V(!zylann::voxel::VoxelGraphNodeDB::get_singleton()->is_valid_type_id(type_id), Dictionary());
return zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type_info_dict(type_id);
}
Array VoxelGeneratorGraph::_b_get_connections() const {

View File

@ -12,6 +12,8 @@
#include <modules/opensimplex/open_simplex_noise.h>
#include <scene/resources/curve.h>
namespace zylann::voxel {
namespace {
VoxelGraphNodeDB *g_node_type_db = nullptr;
}
@ -138,8 +140,6 @@ inline Interval select(const Interval &a, const Interval &b, const Interval &thr
return Interval(min(a.min, b.min), max(a.max, b.max));
}
namespace zylann {
inline float skew3(float x) {
return (x * x * x + x) * 0.5f;
}
@ -206,8 +206,6 @@ inline Interval sdf_sphere_heightmap(Interval x, Interval y, Interval z, float r
return sd - m * h;
}
} // namespace zylann
VoxelGraphNodeDB *VoxelGraphNodeDB::get_singleton() {
CRASH_COND(g_node_type_db == nullptr);
return g_node_type_db;
@ -786,7 +784,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
struct Params {
// TODO Should be `const` but isn't because it auto-bakes, and it's a concern for multithreading
Curve *curve;
zylann::CurveRangeData *curve_range_data;
CurveRangeData *curve_range_data;
};
NodeType &t = types[VoxelGeneratorGraph::NODE_CURVE];
t.name = "Curve";
@ -803,7 +801,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
// Make sure it is baked. We don't want multithreading to bail out because of a write operation
// happening in `interpolate_baked`...
curve->bake();
zylann::CurveRangeData *curve_range_data = memnew(zylann::CurveRangeData);
CurveRangeData *curve_range_data = memnew(CurveRangeData);
get_curve_monotonic_sections(**curve, curve_range_data->sections);
Params p;
p.curve_range_data = curve_range_data;
@ -872,7 +870,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval x = ctx.get_input(0);
const Interval y = ctx.get_input(1);
const Params p = ctx.get_params<Params>();
ctx.set_output(0, zylann::get_osn_range_2d(p.noise, x, y));
ctx.set_output(0, get_osn_range_2d(p.noise, x, y));
};
}
{
@ -918,13 +916,13 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval y = ctx.get_input(1);
const Interval z = ctx.get_input(2);
const Params p = ctx.get_params<Params>();
ctx.set_output(0, zylann::get_osn_range_3d(p.noise, x, y, z));
ctx.set_output(0, get_osn_range_3d(p.noise, x, y, z));
};
}
{
struct Params {
const Image *image;
const zylann::ImageRangeGrid *image_range_grid;
const ImageRangeGrid *image_range_grid;
};
NodeType &t = types[VoxelGeneratorGraph::NODE_IMAGE_2D];
t.name = "Image";
@ -939,7 +937,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
ctx.make_error("Image instance is null");
return;
}
zylann::ImageRangeGrid *im_range = memnew(zylann::ImageRangeGrid);
ImageRangeGrid *im_range = memnew(ImageRangeGrid);
im_range->generate(**image);
Params p;
p.image = *image;
@ -1002,7 +1000,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const VoxelGraphRuntime::Buffer &sz = ctx.get_input(5);
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = zylann::math::sdf_box(
out.data[i] = math::sdf_box(
Vector3(x.data[i], y.data[i], z.data[i]), Vector3(sx.data[i], sy.data[i], sz.data[i]));
}
};
@ -1013,7 +1011,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval sx = ctx.get_input(3);
const Interval sy = ctx.get_input(4);
const Interval sz = ctx.get_input(5);
ctx.set_output(0, zylann::math::sdf_box(x, y, z, sx, sy, sz));
ctx.set_output(0, math::sdf_box(x, y, z, sx, sy, sz));
};
}
{
@ -1061,7 +1059,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const VoxelGraphRuntime::Buffer &r1 = ctx.get_input(4);
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = zylann::math::sdf_torus(x.data[i], y.data[i], z.data[i], r0.data[i], r1.data[i]);
out.data[i] = math::sdf_torus(x.data[i], y.data[i], z.data[i], r0.data[i], r1.data[i]);
}
};
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
@ -1070,7 +1068,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval z = ctx.get_input(2);
const Interval r0 = ctx.get_input(3);
const Interval r1 = ctx.get_input(4);
ctx.set_output(0, zylann::math::sdf_torus(x, y, z, r0, r1));
ctx.set_output(0, math::sdf_torus(x, y, z, r0, r1));
};
}
{
@ -1107,12 +1105,12 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
}
} else if (params.smoothness > 0.0001f) {
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = zylann::math::sdf_smooth_union(a.data[i], b.data[i], params.smoothness);
out.data[i] = math::sdf_smooth_union(a.data[i], b.data[i], params.smoothness);
}
} else {
// Fallback on hard-union, smooth union does not support zero smoothness
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = zylann::math::sdf_union(a.data[i], b.data[i]);
out.data[i] = math::sdf_union(a.data[i], b.data[i]);
}
}
};
@ -1122,39 +1120,39 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Params params = ctx.get_params<Params>();
if (params.smoothness > 0.0001f) {
const zylann::math::SdfAffectingArguments args =
zylann::math::sdf_polynomial_smooth_union_side(a, b, params.smoothness);
const math::SdfAffectingArguments args =
math::sdf_polynomial_smooth_union_side(a, b, params.smoothness);
switch (args) {
case zylann::math::SDF_ONLY_A:
case math::SDF_ONLY_A:
ctx.ignore_input(0);
break;
case zylann::math::SDF_ONLY_B:
case math::SDF_ONLY_B:
ctx.ignore_input(1);
break;
case zylann::math::SDF_BOTH:
case math::SDF_BOTH:
break;
default:
CRASH_NOW();
break;
}
ctx.set_output(0, zylann::math::sdf_smooth_union(a, b, params.smoothness));
ctx.set_output(0, math::sdf_smooth_union(a, b, params.smoothness));
} else {
const zylann::math::SdfAffectingArguments args = zylann::math::sdf_union_side(a, b);
const math::SdfAffectingArguments args = math::sdf_union_side(a, b);
switch (args) {
case zylann::math::SDF_ONLY_A:
case math::SDF_ONLY_A:
ctx.ignore_input(0);
break;
case zylann::math::SDF_ONLY_B:
case math::SDF_ONLY_B:
ctx.ignore_input(1);
break;
case zylann::math::SDF_BOTH:
case math::SDF_BOTH:
break;
default:
CRASH_NOW();
break;
}
ctx.set_output(0, zylann::math::sdf_union(a, b));
ctx.set_output(0, math::sdf_union(a, b));
}
};
}
@ -1192,12 +1190,12 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
}
} else if (params.smoothness > 0.0001f) {
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = zylann::math::sdf_smooth_subtract(a.data[i], b.data[i], params.smoothness);
out.data[i] = math::sdf_smooth_subtract(a.data[i], b.data[i], params.smoothness);
}
} else {
// Fallback on hard-subtract, smooth subtract does not support zero smoothness
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = zylann::math::sdf_subtract(a.data[i], b.data[i]);
out.data[i] = math::sdf_subtract(a.data[i], b.data[i]);
}
}
};
@ -1207,39 +1205,39 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Params params = ctx.get_params<Params>();
if (params.smoothness > 0.0001f) {
const zylann::math::SdfAffectingArguments args =
zylann::math::sdf_polynomial_smooth_subtract_side(a, b, params.smoothness);
const math::SdfAffectingArguments args =
math::sdf_polynomial_smooth_subtract_side(a, b, params.smoothness);
switch (args) {
case zylann::math::SDF_ONLY_A:
case math::SDF_ONLY_A:
ctx.ignore_input(0);
break;
case zylann::math::SDF_ONLY_B:
case math::SDF_ONLY_B:
ctx.ignore_input(1);
break;
case zylann::math::SDF_BOTH:
case math::SDF_BOTH:
break;
default:
CRASH_NOW();
break;
}
ctx.set_output(0, zylann::math::sdf_smooth_subtract(a, b, params.smoothness));
ctx.set_output(0, math::sdf_smooth_subtract(a, b, params.smoothness));
} else {
const zylann::math::SdfAffectingArguments args = zylann::math::sdf_subtract_side(a, b);
const math::SdfAffectingArguments args = math::sdf_subtract_side(a, b);
switch (args) {
case zylann::math::SDF_ONLY_A:
case math::SDF_ONLY_A:
ctx.ignore_input(0);
break;
case zylann::math::SDF_ONLY_B:
case math::SDF_ONLY_B:
ctx.ignore_input(1);
break;
case zylann::math::SDF_BOTH:
case math::SDF_BOTH:
break;
default:
CRASH_NOW();
break;
}
ctx.set_output(0, zylann::math::sdf_subtract(a, b));
ctx.set_output(0, math::sdf_subtract(a, b));
}
};
}
@ -1301,7 +1299,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
float norm_x;
float norm_y;
const Image *image;
const zylann::ImageRangeGrid *image_range_grid;
const ImageRangeGrid *image_range_grid;
};
NodeType &t = types[VoxelGeneratorGraph::NODE_SDF_SPHERE_HEIGHTMAP];
@ -1321,7 +1319,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
ctx.make_error("Image instance is null");
return;
}
zylann::ImageRangeGrid *im_range = memnew(zylann::ImageRangeGrid);
ImageRangeGrid *im_range = memnew(ImageRangeGrid);
im_range->generate(**image);
const float factor = ctx.get_param(2);
const Interval range = im_range->get_range() * factor;
@ -1348,7 +1346,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Params p = ctx.get_params<Params>();
const Image &im = *p.image;
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = zylann::sdf_sphere_heightmap(x.data[i], y.data[i], z.data[i], p.radius, p.factor, im,
out.data[i] = sdf_sphere_heightmap(x.data[i], y.data[i], z.data[i], p.radius, p.factor, im,
p.min_height, p.max_height, p.norm_x, p.norm_y);
}
};
@ -1358,8 +1356,8 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval y = ctx.get_input(1);
const Interval z = ctx.get_input(2);
const Params p = ctx.get_params<Params>();
ctx.set_output(0,
zylann::sdf_sphere_heightmap(x, y, z, p.radius, p.factor, p.image_range_grid, p.norm_x, p.norm_y));
ctx.set_output(
0, sdf_sphere_heightmap(x, y, z, p.radius, p.factor, p.image_range_grid, p.norm_x, p.norm_y));
};
}
{
@ -1449,7 +1447,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval x = ctx.get_input(0);
const Interval y = ctx.get_input(1);
const Params p = ctx.get_params<Params>();
ctx.set_output(0, zylann::get_fnl_range_2d(p.noise, x, y));
ctx.set_output(0, get_fnl_range_2d(p.noise, x, y));
};
}
{
@ -1494,7 +1492,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval y = ctx.get_input(1);
const Interval z = ctx.get_input(2);
const Params p = ctx.get_params<Params>();
ctx.set_output(0, zylann::get_fnl_range_3d(p.noise, x, y, z));
ctx.set_output(0, get_fnl_range_3d(p.noise, x, y, z));
};
}
{
@ -1542,7 +1540,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval x = ctx.get_input(0);
const Interval y = ctx.get_input(1);
const Params p = ctx.get_params<Params>();
const zylann::math::Interval2 r = zylann::get_fnl_gradient_range_2d(p.noise, x, y);
const math::Interval2 r = get_fnl_gradient_range_2d(p.noise, x, y);
ctx.set_output(0, r.x);
ctx.set_output(1, r.y);
};
@ -1599,7 +1597,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval y = ctx.get_input(1);
const Interval z = ctx.get_input(2);
const Params p = ctx.get_params<Params>();
const zylann::math::Interval3 r = zylann::get_fnl_gradient_range_3d(p.noise, x, y, z);
const math::Interval3 r = get_fnl_gradient_range_3d(p.noise, x, y, z);
ctx.set_output(0, r.x);
ctx.set_output(1, r.y);
ctx.set_output(2, r.z);
@ -1819,3 +1817,5 @@ bool VoxelGraphNodeDB::try_get_input_index_from_name(
out_input_index = *p;
return true;
}
} // namespace zylann::voxel

View File

@ -3,6 +3,8 @@
#include "voxel_generator_graph.h"
namespace zylann::voxel {
class VoxelGraphNodeDB {
public:
struct Port {
@ -10,13 +12,9 @@ public:
Variant default_value;
//PortType port_type;
Port(String p_name) :
name(p_name),
default_value(0.f) {}
Port(String p_name) : name(p_name), default_value(0.f) {}
Port(String p_name, float p_default_value) :
name(p_name),
default_value(p_default_value) {}
Port(String p_name, float p_default_value) : name(p_name), default_value(p_default_value) {}
};
struct Param {
@ -30,14 +28,9 @@ public:
int max_value;
Param(String p_name, Variant::Type p_type, Variant p_default_value = Variant()) :
name(p_name),
default_value(p_default_value),
type(p_type) {}
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) : name(p_name), type(Variant::OBJECT), class_name(p_class_name) {}
};
enum Category {
@ -73,9 +66,15 @@ public:
static const char *get_category_name(Category category);
int get_type_count() const { return _types.size(); }
bool is_valid_type_id(int type_id) const { return type_id >= 0 && type_id < static_cast<int>(_types.size()); }
const NodeType &get_type(uint32_t id) const { return _types[id]; }
int get_type_count() const {
return _types.size();
}
bool is_valid_type_id(int type_id) const {
return type_id >= 0 && type_id < static_cast<int>(_types.size());
}
const NodeType &get_type(uint32_t id) const {
return _types[id];
}
Dictionary get_type_info_dict(uint32_t id) const;
bool try_get_type_id_from_name(const String &name, VoxelGeneratorGraph::NodeTypeID &out_type_id) const;
bool try_get_param_index_from_name(uint32_t type_id, const String &name, uint32_t &out_param_index) const;
@ -86,4 +85,6 @@ private:
HashMap<String, VoxelGeneratorGraph::NodeTypeID> _type_name_to_id;
};
} // namespace zylann::voxel
#endif // VOXEL_GRAPH_NODE_DB_H

View File

@ -46,8 +46,9 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr
// Not using the generic `get_terminal_nodes` function because our terminal nodes do have outputs
graph.for_each_node_const([&terminal_nodes](const ProgramGraph::Node &node) {
const VoxelGraphNodeDB::NodeType &type = VoxelGraphNodeDB::get_singleton()->get_type(node.type_id);
if (type.category == VoxelGraphNodeDB::CATEGORY_OUTPUT) {
const zylann::voxel::VoxelGraphNodeDB::NodeType &type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(node.type_id);
if (type.category == zylann::voxel::VoxelGraphNodeDB::CATEGORY_OUTPUT) {
terminal_nodes.push_back(node.id);
}
});
@ -56,7 +57,8 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr
// Exclude debug nodes
unordered_remove_if(terminal_nodes, [&graph](uint32_t node_id) {
const ProgramGraph::Node *node = graph.get_node(node_id);
const VoxelGraphNodeDB::NodeType &type = VoxelGraphNodeDB::get_singleton()->get_type(node->type_id);
const zylann::voxel::VoxelGraphNodeDB::NodeType &type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(node->type_id);
return type.debug_only;
});
}
@ -180,13 +182,13 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr
_program.z_input_address = mem.add_binding();
std::vector<uint16_t> &operations = _program.operations;
const VoxelGraphNodeDB &type_db = *VoxelGraphNodeDB::get_singleton();
const zylann::voxel::VoxelGraphNodeDB &type_db = *zylann::voxel::VoxelGraphNodeDB::get_singleton();
// Run through each node in order, and turn them into program instructions
for (size_t order_index = 0; order_index < order.size(); ++order_index) {
const uint32_t node_id = order[order_index];
const ProgramGraph::Node *node = graph.get_node(node_id);
const VoxelGraphNodeDB::NodeType &type = type_db.get_type(node->type_id);
const zylann::voxel::VoxelGraphNodeDB::NodeType &type = type_db.get_type(node->type_id);
CRASH_COND(node == nullptr);
CRASH_COND(node->inputs.size() != type.inputs.size());
@ -340,7 +342,7 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr
operations[params_size_index] = params_size;
}
if (type.category == VoxelGraphNodeDB::CATEGORY_OUTPUT) {
if (type.category == zylann::voxel::VoxelGraphNodeDB::CATEGORY_OUTPUT) {
CRASH_COND(node->outputs.size() != 1);
{
const uint16_t *aptr = _program.output_port_addresses.getptr(ProgramGraph::PortLocation{ node_id, 0 });
@ -374,8 +376,7 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr
_program.buffer_count = mem.next_address;
PRINT_VERBOSE(String("Compiled voxel graph. Program size: {0}b, buffers: {1}")
.format(varray(
SIZE_T_TO_VARIANT(_program.operations.size() * sizeof(uint16_t)),
.format(varray(SIZE_T_TO_VARIANT(_program.operations.size() * sizeof(uint16_t)),
SIZE_T_TO_VARIANT(_program.buffer_count))));
CompilationResult result;
@ -383,10 +384,10 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr
return result;
}
static Span<const uint16_t> get_outputs_from_op_address(
Span<const uint16_t> operations, uint16_t op_address) {
static Span<const uint16_t> get_outputs_from_op_address(Span<const uint16_t> operations, uint16_t op_address) {
const uint16_t opid = operations[op_address];
const VoxelGraphNodeDB::NodeType &node_type = VoxelGraphNodeDB::get_singleton()->get_type(opid);
const zylann::voxel::VoxelGraphNodeDB::NodeType &node_type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(opid);
const uint32_t inputs_count = node_type.inputs.size();
const uint32_t outputs_count = node_type.outputs.size();
@ -401,8 +402,7 @@ bool VoxelGraphRuntime::is_operation_constant(const State &state, uint16_t op_ad
for (unsigned int i = 0; i < outputs.size(); ++i) {
const uint16_t output_address = outputs[i];
const Buffer &buffer = state.get_buffer(output_address);
if (!(buffer.is_constant ||
state.get_range(output_address).is_single_value() ||
if (!(buffer.is_constant || state.get_range(output_address).is_single_value() ||
buffer.local_users_count == 0)) {
// At least one of the outputs cannot be predicted in the current area
return false;
@ -412,8 +412,8 @@ bool VoxelGraphRuntime::is_operation_constant(const State &state, uint16_t op_ad
return true;
}
void VoxelGraphRuntime::generate_optimized_execution_map(const State &state, ExecutionMap &execution_map,
bool debug) const {
void VoxelGraphRuntime::generate_optimized_execution_map(
const State &state, ExecutionMap &execution_map, bool debug) const {
FixedArray<unsigned int, MAX_OUTPUTS> all_outputs;
for (unsigned int i = 0; i < _program.outputs_count; ++i) {
all_outputs[i] = i;
@ -426,8 +426,8 @@ void VoxelGraphRuntime::generate_optimized_execution_map(const State &state, Exe
// If a non-constant operation only contributes to a constant one, it will also be skipped.
// This has the effect of optimizing locally at runtime without relying on explicit conditionals.
// It can be useful for biomes, where some branches become constant when not used in the final blending.
void VoxelGraphRuntime::generate_optimized_execution_map(const State &state, ExecutionMap &execution_map,
Span<const unsigned int> required_outputs, bool debug) const {
void VoxelGraphRuntime::generate_optimized_execution_map(
const State &state, ExecutionMap &execution_map, Span<const unsigned int> required_outputs, bool debug) const {
VOXEL_PROFILE_SCOPE();
// Range analysis results must have been computed
@ -453,11 +453,7 @@ void VoxelGraphRuntime::generate_optimized_execution_map(const State &state, Exe
to_process.push_back(dg_index);
}
enum ProcessResult {
NOT_PROCESSED,
SKIPPABLE,
REQUIRED
};
enum ProcessResult { NOT_PROCESSED, SKIPPABLE, REQUIRED };
static thread_local std::vector<ProcessResult> results;
results.clear();
@ -570,10 +566,8 @@ void VoxelGraphRuntime::generate_optimized_execution_map(const State &state, Exe
}
void VoxelGraphRuntime::generate_single(State &state, Vector3 position, const ExecutionMap *execution_map) const {
generate_set(state,
Span<float>(&position.x, 1),
Span<float>(&position.y, 1),
Span<float>(&position.z, 1), false, execution_map);
generate_set(state, Span<float>(&position.x, 1), Span<float>(&position.y, 1), Span<float>(&position.z, 1), false,
execution_map);
}
void VoxelGraphRuntime::prepare_state(State &state, unsigned int buffer_size) const {
@ -703,8 +697,7 @@ static inline Span<const uint8_t> read_params(Span<const uint16_t> operations, u
return params;
}
void VoxelGraphRuntime::generate_set(State &state,
Span<float> in_x, Span<float> in_y, Span<float> in_z, bool skip_xz,
void VoxelGraphRuntime::generate_set(State &state, Span<float> in_x, Span<float> in_y, Span<float> in_z, bool skip_xz,
const ExecutionMap *execution_map) const {
// I don't like putting private helper functions in headers.
struct L {
@ -764,9 +757,12 @@ void VoxelGraphRuntime::generate_set(State &state,
const Span<const uint16_t> operations(_program.operations.data(), 0, _program.operations.size());
Span<const uint16_t> op_adresses = execution_map != nullptr ? to_span_const(execution_map->operation_adresses) : to_span_const(_program.default_execution_map.operation_adresses);
Span<const uint16_t> op_adresses = execution_map != nullptr
? to_span_const(execution_map->operation_adresses)
: to_span_const(_program.default_execution_map.operation_adresses);
if (skip_xz && op_adresses.size() > 0) {
const unsigned int offset = execution_map != nullptr ? execution_map->xzy_start_index : _program.default_execution_map.xzy_start_index;
const unsigned int offset = execution_map != nullptr ? execution_map->xzy_start_index
: _program.default_execution_map.xzy_start_index;
op_adresses = op_adresses.sub(offset);
}
@ -774,7 +770,8 @@ void VoxelGraphRuntime::generate_set(State &state,
unsigned int pc = op_adresses[execution_map_index];
const uint16_t opid = operations[pc++];
const VoxelGraphNodeDB::NodeType &node_type = VoxelGraphNodeDB::get_singleton()->get_type(opid);
const zylann::voxel::VoxelGraphNodeDB::NodeType &node_type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(opid);
const uint32_t inputs_count = node_type.inputs.size();
const uint32_t outputs_count = node_type.outputs.size();
@ -832,7 +829,8 @@ void VoxelGraphRuntime::analyze_range(State &state, Vector3i min_pos, Vector3i m
uint32_t pc = 0;
while (pc < operations.size()) {
const uint16_t opid = operations[pc++];
const VoxelGraphNodeDB::NodeType &node_type = VoxelGraphNodeDB::get_singleton()->get_type(opid);
const zylann::voxel::VoxelGraphNodeDB::NodeType &node_type =
zylann::voxel::VoxelGraphNodeDB::get_singleton()->get_type(opid);
const uint32_t inputs_count = node_type.inputs.size();
const uint32_t outputs_count = node_type.outputs.size();

View File

@ -64,7 +64,7 @@
void register_voxel_types() {
VoxelMemoryPool::create_singleton();
VoxelStringNames::create_singleton();
VoxelGraphNodeDB::create_singleton();
zylann::voxel::VoxelGraphNodeDB::create_singleton();
VoxelServer::create_singleton();
Engine::get_singleton()->add_singleton(Engine::Singleton("VoxelServer", VoxelServer::get_singleton()));
@ -174,7 +174,7 @@ void unregister_voxel_types() {
// See https://github.com/Zylann/godot_voxel/issues/189
VoxelStringNames::destroy_singleton();
VoxelGraphNodeDB::destroy_singleton();
zylann::voxel::VoxelGraphNodeDB::destroy_singleton();
VoxelServer::destroy_singleton();
// Do this last as VoxelServer might still be holding some refs to voxel blocks