From da20b32f66315b268842cf56e4ad21a09eec1520 Mon Sep 17 00:00:00 2001 From: Relintai Date: Fri, 29 Jul 2022 17:52:38 +0200 Subject: [PATCH] Ported: Add NavigationServer.region_owns_point() helper function Adds a helper function to check if a world space position is currently owned by a navigation region. - smix8 https://github.com/godotengine/godot/commit/f0069cc1e901e43d1152ecf210933c3f2683b6eb --- doc/classes/Navigation2DServer.xml | 10 ++++++++++ doc/classes/NavigationServer.xml | 10 ++++++++++ modules/navigation/pandemonium_navigation_server.cpp | 10 ++++++++++ modules/navigation/pandemonium_navigation_server.h | 2 ++ servers/navigation_2d_server.cpp | 2 ++ servers/navigation_2d_server.h | 2 ++ servers/navigation_server.cpp | 1 + servers/navigation_server.h | 2 ++ 8 files changed, 39 insertions(+) diff --git a/doc/classes/Navigation2DServer.xml b/doc/classes/Navigation2DServer.xml index 4621b202d..32b31d783 100644 --- a/doc/classes/Navigation2DServer.xml +++ b/doc/classes/Navigation2DServer.xml @@ -297,6 +297,16 @@ Returns the [code]travel_cost[/code] of this [code]region[/code]. + + + + + + Returns [code]true[/code] if the provided [code]point[/code] in world space is currently owned by the provided navigation [code]region[/code]. Owned in this context means that one of the region's navigation mesh polygon faces has a possible position at the closest distance to this point compared to all other navigation meshes from other navigation regions that are also registered on the navigation map of the provided region. + If multiple navigation meshes have positions at equal distance the navigation region whose polygons are processed first wins the ownership. Polygons are processed in the same order that navigation regions were registered on the NavigationServer. + [b]Note:[/b] If navigation meshes from different navigation regions overlap (which should be avoided in general) the result might not be what is expected. + + diff --git a/doc/classes/NavigationServer.xml b/doc/classes/NavigationServer.xml index 59e73fbbc..4d5e3615a 100644 --- a/doc/classes/NavigationServer.xml +++ b/doc/classes/NavigationServer.xml @@ -346,6 +346,16 @@ Returns the [code]travel_cost[/code] of this [code]region[/code]. + + + + + + Returns [code]true[/code] if the provided [code]point[/code] in world space is currently owned by the provided navigation [code]region[/code]. Owned in this context means that one of the region's navigation mesh polygon faces has a possible position at the closest distance to this point compared to all other navigation meshes from other navigation regions that are also registered on the navigation map of the provided region. + If multiple navigation meshes have positions at equal distance the navigation region whose polygons are processed first wins the ownership. Polygons are processed in the same order that navigation regions were registered on the NavigationServer. + [b]Note:[/b] If navigation meshes from different navigation regions overlap (which should be avoided in general) the result might not be what is expected. + + diff --git a/modules/navigation/pandemonium_navigation_server.cpp b/modules/navigation/pandemonium_navigation_server.cpp index fda62f9c3..752261040 100644 --- a/modules/navigation/pandemonium_navigation_server.cpp +++ b/modules/navigation/pandemonium_navigation_server.cpp @@ -373,6 +373,16 @@ real_t PandemoniumNavigationServer::region_get_travel_cost(RID p_region) const { return region->get_travel_cost(); } +bool PandemoniumNavigationServer::region_owns_point(RID p_region, const Vector3 &p_point) const { + const NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND_V(region == nullptr, false); + if (region->get_map()) { + RID closest_point_owner = map_get_closest_point_owner(region->get_map()->get_self(), p_point); + return closest_point_owner == region->get_self(); + } + return false; +} + COMMAND_2(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers) { NavRegion *region = region_owner.getornull(p_region); ERR_FAIL_COND(region == nullptr); diff --git a/modules/navigation/pandemonium_navigation_server.h b/modules/navigation/pandemonium_navigation_server.h index d4500a114..621e94464 100644 --- a/modules/navigation/pandemonium_navigation_server.h +++ b/modules/navigation/pandemonium_navigation_server.h @@ -117,6 +117,8 @@ public: COMMAND_2(region_set_travel_cost, RID, p_region, real_t, p_travel_cost); virtual real_t region_get_travel_cost(RID p_region) const; + virtual bool region_owns_point(RID p_region, const Vector3 &p_point) const; + COMMAND_2(region_set_map, RID, p_region, RID, p_map); virtual RID region_get_map(RID p_region) const; COMMAND_2(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers); diff --git a/servers/navigation_2d_server.cpp b/servers/navigation_2d_server.cpp index 5cf4a9d90..5988c6969 100644 --- a/servers/navigation_2d_server.cpp +++ b/servers/navigation_2d_server.cpp @@ -195,6 +195,7 @@ void Navigation2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &Navigation2DServer::region_get_enter_cost); ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &Navigation2DServer::region_set_travel_cost); ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &Navigation2DServer::region_get_travel_cost); + ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &Navigation2DServer::region_owns_point); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &Navigation2DServer::region_set_map); ClassDB::bind_method(D_METHOD("region_get_map", "region"), &Navigation2DServer::region_get_map); ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &Navigation2DServer::region_set_navigation_layers); @@ -271,6 +272,7 @@ void FORWARD_2_C(region_set_enter_cost, RID, p_region, real_t, p_enter_cost, rid real_t FORWARD_1_C(region_get_enter_cost, RID, p_region, rid_to_rid); void FORWARD_2_C(region_set_travel_cost, RID, p_region, real_t, p_travel_cost, rid_to_rid, real_to_real); real_t FORWARD_1_C(region_get_travel_cost, RID, p_region, rid_to_rid); +bool FORWARD_2_C(region_owns_point, RID, p_region, const Vector2 &, p_point, rid_to_rid, v2_to_v3); void FORWARD_2_C(region_set_map, RID, p_region, RID, p_map, rid_to_rid, rid_to_rid); void FORWARD_2_C(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32); diff --git a/servers/navigation_2d_server.h b/servers/navigation_2d_server.h index 9bffaf07f..37665739e 100644 --- a/servers/navigation_2d_server.h +++ b/servers/navigation_2d_server.h @@ -99,6 +99,8 @@ public: virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const; virtual real_t region_get_travel_cost(RID p_region) const; + virtual bool region_owns_point(RID p_region, const Vector2 &p_point) const; + /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const; virtual RID region_get_map(RID p_region) const; diff --git a/servers/navigation_server.cpp b/servers/navigation_server.cpp index d715ed5b6..eebc76e86 100644 --- a/servers/navigation_server.cpp +++ b/servers/navigation_server.cpp @@ -63,6 +63,7 @@ void NavigationServer::_bind_methods() { ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer::region_get_enter_cost); ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer::region_set_travel_cost); ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer::region_get_travel_cost); + ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &NavigationServer::region_owns_point); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer::region_set_map); ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer::region_get_map); diff --git a/servers/navigation_server.h b/servers/navigation_server.h index 625868360..1b5bf616c 100644 --- a/servers/navigation_server.h +++ b/servers/navigation_server.h @@ -115,6 +115,8 @@ public: virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const = 0; virtual real_t region_get_travel_cost(RID p_region) const = 0; + virtual bool region_owns_point(RID p_region, const Vector3 &p_point) const = 0; + /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const = 0; virtual RID region_get_map(RID p_region) const = 0;