From 08c0756260163f8fb5ea7a462187e49464d60457 Mon Sep 17 00:00:00 2001 From: Relintai Date: Wed, 27 Jul 2022 18:58:09 +0200 Subject: [PATCH] Ported: Add NavigationServer2D/3D API functions to find missing RID info Utility functions for NavigationServer2D/3D to find missing RID information when working with Server API directly. e.g. from map to regions and agents, from agent or region to map, from region to map and agents and so on .... Requirement to work with NavigationServer API exklusive without SceneTree nodes and when juggling agents and regions between multiple navigation maps. - smix8 https://github.com/godotengine/godot/commit/3977eb9107e869ab1b38323978d203910d6efb1a --- doc/classes/Navigation2DServer.xml | 28 ++++ doc/classes/NavigationServer.xml | 28 ++++ .../pandemonium_navigation_server.cpp | 142 +++++++++++------- .../pandemonium_navigation_server.h | 5 + servers/navigation_2d_server.cpp | 13 ++ servers/navigation_2d_server.h | 5 + servers/navigation_server.cpp | 5 + servers/navigation_server.h | 5 + 8 files changed, 176 insertions(+), 55 deletions(-) diff --git a/doc/classes/Navigation2DServer.xml b/doc/classes/Navigation2DServer.xml index 167470d53..d1efa96df 100644 --- a/doc/classes/Navigation2DServer.xml +++ b/doc/classes/Navigation2DServer.xml @@ -20,6 +20,13 @@ Creates the agent. + + + + + Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to. + + @@ -121,6 +128,13 @@ Create a new map. + + + + + Returns all navigation agents [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -161,6 +175,13 @@ Returns the navigation path to reach the destination from the origin. + + + + + Returns all navigation regions [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -198,6 +219,13 @@ Creates a new region. + + + + + Returns the navigation map [RID] the requested [code]region[/code] is currently assigned to. + + diff --git a/doc/classes/NavigationServer.xml b/doc/classes/NavigationServer.xml index 5b331082a..d465e7b1f 100644 --- a/doc/classes/NavigationServer.xml +++ b/doc/classes/NavigationServer.xml @@ -20,6 +20,13 @@ Creates the agent. + + + + + Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to. + + @@ -121,6 +128,13 @@ Create a new map. + + + + + Returns all navigation agents [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -186,6 +200,13 @@ Returns the navigation path to reach the destination from the origin. + + + + + Returns all navigation regions [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -263,6 +284,13 @@ Creates a new region. + + + + + Returns the navigation map [RID] the requested [code]region[/code] is currently assigned to. + + diff --git a/modules/navigation/pandemonium_navigation_server.cpp b/modules/navigation/pandemonium_navigation_server.cpp index 3ae87d4ed..e239cfd33 100644 --- a/modules/navigation/pandemonium_navigation_server.cpp +++ b/modules/navigation/pandemonium_navigation_server.cpp @@ -46,73 +46,73 @@ /// an instance of that struct with the submitted parameters. /// Then, that struct is stored in an array; the `sync` function consume that array. -#define COMMAND_1(F_NAME, T_0, D_0) \ - struct MERGE(F_NAME, _command) : public SetCommand { \ - T_0 d_0; \ - MERGE(F_NAME, _command) \ - (T_0 p_d_0) : \ - d_0(p_d_0) {} \ - virtual void exec(PandemoniumNavigationServer *server) { \ - server->MERGE(_cmd_, F_NAME)(d_0); \ - } \ - }; \ - void PandemoniumNavigationServer::F_NAME(T_0 D_0) const { \ - auto cmd = memnew(MERGE(F_NAME, _command)( \ - D_0)); \ - add_command(cmd); \ - } \ - void PandemoniumNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0) - -#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \ +#define COMMAND_1(F_NAME, T_0, D_0) \ struct MERGE(F_NAME, _command) : public SetCommand { \ T_0 d_0; \ - T_1 d_1; \ MERGE(F_NAME, _command) \ - ( \ - T_0 p_d_0, \ - T_1 p_d_1) : \ - d_0(p_d_0), \ - d_1(p_d_1) {} \ - virtual void exec(PandemoniumNavigationServer *server) { \ - server->MERGE(_cmd_, F_NAME)(d_0, d_1); \ + (T_0 p_d_0) : \ + d_0(p_d_0) {} \ + virtual void exec(PandemoniumNavigationServer *server) { \ + server->MERGE(_cmd_, F_NAME)(d_0); \ } \ }; \ - void PandemoniumNavigationServer::F_NAME(T_0 D_0, T_1 D_1) const { \ + void PandemoniumNavigationServer::F_NAME(T_0 D_0) const { \ auto cmd = memnew(MERGE(F_NAME, _command)( \ - D_0, \ - D_1)); \ + D_0)); \ add_command(cmd); \ } \ + void PandemoniumNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0) + +#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \ + struct MERGE(F_NAME, _command) : public SetCommand { \ + T_0 d_0; \ + T_1 d_1; \ + MERGE(F_NAME, _command) \ + ( \ + T_0 p_d_0, \ + T_1 p_d_1) : \ + d_0(p_d_0), \ + d_1(p_d_1) {} \ + virtual void exec(PandemoniumNavigationServer *server) { \ + server->MERGE(_cmd_, F_NAME)(d_0, d_1); \ + } \ + }; \ + void PandemoniumNavigationServer::F_NAME(T_0 D_0, T_1 D_1) const { \ + auto cmd = memnew(MERGE(F_NAME, _command)( \ + D_0, \ + D_1)); \ + add_command(cmd); \ + } \ void PandemoniumNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1) -#define COMMAND_4(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3) \ - struct MERGE(F_NAME, _command) : public SetCommand { \ - T_0 d_0; \ - T_1 d_1; \ - T_2 d_2; \ - T_3 d_3; \ - MERGE(F_NAME, _command) \ - ( \ - T_0 p_d_0, \ - T_1 p_d_1, \ - T_2 p_d_2, \ - T_3 p_d_3) : \ - d_0(p_d_0), \ - d_1(p_d_1), \ - d_2(p_d_2), \ - d_3(p_d_3) {} \ +#define COMMAND_4(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3) \ + struct MERGE(F_NAME, _command) : public SetCommand { \ + T_0 d_0; \ + T_1 d_1; \ + T_2 d_2; \ + T_3 d_3; \ + MERGE(F_NAME, _command) \ + ( \ + T_0 p_d_0, \ + T_1 p_d_1, \ + T_2 p_d_2, \ + T_3 p_d_3) : \ + d_0(p_d_0), \ + d_1(p_d_1), \ + d_2(p_d_2), \ + d_3(p_d_3) {} \ virtual void exec(PandemoniumNavigationServer *server) { \ - server->MERGE(_cmd_, F_NAME)(d_0, d_1, d_2, d_3); \ - } \ - }; \ + server->MERGE(_cmd_, F_NAME)(d_0, d_1, d_2, d_3); \ + } \ + }; \ void PandemoniumNavigationServer::F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) const { \ - auto cmd = memnew(MERGE(F_NAME, _command)( \ - D_0, \ - D_1, \ - D_2, \ - D_3)); \ - add_command(cmd); \ - } \ + auto cmd = memnew(MERGE(F_NAME, _command)( \ + D_0, \ + D_1, \ + D_2, \ + D_3)); \ + add_command(cmd); \ + } \ void PandemoniumNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) PandemoniumNavigationServer::PandemoniumNavigationServer() : @@ -252,6 +252,38 @@ RID PandemoniumNavigationServer::map_get_closest_point_owner(RID p_map, const Ve return map->get_closest_point_owner(p_point); } +Array PandemoniumNavigationServer::map_get_regions(RID p_map) const { + Array regions_rids; + const NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == nullptr, regions_rids); + for (NavRegion *region : map->get_regions()) { + regions_rids.push_back(region->get_self()); + } + return regions_rids; +} + +Array PandemoniumNavigationServer::map_get_agents(RID p_map) const { + Array agents_rids; + const NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == nullptr, agents_rids); + for (RvoAgent *agent : map->get_agents()) { + agents_rids.push_back(agent->get_self()); + } + return agents_rids; +} + +RID PandemoniumNavigationServer::region_get_map(RID p_region) const { + NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND_V(region == nullptr, RID()); + return region->get_map()->get_self(); +} + +RID PandemoniumNavigationServer::agent_get_map(RID p_agent) const { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND_V(agent == nullptr, RID()); + return agent->get_map()->get_self(); +} + RID PandemoniumNavigationServer::region_create() const { auto mut_this = const_cast(this); MutexLock lock(mut_this->operations_mutex); diff --git a/modules/navigation/pandemonium_navigation_server.h b/modules/navigation/pandemonium_navigation_server.h index e5b1a81c9..749a0ab2e 100644 --- a/modules/navigation/pandemonium_navigation_server.h +++ b/modules/navigation/pandemonium_navigation_server.h @@ -107,14 +107,19 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const; + virtual Array map_get_regions(RID p_map) const; + virtual Array map_get_agents(RID p_map) const; + virtual RID region_create() 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_transform, RID, p_region, Transform, p_transform); COMMAND_2(region_set_navmesh, RID, p_region, Ref, p_nav_mesh); virtual void region_bake_navmesh(Ref r_mesh, Node *p_node) const; virtual RID agent_create() const; COMMAND_2(agent_set_map, RID, p_agent, RID, p_map); + virtual RID agent_get_map(RID p_agent) const; COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist); COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count); COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time); diff --git a/servers/navigation_2d_server.cpp b/servers/navigation_2d_server.cpp index ca81fba98..5bcf80c21 100644 --- a/servers/navigation_2d_server.cpp +++ b/servers/navigation_2d_server.cpp @@ -143,13 +143,18 @@ void Navigation2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &Navigation2DServer::map_get_closest_point); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &Navigation2DServer::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &Navigation2DServer::map_get_regions); + ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &Navigation2DServer::map_get_agents); + ClassDB::bind_method(D_METHOD("region_create"), &Navigation2DServer::region_create); 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_transform", "region", "transform"), &Navigation2DServer::region_set_transform); ClassDB::bind_method(D_METHOD("region_set_navpoly", "region", "nav_poly"), &Navigation2DServer::region_set_navpoly); ClassDB::bind_method(D_METHOD("agent_create"), &Navigation2DServer::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &Navigation2DServer::agent_set_map); + ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &Navigation2DServer::agent_get_map); ClassDB::bind_method(D_METHOD("agent_set_neighbor_dist", "agent", "dist"), &Navigation2DServer::agent_set_neighbor_dist); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &Navigation2DServer::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_time_horizon", "agent", "time"), &Navigation2DServer::agent_set_time_horizon); @@ -172,6 +177,14 @@ Navigation2DServer::~Navigation2DServer() { singleton = nullptr; } +Array FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid); + +Array FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid); + +RID FORWARD_1_C(region_get_map, RID, p_region, rid_to_rid); + +RID FORWARD_1_C(agent_get_map, RID, p_agent, rid_to_rid); + RID FORWARD_0_C(map_create); void FORWARD_2_C(map_set_active, RID, p_map, bool, p_active, rid_to_rid, bool_to_bool); diff --git a/servers/navigation_2d_server.h b/servers/navigation_2d_server.h index 3f8a31edf..a19d2da82 100644 --- a/servers/navigation_2d_server.h +++ b/servers/navigation_2d_server.h @@ -81,11 +81,15 @@ public: virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const; virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const; + virtual Array map_get_regions(RID p_map) const; + virtual Array map_get_agents(RID p_map) const; + /// Creates a new region. virtual RID region_create() 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; /// Set the global transformation of this region. virtual void region_set_transform(RID p_region, Transform2D p_transform) const; @@ -98,6 +102,7 @@ public: /// Put the agent in the map. virtual void agent_set_map(RID p_agent, RID p_map) const; + virtual RID agent_get_map(RID p_agent) const; /// The maximum distance (center point to /// center point) to other agents this agent diff --git a/servers/navigation_server.cpp b/servers/navigation_server.cpp index 2c88a922e..caea0fef0 100644 --- a/servers/navigation_server.cpp +++ b/servers/navigation_server.cpp @@ -57,14 +57,19 @@ void NavigationServer::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer::map_get_closest_point_normal); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer::map_get_regions); + ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer::map_get_agents); + ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer::region_create); 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); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer::region_set_transform); ClassDB::bind_method(D_METHOD("region_set_navmesh", "region", "nav_mesh"), &NavigationServer::region_set_navmesh); ClassDB::bind_method(D_METHOD("region_bake_navmesh", "mesh", "node"), &NavigationServer::region_bake_navmesh); ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer::agent_set_map); + ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer::agent_get_map); ClassDB::bind_method(D_METHOD("agent_set_neighbor_dist", "agent", "dist"), &NavigationServer::agent_set_neighbor_dist); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &NavigationServer::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_time_horizon", "agent", "time"), &NavigationServer::agent_set_time_horizon); diff --git a/servers/navigation_server.h b/servers/navigation_server.h index 0dbb967ac..b1fa9adf6 100644 --- a/servers/navigation_server.h +++ b/servers/navigation_server.h @@ -103,11 +103,15 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const = 0; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const = 0; + virtual Array map_get_regions(RID p_map) const = 0; + virtual Array map_get_agents(RID p_map) const = 0; + /// Creates a new region. virtual RID region_create() 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; /// Set the global transformation of this region. virtual void region_set_transform(RID p_region, Transform p_transform) const = 0; @@ -123,6 +127,7 @@ public: /// Put the agent in the map. virtual void agent_set_map(RID p_agent, RID p_map) const = 0; + virtual RID agent_get_map(RID p_agent) const = 0; /// The maximum distance (center point to /// center point) to other agents this agent