diff --git a/modules/navigation/nav_link.cpp b/modules/navigation/nav_link.cpp index ad87cc0b05c..5607a3253e3 100644 --- a/modules/navigation/nav_link.cpp +++ b/modules/navigation/nav_link.cpp @@ -33,21 +33,33 @@ #include "nav_map.h" void NavLink::set_map(NavMap *p_map) { + if (map == p_map) { + return; + } map = p_map; link_dirty = true; } void NavLink::set_bidirectional(bool p_bidirectional) { + if (bidirectional == p_bidirectional) { + return; + } bidirectional = p_bidirectional; link_dirty = true; } void NavLink::set_start_position(const Vector3 p_position) { + if (start_position == p_position) { + return; + } start_position = p_position; link_dirty = true; } void NavLink::set_end_position(const Vector3 p_position) { + if (end_position == p_position) { + return; + } end_position = p_position; link_dirty = true; } diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index b76295db86d..57d702e8463 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -54,21 +54,33 @@ } 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_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 cad4678e5a7..bcee6ed751b 100644 --- a/modules/navigation/nav_region.cpp +++ b/modules/navigation/nav_region.cpp @@ -33,6 +33,9 @@ #include "nav_map.h" void NavRegion::set_map(NavMap *p_map) { + if (map == p_map) { + return; + } map = p_map; polygons_dirty = true; if (!map) { @@ -41,6 +44,9 @@ void NavRegion::set_map(NavMap *p_map) { } void NavRegion::set_transform(Transform3D p_transform) { + if (transform == p_transform) { + return; + } transform = p_transform; polygons_dirty = true; } diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp index 8adb7c63059..3664040e7be 100644 --- a/scene/2d/navigation_link_2d.cpp +++ b/scene/2d/navigation_link_2d.cpp @@ -106,19 +106,29 @@ void NavigationLink2D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (enabled) { NavigationServer2D::get_singleton()->link_set_map(link, get_world_2d()->get_navigation_map()); + } + current_global_transform = get_global_transform(); + NavigationServer2D::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position)); + NavigationServer2D::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position)); + } break; - // Update global positions for the link. - Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); - NavigationServer2D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); + case NOTIFICATION_TRANSFORM_CHANGED: { + 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; + NavigationServer2D::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position)); + NavigationServer2D::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position)); + queue_redraw(); + } } } break; - case NOTIFICATION_TRANSFORM_CHANGED: { - // Update global positions for the link. - Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); - NavigationServer2D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); - } break; + case NOTIFICATION_EXIT_TREE: { NavigationServer2D::get_singleton()->link_set_map(link, RID()); } break; @@ -242,8 +252,7 @@ void NavigationLink2D::set_start_position(Vector2 p_position) { return; } - Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); + NavigationServer2D::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position)); update_configuration_warnings(); @@ -265,8 +274,7 @@ void NavigationLink2D::set_end_position(Vector2 p_position) { return; } - Transform2D gt = get_global_transform(); - NavigationServer2D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); + NavigationServer2D::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position)); update_configuration_warnings(); diff --git a/scene/2d/navigation_link_2d.h b/scene/2d/navigation_link_2d.h index 8a24d611c99..4259740c900 100644 --- a/scene/2d/navigation_link_2d.h +++ b/scene/2d/navigation_link_2d.h @@ -45,6 +45,8 @@ class NavigationLink2D : public Node2D { real_t enter_cost = 0.0; real_t travel_cost = 1.0; + Transform2D current_global_transform; + protected: static void _bind_methods(); void _notification(int p_what); diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index edce9c94fde..cbcdb9f88ea 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -160,15 +160,12 @@ void NavigationRegion2D::_notification(int p_what) { } } } + current_global_transform = get_global_transform(); + NavigationServer2D::get_singleton()->region_set_transform(region, current_global_transform); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform()); - for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) { - if (constrain_avoidance_obstacles[i].is_valid()) { - NavigationServer2D::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position()); - } - } + set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { @@ -183,6 +180,24 @@ void NavigationRegion2D::_notification(int p_what) { } } 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; + NavigationServer2D::get_singleton()->region_set_transform(region, current_global_transform); + queue_redraw(); + + for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) { + if (constrain_avoidance_obstacles[i].is_valid()) { + NavigationServer2D::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position()); + } + } + } + } + } break; + case NOTIFICATION_DRAW: { #ifdef DEBUG_ENABLED if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || NavigationServer2D::get_singleton()->get_debug_enabled()) && navigation_polygon.is_valid()) { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index fa2edc6112f..bd7bdc28eb0 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -47,6 +47,8 @@ class NavigationRegion2D : public Node2D { LocalVector constrain_avoidance_obstacles; uint32_t avoidance_layers = 1; + Transform2D current_global_transform; + void _navigation_polygon_changed(); void _map_changed(RID p_RID); diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp index 536b0eae5d5..2263d38d6ce 100644 --- a/scene/3d/navigation_link_3d.cpp +++ b/scene/3d/navigation_link_3d.cpp @@ -141,6 +141,8 @@ void NavigationLink3D::_update_debug_mesh() { } else { RS::get_singleton()->instance_set_surface_override_material(debug_instance, 0, disabled_link_material->get_rid()); } + + RS::get_singleton()->instance_set_transform(debug_instance, current_global_transform); } #endif // DEBUG_ENABLED @@ -215,29 +217,37 @@ void NavigationLink3D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (enabled) { NavigationServer3D::get_singleton()->link_set_map(link, get_world_3d()->get_navigation_map()); - - // Update global positions for the link. - Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); - NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); } + current_global_transform = get_global_transform(); + NavigationServer3D::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position)); + NavigationServer3D::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position)); #ifdef DEBUG_ENABLED _update_debug_mesh(); #endif // DEBUG_ENABLED } break; - case NOTIFICATION_TRANSFORM_CHANGED: { - // Update global positions for the link. - Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); - NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); -#ifdef DEBUG_ENABLED - if (is_inside_tree() && debug_instance.is_valid()) { - RS::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); - } -#endif // DEBUG_ENABLED + case NOTIFICATION_TRANSFORM_CHANGED: { + set_physics_process_internal(true); } break; + + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + set_physics_process_internal(false); + if (is_inside_tree()) { + Transform3D new_global_transform = get_global_transform(); + if (current_global_transform != new_global_transform) { + current_global_transform = new_global_transform; + NavigationServer3D::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position)); + NavigationServer3D::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position)); +#ifdef DEBUG_ENABLED + if (debug_instance.is_valid()) { + RS::get_singleton()->instance_set_transform(debug_instance, current_global_transform); + } +#endif // DEBUG_ENABLED + } + } + } break; + case NOTIFICATION_EXIT_TREE: { NavigationServer3D::get_singleton()->link_set_map(link, RID()); @@ -359,8 +369,7 @@ void NavigationLink3D::set_start_position(Vector3 p_position) { return; } - Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_start_position(link, gt.xform(start_position)); + NavigationServer3D::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position)); #ifdef DEBUG_ENABLED _update_debug_mesh(); @@ -381,8 +390,7 @@ void NavigationLink3D::set_end_position(Vector3 p_position) { return; } - Transform3D gt = get_global_transform(); - NavigationServer3D::get_singleton()->link_set_end_position(link, gt.xform(end_position)); + NavigationServer3D::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position)); #ifdef DEBUG_ENABLED _update_debug_mesh(); diff --git a/scene/3d/navigation_link_3d.h b/scene/3d/navigation_link_3d.h index 991f45c85d2..ec92fb9dd93 100644 --- a/scene/3d/navigation_link_3d.h +++ b/scene/3d/navigation_link_3d.h @@ -45,6 +45,8 @@ class NavigationLink3D : public Node3D { real_t enter_cost = 0.0; real_t travel_cost = 1.0; + Transform3D current_global_transform; + #ifdef DEBUG_ENABLED RID debug_instance; Ref debug_mesh; diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index cfe0e673a3c..b775ef94cb1 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -157,6 +157,8 @@ void NavigationRegion3D::_notification(int p_what) { if (enabled) { NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); } + current_global_transform = get_global_transform(); + NavigationServer3D::get_singleton()->region_set_transform(region, current_global_transform); #ifdef DEBUG_ENABLED if (NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { @@ -167,14 +169,24 @@ void NavigationRegion3D::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - NavigationServer3D::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()) { + Transform3D new_global_transform = get_global_transform(); + if (current_global_transform != new_global_transform) { + current_global_transform = new_global_transform; + NavigationServer3D::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: { @@ -552,6 +564,7 @@ void NavigationRegion3D::_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_region_3d.h b/scene/3d/navigation_region_3d.h index d4045ae1ac1..4732c340ba7 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -44,6 +44,8 @@ class NavigationRegion3D : public Node3D { real_t travel_cost = 1.0; Ref navigation_mesh; + Transform3D current_global_transform; + Thread bake_thread; void _navigation_changed();