Skip to content

Commit 183c634

Browse files
committed
Merge pull request godotengine#92372 from smix8/navregion2d_debug
Improve NavigationRegion2D debug performance
2 parents 47fa384 + 5f5fe73 commit 183c634

File tree

2 files changed

+160
-24
lines changed

2 files changed

+160
-24
lines changed

scene/2d/navigation_region_2d.cpp

Lines changed: 154 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,19 @@ void NavigationRegion2D::_notification(int p_what) {
162162
set_physics_process_internal(true);
163163
} break;
164164

165+
case NOTIFICATION_VISIBILITY_CHANGED: {
166+
#ifdef DEBUG_ENABLED
167+
if (debug_instance_rid.is_valid()) {
168+
RS::get_singleton()->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree());
169+
}
170+
#endif // DEBUG_ENABLED
171+
} break;
172+
165173
case NOTIFICATION_EXIT_TREE: {
166174
_region_exit_navigation_map();
175+
#ifdef DEBUG_ENABLED
176+
_free_debug();
177+
#endif // DEBUG_ENABLED
167178
} break;
168179

169180
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -189,6 +200,9 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_
189200
}
190201

191202
navigation_polygon = p_navigation_polygon;
203+
#ifdef DEBUG_ENABLED
204+
debug_mesh_dirty = true;
205+
#endif // DEBUG_ENABLED
192206
NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon);
193207

