Skip to content

Commit 1c9bc22

Browse files
committed
Improve NavigationAgent2D debug performance
Improves NavigationAgent2D debug performance by using static mesh and multimesh.
1 parent ca1e478 commit 1c9bc22

File tree

3 files changed

+107
-28
lines changed

3 files changed

+107
-28
lines changed

doc/classes/NavigationAgent2D.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@
158158
<member name="debug_path_custom_color" type="Color" setter="set_debug_path_custom_color" getter="get_debug_path_custom_color" default="Color(1, 1, 1, 1)">
159159
If [member debug_use_custom] is [code]true[/code] uses this color for this agent instead of global color.
160160
</member>
161-
<member name="debug_path_custom_line_width" type="float" setter="set_debug_path_custom_line_width" getter="get_debug_path_custom_line_width" default="-1.0">
162-
If [member debug_use_custom] is [code]true[/code] uses this line width for rendering paths for this agent instead of global line width.
161+
<member name="debug_path_custom_line_width" type="float" setter="set_debug_path_custom_line_width" getter="get_debug_path_custom_line_width" default="-1.0" deprecated="">
162+
This property does nothing.
163163
</member>
164164
<member name="debug_path_custom_point_size" type="float" setter="set_debug_path_custom_point_size" getter="get_debug_path_custom_point_size" default="4.0">
165165
If [member debug_use_custom] is [code]true[/code] uses this rasterized point size for rendering path points for this agent instead of global point size.

scene/2d/navigation/navigation_agent_2d.cpp

Lines changed: 102 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ void NavigationAgent2D::_bind_methods() {
167167
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom");
168168
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color");
169169
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "0,50,0.01,or_greater,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size");
170-
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_line_width", PROPERTY_HINT_RANGE, "-1,50,0.01,or_greater,suffix:px"), "set_debug_path_custom_line_width", "get_debug_path_custom_line_width");
170+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_line_width", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_debug_path_custom_line_width", "get_debug_path_custom_line_width");
171171

172172
ADD_SIGNAL(MethodInfo("path_changed"));
173173
ADD_SIGNAL(MethodInfo("target_reached"));
@@ -326,6 +326,16 @@ NavigationAgent2D::NavigationAgent2D() {
326326

327327
#ifdef DEBUG_ENABLED
328328
NavigationServer2D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed));
329+
330+
ERR_FAIL_NULL(RS::get_singleton());
331+
RenderingServer *rs = RS::get_singleton();
332+
333+
debug_path_instance = rs->canvas_item_create();
334+
debug_path_segments_mesh_rid = rs->mesh_create();
335+
debug_path_point_mesh_rid = rs->mesh_create();
336+
debug_path_points_multimesh_rid = rs->multimesh_create();
337+
338+
rs->multimesh_set_mesh(debug_path_points_multimesh_rid, debug_path_point_mesh_rid);
329339
#endif // DEBUG_ENABLED
330340
}
331341

@@ -337,10 +347,12 @@ NavigationAgent2D::~NavigationAgent2D() {
337347
#ifdef DEBUG_ENABLED
338348
NavigationServer2D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed));
339349

340-
ERR_FAIL_NULL(RenderingServer::get_singleton());
341-
if (debug_path_instance.is_valid()) {
342-
RenderingServer::get_singleton()->free(debug_path_instance);
343-
}
350+
ERR_FAIL_NULL(RS::get_singleton());
351+
RenderingServer *rs = RS::get_singleton();
352+
rs->free(debug_path_instance);
353+
rs->free(debug_path_points_multimesh_rid);
354+
rs->free(debug_path_point_mesh_rid);
355+
rs->free(debug_path_segments_mesh_rid);
344356
#endif // DEBUG_ENABLED
345357
}
346358

