Skip to content

Commit f08290e

Browse files
committed
Improve NavigationAgent2D debug performance
Improves NavigationAgent2D debug performance by using static mesh and multimesh.
1 parent 42c7f14 commit f08290e

File tree

3 files changed

+146
-28
lines changed

3 files changed

+146
-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="Deprecated and has no effect.">
162+
Deprecated.
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: 141 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,55 @@ 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+
337+
{
338+
debug_path_point_mesh_rid = rs->mesh_create();
339+
340+
Vector<Vector2> vertex_array;
341+
vertex_array.resize(4);
342+
Vector2 *vertex_array_ptrw = vertex_array.ptrw();
343+
vertex_array_ptrw[0] = Vector2(-1.0, -1.0);
344+
vertex_array_ptrw[1] = Vector2(1.0, -1.0);
345+
vertex_array_ptrw[2] = Vector2(1.0, 1.0);
346+
vertex_array_ptrw[3] = Vector2(-1.0, 1.0);
347+
348+
Vector<Vector2> uv_array;
349+
uv_array.resize(4);
350+
Vector2 *uv_array_ptrw = uv_array.ptrw();
351+
uv_array_ptrw[0] = Vector2(0.0, 0.0);
352+
uv_array_ptrw[1] = Vector2(1.0, 0.0);
353+
uv_array_ptrw[2] = Vector2(1.0, 1.0);
354+
uv_array_ptrw[3] = Vector2(0.0, 1.0);
355+
356+
Vector<int> index_array;
357+
index_array.resize(6);
358+
int *index_array_ptrw = index_array.ptrw();
359+
index_array_ptrw[0] = 0;
360+
index_array_ptrw[1] = 1;
361+
index_array_ptrw[2] = 3;
362+
index_array_ptrw[3] = 1;
363+
index_array_ptrw[4] = 2;
364+
index_array_ptrw[5] = 3;
365+
366+
Array mesh_arrays;
367+
mesh_arrays.resize(RS::ARRAY_MAX);
368+
mesh_arrays[RS::ARRAY_VERTEX] = vertex_array;
369+
mesh_arrays[RS::ARRAY_TEX_UV] = uv_array;
370+
mesh_arrays[RS::ARRAY_INDEX] = index_array;
371+
372+
rs->mesh_add_surface_from_arrays(debug_path_point_mesh_rid, RS::PRIMITIVE_TRIANGLES, mesh_arrays, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
373+
374+
debug_path_points_multimesh_rid = rs->multimesh_create();
375+
376+
rs->multimesh_set_mesh(debug_path_points_multimesh_rid, debug_path_point_mesh_rid);
377+
}
329378
#endif // DEBUG_ENABLED
330379
}
331380

@@ -337,10 +386,12 @@ NavigationAgent2D::~NavigationAgent2D() {
337386
#ifdef DEBUG_ENABLED
338387
NavigationServer2D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed));
339388

340-
ERR_FAIL_NULL(RenderingServer::get_singleton());
341-
if (debug_path_instance.is_valid()) {
342-
RenderingServer::get_singleton()->free(debug_path_instance);
343-
}
389+
ERR_FAIL_NULL(RS::get_singleton());
390+
RenderingServer *rs = RS::get_singleton();
391+
rs->free(debug_path_instance);
392+
rs->free(debug_path_points_multimesh_rid);
393+
rs->free(debug_path_point_mesh_rid);
394+
rs->free(debug_path_segments_mesh_rid);
344395
#endif // DEBUG_ENABLED
345396
}
346397

