Merge branch 'master' into smooth_normalmaps
This commit is contained in:
commit
14f841fd7f
@ -28,6 +28,8 @@ Godot 4 is required from this version.
|
||||
- `VoxelGeneratorGraph`: editor: allow to change the axes on preview nodes 3D slices
|
||||
- `VoxelGeneratorGraph`: editor: replace existing connection if dragging from/to an input port having one already
|
||||
- `VoxelGeneratorGraph`: editor: creating noise and curve nodes now auto-create their resource instead of coming up null
|
||||
- `VoxelGeneratorGraph`: editor: added pin button to keep the graph editor shown even after deselecting the terrain.
|
||||
- `VoxelGeneratorGraph`: editor: added popout button to open the graph editor in a separate window
|
||||
- `VoxelGeneratorGraph`: added `OutputSingleTexture` node for outputting a single texture index per voxel, as an alternative to weights. This is specific to smooth voxels.
|
||||
- `VoxelGeneratorGraph`: added math expression node
|
||||
- `VoxelGeneratorGraph`: added Pow and Powi nodes
|
||||
|
@ -168,7 +168,7 @@ struct SdfSubtract {
|
||||
};
|
||||
|
||||
struct SdfSet {
|
||||
float strength;
|
||||
real_t strength;
|
||||
inline real_t operator()(real_t a, real_t b) const {
|
||||
return Math::lerp(a, b, strength);
|
||||
}
|
||||
@ -257,6 +257,8 @@ struct SdfBufferShape {
|
||||
// Outside the buffer
|
||||
return 100;
|
||||
}
|
||||
// TODO Trilinear looks bad when the shape is scaled up.
|
||||
// Use Hermite in 3D https://www.researchgate.net/publication/360206102_Hermite_interpolation_of_heightmaps
|
||||
return interpolate_trilinear(buffer, buffer_size, lpos) * sdf_scale - isolevel;
|
||||
}
|
||||
|
||||
|
@ -662,7 +662,7 @@ Array separate_floating_chunks(VoxelTool &voxel_tool, Box3i world_box, Node *par
|
||||
collision_shape->set_position(offset);
|
||||
|
||||
RigidDynamicBody3D *rigid_body = memnew(RigidDynamicBody3D);
|
||||
rigid_body->set_transform(transform * local_transform.translated(-offset));
|
||||
rigid_body->set_transform(transform * local_transform.translated_local(-offset));
|
||||
rigid_body->add_child(collision_shape);
|
||||
rigid_body->set_freeze_mode(RigidDynamicBody3D::FREEZE_MODE_KINEMATIC);
|
||||
rigid_body->set_freeze_enabled(true);
|
||||
@ -672,7 +672,7 @@ Array separate_floating_chunks(VoxelTool &voxel_tool, Box3i world_box, Node *par
|
||||
Timer *timer = memnew(Timer);
|
||||
timer->set_wait_time(0.2);
|
||||
timer->set_one_shot(true);
|
||||
timer->connect("timeout", callable_mp(rigid_body, &RigidDynamicBody3D::set_freeze_enabled), varray(false));
|
||||
timer->connect("timeout", callable_mp(rigid_body, &RigidDynamicBody3D::set_freeze_enabled).bind(false));
|
||||
// Cannot use start() here because it requires to be inside the SceneTree,
|
||||
// and we don't know if it will be after we add to the parent.
|
||||
timer->set_autostart(true);
|
||||
|
@ -411,7 +411,7 @@ void VoxelToolTerrain::run_blocky_random_tick(
|
||||
Callable::CallError error;
|
||||
Variant retval; // We don't care about the return value, Callable API requires it
|
||||
const CallbackData *cd = (const CallbackData *)self;
|
||||
cd->callable.call(args, 2, retval, error);
|
||||
cd->callable.callp(args, 2, retval, error);
|
||||
// TODO I would really like to know what's the correct way to report such errors...
|
||||
// Examples I found in the engine are inconsistent
|
||||
ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, false);
|
||||
@ -450,7 +450,7 @@ void VoxelToolTerrain::for_each_voxel_metadata_in_area(AABB voxel_area, const Ca
|
||||
const Variant *args[2] = { &key, &v };
|
||||
Callable::CallError err;
|
||||
Variant retval; // We don't care about the return value, Callable API requires it
|
||||
callback.call(args, 2, retval, err);
|
||||
callback.callp(args, 2, retval, err);
|
||||
|
||||
ERR_FAIL_COND_MSG(err.error != Callable::CallError::CALL_OK,
|
||||
String("Callable failed at {0}").format(varray(key)));
|
||||
|
@ -28,6 +28,8 @@ namespace zylann::voxel {
|
||||
const char *VoxelGraphEditor::SIGNAL_NODE_SELECTED = "node_selected";
|
||||
const char *VoxelGraphEditor::SIGNAL_NOTHING_SELECTED = "nothing_selected";
|
||||
const char *VoxelGraphEditor::SIGNAL_NODES_DELETED = "nodes_deleted";
|
||||
const char *VoxelGraphEditor::SIGNAL_REGENERATE_REQUESTED = "regenerate_requested";
|
||||
const char *VoxelGraphEditor::SIGNAL_POPOUT_REQUESTED = "popout_requested";
|
||||
|
||||
static NodePath to_node_path(StringName sn) {
|
||||
Vector<StringName> path;
|
||||
@ -88,6 +90,23 @@ VoxelGraphEditor::VoxelGraphEditor() {
|
||||
live_update_checkbox->connect("toggled", callable_mp(this, &VoxelGraphEditor::_on_live_update_toggled));
|
||||
toolbar->add_child(live_update_checkbox);
|
||||
|
||||
Control *spacer = memnew(Control);
|
||||
spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
toolbar->add_child(spacer);
|
||||
|
||||
_pin_button = memnew(Button);
|
||||
_pin_button->set_flat(true);
|
||||
_pin_button->set_toggle_mode(true);
|
||||
_pin_button->set_tooltip(TTR("Pin AnimationPlayer"));
|
||||
toolbar->add_child(_pin_button);
|
||||
//_pin_button->connect("pressed", callable_mp(this, &AnimationPlayerEditor::_pin_pressed));
|
||||
|
||||
_popout_button = memnew(Button);
|
||||
_popout_button->set_flat(true);
|
||||
_popout_button->set_tooltip(TTR("Pop-out as separate window"));
|
||||
_popout_button->connect("pressed", callable_mp(this, &VoxelGraphEditor::_on_popout_button_pressed));
|
||||
toolbar->add_child(_popout_button);
|
||||
|
||||
vbox_container->add_child(toolbar);
|
||||
}
|
||||
|
||||
@ -195,6 +214,11 @@ void VoxelGraphEditor::_notification(int p_what) {
|
||||
case NOTIFICATION_VISIBILITY_CHANGED:
|
||||
set_process_internal(is_visible());
|
||||
break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED:
|
||||
_pin_button->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons")));
|
||||
_popout_button->set_icon(get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,7 +306,7 @@ void VoxelGraphEditor::create_node_gui(uint32_t node_id) {
|
||||
|
||||
VoxelGraphEditorNode *node_view = VoxelGraphEditorNode::create(**_graph, node_id);
|
||||
node_view->set_name(ui_node_name);
|
||||
node_view->connect("dragged", callable_mp(this, &VoxelGraphEditor::_on_graph_node_dragged), varray(node_id));
|
||||
node_view->connect("dragged", callable_mp(this, &VoxelGraphEditor::_on_graph_node_dragged).bind(node_id));
|
||||
|
||||
_graph_edit->add_child(node_view);
|
||||
}
|
||||
@ -371,6 +395,10 @@ void VoxelGraphEditor::update_node_layout(uint32_t node_id) {
|
||||
}
|
||||
}
|
||||
|
||||
bool VoxelGraphEditor::is_pinned_hint() const {
|
||||
return _pin_button->is_pressed();
|
||||
}
|
||||
|
||||
static bool is_nothing_selected(GraphEdit *graph_edit) {
|
||||
for (int i = 0; i < graph_edit->get_child_count(); ++i) {
|
||||
GraphNode *node = Object::cast_to<GraphNode>(graph_edit->get_child(i));
|
||||
@ -659,9 +687,12 @@ void VoxelGraphEditor::update_previews(bool with_live_update) {
|
||||
|
||||
if (hash != _last_output_graph_hash) {
|
||||
_last_output_graph_hash = hash;
|
||||
// Re-generate the terrain.
|
||||
// Only do that if the graph is valid.
|
||||
_voxel_node->restart_stream();
|
||||
|
||||
// Not calling into `_voxel_node` directly because the editor could be pinned and the terrain not actually
|
||||
// selected. In this situation the plugin may reset the node to null. But it is desirable for terrains
|
||||
// using the current graph to update if they are in the edited scene, so this may be delegated to the editor
|
||||
// plugin. There isn't enough context from here to do this cleanly.
|
||||
emit_signal(SIGNAL_REGENERATE_REQUESTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -968,6 +999,14 @@ void VoxelGraphEditor::_on_live_update_toggled(bool enabled) {
|
||||
_live_update_enabled = enabled;
|
||||
}
|
||||
|
||||
void VoxelGraphEditor::_on_popout_button_pressed() {
|
||||
emit_signal(SIGNAL_POPOUT_REQUESTED);
|
||||
}
|
||||
|
||||
void VoxelGraphEditor::set_popout_button_enabled(bool enable) {
|
||||
_popout_button->set_visible(enable);
|
||||
}
|
||||
|
||||
void VoxelGraphEditor::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_check_nothing_selected"), &VoxelGraphEditor::_check_nothing_selected);
|
||||
|
||||
@ -977,8 +1016,10 @@ void VoxelGraphEditor::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("update_node_layout", "node_id"), &VoxelGraphEditor::update_node_layout);
|
||||
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_NODE_SELECTED, PropertyInfo(Variant::INT, "node_id")));
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_NOTHING_SELECTED, PropertyInfo(Variant::INT, "nothing_selected")));
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_NODES_DELETED, PropertyInfo(Variant::INT, "nodes_deleted")));
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_NOTHING_SELECTED));
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_NODES_DELETED));
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_REGENERATE_REQUESTED));
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_POPOUT_REQUESTED));
|
||||
}
|
||||
|
||||
} // namespace zylann::voxel
|
||||
|
@ -8,6 +8,7 @@ class GraphEdit;
|
||||
class PopupMenu;
|
||||
class AcceptDialog;
|
||||
class UndoRedo;
|
||||
class Button;
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
@ -23,6 +24,8 @@ public:
|
||||
static const char *SIGNAL_NODE_SELECTED;
|
||||
static const char *SIGNAL_NOTHING_SELECTED;
|
||||
static const char *SIGNAL_NODES_DELETED;
|
||||
static const char *SIGNAL_REGENERATE_REQUESTED;
|
||||
static const char *SIGNAL_POPOUT_REQUESTED;
|
||||
|
||||
VoxelGraphEditor();
|
||||
|
||||
@ -38,6 +41,9 @@ public:
|
||||
// Rebuilds the node's internal controls, and updates GUI connections going to it from the graph.
|
||||
void update_node_layout(uint32_t node_id);
|
||||
|
||||
bool is_pinned_hint() const;
|
||||
void set_popout_button_enabled(bool enable);
|
||||
|
||||
private:
|
||||
void _notification(int p_what);
|
||||
void _process(float delta);
|
||||
@ -74,6 +80,7 @@ private:
|
||||
void _on_preview_axes_menu_id_pressed(int id);
|
||||
void _on_generate_shader_button_pressed();
|
||||
void _on_live_update_toggled(bool enabled);
|
||||
void _on_popout_button_pressed();
|
||||
|
||||
void _check_nothing_selected();
|
||||
|
||||
@ -95,6 +102,8 @@ private:
|
||||
VoxelGraphEditorShaderDialog *_shader_dialog = nullptr;
|
||||
bool _live_update_enabled = false;
|
||||
uint64_t _last_output_graph_hash = 0;
|
||||
Button *_pin_button = nullptr;
|
||||
Button *_popout_button = nullptr;
|
||||
|
||||
enum PreviewAxes { //
|
||||
PREVIEW_XY = 0,
|
||||
|
@ -10,6 +10,35 @@
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
// TODO It would be really nice if we were not forced to use an AcceptDialog for making a window.
|
||||
// AcceptDialog adds stuff I don't need, but Window is too low level.
|
||||
class VoxelGraphEditorWindow : public AcceptDialog {
|
||||
GDCLASS(VoxelGraphEditorWindow, AcceptDialog)
|
||||
public:
|
||||
VoxelGraphEditorWindow() {
|
||||
set_exclusive(false);
|
||||
set_close_on_escape(false);
|
||||
get_ok_button()->hide();
|
||||
set_min_size(Vector2(600, 300) * EDSCALE);
|
||||
// I want the window to remain on top of the editor if the editor is given focus. `always_on_top` is the only
|
||||
// property allowing that, but it requires `transient` to be `false`. Without `transient`, the window is no
|
||||
// longer considered a child and won't give back focus to the editor when closed.
|
||||
// So for now, the window will get hidden behind the editor if you click on the editor.
|
||||
// you'll have to suffer moving popped out windows out of the editor area if you want to see them both...
|
||||
//set_flag(Window::FLAG_ALWAYS_ON_TOP, true);
|
||||
}
|
||||
|
||||
// void _notification(int p_what) {
|
||||
// switch (p_what) {
|
||||
// case NOTIFICATION_WM_CLOSE_REQUEST:
|
||||
// call_deferred(SNAME("hide"));
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
static void _bind_methods() {}
|
||||
};
|
||||
|
||||
// Changes string editors of the inspector to call setters only when enter key is pressed, similar to Unreal.
|
||||
// Because the default behavior of `EditorPropertyText` is to call the setter on every character typed, which is a
|
||||
// nightmare when editing an Expression node: inputs change constantly as the code is written which has much higher
|
||||
@ -41,6 +70,10 @@ VoxelGraphEditorPlugin::VoxelGraphEditorPlugin() {
|
||||
callable_mp(this, &VoxelGraphEditorPlugin::_on_graph_editor_nothing_selected));
|
||||
_graph_editor->connect(VoxelGraphEditor::SIGNAL_NODES_DELETED,
|
||||
callable_mp(this, &VoxelGraphEditorPlugin::_on_graph_editor_nodes_deleted));
|
||||
_graph_editor->connect(VoxelGraphEditor::SIGNAL_REGENERATE_REQUESTED,
|
||||
callable_mp(this, &VoxelGraphEditorPlugin::_on_graph_editor_regenerate_requested));
|
||||
_graph_editor->connect(VoxelGraphEditor::SIGNAL_POPOUT_REQUESTED,
|
||||
callable_mp(this, &VoxelGraphEditorPlugin::_on_graph_editor_popout_requested));
|
||||
_bottom_panel_button = add_control_to_bottom_panel(_graph_editor, TTR("Voxel Graph"));
|
||||
_bottom_panel_button->hide();
|
||||
|
||||
@ -87,22 +120,36 @@ void VoxelGraphEditorPlugin::edit(Object *p_object) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_voxel_node = voxel_node;
|
||||
_graph_editor->set_voxel_node(voxel_node);
|
||||
|
||||
if (_graph_editor_window != nullptr) {
|
||||
update_graph_editor_window_title();
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGraphEditorPlugin::make_visible(bool visible) {
|
||||
if (_graph_editor_window != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
_bottom_panel_button->show();
|
||||
make_bottom_panel_item_visible(_graph_editor);
|
||||
|
||||
} else {
|
||||
_bottom_panel_button->hide();
|
||||
_voxel_node = nullptr;
|
||||
_graph_editor->set_voxel_node(nullptr);
|
||||
|
||||
// TODO Awful hack to handle the nonsense happening in `_on_graph_editor_node_selected`
|
||||
if (!_deferred_visibility_scheduled) {
|
||||
_deferred_visibility_scheduled = true;
|
||||
call_deferred("_hide_deferred");
|
||||
const bool pinned = _graph_editor_window != nullptr || _graph_editor->is_pinned_hint();
|
||||
if (!pinned) {
|
||||
_bottom_panel_button->hide();
|
||||
|
||||
// TODO Awful hack to handle the nonsense happening in `_on_graph_editor_node_selected`
|
||||
if (!_deferred_visibility_scheduled) {
|
||||
_deferred_visibility_scheduled = true;
|
||||
call_deferred("_hide_deferred");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,6 +199,92 @@ void VoxelGraphEditorPlugin::_on_graph_editor_nodes_deleted() {
|
||||
get_editor_interface()->inspect_object(*graph);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void for_each_node(Node *parent, F action) {
|
||||
action(parent);
|
||||
for (int i = 0; i < parent->get_child_count(); ++i) {
|
||||
for_each_node(parent->get_child(i), action);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGraphEditorPlugin::_on_graph_editor_regenerate_requested() {
|
||||
// We could be editing the graph standalone with no terrain loaded
|
||||
if (_voxel_node != nullptr) {
|
||||
// Re-generate the selected terrain.
|
||||
_voxel_node->restart_stream();
|
||||
|
||||
} else {
|
||||
// The node is not selected, but it might be in the tree
|
||||
Node *root = get_editor_interface()->get_edited_scene_root();
|
||||
|
||||
if (root != nullptr) {
|
||||
Ref<VoxelGeneratorGraph> generator = _graph_editor->get_graph();
|
||||
ERR_FAIL_COND(generator.is_null());
|
||||
|
||||
for_each_node(root, [&generator](Node *node) {
|
||||
VoxelNode *vnode = Object::cast_to<VoxelNode>(node);
|
||||
if (vnode != nullptr && vnode->get_generator() == generator) {
|
||||
vnode->restart_stream();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGraphEditorPlugin::_on_graph_editor_popout_requested() {
|
||||
undock_graph_editor();
|
||||
}
|
||||
|
||||
void VoxelGraphEditorPlugin::undock_graph_editor() {
|
||||
ERR_FAIL_COND(_graph_editor_window != nullptr);
|
||||
ZN_PRINT_VERBOSE("Undock voxel graph editor");
|
||||
|
||||
remove_control_from_bottom_panel(_graph_editor);
|
||||
_bottom_panel_button = nullptr;
|
||||
|
||||
_graph_editor->set_popout_button_enabled(false);
|
||||
_graph_editor->set_anchors_preset(Control::PRESET_FULL_RECT);
|
||||
// I don't know what hides it but I needed to make it visible again
|
||||
_graph_editor->show();
|
||||
|
||||
_graph_editor_window = memnew(VoxelGraphEditorWindow);
|
||||
update_graph_editor_window_title();
|
||||
_graph_editor_window->add_child(_graph_editor);
|
||||
_graph_editor_window->connect("close_requested", callable_mp(this, &VoxelGraphEditorPlugin::dock_graph_editor));
|
||||
|
||||
Node *base_control = get_editor_interface()->get_base_control();
|
||||
base_control->add_child(_graph_editor_window);
|
||||
|
||||
_graph_editor_window->popup_centered_ratio(0.6);
|
||||
}
|
||||
|
||||
void VoxelGraphEditorPlugin::dock_graph_editor() {
|
||||
ERR_FAIL_COND(_graph_editor_window == nullptr);
|
||||
ZN_PRINT_VERBOSE("Dock voxel graph editor");
|
||||
|
||||
_graph_editor->get_parent()->remove_child(_graph_editor);
|
||||
_graph_editor_window->queue_delete();
|
||||
_graph_editor_window = nullptr;
|
||||
|
||||
_graph_editor->set_popout_button_enabled(true);
|
||||
|
||||
_bottom_panel_button = add_control_to_bottom_panel(_graph_editor, TTR("Voxel Graph"));
|
||||
|
||||
_bottom_panel_button->show();
|
||||
make_bottom_panel_item_visible(_graph_editor);
|
||||
}
|
||||
|
||||
void VoxelGraphEditorPlugin::update_graph_editor_window_title() {
|
||||
ERR_FAIL_COND(_graph_editor_window == nullptr);
|
||||
String title;
|
||||
if (_graph_editor->get_graph().is_valid()) {
|
||||
title = _graph_editor->get_graph()->get_path();
|
||||
title += " - ";
|
||||
}
|
||||
title += VoxelGeneratorGraph::get_class_static();
|
||||
_graph_editor_window->set_title(title);
|
||||
}
|
||||
|
||||
void VoxelGraphEditorPlugin::_bind_methods() {
|
||||
// ClassDB::bind_method(D_METHOD("_on_graph_editor_node_selected", "node_id"),
|
||||
// &VoxelGraphEditorPlugin::_on_graph_editor_node_selected);
|
||||
|
@ -6,6 +6,8 @@
|
||||
namespace zylann::voxel {
|
||||
|
||||
class VoxelGraphEditor;
|
||||
class VoxelNode;
|
||||
class VoxelGraphEditorWindow;
|
||||
|
||||
class VoxelGraphEditorPlugin : public EditorPlugin {
|
||||
GDCLASS(VoxelGraphEditorPlugin, EditorPlugin)
|
||||
@ -17,16 +19,24 @@ public:
|
||||
void make_visible(bool visible) override;
|
||||
|
||||
private:
|
||||
void undock_graph_editor();
|
||||
void dock_graph_editor();
|
||||
void update_graph_editor_window_title();
|
||||
|
||||
void _on_graph_editor_node_selected(uint32_t node_id);
|
||||
void _on_graph_editor_nothing_selected();
|
||||
void _on_graph_editor_nodes_deleted();
|
||||
void _on_graph_editor_regenerate_requested();
|
||||
void _on_graph_editor_popout_requested();
|
||||
void _hide_deferred();
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
VoxelGraphEditor *_graph_editor = nullptr;
|
||||
VoxelGraphEditorWindow *_graph_editor_window = nullptr;
|
||||
Button *_bottom_panel_button = nullptr;
|
||||
bool _deferred_visibility_scheduled = false;
|
||||
VoxelNode *_voxel_node = nullptr;
|
||||
};
|
||||
|
||||
} // namespace zylann::voxel
|
||||
|
@ -196,7 +196,6 @@ bool VoxelGraphNodeInspectorWrapper::_set(const StringName &p_name, const Varian
|
||||
const uint32_t node_type_id = graph->get_node_type_id(_node_id);
|
||||
|
||||
const VoxelGraphNodeDB &db = VoxelGraphNodeDB::get_singleton();
|
||||
const bool autoconnect = graph->get_node_default_inputs_autoconnect(_node_id);
|
||||
|
||||
uint32_t index;
|
||||
if (db.try_get_param_index_from_name(node_type_id, p_name, index)) {
|
||||
|
@ -50,8 +50,8 @@ void VoxelInstanceLibraryEditorInspectorPlugin::add_buttons() {
|
||||
button_remove->set_icon(icon_provider->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
|
||||
button_remove->set_flat(true);
|
||||
button_remove->connect("pressed",
|
||||
callable_mp(button_listener, &VoxelInstanceLibraryEditorPlugin::_on_button_pressed),
|
||||
varray(BUTTON_REMOVE_ITEM));
|
||||
callable_mp(button_listener, &VoxelInstanceLibraryEditorPlugin::_on_button_pressed)
|
||||
.bind(BUTTON_REMOVE_ITEM));
|
||||
hb->add_child(button_remove);
|
||||
|
||||
Control *spacer = memnew(Control);
|
||||
@ -61,8 +61,8 @@ void VoxelInstanceLibraryEditorInspectorPlugin::add_buttons() {
|
||||
Button *button_update = memnew(Button);
|
||||
button_update->set_text(TTR("Update From Scene..."));
|
||||
button_update->connect("pressed",
|
||||
callable_mp(button_listener, &VoxelInstanceLibraryEditorPlugin::_on_button_pressed),
|
||||
varray(BUTTON_UPDATE_MULTIMESH_ITEM_FROM_SCENE));
|
||||
callable_mp(button_listener, &VoxelInstanceLibraryEditorPlugin::_on_button_pressed)
|
||||
.bind(BUTTON_UPDATE_MULTIMESH_ITEM_FROM_SCENE));
|
||||
hb->add_child(button_update);
|
||||
|
||||
add_custom_control(hb);
|
||||
|
@ -23,7 +23,7 @@ EditorPropertyAABBMinMax::EditorPropertyAABBMinMax() {
|
||||
EditorSpinSlider *sb = memnew(EditorSpinSlider);
|
||||
sb->set_flat(true);
|
||||
sb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
sb->connect("value_changed", callable_mp(this, &EditorPropertyAABBMinMax::_value_changed), varray(i));
|
||||
sb->connect("value_changed", callable_mp(this, &EditorPropertyAABBMinMax::_value_changed).bind(i));
|
||||
_spinboxes[i] = sb;
|
||||
|
||||
add_focusable(sb);
|
||||
|
@ -156,9 +156,9 @@ void VoxelTerrainEditorPlugin::set_node(VoxelNode *node) {
|
||||
|
||||
if (_node != nullptr) {
|
||||
_node->connect(
|
||||
"tree_entered", callable_mp(this, &VoxelTerrainEditorPlugin::_on_terrain_tree_entered), varray(_node));
|
||||
"tree_entered", callable_mp(this, &VoxelTerrainEditorPlugin::_on_terrain_tree_entered).bind(_node));
|
||||
_node->connect(
|
||||
"tree_exited", callable_mp(this, &VoxelTerrainEditorPlugin::_on_terrain_tree_exited), varray(_node));
|
||||
"tree_exited", callable_mp(this, &VoxelTerrainEditorPlugin::_on_terrain_tree_exited).bind(_node));
|
||||
|
||||
VoxelLodTerrain *vlt = Object::cast_to<VoxelLodTerrain>(_node);
|
||||
|
||||
|
@ -357,7 +357,7 @@ Error VoxelVoxMeshImporter::import(const String &p_source_file, const String &p_
|
||||
{
|
||||
ZN_PROFILE_SCOPE();
|
||||
String mesh_save_path = String("{0}.mesh").format(varray(p_save_path));
|
||||
const Error mesh_save_err = ResourceSaver::save(mesh_save_path, mesh);
|
||||
const Error mesh_save_err = ResourceSaver::save(mesh, mesh_save_path);
|
||||
ERR_FAIL_COND_V_MSG(
|
||||
mesh_save_err != OK, mesh_save_err, String("Failed to save {0}").format(varray(mesh_save_path)));
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ Error VoxelVoxSceneImporter::import(const String &p_source_file, const String &p
|
||||
String res_save_path = String("{0}.model{1}.mesh").format(varray(p_save_path, model_index));
|
||||
// `FLAG_CHANGE_PATH` did not do what I thought it did.
|
||||
mesh->set_path(res_save_path);
|
||||
const Error mesh_save_err = ResourceSaver::save(res_save_path, mesh);
|
||||
const Error mesh_save_err = ResourceSaver::save(mesh, res_save_path);
|
||||
ERR_FAIL_COND_V_MSG(
|
||||
mesh_save_err != OK, mesh_save_err, String("Failed to save {0}").format(varray(res_save_path)));
|
||||
}
|
||||
@ -387,7 +387,7 @@ Error VoxelVoxSceneImporter::import(const String &p_source_file, const String &p
|
||||
scene.instantiate();
|
||||
scene->pack(root_node);
|
||||
String scene_save_path = p_save_path + ".tscn";
|
||||
const Error save_err = ResourceSaver::save(scene_save_path, scene);
|
||||
const Error save_err = ResourceSaver::save(scene, scene_save_path);
|
||||
memdelete(root_node);
|
||||
ERR_FAIL_COND_V_MSG(save_err != OK, save_err, "Cannot save scene to file '" + scene_save_path);
|
||||
}
|
||||
|
@ -338,7 +338,7 @@ static bool is_node_equivalent(const ProgramGraph &graph, const ProgramGraph::No
|
||||
return false;
|
||||
}
|
||||
ZN_ASSERT_RETURN_V_MSG(
|
||||
node1_input.connections.size() <= 1, "Multiple input connections isn't supported", false);
|
||||
node1_input.connections.size() <= 1, false, "Multiple input connections isn't supported");
|
||||
// TODO Some nodes like `*` and `+` have unordered inputs, we need to handle that
|
||||
if (node1_input.connections.size() == 0) {
|
||||
// No ancestor, check default inputs (autoconnect is ignored, it must have been applied earlier)
|
||||
|
@ -152,7 +152,7 @@ void VoxelBuffer::for_each_voxel_metadata(const Callable &callback) const {
|
||||
const Variant *args[2] = { &key, &v };
|
||||
Callable::CallError err;
|
||||
Variant retval; // We don't care about the return value, Callable API requires it
|
||||
callback.call(args, 2, retval, err);
|
||||
callback.callp(args, 2, retval, err);
|
||||
|
||||
ERR_FAIL_COND_MSG(
|
||||
err.error != Callable::CallError::CALL_OK, String("Callable failed at {0}").format(varray(key)));
|
||||
@ -174,7 +174,7 @@ void VoxelBuffer::for_each_voxel_metadata_in_area(const Callable &callback, Vect
|
||||
const Variant *args[2] = { &key, &v };
|
||||
Callable::CallError err;
|
||||
Variant retval; // We don't care about the return value, Callable API requires it
|
||||
callback.call(args, 2, retval, err);
|
||||
callback.callp(args, 2, retval, err);
|
||||
|
||||
ERR_FAIL_COND_MSG(
|
||||
err.error != Callable::CallError::CALL_OK, String("Callable failed at {0}").format(varray(key)));
|
||||
|
@ -1642,7 +1642,7 @@ void VoxelInstancer::debug_dump_as_scene(String fpath) const {
|
||||
memdelete(root);
|
||||
ERR_FAIL_COND(pack_result != OK);
|
||||
|
||||
const Error save_result = ResourceSaver::save(fpath, packed_scene, ResourceSaver::FLAG_BUNDLE_RESOURCES);
|
||||
const Error save_result = ResourceSaver::save(packed_scene, fpath, ResourceSaver::FLAG_BUNDLE_RESOURCES);
|
||||
ERR_FAIL_COND(save_result != OK);
|
||||
}
|
||||
|
||||
|
@ -2609,7 +2609,7 @@ Error VoxelLodTerrain::_b_debug_dump_as_scene(String fpath, bool include_instanc
|
||||
return pack_result;
|
||||
}
|
||||
|
||||
const Error save_result = ResourceSaver::save(fpath, scene, ResourceSaver::FLAG_BUNDLE_RESOURCES);
|
||||
const Error save_result = ResourceSaver::save(scene, fpath, ResourceSaver::FLAG_BUNDLE_RESOURCES);
|
||||
return save_result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user