@@ -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
422436void 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
0 commit comments