From 9802914f9793b6888cc70e3d7f0d815bdd5188bb Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Fri, 30 Dec 2022 05:19:15 +0100 Subject: [PATCH] Add NavigationServer Performance Monitor Adds Performance Monitor for NavigationServer3D. --- doc/classes/NavigationServer3D.xml | 36 ++++++++++ doc/classes/Performance.xml | 72 +++++++++++++------ main/main.cpp | 10 +++ main/performance.cpp | 53 +++++++++++++- main/performance.h | 12 ++++ .../navigation/godot_navigation_server.cpp | 61 ++++++++++++++++ modules/navigation/godot_navigation_server.h | 12 ++++ modules/navigation/nav_map.cpp | 33 +++++++++ modules/navigation/nav_map.h | 20 ++++++ servers/navigation_server_3d.cpp | 12 ++++ servers/navigation_server_3d.h | 16 +++++ 11 files changed, 315 insertions(+), 22 deletions(-) diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index c38f6e0c0426..312cad54551a 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -133,6 +133,13 @@ Returns all created navigation map [RID]s on the NavigationServer. This returns both 2D and 3D created navigation maps as there is technically no distinction between them. + + + + + Returns information about the current state of the NavigationServer. See [enum ProcessInfo] for a list of available states. + + @@ -592,4 +599,33 @@ + + + Constant to get the number of active navigation maps. + + + Constant to get the number of active navigation regions. + + + Constant to get the number of active navigation agents processing avoidance. + + + Constant to get the number of active navigation links. + + + Constant to get the number of navigation mesh polygons. + + + Constant to get the number of navigation mesh polygon edges. + + + Constant to get the number of navigation mesh polygon edges that were merged due to edge key overlap. + + + Constant to get the number of navigation mesh polygon edges that are considered connected by edge proximity. + + + Constant to get the number of navigation mesh polygon edges that could not be merged but may be still connected by edge proximity or with links. + + diff --git a/doc/classes/Performance.xml b/doc/classes/Performance.xml index 381fa3e9effd..6b7daa534e10 100644 --- a/doc/classes/Performance.xml +++ b/doc/classes/Performance.xml @@ -131,67 +131,97 @@ Time it took to complete one physics frame, in seconds. [i]Lower is better.[/i] - + + Time it took to complete one navigation step, in seconds. This includes navigation map updates as well as agent avoidance calculations. [i]Lower is better.[/i] + + Static memory currently used, in bytes. Not available in release builds. [i]Lower is better.[/i] - + Available static memory. Not available in release builds. [i]Lower is better.[/i] - + Largest amount of memory the message queue buffer has used, in bytes. The message queue is used for deferred functions calls and notifications. [i]Lower is better.[/i] - + Number of objects currently instantiated (including nodes). [i]Lower is better.[/i] - + Number of resources currently used. [i]Lower is better.[/i] - + Number of nodes currently instantiated in the scene tree. This also includes the root node. [i]Lower is better.[/i] - + Number of orphan nodes, i.e. nodes which are not parented to a node of the scene tree. [i]Lower is better.[/i] - + The total number of objects in the last rendered frame. This metric doesn't include culled objects (either via hiding nodes, frustum culling or occlusion culling). [i]Lower is better.[/i] - + The total number of vertices or indices rendered in the last rendered frame. This metric doesn't include primitives from culled objects (either via hiding nodes, frustum culling or occlusion culling). Due to the depth prepass and shadow passes, the number of primitives is always higher than the actual number of vertices in the scene (typically double or triple the original vertex count). [i]Lower is better.[/i] - + The total number of draw calls performed in the last rendered frame. This metric doesn't include culled objects (either via hiding nodes, frustum culling or occlusion culling), since they do not result in draw calls. [i]Lower is better.[/i] - + The amount of video memory used (texture and vertex memory combined, in bytes). Since this metric also includes miscellaneous allocations, this value is always greater than the sum of [constant RENDER_TEXTURE_MEM_USED] and [constant RENDER_BUFFER_MEM_USED]. [i]Lower is better.[/i] - + The amount of texture memory used (in bytes). [i]Lower is better.[/i] - + The amount of render buffer memory used (in bytes). [i]Lower is better.[/i] - + Number of active [RigidBody2D] nodes in the game. [i]Lower is better.[/i] - + Number of collision pairs in the 2D physics engine. [i]Lower is better.[/i] - + Number of islands in the 2D physics engine. [i]Lower is better.[/i] - + Number of active [RigidBody3D] and [VehicleBody3D] nodes in the game. [i]Lower is better.[/i] - + Number of collision pairs in the 3D physics engine. [i]Lower is better.[/i] - + Number of islands in the 3D physics engine. [i]Lower is better.[/i] - + Output latency of the [AudioServer]. [i]Lower is better.[/i] - + + Number of active navigation maps in the [NavigationServer3D]. This also includes the two empty default navigation maps created by World2D and World3D. + + + Number of active navigation regions in the [NavigationServer3D]. + + + Number of active navigation agents processing avoidance in the [NavigationServer3D]. + + + Number of active navigation links in the [NavigationServer3D]. + + + Number of navigation mesh polygons in the [NavigationServer3D]. + + + Number of navigation mesh polygon edges in the [NavigationServer3D]. + + + Number of navigation mesh polygon edges that were merged due to edge key overlap in the [NavigationServer3D]. + + + Number of polygon edges that are considered connected by edge proximity [NavigationServer3D]. + + + Number of navigation mesh polygon edges that could not be merged in the [NavigationServer3D]. The edges still may be connected by edge proximity or with links. + + Represents the size of the [enum Monitor] enum. diff --git a/main/main.cpp b/main/main.cpp index d21574b0e3ba..653c6cbc5f5b 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2968,6 +2968,7 @@ bool Main::is_iterating() { // For performance metrics. static uint64_t physics_process_max = 0; static uint64_t process_max = 0; +static uint64_t navigation_process_max = 0; bool Main::iteration() { //for now do not error on this @@ -2996,6 +2997,7 @@ bool Main::iteration() { uint64_t physics_process_ticks = 0; uint64_t process_ticks = 0; + uint64_t navigation_process_ticks = 0; frame += ticks_elapsed; @@ -3033,6 +3035,12 @@ bool Main::iteration() { } NavigationServer3D::get_singleton()->process(physics_step * time_scale); + uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec(); + + NavigationServer3D::get_singleton()->process(physics_step * time_scale); + + navigation_process_ticks = MAX(navigation_process_ticks, OS::get_singleton()->get_ticks_usec() - navigation_begin); // keep the largest one for reference + navigation_process_max = MAX(OS::get_singleton()->get_ticks_usec() - navigation_begin, navigation_process_max); message_queue->flush(); @@ -3112,8 +3120,10 @@ bool Main::iteration() { Engine::get_singleton()->_fps = frames; performance->set_process_time(USEC_TO_SEC(process_max)); performance->set_physics_process_time(USEC_TO_SEC(physics_process_max)); + performance->set_navigation_process_time(USEC_TO_SEC(navigation_process_max)); process_max = 0; physics_process_max = 0; + navigation_process_max = 0; frame %= 1000000; frames = 0; diff --git a/main/performance.cpp b/main/performance.cpp index c2624c708f6f..448ddd0e9630 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -36,6 +36,7 @@ #include "scene/main/node.h" #include "scene/main/scene_tree.h" #include "servers/audio_server.h" +#include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" #include "servers/physics_server_3d.h" #include "servers/rendering_server.h" @@ -54,6 +55,7 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(TIME_FPS); BIND_ENUM_CONSTANT(TIME_PROCESS); BIND_ENUM_CONSTANT(TIME_PHYSICS_PROCESS); + BIND_ENUM_CONSTANT(TIME_NAVIGATION_PROCESS); BIND_ENUM_CONSTANT(MEMORY_STATIC); BIND_ENUM_CONSTANT(MEMORY_STATIC_MAX); BIND_ENUM_CONSTANT(MEMORY_MESSAGE_BUFFER_MAX); @@ -74,7 +76,15 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(PHYSICS_3D_COLLISION_PAIRS); BIND_ENUM_CONSTANT(PHYSICS_3D_ISLAND_COUNT); BIND_ENUM_CONSTANT(AUDIO_OUTPUT_LATENCY); - + BIND_ENUM_CONSTANT(NAVIGATION_ACTIVE_MAPS); + BIND_ENUM_CONSTANT(NAVIGATION_REGION_COUNT); + BIND_ENUM_CONSTANT(NAVIGATION_AGENT_COUNT); + BIND_ENUM_CONSTANT(NAVIGATION_LINK_COUNT); + BIND_ENUM_CONSTANT(NAVIGATION_POLYGON_COUNT); + BIND_ENUM_CONSTANT(NAVIGATION_EDGE_COUNT); + BIND_ENUM_CONSTANT(NAVIGATION_EDGE_MERGE_COUNT); + BIND_ENUM_CONSTANT(NAVIGATION_EDGE_CONNECTION_COUNT); + BIND_ENUM_CONSTANT(NAVIGATION_EDGE_FREE_COUNT); BIND_ENUM_CONSTANT(MONITOR_MAX); } @@ -93,6 +103,7 @@ String Performance::get_monitor_name(Monitor p_monitor) const { "time/fps", "time/process", "time/physics_process", + "time/navigation_process", "memory/static", "memory/static_max", "memory/msg_buf_max", @@ -113,6 +124,15 @@ String Performance::get_monitor_name(Monitor p_monitor) const { "physics_3d/collision_pairs", "physics_3d/islands", "audio/driver/output_latency", + "navigation/active_maps", + "navigation/regions", + "navigation/agents", + "navigation/links", + "navigation/polygons", + "navigation/edges", + "navigation/edges_merged", + "navigation/edges_connected", + "navigation/edges_free", }; @@ -127,6 +147,8 @@ double Performance::get_monitor(Monitor p_monitor) const { return _process_time; case TIME_PHYSICS_PROCESS: return _physics_process_time; + case TIME_NAVIGATION_PROCESS: + return _navigation_process_time; case MEMORY_STATIC: return Memory::get_mem_usage(); case MEMORY_STATIC_MAX: @@ -167,6 +189,24 @@ double Performance::get_monitor(Monitor p_monitor) const { return PhysicsServer3D::get_singleton()->get_process_info(PhysicsServer3D::INFO_ISLAND_COUNT); case AUDIO_OUTPUT_LATENCY: return AudioServer::get_singleton()->get_output_latency(); + case NAVIGATION_ACTIVE_MAPS: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_ACTIVE_MAPS); + case NAVIGATION_REGION_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_REGION_COUNT); + case NAVIGATION_AGENT_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_AGENT_COUNT); + case NAVIGATION_LINK_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_LINK_COUNT); + case NAVIGATION_POLYGON_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_POLYGON_COUNT); + case NAVIGATION_EDGE_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_COUNT); + case NAVIGATION_EDGE_MERGE_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_MERGE_COUNT); + case NAVIGATION_EDGE_CONNECTION_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_CONNECTION_COUNT); + case NAVIGATION_EDGE_FREE_COUNT: + return NavigationServer3D::get_singleton()->get_process_info(NavigationServer3D::INFO_EDGE_FREE_COUNT); default: { } @@ -182,6 +222,7 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const MONITOR_TYPE_QUANTITY, MONITOR_TYPE_TIME, MONITOR_TYPE_TIME, + MONITOR_TYPE_TIME, MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, @@ -202,6 +243,12 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const MONITOR_TYPE_QUANTITY, MONITOR_TYPE_QUANTITY, MONITOR_TYPE_TIME, + MONITOR_TYPE_QUANTITY, + MONITOR_TYPE_QUANTITY, + MONITOR_TYPE_QUANTITY, + MONITOR_TYPE_QUANTITY, + MONITOR_TYPE_QUANTITY, + MONITOR_TYPE_QUANTITY, }; @@ -216,6 +263,10 @@ void Performance::set_physics_process_time(double p_pt) { _physics_process_time = p_pt; } +void Performance::set_navigation_process_time(double p_pt) { + _navigation_process_time = p_pt; +} + void Performance::add_custom_monitor(const StringName &p_id, const Callable &p_callable, const Vector &p_args) { ERR_FAIL_COND_MSG(has_custom_monitor(p_id), "Custom monitor with id '" + String(p_id) + "' already exists."); _monitor_map.insert(p_id, MonitorCall(p_callable, p_args)); diff --git a/main/performance.h b/main/performance.h index 14695ab5a365..34162b2da9c4 100644 --- a/main/performance.h +++ b/main/performance.h @@ -50,6 +50,7 @@ class Performance : public Object { double _process_time; double _physics_process_time; + double _navigation_process_time; class MonitorCall { Callable _callable; @@ -69,6 +70,7 @@ public: TIME_FPS, TIME_PROCESS, TIME_PHYSICS_PROCESS, + TIME_NAVIGATION_PROCESS, MEMORY_STATIC, MEMORY_STATIC_MAX, MEMORY_MESSAGE_BUFFER_MAX, @@ -89,6 +91,15 @@ public: PHYSICS_3D_COLLISION_PAIRS, PHYSICS_3D_ISLAND_COUNT, AUDIO_OUTPUT_LATENCY, + NAVIGATION_ACTIVE_MAPS, + NAVIGATION_REGION_COUNT, + NAVIGATION_AGENT_COUNT, + NAVIGATION_LINK_COUNT, + NAVIGATION_POLYGON_COUNT, + NAVIGATION_EDGE_COUNT, + NAVIGATION_EDGE_MERGE_COUNT, + NAVIGATION_EDGE_CONNECTION_COUNT, + NAVIGATION_EDGE_FREE_COUNT, MONITOR_MAX }; @@ -105,6 +116,7 @@ public: void set_process_time(double p_pt); void set_physics_process_time(double p_pt); + void set_navigation_process_time(double p_pt); void add_custom_monitor(const StringName &p_id, const Callable &p_callable, const Vector &p_args); void remove_custom_monitor(const StringName &p_id); diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index b9b92b77c9bb..9b5d78d46572 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -829,6 +829,15 @@ void GodotNavigationServer::process(real_t p_delta_time) { return; } + int _new_pm_region_count = 0; + int _new_pm_agent_count = 0; + int _new_pm_link_count = 0; + int _new_pm_polygon_count = 0; + int _new_pm_edge_count = 0; + int _new_pm_edge_merge_count = 0; + int _new_pm_edge_connection_count = 0; + int _new_pm_edge_free_count = 0; + // In c++ we can't be sure that this is performed in the main thread // even with mutable functions. MutexLock lock(operations_mutex); @@ -837,6 +846,15 @@ void GodotNavigationServer::process(real_t p_delta_time) { active_maps[i]->step(p_delta_time); active_maps[i]->dispatch_callbacks(); + _new_pm_region_count += active_maps[i]->get_pm_region_count(); + _new_pm_agent_count += active_maps[i]->get_pm_agent_count(); + _new_pm_link_count += active_maps[i]->get_pm_link_count(); + _new_pm_polygon_count += active_maps[i]->get_pm_polygon_count(); + _new_pm_edge_count += active_maps[i]->get_pm_edge_count(); + _new_pm_edge_merge_count += active_maps[i]->get_pm_edge_merge_count(); + _new_pm_edge_connection_count += active_maps[i]->get_pm_edge_connection_count(); + _new_pm_edge_free_count += active_maps[i]->get_pm_edge_free_count(); + // Emit a signal if a map changed. const uint32_t new_map_update_id = active_maps[i]->get_map_update_id(); if (new_map_update_id != active_maps_update_id[i]) { @@ -844,6 +862,15 @@ void GodotNavigationServer::process(real_t p_delta_time) { active_maps_update_id[i] = new_map_update_id; } } + + pm_region_count = _new_pm_region_count; + pm_agent_count = _new_pm_agent_count; + pm_link_count = _new_pm_link_count; + pm_polygon_count = _new_pm_polygon_count; + pm_edge_count = _new_pm_edge_count; + pm_edge_merge_count = _new_pm_edge_merge_count; + pm_edge_connection_count = _new_pm_edge_connection_count; + pm_edge_free_count = _new_pm_edge_free_count; } PathQueryResult GodotNavigationServer::_query_path(const PathQueryParameters &p_parameters) const { @@ -886,6 +913,40 @@ PathQueryResult GodotNavigationServer::_query_path(const PathQueryParameters &p_ return r_query_result; } +int GodotNavigationServer::get_process_info(ProcessInfo p_info) const { + switch (p_info) { + case INFO_ACTIVE_MAPS: { + return active_maps.size(); + } break; + case INFO_REGION_COUNT: { + return pm_region_count; + } break; + case INFO_AGENT_COUNT: { + return pm_agent_count; + } break; + case INFO_LINK_COUNT: { + return pm_link_count; + } break; + case INFO_POLYGON_COUNT: { + return pm_polygon_count; + } break; + case INFO_EDGE_COUNT: { + return pm_edge_count; + } break; + case INFO_EDGE_MERGE_COUNT: { + return pm_edge_merge_count; + } break; + case INFO_EDGE_CONNECTION_COUNT: { + return pm_edge_connection_count; + } break; + case INFO_EDGE_FREE_COUNT: { + return pm_edge_free_count; + } break; + } + + return 0; +} + #undef COMMAND_1 #undef COMMAND_2 #undef COMMAND_4 diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 7a6e5bb20843..a87a88d3bcde 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -81,6 +81,16 @@ class GodotNavigationServer : public NavigationServer3D { LocalVector active_maps; LocalVector active_maps_update_id; + // Performance Monitor + int pm_region_count = 0; + int pm_agent_count = 0; + int pm_link_count = 0; + int pm_polygon_count = 0; + int pm_edge_count = 0; + int pm_edge_merge_count = 0; + int pm_edge_connection_count = 0; + int pm_edge_free_count = 0; + public: GodotNavigationServer(); virtual ~GodotNavigationServer(); @@ -182,6 +192,8 @@ public: virtual void process(real_t p_delta_time) override; virtual NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const override; + + int get_process_info(ProcessInfo p_info) const override; }; #undef COMMAND_1 diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 2a2f8aa1b742..fd735f879354 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -611,6 +611,16 @@ void NavMap::remove_agent_as_controlled(RvoAgent *agent) { } void NavMap::sync() { + // Performance Monitor + int _new_pm_region_count = regions.size(); + int _new_pm_agent_count = agents.size(); + int _new_pm_link_count = links.size(); + int _new_pm_polygon_count = pm_polygon_count; + int _new_pm_edge_count = pm_edge_count; + int _new_pm_edge_merge_count = pm_edge_merge_count; + int _new_pm_edge_connection_count = pm_edge_connection_count; + int _new_pm_edge_free_count = pm_edge_free_count; + // Check if we need to update the links. if (regenerate_polygons) { for (uint32_t r = 0; r < regions.size(); r++) { @@ -632,6 +642,12 @@ void NavMap::sync() { } if (regenerate_links) { + _new_pm_polygon_count = 0; + _new_pm_edge_count = 0; + _new_pm_edge_merge_count = 0; + _new_pm_edge_connection_count = 0; + _new_pm_edge_free_count = 0; + // Remove regions connections. for (uint32_t r = 0; r < regions.size(); r++) { regions[r]->get_connections().clear(); @@ -654,6 +670,8 @@ void NavMap::sync() { count += regions[r]->get_polygons().size(); } + _new_pm_polygon_count = polygons.size(); + // Group all edges per key. HashMap, gd::EdgeKey> connections; for (uint32_t poly_id = 0; poly_id < polygons.size(); poly_id++) { @@ -666,6 +684,7 @@ void NavMap::sync() { HashMap, gd::EdgeKey>::Iterator connection = connections.find(ek); if (!connection) { connections[ek] = Vector(); + _new_pm_edge_count += 1; } if (connections[ek].size() <= 1) { // Add the polygon/edge tuple to this key. @@ -691,6 +710,7 @@ void NavMap::sync() { c1.polygon->edges[c1.edge].connections.push_back(c2); c2.polygon->edges[c2.edge].connections.push_back(c1); // Note: The pathway_start/end are full for those connection and do not need to be modified. + _new_pm_edge_merge_count += 1; } else { CRASH_COND_MSG(E.value.size() != 1, vformat("Number of connection != 1. Found: %d", E.value.size())); free_edges.push_back(E.value[0]); @@ -704,6 +724,8 @@ void NavMap::sync() { // to be connected, create new polygons to remove that small gap is // not really useful and would result in wasteful computation during // connection, integration and path finding. + _new_pm_edge_free_count = free_edges.size(); + for (int i = 0; i < free_edges.size(); i++) { const gd::Edge::Connection &free_edge = free_edges[i]; Vector3 edge_p1 = free_edge.polygon->points[free_edge.edge].pos; @@ -757,6 +779,7 @@ void NavMap::sync() { // Add the connection to the region_connection map. ((NavRegion *)free_edge.polygon->owner)->get_connections().push_back(new_connection); + _new_pm_edge_connection_count += 1; } } @@ -892,6 +915,16 @@ void NavMap::sync() { regenerate_polygons = false; regenerate_links = false; agents_dirty = false; + + // Performance Monitor + pm_region_count = _new_pm_region_count; + pm_agent_count = _new_pm_agent_count; + pm_link_count = _new_pm_link_count; + pm_polygon_count = _new_pm_polygon_count; + pm_edge_count = _new_pm_edge_count; + pm_edge_merge_count = _new_pm_edge_merge_count; + pm_edge_connection_count = _new_pm_edge_connection_count; + pm_edge_free_count = _new_pm_edge_free_count; } void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) { diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index 321d5560f0af..fce7aff3ba5e 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -89,6 +89,16 @@ class NavMap : public NavRid { /// Change the id each time the map is updated. uint32_t map_update_id = 0; + // Performance Monitor + int pm_region_count = 0; + int pm_agent_count = 0; + int pm_link_count = 0; + int pm_polygon_count = 0; + int pm_edge_count = 0; + int pm_edge_merge_count = 0; + int pm_edge_connection_count = 0; + int pm_edge_free_count = 0; + public: NavMap(); ~NavMap(); @@ -152,6 +162,16 @@ public: void step(real_t p_deltatime); void dispatch_callbacks(); + // Performance Monitor + int get_pm_region_count() const { return pm_region_count; } + int get_pm_agent_count() const { return pm_agent_count; } + int get_pm_link_count() const { return pm_link_count; } + int get_pm_polygon_count() const { return pm_polygon_count; } + int get_pm_edge_count() const { return pm_edge_count; } + int get_pm_edge_merge_count() const { return pm_edge_merge_count; } + int get_pm_edge_connection_count() const { return pm_edge_connection_count; } + int get_pm_edge_free_count() const { return pm_edge_free_count; } + private: void compute_single_step(uint32_t index, RvoAgent **agent); void clip_path(const LocalVector &p_navigation_polys, Vector &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly, Vector *r_path_types, TypedArray *r_path_rids, Vector *r_path_owners) const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 97c0ae0d540f..253b28a62399 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -123,6 +123,18 @@ void NavigationServer3D::_bind_methods() { ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); ADD_SIGNAL(MethodInfo("navigation_debug_changed")); + + ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &NavigationServer3D::get_process_info); + + BIND_ENUM_CONSTANT(INFO_ACTIVE_MAPS); + BIND_ENUM_CONSTANT(INFO_REGION_COUNT); + BIND_ENUM_CONSTANT(INFO_AGENT_COUNT); + BIND_ENUM_CONSTANT(INFO_LINK_COUNT); + BIND_ENUM_CONSTANT(INFO_POLYGON_COUNT); + BIND_ENUM_CONSTANT(INFO_EDGE_COUNT); + BIND_ENUM_CONSTANT(INFO_EDGE_MERGE_COUNT); + BIND_ENUM_CONSTANT(INFO_EDGE_CONNECTION_COUNT); + BIND_ENUM_CONSTANT(INFO_EDGE_FREE_COUNT); } NavigationServer3D *NavigationServer3D::get_singleton() { diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index afd7216a4357..6c4bd2e1518f 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -260,6 +260,20 @@ public: NavigationServer3D(); virtual ~NavigationServer3D(); + enum ProcessInfo { + INFO_ACTIVE_MAPS, + INFO_REGION_COUNT, + INFO_AGENT_COUNT, + INFO_LINK_COUNT, + INFO_POLYGON_COUNT, + INFO_EDGE_COUNT, + INFO_EDGE_MERGE_COUNT, + INFO_EDGE_CONNECTION_COUNT, + INFO_EDGE_FREE_COUNT, + }; + + virtual int get_process_info(ProcessInfo p_info) const = 0; + #ifdef DEBUG_ENABLED private: bool debug_enabled = false; @@ -357,4 +371,6 @@ public: static NavigationServer3D *new_default_server(); }; +VARIANT_ENUM_CAST(NavigationServer3D::ProcessInfo); + #endif // NAVIGATION_SERVER_3D_H