@@ -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) {
@@ -203,6 +206,9 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
203206
204207 // Check if we should cleanup everything.
205208 bool forced_cleanup = p_force_cleanup || !enabled || tile_set.is_null () || !is_visible_in_tree ();
209+ if (forced_cleanup && _rendering_was_cleaned_up) {
210+ return ;
211+ }
206212
207213 // ----------- Layer level processing -----------
208214 if (!forced_cleanup) {
@@ -231,7 +237,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
231237 (!is_y_sort_enabled () && dirty.flags [DIRTY_FLAGS_LAYER_RENDERING_QUADRANT_SIZE]);
232238
233239 // Free all quadrants.
234- if (forced_cleanup || quadrant_shape_changed) {
240+ if (!_rendering_was_cleaned_up && ( forced_cleanup || quadrant_shape_changed) ) {
235241 for (const KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
236242 for (const RID &ci : kv.value ->canvas_items ) {
237243 if (ci.is_valid ()) {
@@ -395,15 +401,23 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
395401 int index = -(int64_t )0x80000000 ; // Always must be drawn below children.
396402
397403 // Sort the quadrants coords per local coordinates.
398- RBMap<Vector2, Ref<RenderingQuadrant>, RenderingQuadrant::CoordsWorldComparator> local_to_map;
404+ LocalVector<Pair<Vector2, Ref<RenderingQuadrant>>> sortable_quadrant_keys;
405+ sortable_quadrant_keys.reserve (rendering_quadrant_map.size ());
399406 for (KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
400- Ref<RenderingQuadrant> &rendering_quadrant = kv.value ;
401- local_to_map[tile_set-> map_to_local (rendering_quadrant-> quadrant_coords )] = rendering_quadrant ;
407+ Vector2 local_coords = tile_set-> map_to_local ( kv.value -> quadrant_coords ) ;
408+ sortable_quadrant_keys. push_back (Pair<Vector2, Ref<RenderingQuadrant>>(local_coords, kv. value )) ;
402409 }
410+ struct PairedQuadrantSorter {
411+ RenderingQuadrant::CoordsWorldComparator comparator;
412+ _ALWAYS_INLINE_ bool operator ()(const Pair<Vector2, Ref<RenderingQuadrant>> &p_a, const Pair<Vector2, Ref<RenderingQuadrant>> &p_b) const {
413+ return comparator (p_a.first , p_b.first );
414+ }
415+ };
416+ sortable_quadrant_keys.sort_custom <PairedQuadrantSorter>();
403417
404- // Sort the quadrants .
405- for (const KeyValue <Vector2, Ref<RenderingQuadrant>> &E : local_to_map ) {
406- for (const RID &ci : E.value ->canvas_items ) {
418+ // Set the draw indices .
419+ for (const Pair <Vector2, Ref<RenderingQuadrant>> &E : sortable_quadrant_keys ) {
420+ for (const RID &ci : E.second ->canvas_items ) {
407421 RS::get_singleton ()->canvas_item_set_draw_index (ci, index++);
408422 }
409423 }
@@ -426,14 +440,23 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
426440 }
427441 }
428442
443+ // -----------
444+ // Mark the rendering state as up to date.
445+ _rendering_was_cleaned_up = forced_cleanup;
446+
429447 // ----------- Occluders processing -----------
430- if (forced_cleanup || !occlusion_enabled) {
448+ bool cleanup_occlusion = forced_cleanup || !occlusion_enabled;
449+ if (cleanup_occlusion && _occlusion_was_cleaned_up) {
450+ return ;
451+ }
452+
453+ if (cleanup_occlusion) {
431454 // Clean everything.
432455 for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) {
433456 _rendering_occluders_clear_cell (kv.value );
434457 }
435458 } else {
436- if (_rendering_was_cleaned_up || dirty.flags [DIRTY_FLAGS_TILE_SET]) {
459+ if (_occlusion_was_cleaned_up || dirty.flags [DIRTY_FLAGS_TILE_SET]) {
437460 // Update all cells.
438461 for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) {
439462 _rendering_occluders_update_cell (kv.value );
@@ -448,8 +471,8 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
448471 }
449472
450473 // -----------
451- // Mark the rendering state as up to date.
452- _rendering_was_cleaned_up = forced_cleanup || !occlusion_enabled ;
474+ // Mark the occlusion state as up to date.
475+ _occlusion_was_cleaned_up = cleanup_occlusion ;
453476}
454477
455478void TileMapLayer::_rendering_notification (int p_what) {
@@ -718,6 +741,9 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) {
718741
719742 // Check if we should cleanup everything.
720743 bool forced_cleanup = p_force_cleanup || !enabled || !collision_enabled || !is_inside_tree () || tile_set.is_null ();
744+ if (forced_cleanup && _physics_was_cleaned_up) {
745+ return ;
746+ }
721747
722748 // ----------- Quadrants processing -----------
723749
@@ -729,7 +755,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) {
729755 bool quadrant_shape_changed = dirty.flags [DIRTY_FLAGS_TILE_SET] || dirty.flags [DIRTY_FLAGS_LAYER_PHYSICS_QUADRANT_SIZE];
730756
731757 // Free all quadrants.
732- if (forced_cleanup || quadrant_shape_changed) {
758+ if (!_physics_was_cleaned_up && ( forced_cleanup || quadrant_shape_changed) ) {
733759 for (const KeyValue<Vector2i, Ref<PhysicsQuadrant>> &kv : physics_quadrant_map) {
734760 // Clear bodies.
735761 for (KeyValue<PhysicsQuadrant::PhysicsBodyKey, PhysicsQuadrant::PhysicsBodyValue> &kvbody : kv.value ->bodies ) {
@@ -936,7 +962,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) {
936962
937963 // -----------
938964 // Mark the physics state as up to date.
939- _physics_was_cleaned_up = forced_cleanup || !occlusion_enabled ;
965+ _physics_was_cleaned_up = forced_cleanup;
940966}
941967
942968void TileMapLayer::_physics_quadrants_update_cell (CellData &r_cell_data, SelfList<PhysicsQuadrant>::List &r_dirty_physics_quadrant_list) {
@@ -1256,6 +1282,9 @@ void TileMapLayer::_navigation_update(bool p_force_cleanup) {
12561282
12571283 // Check if we should cleanup everything.
12581284 bool forced_cleanup = p_force_cleanup || !enabled || !navigation_enabled || !is_inside_tree () || tile_set.is_null ();
1285+ if (forced_cleanup && _navigation_was_cleaned_up) {
1286+ return ;
1287+ }
12591288
12601289 // ----------- Layer level processing -----------
12611290 // All this processing is kept for compatibility with the TileMap node.
@@ -1527,6 +1556,9 @@ void TileMapLayer::_navigation_draw_cell_debug(const RID &p_canvas_item, const V
15271556void TileMapLayer::_scenes_update (bool p_force_cleanup) {
15281557 // Check if we should cleanup everything.
15291558 bool forced_cleanup = p_force_cleanup || !enabled || !is_inside_tree () || tile_set.is_null ();
1559+ if (forced_cleanup && _scenes_was_cleaned_up) {
1560+ return ;
1561+ }
15301562
15311563 if (forced_cleanup) {
15321564 // Clean everything.
@@ -1682,7 +1714,7 @@ void TileMapLayer::_build_runtime_update_tile_data(bool p_force_cleanup) {
16821714 }
16831715
16841716 // -----------
1685- // Mark the navigation state as up to date.
1717+ // Mark the tile data state as up to date.
16861718 _runtime_update_tile_data_was_cleaned_up = forced_cleanup;
16871719}
16881720
0 commit comments