Skip to content

Commit

Permalink
Added pinning to voxel graph editor
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed Aug 1, 2022
1 parent cff51fb commit f81e64d
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 11 deletions.
1 change: 1 addition & 0 deletions doc/source/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ 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`: 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
Expand Down
32 changes: 26 additions & 6 deletions editor/graph/voxel_graph_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ 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";

static NodePath to_node_path(StringName sn) {
Vector<StringName> path;
Expand Down Expand Up @@ -88,6 +89,17 @@ 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));

vbox_container->add_child(toolbar);
}

Expand Down Expand Up @@ -195,6 +207,10 @@ 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")));
break;
}
}

Expand Down Expand Up @@ -371,6 +387,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));
Expand Down Expand Up @@ -660,12 +680,11 @@ void VoxelGraphEditor::update_previews(bool with_live_update) {
if (hash != _last_output_graph_hash) {
_last_output_graph_hash = hash;

// We could be editing the graph standalone with no terrain loaded
if (_voxel_node != nullptr) {
// 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);
}
}
}
Expand Down Expand Up @@ -983,6 +1002,7 @@ void VoxelGraphEditor::_bind_methods() {
ADD_SIGNAL(MethodInfo(SIGNAL_NODE_SELECTED, PropertyInfo(Variant::INT, "node_id")));
ADD_SIGNAL(MethodInfo(SIGNAL_NOTHING_SELECTED));
ADD_SIGNAL(MethodInfo(SIGNAL_NODES_DELETED));
ADD_SIGNAL(MethodInfo(SIGNAL_REGENERATE_REQUESTED));
}

} // namespace zylann::voxel
5 changes: 5 additions & 0 deletions editor/graph/voxel_graph_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class GraphEdit;
class PopupMenu;
class AcceptDialog;
class UndoRedo;
class Button;

namespace zylann::voxel {

Expand All @@ -23,6 +24,7 @@ class VoxelGraphEditor : public Control {
static const char *SIGNAL_NODE_SELECTED;
static const char *SIGNAL_NOTHING_SELECTED;
static const char *SIGNAL_NODES_DELETED;
static const char *SIGNAL_REGENERATE_REQUESTED;

VoxelGraphEditor();

Expand All @@ -38,6 +40,8 @@ class VoxelGraphEditor : public Control {
// 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;

private:
void _notification(int p_what);
void _process(float delta);
Expand Down Expand Up @@ -95,6 +99,7 @@ class VoxelGraphEditor : public Control {
VoxelGraphEditorShaderDialog *_shader_dialog = nullptr;
bool _live_update_enabled = false;
uint64_t _last_output_graph_hash = 0;
Button *_pin_button = nullptr;

enum PreviewAxes { //
PREVIEW_XY = 0,
Expand Down
49 changes: 44 additions & 5 deletions editor/graph/voxel_graph_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ 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));
_bottom_panel_button = add_control_to_bottom_panel(_graph_editor, TTR("Voxel Graph"));
_bottom_panel_button->hide();

Expand Down Expand Up @@ -87,6 +89,7 @@ void VoxelGraphEditorPlugin::edit(Object *p_object) {
break;
}
}
_voxel_node = voxel_node;
_graph_editor->set_voxel_node(voxel_node);
}

Expand All @@ -96,13 +99,17 @@ void VoxelGraphEditorPlugin::make_visible(bool visible) {
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");
if (!_graph_editor->is_pinned_hint()) {
_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");
}
}
}
}
Expand Down Expand Up @@ -152,6 +159,38 @@ 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::_bind_methods() {
// ClassDB::bind_method(D_METHOD("_on_graph_editor_node_selected", "node_id"),
// &VoxelGraphEditorPlugin::_on_graph_editor_node_selected);
Expand Down
3 changes: 3 additions & 0 deletions editor/graph/voxel_graph_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace zylann::voxel {

class VoxelGraphEditor;
class VoxelNode;

class VoxelGraphEditorPlugin : public EditorPlugin {
GDCLASS(VoxelGraphEditorPlugin, EditorPlugin)
Expand All @@ -20,13 +21,15 @@ class VoxelGraphEditorPlugin : public EditorPlugin {
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 _hide_deferred();

static void _bind_methods();

VoxelGraphEditor *_graph_editor = nullptr;
Button *_bottom_panel_button = nullptr;
bool _deferred_visibility_scheduled = false;
VoxelNode *_voxel_node = nullptr;
};

} // namespace zylann::voxel
Expand Down

0 comments on commit f81e64d

Please sign in to comment.