summaryrefslogtreecommitdiffstats
path: root/scene/2d/navigation_region_2d.cpp
diff options
context:
space:
mode:
authorsmix8 <52464204+smix8@users.noreply.github.com>2023-08-17 18:32:30 +0200
committersmix8 <52464204+smix8@users.noreply.github.com>2023-09-25 19:48:14 +0200
commit0ee7e3102b6072d2f5a9d157c8afdb99e13624e6 (patch)
tree80e45613d1cdc8a850d6ceb1f9bce7f63d0db94e /scene/2d/navigation_region_2d.cpp
parent82f6e9be5ea06bfef1adb315f15a409939b4a100 (diff)
downloadredot-engine-0ee7e3102b6072d2f5a9d157c8afdb99e13624e6.tar.gz
Add 2D navigation mesh baking
Adds 2D navigation mesh baking.
Diffstat (limited to 'scene/2d/navigation_region_2d.cpp')
-rw-r--r--scene/2d/navigation_region_2d.cpp35
1 files changed, 31 insertions, 4 deletions
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index 670a2c641c..706b26bd05 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -179,10 +179,6 @@ void NavigationRegion2D::_notification(int p_what) {
}
void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_navigation_polygon) {
- if (p_navigation_polygon == navigation_polygon) {
- return;
- }
-
if (navigation_polygon.is_valid()) {
navigation_polygon->disconnect_changed(callable_mp(this, &NavigationRegion2D::_navigation_polygon_changed));
}
@@ -226,6 +222,32 @@ RID NavigationRegion2D::get_navigation_map() const {
return RID();
}
+void NavigationRegion2D::bake_navigation_polygon(bool p_on_thread) {
+ ERR_FAIL_COND_MSG(!Thread::is_main_thread(), "The SceneTree can only be parsed on the main thread. Call this function from the main thread or use call_deferred().");
+ ERR_FAIL_COND_MSG(!navigation_polygon.is_valid(), "Baking the navigation polygon requires a valid `NavigationPolygon` resource.");
+
+ Ref<NavigationMeshSourceGeometryData2D> source_geometry_data;
+ source_geometry_data.instantiate();
+
+ NavigationServer2D::get_singleton()->parse_source_geometry_data(navigation_polygon, source_geometry_data, this);
+
+ if (p_on_thread) {
+ NavigationServer2D::get_singleton()->bake_from_source_geometry_data_async(navigation_polygon, source_geometry_data, callable_mp(this, &NavigationRegion2D::_bake_finished).bind(navigation_polygon));
+ } else {
+ NavigationServer2D::get_singleton()->bake_from_source_geometry_data(navigation_polygon, source_geometry_data, callable_mp(this, &NavigationRegion2D::_bake_finished).bind(navigation_polygon));
+ }
+}
+
+void NavigationRegion2D::_bake_finished(Ref<NavigationPolygon> p_navigation_polygon) {
+ if (!Thread::is_main_thread()) {
+ call_deferred(SNAME("_bake_finished"), p_navigation_polygon);
+ return;
+ }
+
+ set_navigation_polygon(p_navigation_polygon);
+ emit_signal(SNAME("bake_finished"));
+}
+
void NavigationRegion2D::_navigation_polygon_changed() {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) {
queue_redraw();
@@ -290,6 +312,8 @@ void NavigationRegion2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationRegion2D::set_travel_cost);
ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationRegion2D::get_travel_cost);
+ ClassDB::bind_method(D_METHOD("bake_navigation_polygon", "on_thread"), &NavigationRegion2D::bake_navigation_polygon, DEFVAL(true));
+
ClassDB::bind_method(D_METHOD("_navigation_polygon_changed"), &NavigationRegion2D::_navigation_polygon_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navigation_polygon", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon");
@@ -300,6 +324,9 @@ void NavigationRegion2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "constrain_avoidance"), "set_constrain_avoidance", "get_constrain_avoidance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "avoidance_layers", PROPERTY_HINT_LAYERS_AVOIDANCE), "set_avoidance_layers", "get_avoidance_layers");
+
+ ADD_SIGNAL(MethodInfo("navigation_polygon_changed"));
+ ADD_SIGNAL(MethodInfo("bake_finished"));
}
#ifndef DISABLE_DEPRECATED