Namespaced VoxelGraphNodeDB
parent
8777bb2bf1
commit
e68f59643b
|
@ -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));
|
||||
|
|
|
@ -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 ¶m = node_type.params[i];
|
||||
const zylann::voxel::VoxelGraphNodeDB::Param ¶m = 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 {
|
||||
|
|
|
@ -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 ¶m = type.params[j];
|
||||
const zylann::voxel::VoxelGraphNodeDB::Param ¶m = 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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue