@@ -64,6 +64,9 @@ void TileMapLayer::_debug_update(bool p_force_cleanup) {
6464
6565 // Check if we should cleanup everything.
6666 bool forced_cleanup = p_force_cleanup || !enabled || tile_set.is_null () || !is_visible_in_tree ();
67+ if (forced_cleanup && _debug_was_cleaned_up) {
68+ return ;
69+ }
6770
6871 if (forced_cleanup) {
6972 for (KeyValue<Vector2i, Ref<DebugQuadrant>> &kv : debug_quadrant_map) {
@@ -206,6 +209,9 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
206209
207210 // Check if we should cleanup everything.
208211 bool forced_cleanup = p_force_cleanup || !enabled || tile_set.is_null () || !is_visible_in_tree ();
212+ if (forced_cleanup && _rendering_was_cleaned_up) {
213+ return ;
214+ }
209215
210216 // ----------- Layer level processing -----------
211217 if (!forced_cleanup) {
@@ -234,7 +240,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
234240 (!is_y_sort_enabled () && dirty.flags [DIRTY_FLAGS_LAYER_RENDERING_QUADRANT_SIZE]);
235241
236242 // Free all quadrants.
237- if (forced_cleanup || quadrant_shape_changed) {
243+ if (!_rendering_was_cleaned_up && ( forced_cleanup || quadrant_shape_changed) ) {
238244 for (const KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
239245 for (const RID &ci : kv.value ->canvas_items ) {
240246 if (ci.is_valid ()) {
@@ -398,15 +404,23 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
398404 int index = -(int64_t )0x80000000 ; // Always must be drawn below children.
399405
400406 // Sort the quadrants coords per local coordinates.
401- RBMap<Vector2, Ref<RenderingQuadrant>, RenderingQuadrant::CoordsWorldComparator> local_to_map;
407+ LocalVector<Pair<Vector2, Ref<RenderingQuadrant>>> sortable_quadrant_keys;
408+ sortable_quadrant_keys.reserve (rendering_quadrant_map.size ());
402409 for (KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
403- Ref<RenderingQuadrant> &rendering_quadrant = kv.value ;
404- local_to_map[tile_set-> map_to_local (rendering_quadrant-> quadrant_coords )] = rendering_quadrant ;
410+ Vector2 local_coords = tile_set-> map_to_local ( kv.value -> quadrant_coords ) ;
411+ sortable_quadrant_keys. push_back (Pair<Vector2, Ref<RenderingQuadrant>>(local_coords, kv. value )) ;
405412 }
413+ struct PairedQuadrantSorter {
414+ RenderingQuadrant::CoordsWorldComparator comparator;
415+ _ALWAYS_INLINE_ bool operator ()(const Pair<Vector2, Ref<RenderingQuadrant>> &p_a, const Pair<Vector2, Ref<RenderingQuadrant>> &p_b) const {
416+ return comparator (p_a.first , p_b.first );
417+ }
418+ };
419+ sortable_quadrant_keys.sort_custom <PairedQuadrantSorter>();
406420
407- // Sort the quadrants .
408- for (const KeyValue <Vector2, Ref<RenderingQuadrant>> &E : local_to_map ) {
409- for (const RID &ci : E.value ->canvas_items ) {
421+ // Set the draw indices .
422+ for (const Pair <Vector2, Ref<RenderingQuadrant>> &E : sortable_quadrant_keys ) {
423+ for (const RID &ci : E.second ->canvas_items ) {
410424 RS::get_singleton ()->canvas_item_set_draw_index (ci, index++);
411425 }
412426 }
@@ -429,14 +443,23 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
429443 }
430444 }
431445
446+ // -----------
447+ // Mark the rendering state as up to date.
448+ _rendering_was_cleaned_up = forced_cleanup;
449+
432450 // ----------- Occluders processing -----------
433- if (forced_cleanup || !occlusion_enabled) {
451+ bool cleanup_occlusion = forced_cleanup || !occlusion_enabled;
452+ if (cleanup_occlusion && _occlusion_was_cleaned_up) {
453+ return ;
454+ }
455+
456+ if (cleanup_occlusion) {
434457 // Clean everything.
435458 for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) {
436459 _rendering_occluders_clear_cell (kv.value );
437460 }
438461 } else {
439- if (_rendering_was_cleaned_up || dirty.flags [DIRTY_FLAGS_TILE_SET]) {
462+ if (_occlusion_was_cleaned_up || dirty.flags [DIRTY_FLAGS_TILE_SET]) {
440463 // Update all cells.
441464 for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) {
442465 _rendering_occluders_update_cell (kv.value );
@@ -451,8 +474,8 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
451474 }
452475
453476 // -----------
454- // Mark the rendering state as up to date.
455- _rendering_was_cleaned_up = forced_cleanup || !occlusion_enabled ;
477+ // Mark the occlusion state as up to date.
478+ _occlusion_was_cleaned_up = cleanup_occlusion ;
456479}
457480
458481void TileMapLayer::_rendering_notification (int p_what) {
@@ -721,6 +744,9 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) {
721744
722745 // Check if we should cleanup everything.
723746 bool forced_cleanup = p_force_cleanup || !enabled || !collision_enabled || !is_inside_tree () || tile_set.is_null ();
747+ if (forced_cleanup && _physics_was_cleaned_up) {
748+ return ;
749+ }
724750
725751 // ----------- Quadrants processing -----------
726752
@@ -732,7 +758,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) {
732758 bool quadrant_shape_changed = dirty.flags [DIRTY_FLAGS_TILE_SET] || dirty.flags [DIRTY_FLAGS_LAYER_PHYSICS_QUADRANT_SIZE];
733759
734760 // Free all quadrants.
735- if (forced_cleanup || quadrant_shape_changed) {
761+ if (!_physics_was_cleaned_up && ( forced_cleanup || quadrant_shape_changed) ) {
736762 for (const KeyValue<Vector2i, Ref<PhysicsQuadrant>> &kv : physics_quadrant_map) {
737763 // Clear bodies.
738764 for (KeyValue<PhysicsQuadrant::PhysicsBodyKey, PhysicsQuadrant::PhysicsBodyValue> &kvbody : kv.value ->bodies ) {
@@ -940,7 +966,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) {
940966
941967 // -----------
942968 // Mark the physics state as up to date.
943- _physics_was_cleaned_up = forced_cleanup || !occlusion_enabled ;
969+ _physics_was_cleaned_up = forced_cleanup;
944970}
945971
946972void TileMapLayer::_physics_quadrants_update_cell (CellData &r_cell_data, SelfList<PhysicsQuadrant>::List &r_dirty_physics_quadrant_list) {
@@ -1260,6 +1286,9 @@ void TileMapLayer::_navigation_update(bool p_force_cleanup) {
12601286
12611287 // Check if we should cleanup everything.
12621288 bool forced_cleanup = p_force_cleanup || !enabled || !navigation_enabled || !is_inside_tree () || tile_set.is_null ();
1289+ if (forced_cleanup && _navigation_was_cleaned_up) {
1290+ return ;
1291+ }
12631292
12641293 // ----------- Layer level processing -----------
12651294 // All this processing is kept for compatibility with the TileMap node.
@@ -1531,6 +1560,9 @@ void TileMapLayer::_navigation_draw_cell_debug(const RID &p_canvas_item, const V
15311560void TileMapLayer::_scenes_update (bool p_force_cleanup) {
15321561 // Check if we should cleanup everything.
15331562 bool forced_cleanup = p_force_cleanup || !enabled || !is_inside_tree () || tile_set.is_null ();
1563+ if (forced_cleanup && _scenes_was_cleaned_up) {
1564+ return ;
1565+ }
15341566
15351567 if (forced_cleanup) {
15361568 // Clean everything.
@@ -1686,7 +1718,7 @@ void TileMapLayer::_build_runtime_update_tile_data(bool p_force_cleanup) {
16861718 }
16871719
16881720 // -----------
1689- // Mark the navigation state as up to date.
1721+ // Mark the tile data state as up to date.
16901722 _runtime_update_tile_data_was_cleaned_up = forced_cleanup;
16911723}
16921724
0 commit comments