From e07fd6da59b754b87c70cad42ead48a14a536539 Mon Sep 17 00:00:00 2001 From: Relintai Date: Fri, 9 Jun 2023 16:43:14 +0200 Subject: [PATCH] Ported from godot4: Prevent unnecessary navigation map synchronizations Prevents unnecessary navigation map synchronizations triggered by redundant calls to setters of e.g. region, link or map properties. - smix8 https://github.com/godotengine/godot/commit/7e1a261cc661ddbefb90208b94a6828c50750237 --- modules/navigation/nav_map.cpp | 20 +++++++++++++++++++ modules/navigation/nav_region.cpp | 8 ++++++++ scene/2d/navigation_polygon_instance.cpp | 23 +++++++++++++++++++++- scene/2d/navigation_polygon_instance.h | 2 ++ scene/3d/navigation_mesh_instance.cpp | 25 +++++++++++++++++++----- scene/3d/navigation_mesh_instance.h | 10 ++++++---- 6 files changed, 78 insertions(+), 10 deletions(-) diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index c5aae67ef..6f026454e 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -41,26 +41,46 @@ #define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a))) void NavMap::set_up(Vector3 p_up) { + if (up == p_up) { + return; + } + up = p_up; regenerate_polygons = true; } void NavMap::set_cell_size(real_t p_cell_size) { + if (cell_size == p_cell_size) { + return; + } + cell_size = p_cell_size; regenerate_polygons = true; } void NavMap::set_cell_height(real_t p_cell_height) { + if (cell_height == p_cell_height) { + return; + } + cell_height = p_cell_height; regenerate_polygons = true; } void NavMap::set_edge_connection_margin(real_t p_edge_connection_margin) { + if (edge_connection_margin == p_edge_connection_margin) { + return; + } + edge_connection_margin = p_edge_connection_margin; regenerate_links = true; } void NavMap::set_link_connection_radius(real_t p_link_connection_radius) { + if (link_connection_radius == p_link_connection_radius) { + return; + } + link_connection_radius = p_link_connection_radius; regenerate_links = true; } diff --git a/modules/navigation/nav_region.cpp b/modules/navigation/nav_region.cpp index 4114dbce0..1717acb1e 100644 --- a/modules/navigation/nav_region.cpp +++ b/modules/navigation/nav_region.cpp @@ -33,6 +33,10 @@ #include "nav_map.h" void NavRegion::set_map(NavMap *p_map) { + if (map == p_map) { + return; + } + map = p_map; polygons_dirty = true; @@ -42,6 +46,10 @@ void NavRegion::set_map(NavMap *p_map) { } void NavRegion::set_transform(Transform p_transform) { + if (transform == p_transform) { + return; + } + transform = p_transform; polygons_dirty = true; } diff --git a/scene/2d/navigation_polygon_instance.cpp b/scene/2d/navigation_polygon_instance.cpp index b6d8327df..d6083c8be 100644 --- a/scene/2d/navigation_polygon_instance.cpp +++ b/scene/2d/navigation_polygon_instance.cpp @@ -178,9 +178,30 @@ void NavigationPolygonInstance::_notification(int p_what) { Navigation2DServer::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); } } + + current_global_transform = get_global_transform(); + Navigation2DServer::get_singleton()->region_set_transform(region, current_global_transform); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - Navigation2DServer::get_singleton()->region_set_transform(region, get_global_transform()); + set_physics_process_internal(true); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + set_physics_process_internal(false); + if (is_inside_tree()) { + Transform2D new_global_transform = get_global_transform(); + if (current_global_transform != new_global_transform) { + current_global_transform = new_global_transform; + Navigation2DServer::get_singleton()->region_set_transform(region, current_global_transform); + update(); + + //TODO reenable! + //for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) { + // if (constrain_avoidance_obstacles[i].is_valid()) { + // Navigation2DServer::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position()); + // } + //} + } + } } break; case NOTIFICATION_EXIT_TREE: { if (navigation) { diff --git a/scene/2d/navigation_polygon_instance.h b/scene/2d/navigation_polygon_instance.h index 07ea96f42..8a357fed4 100644 --- a/scene/2d/navigation_polygon_instance.h +++ b/scene/2d/navigation_polygon_instance.h @@ -53,6 +53,8 @@ class NavigationPolygonInstance : public Node2D { uint32_t navigation_layers; + Transform2D current_global_transform; + void _navpoly_changed(); #ifdef DEBUG_ENABLED diff --git a/scene/3d/navigation_mesh_instance.cpp b/scene/3d/navigation_mesh_instance.cpp index ba0f1927a..b77e0dd3b 100644 --- a/scene/3d/navigation_mesh_instance.cpp +++ b/scene/3d/navigation_mesh_instance.cpp @@ -183,6 +183,9 @@ void NavigationMeshInstance::_notification(int p_what) { } } + current_global_transform = get_global_transform(); + NavigationServer::get_singleton()->region_set_transform(region, current_global_transform); + #ifdef DEBUG_ENABLED if (NavigationServer::get_singleton()->get_debug_enabled()) { _update_debug_mesh(); @@ -191,14 +194,23 @@ void NavigationMeshInstance::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - NavigationServer::get_singleton()->region_set_transform(region, get_global_transform()); + set_physics_process_internal(true); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + set_physics_process_internal(false); + if (is_inside_tree()) { + Transform new_global_transform = get_global_transform(); + if (current_global_transform != new_global_transform) { + current_global_transform = new_global_transform; + NavigationServer::get_singleton()->region_set_transform(region, current_global_transform); #ifdef DEBUG_ENABLED - if (is_inside_tree() && debug_instance.is_valid()) { - RS::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); - } + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_transform(debug_instance, current_global_transform); + } #endif // DEBUG_ENABLED - + } + } } break; case NOTIFICATION_EXIT_TREE: { NavigationServer::get_singleton()->region_set_map(region, RID()); @@ -382,6 +394,8 @@ void NavigationMeshInstance::_changed_callback(Object *p_changed, const char *p_ NavigationMeshInstance::NavigationMeshInstance() { set_notify_transform(true); + navigation = nullptr; + enter_cost = 0.0; travel_cost = 1.0; @@ -572,6 +586,7 @@ void NavigationMeshInstance::_update_debug_mesh() { RS::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid()); if (is_inside_tree()) { RS::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario()); + RS::get_singleton()->instance_set_transform(debug_instance, current_global_transform); RS::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); } if (!is_enabled()) { diff --git a/scene/3d/navigation_mesh_instance.h b/scene/3d/navigation_mesh_instance.h index b11eb4692..ac187cc3c 100644 --- a/scene/3d/navigation_mesh_instance.h +++ b/scene/3d/navigation_mesh_instance.h @@ -45,12 +45,14 @@ class NavigationMeshInstance : public Spatial { RID map_override; Ref navmesh; - real_t enter_cost = 0.0; - real_t travel_cost = 1.0; + Transform current_global_transform; - uint32_t navigation_layers = 1; + real_t enter_cost; + real_t travel_cost; - Navigation *navigation = nullptr; + uint32_t navigation_layers; + + Navigation *navigation; bool baking_started;