@@ -362,6 +362,134 @@ bool GridMap::get_center_z() const {
362362 return center_z;
363363}
364364
365+ void GridMap::set_debug_octant_color (const Color &p_color) {
366+ #ifdef DEBUG_ENABLED
367+ if (debug_octant_color == p_color) {
368+ return ;
369+ }
370+
371+ debug_octant_color = p_color;
372+
373+ if (debug_octant_line_material.is_valid ()) {
374+ debug_octant_line_material->set_albedo (debug_octant_color);
375+ }
376+ #endif
377+ }
378+
379+ Color GridMap::get_debug_octant_color () const {
380+ return debug_octant_color;
381+ }
382+
383+ #ifdef DEBUG_ENABLED
384+ void GridMap::_debug_update () {
385+ if (debug_dirty || !is_inside_tree ()) {
386+ return ;
387+ }
388+ debug_dirty = true ;
389+
390+ callable_mp (this , &GridMap::_debug_update_octants).call_deferred ();
391+ }
392+
393+ void GridMap::_debug_update_octants () {
394+ debug_dirty = false ;
395+
396+ if (!debug_show_octants) {
397+ _debug_clear_octants ();
398+ return ;
399+ }
400+
401+ if (debug_octant_line_material.is_null ()) {
402+ debug_octant_line_material.instantiate ();
403+ debug_octant_line_material->set_shading_mode (StandardMaterial3D::SHADING_MODE_UNSHADED );
404+ debug_octant_line_material->set_transparency (StandardMaterial3D::TRANSPARENCY_ALPHA );
405+ debug_octant_line_material->set_flag (StandardMaterial3D::FLAG_DISABLE_FOG , true );
406+ debug_octant_line_material->set_albedo (debug_octant_color);
407+ }
408+
409+ Array debug_mesh_arrays = _build_octant_line_mesh_arrays ();
410+
411+ if (debug_octant_line_mesh_rid.is_null ()) {
412+ debug_octant_line_mesh_rid = RS::get_singleton ()->mesh_create ();
413+ }
414+ RS::get_singleton ()->mesh_clear (debug_octant_line_mesh_rid);
415+ RS::get_singleton ()->mesh_add_surface_from_arrays (debug_octant_line_mesh_rid, RSE ::PRIMITIVE_LINES , debug_mesh_arrays);
416+ RS::get_singleton ()->mesh_surface_set_material (debug_octant_line_mesh_rid, 0 , debug_octant_line_material->get_rid ());
417+
418+ RID debug_scenario = get_world_3d ()->get_scenario ();
419+ const Transform3D &gridmap_xform = get_global_transform ();
420+
421+ for (const KeyValue<OctantKey, Octant *> &ele : octant_map) {
422+ OctantKey octant_key = ele.key ;
423+ HashMap<OctantKey, OctantDebug *, OctantKey>::Iterator E = debug_octant_map.find (octant_key);
424+ if (!E) {
425+ OctantDebug *octant_debug = memnew (OctantDebug);
426+
427+ RID debug_octant_line_instance_rid = RS::get_singleton ()->instance_create ();
428+
429+ RS::get_singleton ()->instance_set_base (debug_octant_line_instance_rid, debug_octant_line_mesh_rid);
430+ RS::get_singleton ()->instance_set_scenario (debug_octant_line_instance_rid, debug_scenario);
431+
432+ octant_debug->debug_line_instance_rid = debug_octant_line_instance_rid;
433+
434+ E = debug_octant_map.insert (octant_key, octant_debug);
435+ }
436+
437+ OctantDebug &octant_debug = *E->value ;
438+ const Transform3D octant_transform = gridmap_xform * (Transform3D (Basis (), Vector3 (octant_key.x , octant_key.y , octant_key.z ) * octant_size * cell_size));
439+
440+ RS::get_singleton ()->instance_set_scenario (octant_debug.debug_line_instance_rid , debug_scenario);
441+ RS::get_singleton ()->instance_set_transform (octant_debug.debug_line_instance_rid , octant_transform);
442+ RS::get_singleton ()->instance_set_visible (octant_debug.debug_line_instance_rid , is_visible_in_tree ());
443+ }
444+ }
445+
446+ void GridMap::_debug_clear_octants () {
447+ for (const KeyValue<OctantKey, Octant *> &ele : octant_map) {
448+ OctantKey octant_key = ele.key ;
449+ HashMap<OctantKey, OctantDebug *, OctantKey>::Iterator E = debug_octant_map.find (octant_key);
450+ if (E) {
451+ OctantDebug &octant_debug = *E->value ;
452+
453+ if (octant_debug.debug_line_mesh_rid .is_valid ()) {
454+ RS::get_singleton ()->free_rid (octant_debug.debug_line_mesh_rid );
455+ octant_debug.debug_line_mesh_rid = RID ();
456+ }
457+ if (octant_debug.debug_line_instance_rid .is_valid ()) {
458+ RS::get_singleton ()->free_rid (octant_debug.debug_line_instance_rid );
459+ octant_debug.debug_line_instance_rid = RID ();
460+ }
461+
462+ memdelete (&octant_debug);
463+ }
464+ }
465+
466+ debug_octant_map.clear ();
467+ }
468+
469+ Array GridMap::_build_octant_line_mesh_arrays () const {
470+ AABB aabb;
471+ aabb.size = octant_size * cell_size;
472+
473+ Vector<Vector3> vertex_array;
474+ vertex_array.resize (24 );
475+ Vector3 *vertex_array_ptrw = vertex_array.ptrw ();
476+ int vertex_index = 0 ;
477+
478+ for (int i = 0 ; i < 12 ; i++) {
479+ Vector3 a, b;
480+ aabb.get_edge (i, a, b);
481+ vertex_array_ptrw[vertex_index++] = a;
482+ vertex_array_ptrw[vertex_index++] = b;
483+ }
484+
485+ Array mesh_arrays;
486+ mesh_arrays.resize (Mesh::ARRAY_MAX );
487+ mesh_arrays[Mesh::ARRAY_VERTEX ] = vertex_array;
488+
489+ return mesh_arrays;
490+ }
491+ #endif // DEBUG_ENABLED
492+
365493void GridMap::set_cell_item (const Vector3i &p_position, int p_item, int p_rot) {
366494 if (baked_meshes.size () && !recreating_octants) {
367495 // if you set a cell item, baked meshes go good bye
@@ -992,6 +1120,8 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) {
9921120 }
9931121 }
9941122#endif // DEBUG_ENABLED
1123+
1124+ _debug_clear_octants ();
9951125}
9961126
9971127void GridMap::_octant_clean_up (const OctantKey &p_key) {
@@ -1049,6 +1179,8 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
10491179 RS::get_singleton ()->free_rid (g.multimesh_instances [i].multimesh );
10501180 }
10511181 g.multimesh_instances .clear ();
1182+
1183+ _debug_clear_octants ();
10521184}
10531185
10541186void GridMap::_notification (int p_what) {
@@ -1072,7 +1204,13 @@ void GridMap::_notification(int p_what) {
10721204 _update_navigation_debug_edge_connections ();
10731205 }
10741206#endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED)
1207+
10751208 _update_visibility ();
1209+ _debug_update ();
1210+ } break ;
1211+
1212+ case NOTIFICATION_EXIT_TREE : {
1213+ _debug_clear_octants ();
10761214 } break ;
10771215
10781216 case NOTIFICATION_TRANSFORM_CHANGED : {
@@ -1090,16 +1228,24 @@ void GridMap::_notification(int p_what) {
10901228 for (int i = 0 ; i < baked_meshes.size (); i++) {
10911229 RS::get_singleton ()->instance_set_transform (baked_meshes[i].instance , get_global_transform ());
10921230 }
1231+
1232+ #ifdef DEBUG_ENABLED
1233+ for (const KeyValue<OctantKey, OctantDebug *> &E : debug_octant_map) {
1234+ OctantKey octant_key = E.key ;
1235+ OctantDebug &octant_debug = *E.value ;
1236+ if (octant_debug.debug_line_instance_rid .is_valid ()) {
1237+ const Transform3D octant_transform = new_xform * (Transform3D (Basis (), Vector3 (octant_key.x , octant_key.y , octant_key.z ) * octant_size * cell_size));
1238+ RS::get_singleton ()->instance_set_transform (octant_debug.debug_line_instance_rid , octant_transform);
1239+ }
1240+ }
1241+ #endif
10931242 } break ;
10941243
10951244 case NOTIFICATION_EXIT_WORLD : {
10961245 for (const KeyValue<OctantKey, Octant *> &E : octant_map) {
10971246 _octant_exit_world (E.key );
10981247 }
10991248
1100- // _queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS);
1101- // _update_octants_callback();
1102- // _update_area_instances();
11031249 for (int i = 0 ; i < baked_meshes.size (); i++) {
11041250 RS::get_singleton ()->instance_set_scenario (baked_meshes[i].instance , RID ());
11051251 }
@@ -1127,6 +1273,15 @@ void GridMap::_update_visibility() {
11271273 for (int i = 0 ; i < baked_meshes.size (); i++) {
11281274 RS::get_singleton ()->instance_set_visible (baked_meshes[i].instance , is_visible_in_tree ());
11291275 }
1276+
1277+ #ifdef DEBUG_ENABLED
1278+ for (const KeyValue<OctantKey, OctantDebug *> &E : debug_octant_map) {
1279+ OctantDebug &octant_debug = *E.value ;
1280+ if (octant_debug.debug_line_instance_rid .is_valid ()) {
1281+ RS::get_singleton ()->instance_set_visible (octant_debug.debug_line_instance_rid , is_visible_in_tree ());
1282+ }
1283+ }
1284+ #endif
11301285}
11311286
11321287void GridMap::_queue_octants_dirty () {
@@ -1140,12 +1295,15 @@ void GridMap::_queue_octants_dirty() {
11401295
11411296void GridMap::_recreate_octant_data () {
11421297 recreating_octants = true ;
1298+
11431299 HashMap<IndexKey, Cell, IndexKey> cell_copy (cell_map);
11441300 _clear_internal ();
11451301 for (const KeyValue<IndexKey, Cell> &E : cell_copy) {
11461302 set_cell_item (Vector3i (E.key ), E.value .item , E.value .rot );
11471303 }
1304+
11481305 recreating_octants = false ;
1306+ _debug_update ();
11491307}
11501308
11511309void GridMap::_clear_internal () {
@@ -1160,6 +1318,8 @@ void GridMap::_clear_internal() {
11601318
11611319 octant_map.clear ();
11621320 cell_map.clear ();
1321+ _debug_clear_octants ();
1322+ _debug_update ();
11631323}
11641324
11651325void GridMap::clear () {
@@ -1194,6 +1354,8 @@ void GridMap::_update_octants_callback() {
11941354
11951355 _update_visibility ();
11961356 awaiting_update = false ;
1357+
1358+ _debug_update_octants ();
11971359}
11981360
11991361void GridMap::_bind_methods () {
@@ -1284,6 +1446,12 @@ void GridMap::_bind_methods() {
12841446 ClassDB::bind_method (D_METHOD (" clear_baked_meshes" ), &GridMap::clear_baked_meshes);
12851447 ClassDB::bind_method (D_METHOD (" make_baked_meshes" , " gen_lightmap_uv" , " lightmap_uv_texel_size" ), &GridMap::make_baked_meshes, DEFVAL (false ), DEFVAL (0.1 ));
12861448
1449+ ClassDB::bind_method (D_METHOD (" set_debug_show_octants" , " enable" ), &GridMap::set_debug_show_octants);
1450+ ClassDB::bind_method (D_METHOD (" get_debug_show_octants" ), &GridMap::get_debug_show_octants);
1451+
1452+ ClassDB::bind_method (D_METHOD (" set_debug_octant_color" , " color" ), &GridMap::set_debug_octant_color);
1453+ ClassDB::bind_method (D_METHOD (" get_debug_octant_color" ), &GridMap::get_debug_octant_color);
1454+
12871455 ADD_PROPERTY (PropertyInfo (Variant::OBJECT , " mesh_library" , PROPERTY_HINT_RESOURCE_TYPE , MeshLibrary::get_class_static ()), " set_mesh_library" , " get_mesh_library" );
12881456#ifndef PHYSICS_3D_DISABLED
12891457 ADD_PROPERTY (PropertyInfo (Variant::OBJECT , " physics_material" , PROPERTY_HINT_RESOURCE_TYPE , PhysicsMaterial::get_class_static ()), " set_physics_material" , " get_physics_material" );
@@ -1304,6 +1472,9 @@ void GridMap::_bind_methods() {
13041472#endif // PHYSICS_3D_DISABLED
13051473 ADD_GROUP (" Navigation" , " " );
13061474 ADD_PROPERTY (PropertyInfo (Variant::BOOL , " bake_navigation" ), " set_bake_navigation" , " is_baking_navigation" );
1475+ ADD_GROUP (" Debug" , " " );
1476+ ADD_PROPERTY (PropertyInfo (Variant::BOOL , " debug_show_octants" ), " set_debug_show_octants" , " get_debug_show_octants" );
1477+ ADD_PROPERTY (PropertyInfo (Variant::COLOR , " debug_octant_color" ), " set_debug_octant_color" , " get_debug_octant_color" );
13071478
13081479 BIND_CONSTANT (INVALID_CELL_ITEM );
13091480
@@ -1689,6 +1860,21 @@ RID GridMap::get_bake_mesh_instance(int p_idx) {
16891860 return baked_meshes[p_idx].instance ;
16901861}
16911862
1863+ void GridMap::set_debug_show_octants (bool p_enable) {
1864+ #ifdef DEBUG_ENABLED
1865+ if (debug_show_octants == p_enable) {
1866+ return ;
1867+ }
1868+
1869+ debug_show_octants = p_enable;
1870+ _debug_update ();
1871+ #endif
1872+ }
1873+
1874+ bool GridMap::get_debug_show_octants () const {
1875+ return debug_show_octants;
1876+ }
1877+
16921878GridMap::GridMap () {
16931879 set_notify_transform (true );
16941880#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED)
@@ -1857,10 +2043,16 @@ void GridMap::_navigation_map_changed(RID p_map) {
18572043
18582044GridMap::~GridMap () {
18592045 clear ();
1860- #if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED)
2046+
2047+ #ifdef DEBUG_ENABLED
2048+ _debug_clear_octants ();
2049+
2050+ #ifndef NAVIGATION_3D_DISABLED
18612051 NavigationServer3D::get_singleton ()->disconnect (" map_changed" , callable_mp (this , &GridMap::_navigation_map_changed));
18622052 NavigationServer3D::get_singleton ()->disconnect (" navigation_debug_changed" , callable_mp (this , &GridMap::_update_navigation_debug_edge_connections));
1863- #endif // defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED)
2053+ #endif // NAVIGATION_3D_DISABLED
2054+
2055+ #endif // DEBUG_ENABLED
18642056}
18652057
18662058#if defined(DEBUG_ENABLED) && !defined(NAVIGATION_3D_DISABLED)
0 commit comments