From 4c426b0be5d423974ad696f4133ed770befe1f75 Mon Sep 17 00:00:00 2001 From: Ricardo Buring Date: Mon, 17 Jun 2024 23:26:46 +0200 Subject: [PATCH] Fix TileMapLayer not respecting physics interpolation mode --- scene/2d/tile_map_layer.cpp | 52 +++++++++++++++++++++++++++++++++---- scene/2d/tile_map_layer.h | 2 ++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index cdd7b151103..b6d0a8d73a2 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -96,6 +96,7 @@ void TileMapLayer::_debug_update(bool p_force_cleanup) { } // Update those quadrants. + bool needs_set_not_interpolated = is_inside_tree() && get_tree()->is_physics_interpolation_enabled() && !is_physics_interpolated(); for (SelfList *quadrant_list_element = dirty_debug_quadrant_list.first(); quadrant_list_element;) { SelfList *next_quadrant_list_element = quadrant_list_element->next(); // "Hack" to clear the list while iterating. @@ -118,6 +119,9 @@ void TileMapLayer::_debug_update(bool p_force_cleanup) { rs->canvas_item_clear(ci); } else { ci = rs->canvas_item_create(); + if (needs_set_not_interpolated) { + rs->canvas_item_set_interpolated(ci, false); + } rs->canvas_item_set_z_index(ci, RS::CANVAS_ITEM_Z_MAX - 1); rs->canvas_item_set_parent(ci, get_canvas_item()); } @@ -240,6 +244,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { } // Update all dirty quadrants. + bool needs_set_not_interpolated = is_inside_tree() && get_tree()->is_physics_interpolation_enabled() && !is_physics_interpolated(); for (SelfList *quadrant_list_element = dirty_rendering_quadrant_list.first(); quadrant_list_element;) { SelfList *next_quadrant_list_element = quadrant_list_element->next(); // "Hack" to clear the list while iterating. @@ -301,6 +306,9 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { if (prev_ci == RID() || prev_material != mat || prev_z_index != tile_z_index) { // If so, create a new CanvasItem. ci = rs->canvas_item_create(); + if (needs_set_not_interpolated) { + rs->canvas_item_set_interpolated(ci, false); + } if (mat.is_valid()) { rs->canvas_item_set_material(ci, mat->get_rid()); } @@ -446,12 +454,13 @@ void TileMapLayer::_rendering_notification(int p_what) { } } } else if (p_what == NOTIFICATION_RESET_PHYSICS_INTERPOLATION) { - for (const KeyValue> &kv : rendering_quadrant_map) { - for (const RID &ci : kv.value->canvas_items) { - if (ci.is_null()) { - continue; + if (is_physics_interpolated_and_enabled() && is_visible_in_tree()) { + for (const KeyValue> &kv : rendering_quadrant_map) { + for (const RID &ci : kv.value->canvas_items) { + if (ci.is_valid()) { + rs->canvas_item_reset_physics_interpolation(ci); + } } - rs->canvas_item_reset_physics_interpolation(ci); } } } @@ -587,6 +596,7 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) { bool transpose = (r_cell_data.cell.alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE); // Create, update or clear occluders. + bool needs_set_not_interpolated = is_inside_tree() && get_tree()->is_physics_interpolation_enabled() && !is_physics_interpolated(); for (uint32_t occlusion_layer_index = 0; occlusion_layer_index < r_cell_data.occluders.size(); occlusion_layer_index++) { Ref occluder_polygon = tile_data->get_occluder(occlusion_layer_index); @@ -598,6 +608,9 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) { xform.set_origin(tile_set->map_to_local(r_cell_data.coords)); if (!occluder.is_valid()) { occluder = rs->canvas_light_occluder_create(); + if (needs_set_not_interpolated) { + rs->canvas_light_occluder_set_interpolated(occluder, false); + } } rs->canvas_light_occluder_set_transform(occluder, get_global_transform() * xform); rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder(occlusion_layer_index, flip_h, flip_v, transpose)->get_rid()); @@ -1678,6 +1691,35 @@ void TileMapLayer::_internal_update(bool p_force_cleanup) { pending_update = false; } +void TileMapLayer::_physics_interpolated_changed() { + RenderingServer *rs = RenderingServer::get_singleton(); + + bool interpolated = is_physics_interpolated(); + bool needs_reset = interpolated && is_visible_in_tree(); + + for (const KeyValue> &kv : rendering_quadrant_map) { + for (const RID &ci : kv.value->canvas_items) { + if (ci.is_valid()) { + rs->canvas_item_set_interpolated(ci, interpolated); + if (needs_reset) { + rs->canvas_item_reset_physics_interpolation(ci); + } + } + } + } + + for (const KeyValue &E : tile_map_layer_data) { + for (const RID &occluder : E.value.occluders) { + if (occluder.is_valid()) { + rs->canvas_light_occluder_set_interpolated(occluder, interpolated); + if (needs_reset) { + rs->canvas_light_occluder_reset_physics_interpolation(occluder); + } + } + } + } +} + void TileMapLayer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_POSTINITIALIZE: { diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h index 19c6fc128bf..b0aaaafe5dd 100644 --- a/scene/2d/tile_map_layer.h +++ b/scene/2d/tile_map_layer.h @@ -381,6 +381,8 @@ private: void _deferred_internal_update(); void _internal_update(bool p_force_cleanup); + virtual void _physics_interpolated_changed() override; + protected: void _notification(int p_what);