Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-bake edited NavigationPolygons in the Editor on a timer #87504

Merged
merged 1 commit into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/EditorSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@
<member name="editors/panning/warped_mouse_panning" type="bool" setter="" getter="">
If [code]true[/code], warps the mouse around the 2D viewport while panning in the 2D editor. This makes it possible to pan over a large area without having to exit panning and adjust the mouse cursor.
</member>
<member name="editors/polygon_editor/auto_bake_delay" type="float" setter="" getter="">
The delay in seconds until more complex and performance costly polygon editors commit their outlines, e.g. the 2D navigation polygon editor rebakes the navigation mesh polygons. A negative value stops the auto bake.
</member>
<member name="editors/polygon_editor/point_grab_radius" type="int" setter="" getter="">
The radius in which points can be selected in the [Polygon2D] and [CollisionPolygon2D] editors (in pixels). Higher values make it easier to select points quickly, but can make it more difficult to select the expected point when several points are located close to each other.
</member>
Expand Down
1 change: 1 addition & 0 deletions editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Polygon editor
_initial_set("editors/polygon_editor/point_grab_radius", has_touchscreen_ui ? 32 : 8);
_initial_set("editors/polygon_editor/show_previous_outline", true);
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/polygon_editor/auto_bake_delay", 1.5, "-1.0,10.0,0.01");

// Animation
_initial_set("editors/animation/autorename_animation_tracks", true);
Expand Down
62 changes: 61 additions & 1 deletion editor/plugins/navigation_polygon_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "navigation_polygon_editor_plugin.h"

#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/navigation_region_2d.h"
#include "scene/gui/dialogs.h"
Expand All @@ -50,6 +51,13 @@ Node2D *NavigationPolygonEditor::_get_node() const {

void NavigationPolygonEditor::_set_node(Node *p_polygon) {
node = Object::cast_to<NavigationRegion2D>(p_polygon);
if (node) {
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
if (navpoly.is_valid() && navpoly->get_outline_count() > 0 && navpoly->get_polygon_count() == 0) {
// We have outlines drawn / added by the user but no polygons were created for this navmesh yet so let's bake once immediately.
_rebake_timer_timeout();
}
}
}

int NavigationPolygonEditor::_get_polygon_count() const {
Expand All @@ -73,27 +81,43 @@ Variant NavigationPolygonEditor::_get_polygon(int p_idx) const {
void NavigationPolygonEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
navpoly->set_outline(p_idx, p_polygon);

if (rebake_timer && _rebake_timer_delay >= 0.0) {
rebake_timer->start();
}
}

void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->add_do_method(navpoly.ptr(), "add_outline", p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "remove_outline", navpoly->get_outline_count());

if (rebake_timer && _rebake_timer_delay >= 0.0) {
rebake_timer->start();
}
}

void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->add_do_method(navpoly.ptr(), "remove_outline", p_idx);
undo_redo->add_undo_method(navpoly.ptr(), "add_outline_at_index", navpoly->get_outline(p_idx), p_idx);

if (rebake_timer && _rebake_timer_delay >= 0.0) {
rebake_timer->start();
}
}

void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->add_do_method(navpoly.ptr(), "set_outline", p_idx, p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "set_outline", p_idx, p_previous);

if (rebake_timer && _rebake_timer_delay >= 0.0) {
rebake_timer->start();
}
}

bool NavigationPolygonEditor::_has_resource() const {
Expand Down Expand Up @@ -136,6 +160,15 @@ NavigationPolygonEditor::NavigationPolygonEditor() {
bake_info = memnew(Label);
bake_hbox->add_child(bake_info);

rebake_timer = memnew(Timer);
add_child(rebake_timer);
rebake_timer->set_one_shot(true);
_rebake_timer_delay = EDITOR_GET("editors/polygon_editor/auto_bake_delay");
if (_rebake_timer_delay >= 0.0) {
rebake_timer->set_wait_time(_rebake_timer_delay);
}
rebake_timer->connect("timeout", callable_mp(this, &NavigationPolygonEditor::_rebake_timer_timeout));

err_dialog = memnew(AcceptDialog);
add_child(err_dialog);
node = nullptr;
Expand All @@ -147,15 +180,26 @@ void NavigationPolygonEditor::_notification(int p_what) {
button_bake->set_icon(get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
button_reset->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (rebake_timer) {
_rebake_timer_delay = EDITOR_GET("editors/polygon_editor/auto_bake_delay");
if (_rebake_timer_delay >= 0.0) {
rebake_timer->set_wait_time(_rebake_timer_delay);
}
}
} break;
}
}

void NavigationPolygonEditor::_bake_pressed() {
if (rebake_timer) {
rebake_timer->stop();
}
button_bake->set_pressed(false);

ERR_FAIL_NULL(node);
Ref<NavigationPolygon> navigation_polygon = node->get_navigation_polygon();
if (!navigation_polygon.is_valid()) {
if (navigation_polygon.is_null()) {
err_dialog->set_text(TTR("A NavigationPolygon resource must be set or created for this node to work."));
err_dialog->popup_centered();
return;
Expand All @@ -167,6 +211,9 @@ void NavigationPolygonEditor::_bake_pressed() {
}

void NavigationPolygonEditor::_clear_pressed() {
if (rebake_timer) {
rebake_timer->stop();
}
if (node) {
if (node->get_navigation_polygon().is_valid()) {
node->get_navigation_polygon()->clear();
Expand All @@ -193,6 +240,19 @@ void NavigationPolygonEditor::_update_polygon_editing_state() {
}
}

void NavigationPolygonEditor::_rebake_timer_timeout() {
if (!node) {
return;
}
Ref<NavigationPolygon> navigation_polygon = node->get_navigation_polygon();
if (!navigation_polygon.is_valid()) {
smix8 marked this conversation as resolved.
Show resolved Hide resolved
return;
}

node->bake_navigation_polygon(true);
node->queue_redraw();
}

NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin() :
AbstractPolygon2DEditorPlugin(memnew(NavigationPolygonEditor), "NavigationRegion2D") {
}
4 changes: 4 additions & 0 deletions editor/plugins/navigation_polygon_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class NavigationPolygonEditor : public AbstractPolygon2DEditor {
Button *button_reset = nullptr;
Label *bake_info = nullptr;

Timer *rebake_timer = nullptr;
float _rebake_timer_delay = 1.5;
void _rebake_timer_timeout();

void _bake_pressed();
void _clear_pressed();

Expand Down
Loading