@@ -997,12 +1048,9 @@ float NavigationAgent2D::get_debug_path_custom_point_size() const {
9971048

9981049
void NavigationAgent2D::set_debug_path_custom_line_width(float p_line_width) {
9991050
#ifdef DEBUG_ENABLED
1000-
if (Math::is_equal_approx(debug_path_custom_line_width, p_line_width)) {
1001-
return;
1051+
if (p_line_width != -1.0) {
1052+
WARN_DEPRECATED_MSG(R"(NavigationAgent2D "debug_path_custom_line_width" property is deprecated and has no effect.)");
10021053
}
1003-
1004-
debug_path_custom_line_width = p_line_width;
1005-
debug_path_dirty = true;
10061054
#endif // DEBUG_ENABLED
10071055
}
10081056

@@ -1021,11 +1069,12 @@ void NavigationAgent2D::_update_debug_path() {
10211069
}
10221070
debug_path_dirty = false;
10231071

1024-
if (!debug_path_instance.is_valid()) {
1025-
debug_path_instance = RenderingServer::get_singleton()->canvas_item_create();
1026-
}
1072+
RenderingServer *rs = RS::get_singleton();
1073+
ERR_FAIL_NULL(rs);
10271074

1028-
RenderingServer::get_singleton()->canvas_item_clear(debug_path_instance);
1075+
rs->canvas_item_clear(debug_path_instance);
1076+
rs->mesh_clear(debug_path_segments_mesh_rid);
1077+
rs->multimesh_set_visible_instances(debug_path_points_multimesh_rid, 0);
10291078

10301079
if (!(debug_enabled && NavigationServer2D::get_singleton()->get_debug_navigation_enable_agent_paths())) {
10311080
return;
@@ -1035,13 +1084,14 @@ void NavigationAgent2D::_update_debug_path() {
10351084
return;
10361085
}
10371086

1038-
RenderingServer::get_singleton()->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas());
1039-
RenderingServer::get_singleton()->canvas_item_set_z_index(debug_path_instance, RS::CANVAS_ITEM_Z_MAX - 1);
1040-
RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
1087+
rs->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas());
1088+
rs->canvas_item_set_z_index(debug_path_instance, RS::CANVAS_ITEM_Z_MAX - 1);
1089+
rs->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
10411090

10421091
const Vector<Vector2> &navigation_path = navigation_result->get_path();
1092+
const int navigation_path_size = navigation_path.size();
10431093

1044-
if (navigation_path.size() <= 1) {
1094+
if (navigation_path_size <= 1) {
10451095
return;
10461096
}
10471097

@@ -1050,11 +1100,16 @@ void NavigationAgent2D::_update_debug_path() {
10501100
debug_path_color = debug_path_custom_color;
10511101
}
10521102

1053-
Vector<Color> debug_path_colors;
1054-
debug_path_colors.resize(navigation_path.size());
1055-
debug_path_colors.fill(debug_path_color);
1103+
rs->canvas_item_set_self_modulate(debug_path_instance, debug_path_color);
10561104

1057-
RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false);
1105+
{
1106+
Array mesh_arrays;
1107+
mesh_arrays.resize(RS::ARRAY_MAX);
1108+
mesh_arrays[RS::ARRAY_VERTEX] = navigation_path;
1109+
1110+
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);
1111+
rs->canvas_item_add_mesh(debug_path_instance, debug_path_segments_mesh_rid, Transform2D());
1112+
}
10581113

