From 09b79ead802b9a861ecea0e43f160db68bfb2a50 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Thu, 24 Aug 2023 09:45:52 +0100 Subject: [PATCH] Physics Interpolation - automatic resets for Camera2D and TileMap. Extra reset required for Camera2D. TileMaps require resetting by quadrant. --- scene/2d/camera_2d.cpp | 8 ++++++++ scene/2d/tile_map.cpp | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 56554f2b7e15..51853418ee9f 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -318,6 +318,14 @@ void Camera2D::_notification(int p_what) { first = true; _set_current(current); + // Note that NOTIFICATION_RESET_PHYSICS_INTERPOLATION + // is automatically called before this because Camera2D is inherited + // from CanvasItem. However, the camera transform is not up to date + // until this point, so we do an extra manual reset. + if (is_physics_interpolated_and_enabled()) { + _interpolation_data.xform_curr = get_camera_transform(); + _interpolation_data.xform_prev = _interpolation_data.xform_curr; + } } break; case NOTIFICATION_EXIT_TREE: { const bool viewport_valid = !custom_viewport || ObjectDB::get_instance(custom_viewport_id); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index fabcf5bbb6f4..36f1f6c1f190 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -132,6 +132,17 @@ void TileMap::_notification(int p_what) { } } break; + + case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: { + if (is_visible_in_tree() && is_physics_interpolated_and_enabled()) { + for (Map::Element *E = quadrant_map.front(); E; E = E->next()) { + Quadrant &q = E->get(); + for (List::Element *F = q.canvas_items.front(); F; F = F->next()) { + VisualServer::get_singleton()->canvas_item_reset_physics_interpolation(F->get()); + } + } + } + } break; } } @@ -744,6 +755,13 @@ void TileMap::update_dirty_quadrants() { VisualServerCanvasHelper::tilemap_end(); } + // Reset physics interpolation for any recreated canvas items. + if (is_physics_interpolated_and_enabled() && is_visible_in_tree()) { + for (List::Element *F = q.canvas_items.front(); F; F = F->next()) { + VisualServer::get_singleton()->canvas_item_reset_physics_interpolation(F->get()); + } + } + dirty_quadrant_list.remove(dirty_quadrant_list.first()); quadrant_order_dirty = true; }