194208
if (navigation_polygon.is_valid()) {
@@ -420,12 +434,42 @@ void NavigationRegion2D::_region_update_transform() {
420434

421435
#ifdef DEBUG_ENABLED
422436
void NavigationRegion2D::_update_debug_mesh() {
423-
Vector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices();
424-
if (navigation_polygon_vertices.size() < 3) {
437+
if (!is_inside_tree()) {
438+
_free_debug();
425439
return;
426440
}
427441

428442
const NavigationServer2D *ns2d = NavigationServer2D::get_singleton();
443+
RenderingServer *rs = RenderingServer::get_singleton();
444+
445+
if (!debug_instance_rid.is_valid()) {
446+
debug_instance_rid = rs->canvas_item_create();
447+
}
448+
if (!debug_mesh_rid.is_valid()) {
449+
debug_mesh_rid = rs->mesh_create();
450+
}
451+
452+
const Transform2D region_gt = get_global_transform();
453+
454+
rs->canvas_item_set_parent(debug_instance_rid, get_world_2d()->get_canvas());
455+
rs->canvas_item_set_transform(debug_instance_rid, region_gt);
456+
457+
if (!debug_mesh_dirty) {
458+
return;
459+
}
460+
461+
rs->mesh_clear(debug_mesh_rid);
462+
debug_mesh_dirty = false;
463+
464+
const Vector<Vector2> &vertices = navigation_polygon->get_vertices();
465+
if (vertices.size() < 3) {
466+
return;
467+
}
468+
469+
int polygon_count = navigation_polygon->get_polygon_count();
470+
if (polygon_count == 0) {
471+
return;
472+
}
429473

430474
bool enabled_geometry_face_random_color = ns2d->get_debug_navigation_enable_geometry_face_random_color();
431475
bool enabled_edge_lines = ns2d->get_debug_navigation_enable_edge_lines();
@@ -438,39 +482,109 @@ void NavigationRegion2D::_update_debug_mesh() {
438482
debug_edge_color = ns2d->get_debug_navigation_geometry_edge_disabled_color();
439483
}
440484

485+
int vertex_count = 0;
486+
int line_count = 0;
487+
488+
for (int i = 0; i < polygon_count; i++) {
489+
const Vector<int> &polygon = navigation_polygon->get_polygon(i);
490+
int polygon_size = polygon.size();
491+
if (polygon_size < 3) {
492+
continue;
493+
}
494+
line_count += polygon_size * 2;
495+
vertex_count += (polygon_size - 2) * 3;
496+
}
497+
498+
Vector<Vector2> face_vertex_array;
499+
face_vertex_array.resize(vertex_count);
500+
501+
Vector<Color> face_color_array;
502+
if (enabled_geometry_face_random_color) {
503+
face_color_array.resize(vertex_count);
504+
}
505+
506+
Vector<Vector2> line_vertex_array;
507+
if (enabled_edge_lines) {
508+
line_vertex_array.resize(line_count);
509+
}
510+
441511
RandomPCG rand;
512+
Color polygon_color = debug_face_color;
442513

443-
for (int i = 0; i < navigation_polygon->get_polygon_count(); i++) {
444-
// An array of vertices for this polygon.
445-
Vector<int> polygon = navigation_polygon->get_polygon(i);
446-
Vector<Vector2> debug_polygon_vertices;
447-
debug_polygon_vertices.resize(polygon.size());
448-
for (int j = 0; j < polygon.size(); j++) {
449-
ERR_FAIL_INDEX(polygon[j], navigation_polygon_vertices.size());
450-
debug_polygon_vertices.write[j] = navigation_polygon_vertices[polygon[j]];
514+
int face_vertex_index = 0;
515+
int line_vertex_index = 0;
516+
517+
Vector2 *face_vertex_array_ptrw = face_vertex_array.ptrw();
518+
Color *face_color_array_ptrw = face_color_array.ptrw();
519+
Vector2 *line_vertex_array_ptrw = line_vertex_array.ptrw();
520+
521+
for (int polygon_index = 0; polygon_index < polygon_count; polygon_index++) {
522+
const Vector<int> &polygon_indices = navigation_polygon->get_polygon(polygon_index);
523+
int polygon_indices_size = polygon_indices.size();
524+
if (polygon_indices_size < 3) {
525+
continue;
451526
}
452527

453-
// Generate the polygon color, slightly randomly modified from the settings one.
454-
Color random_variation_color = debug_face_color;
455528
if (enabled_geometry_face_random_color) {
456-
random_variation_color.set_hsv(
457-
debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1,
458-
debug_face_color.get_s(),
459-
debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2);
529+
// Generate the polygon color, slightly randomly modified from the settings one.
530+
polygon_color.set_hsv(debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1, debug_face_color.get_s(), debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2);
531+
polygon_color.a = debug_face_color.a;
460532
}
461-
random_variation_color.a = debug_face_color.a;
462533

463-
Vector<Color> debug_face_colors;
464-
debug_face_colors.push_back(random_variation_color);
465-
RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), debug_polygon_vertices, debug_face_colors);
534+
for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size - 2; polygon_indices_index++) {
535+
face_vertex_array_ptrw[face_vertex_index] = vertices[polygon_indices[0]];
536+
face_vertex_array_ptrw[face_vertex_index + 1] = vertices[polygon_indices[polygon_indices_index + 1]];
537+
face_vertex_array_ptrw[face_vertex_index + 2] = vertices[polygon_indices[polygon_indices_index + 2]];
538+
if (enabled_geometry_face_random_color) {
539+
face_color_array_ptrw[face_vertex_index] = polygon_color;
540+
face_color_array_ptrw[face_vertex_index + 1] = polygon_color;
541+
face_color_array_ptrw[face_vertex_index + 2] = polygon_color;
542+
}
543+
face_vertex_index += 3;
544+
}
466545

467546
if (enabled_edge_lines) {
468-
Vector<Color> debug_edge_colors;
469-
debug_edge_colors.push_back(debug_edge_color);
470-
debug_polygon_vertices.push_back(debug_polygon_vertices[0]); // Add first again for closing polyline.
471-
RS::get_singleton()->canvas_item_add_polyline(get_canvas_item(), debug_polygon_vertices, debug_edge_colors);
547+
for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size; polygon_indices_index++) {
548+
line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index]];
549+
line_vertex_index += 1;
550+
if (polygon_indices_index + 1 == polygon_indices_size) {
551+
line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[0]];
552+
line_vertex_index += 1;
553+
} else {
554+
line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index + 1]];
555+
line_vertex_index += 1;
556+
}
557+
}
472558
}
473559
}
560+
561+
if (!enabled_geometry_face_random_color) {
562+
face_color_array.resize(face_vertex_array.size());
563+
face_color_array.fill(debug_face_color);
564+
}
565+
566+
Array face_mesh_array;
567+
face_mesh_array.resize(Mesh::ARRAY_MAX);
568+
face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array;
569+
face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array;
570+
571+
rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_TRIANGLES, face_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
572+
573+
if (enabled_edge_lines) {
574+
Vector<Color> line_color_array;
575+
line_color_array.resize(line_vertex_array.size());
576+
line_color_array.fill(debug_edge_color);
577+
578+
Array line_mesh_array;
579+
line_mesh_array.resize(Mesh::ARRAY_MAX);
580+
line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array;
581+
line_mesh_array[Mesh::ARRAY_COLOR] = line_color_array;
582+
583+
rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_LINES, line_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
584+
}
585+
586+
rs->canvas_item_add_mesh(debug_instance_rid, debug_mesh_rid, Transform2D());
587+
rs->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree());
474588
}
475589
#endif // DEBUG_ENABLED
476590

@@ -512,3 +626,19 @@ void NavigationRegion2D::_update_debug_baking_rect() {
512626
}
513627
}
514628
#endif // DEBUG_ENABLED
629+
630+
#ifdef DEBUG_ENABLED
631+
void NavigationRegion2D::_free_debug() {
632+
RenderingServer *rs = RenderingServer::get_singleton();
633+
ERR_FAIL_NULL(rs);
634+
if (debug_instance_rid.is_valid()) {
635+
rs->canvas_item_clear(debug_instance_rid);
636+
rs->free(debug_instance_rid);
637+
debug_instance_rid = RID();
638+
}
639+
if (debug_mesh_rid.is_valid()) {
640+
rs->free(debug_mesh_rid);
641+
debug_mesh_rid = RID();
642+
}
643+
}
644+
#endif // DEBUG_ENABLED

scene/2d/navigation_region_2d.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ class NavigationRegion2D : public Node2D {
5252

5353
#ifdef DEBUG_ENABLED
5454
private:
55+
RID debug_mesh_rid;
56+
RID debug_instance_rid;
57+
58+
bool debug_mesh_dirty = true;
59+
60+
void _free_debug();
5561
void _update_debug_mesh();
5662
void _update_debug_edge_connections_mesh();
5763
void _update_debug_baking_rect();

0 commit comments

Comments
 (0)