@@ -996,12 +1008,9 @@ float NavigationAgent2D::get_debug_path_custom_point_size() const {
9961008

9971009
void NavigationAgent2D::set_debug_path_custom_line_width(float p_line_width) {
9981010
#ifdef DEBUG_ENABLED
999-
if (Math::is_equal_approx(debug_path_custom_line_width, p_line_width)) {
1000-
return;
1011+
if (p_line_width != -1.0) {
1012+
WARN_DEPRECATED_MSG(R"(NavigationAgent2D "debug_path_custom_line_width" property is deprecated and has no effect.)");
10011013
}
1002-
1003-
debug_path_custom_line_width = p_line_width;
1004-
debug_path_dirty = true;
10051014
#endif // DEBUG_ENABLED
10061015
}
10071016

@@ -1020,11 +1029,12 @@ void NavigationAgent2D::_update_debug_path() {
10201029
}
10211030
debug_path_dirty = false;
10221031

1023-
if (!debug_path_instance.is_valid()) {
1024-
debug_path_instance = RenderingServer::get_singleton()->canvas_item_create();
1025-
}
1032+
RenderingServer *rs = RS::get_singleton();
1033+
ERR_FAIL_NULL(rs);
10261034

1027-
RenderingServer::get_singleton()->canvas_item_clear(debug_path_instance);
1035+
rs->canvas_item_clear(debug_path_instance);
1036+
rs->mesh_clear(debug_path_segments_mesh_rid);
1037+
rs->multimesh_set_visible_instances(debug_path_points_multimesh_rid, 0);
10281038

10291039
if (!(debug_enabled && NavigationServer2D::get_singleton()->get_debug_navigation_enable_agent_paths())) {
10301040
return;
@@ -1034,13 +1044,14 @@ void NavigationAgent2D::_update_debug_path() {
10341044
return;
10351045
}
10361046

1037-
RenderingServer::get_singleton()->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas());
1038-
RenderingServer::get_singleton()->canvas_item_set_z_index(debug_path_instance, RS::CANVAS_ITEM_Z_MAX - 1);
1039-
RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
1047+
rs->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas());
1048+
rs->canvas_item_set_z_index(debug_path_instance, RS::CANVAS_ITEM_Z_MAX - 1);
1049+
rs->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
10401050

10411051
const Vector<Vector2> &navigation_path = navigation_result->get_path();
1052+
const int navigation_path_size = navigation_path.size();
10421053

1043-
if (navigation_path.size() <= 1) {
1054+
if (navigation_path_size <= 1) {
10441055
return;
10451056
}
10461057

@@ -1049,11 +1060,16 @@ void NavigationAgent2D::_update_debug_path() {
10491060
debug_path_color = debug_path_custom_color;
10501061
}
10511062

1052-
Vector<Color> debug_path_colors;
1053-
debug_path_colors.resize(navigation_path.size());
1054-
debug_path_colors.fill(debug_path_color);
1063+
rs->canvas_item_set_self_modulate(debug_path_instance, debug_path_color);
10551064

1056-
RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false);
1065+
{
1066+
Array mesh_arrays;
1067+
mesh_arrays.resize(RS::ARRAY_MAX);
1068+
mesh_arrays[RS::ARRAY_VERTEX] = navigation_path;
1069+
1070+
rs->mesh_add_surface_from_arrays(debug_path_segments_mesh_rid, RS::PRIMITIVE_LINE_STRIP, mesh_arrays, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
1071+
rs->canvas_item_add_mesh(debug_path_instance, debug_path_segments_mesh_rid, Transform2D());
1072+
}
10571073

10581074
if (debug_path_custom_point_size <= 0.0) {
10591075
return;
@@ -1067,10 +1083,70 @@ void NavigationAgent2D::_update_debug_path() {
10671083
half_point_size = debug_path_custom_point_size * 0.5;
10681084
}
10691085

1070-
for (int i = 0; i < navigation_path.size(); i++) {
1071-
const Vector2 &vert = navigation_path[i];
1072-
Rect2 path_point_rect = Rect2(vert.x - half_point_size, vert.y - half_point_size, point_size, point_size);
1073-
RenderingServer::get_singleton()->canvas_item_add_rect(debug_path_instance, path_point_rect, debug_path_color);
1086+
{
1087+
rs->mesh_clear(debug_path_point_mesh_rid);
1088+
1089+
Vector<Vector2> vertex_array;
1090+
vertex_array.resize(4);
1091+
Vector2 *vertex_array_ptrw = vertex_array.ptrw();
1092+
vertex_array_ptrw[0] = Vector2(-1.0, -1.0) * half_point_size;
1093+
vertex_array_ptrw[1] = Vector2(1.0, -1.0) * half_point_size;
1094+
vertex_array_ptrw[2] = Vector2(1.0, 1.0) * half_point_size;
1095+
vertex_array_ptrw[3] = Vector2(-1.0, 1.0) * half_point_size;
1096+
1097+
Vector<Vector2> uv_array;
1098+
uv_array.resize(4);
1099+
Vector2 *uv_array_ptrw = uv_array.ptrw();
1100+
uv_array_ptrw[0] = Vector2(0.0, 0.0);
1101+
uv_array_ptrw[1] = Vector2(1.0, 0.0);
1102+
uv_array_ptrw[2] = Vector2(1.0, 1.0);
1103+
uv_array_ptrw[3] = Vector2(0.0, 1.0);
1104+
1105+
Vector<int> index_array;
1106+
index_array.resize(6);
1107+
int *index_array_ptrw = index_array.ptrw();
1108+
index_array_ptrw[0] = 0;
1109+
index_array_ptrw[1] = 1;
1110+
index_array_ptrw[2] = 3;
1111+
index_array_ptrw[3] = 1;
1112+
index_array_ptrw[4] = 2;
1113+
index_array_ptrw[5] = 3;
1114+
1115+
Array mesh_arrays;
1116+
mesh_arrays.resize(RS::ARRAY_MAX);
1117+
mesh_arrays[RS::ARRAY_VERTEX] = vertex_array;
1118+
mesh_arrays[RS::ARRAY_TEX_UV] = uv_array;
1119+
mesh_arrays[RS::ARRAY_INDEX] = index_array;
1120+
1121+
rs->mesh_add_surface_from_arrays(debug_path_point_mesh_rid, RS::PRIMITIVE_TRIANGLES, mesh_arrays, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
10741122
}
1123+
1124+
if (rs->multimesh_get_instance_count(debug_path_points_multimesh_rid) != int(navigation_path_size)) {
1125+
rs->multimesh_allocate_data(debug_path_points_multimesh_rid, navigation_path_size, RS::MULTIMESH_TRANSFORM_2D);
1126+
}
1127+
1128+
Vector<float> multimesh_buffer;
1129+
multimesh_buffer.resize(8 * navigation_path_size);
1130+
float *multimesh_buffer_ptrw = multimesh_buffer.ptrw();
1131+
1132+
const Vector2 *point_ptr = navigation_path.ptr();
1133+
1134+
for (int i = 0; i < navigation_path_size; i++) {
1135+
const Vector2 &point = point_ptr[i];
1136+
1137+
multimesh_buffer_ptrw[i * 8 + 0] = 1.0;
1138+
multimesh_buffer_ptrw[i * 8 + 1] = 0.0;
1139+
multimesh_buffer_ptrw[i * 8 + 2] = 0;
1140+
multimesh_buffer_ptrw[i * 8 + 3] = point[0];
1141+
multimesh_buffer_ptrw[i * 8 + 4] = 0.0;
1142+
multimesh_buffer_ptrw[i * 8 + 5] = 1.0;
1143+
multimesh_buffer_ptrw[i * 8 + 6] = 0;
1144+
multimesh_buffer_ptrw[i * 8 + 7] = point[1];
1145+
}
1146+
1147+
rs->multimesh_set_buffer(debug_path_points_multimesh_rid, multimesh_buffer);
1148+
rs->multimesh_set_visible_instances(debug_path_points_multimesh_rid, navigation_path_size);
1149+
1150+
rs->canvas_item_add_multimesh(debug_path_instance, debug_path_points_multimesh_rid);
10751151
}
10761152
#endif // DEBUG_ENABLED

scene/2d/navigation/navigation_agent_2d.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ class NavigationAgent2D : public Node {
102102
#ifdef DEBUG_ENABLED
103103
// Debug properties internal only
104104
bool debug_path_dirty = true;
105+
RID debug_path_segments_mesh_rid;
106+
RID debug_path_point_mesh_rid;
107+
RID debug_path_points_multimesh_rid;
105108
RID debug_path_instance;
106109
#endif // DEBUG_ENABLED
107110

0 commit comments

Comments
 (0)