10591114
if (debug_path_custom_point_size <= 0.0) {
10601115
return;
@@ -1068,10 +1123,70 @@ void NavigationAgent2D::_update_debug_path() {
10681123
half_point_size = debug_path_custom_point_size * 0.5;
10691124
}
10701125

1071-
for (int i = 0; i < navigation_path.size(); i++) {
1072-
const Vector2 &vert = navigation_path[i];
1073-
Rect2 path_point_rect = Rect2(vert.x - half_point_size, vert.y - half_point_size, point_size, point_size);
1074-
RenderingServer::get_singleton()->canvas_item_add_rect(debug_path_instance, path_point_rect, debug_path_color);
1126+
{
1127+
rs->mesh_clear(debug_path_point_mesh_rid);
1128+
1129+
Vector<Vector2> vertex_array;
1130+
vertex_array.resize(4);
1131+
Vector2 *vertex_array_ptrw = vertex_array.ptrw();
1132+
vertex_array_ptrw[0] = Vector2(-1.0, -1.0) * half_point_size;
1133+
vertex_array_ptrw[1] = Vector2(1.0, -1.0) * half_point_size;
1134+
vertex_array_ptrw[2] = Vector2(1.0, 1.0) * half_point_size;
1135+
vertex_array_ptrw[3] = Vector2(-1.0, 1.0) * half_point_size;
1136+
1137+
Vector<Vector2> uv_array;
1138+
uv_array.resize(4);
1139+
Vector2 *uv_array_ptrw = uv_array.ptrw();
1140+
uv_array_ptrw[0] = Vector2(0.0, 0.0);
1141+
uv_array_ptrw[1] = Vector2(1.0, 0.0);
1142+
uv_array_ptrw[2] = Vector2(1.0, 1.0);
1143+
uv_array_ptrw[3] = Vector2(0.0, 1.0);
1144+
1145+
Vector<int> index_array;
1146+
index_array.resize(6);
1147+
int *index_array_ptrw = index_array.ptrw();
1148+
index_array_ptrw[0] = 0;
1149+
index_array_ptrw[1] = 1;
1150+
index_array_ptrw[2] = 3;
1151+
index_array_ptrw[3] = 1;
1152+
index_array_ptrw[4] = 2;
1153+
index_array_ptrw[5] = 3;
1154+
1155+
Array mesh_arrays;
1156+
mesh_arrays.resize(RS::ARRAY_MAX);
1157+
mesh_arrays[RS::ARRAY_VERTEX] = vertex_array;
1158+
mesh_arrays[RS::ARRAY_TEX_UV] = uv_array;
1159+
mesh_arrays[RS::ARRAY_INDEX] = index_array;
1160+
1161+
rs->mesh_add_surface_from_arrays(debug_path_point_mesh_rid, RS::PRIMITIVE_TRIANGLES, mesh_arrays, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
10751162
}
1163+
1164+
if (rs->multimesh_get_instance_count(debug_path_points_multimesh_rid) != int(navigation_path_size)) {
1165+
rs->multimesh_allocate_data(debug_path_points_multimesh_rid, navigation_path_size, RS::MULTIMESH_TRANSFORM_2D);
1166+
}
1167+
1168+
Vector<float> multimesh_buffer;
1169+
multimesh_buffer.resize(8 * navigation_path_size);
1170+
float *multimesh_buffer_ptrw = multimesh_buffer.ptrw();
1171+
1172+
const Vector2 *point_ptr = navigation_path.ptr();
1173+
1174+
for (int i = 0; i < navigation_path_size; i++) {
1175+
const Vector2 &point = point_ptr[i];
1176+
1177+
multimesh_buffer_ptrw[i * 8 + 0] = 1.0;
1178+
multimesh_buffer_ptrw[i * 8 + 1] = 0.0;
1179+
multimesh_buffer_ptrw[i * 8 + 2] = 0;
1180+
multimesh_buffer_ptrw[i * 8 + 3] = point[0];
1181+
multimesh_buffer_ptrw[i * 8 + 4] = 0.0;
1182+
multimesh_buffer_ptrw[i * 8 + 5] = 1.0;
1183+
multimesh_buffer_ptrw[i * 8 + 6] = 0;
1184+
multimesh_buffer_ptrw[i * 8 + 7] = point[1];
1185+
}
1186+
1187+
rs->multimesh_set_buffer(debug_path_points_multimesh_rid, multimesh_buffer);
1188+
rs->multimesh_set_visible_instances(debug_path_points_multimesh_rid, navigation_path_size);
1189+
1190+
rs->canvas_item_add_multimesh(debug_path_instance, debug_path_points_multimesh_rid);
10761191
}
10771192
#endif // DEBUG_ENABLED

scene/2d/navigation/navigation_agent_2d.h

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

0 commit comments

Comments
 (0)