From 942a304f4e4c7bb536d009536f06c283a3d45850 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Sat, 16 Mar 2024 16:02:22 +0000 Subject: [PATCH] Physics Interpolation 2D - fix light and light occluder resetting It turns out `NOTIFICATION_TRANSFORM_CHANGED` is deferred for these nodes, which can mean the transform is not set in the `VisualServer` until after the reset has been sent, even if the transform is set before the reset in script. This prevented the reset from acting correctly. Here we explicitly set the transform prior to each reset, to ensure the `VisualServer` is up to date. --- scene/2d/light_2d.cpp | 7 ++++++- scene/2d/light_occluder_2d.cpp | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 55b8e8020..4652685f9 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -320,7 +320,12 @@ void Light2D::_notification(int p_what) { } break; case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: { if (is_visible_in_tree() && is_physics_interpolated()) { - RenderingServer::get_singleton()->canvas_light_reset_physics_interpolation(canvas_light); + // Explicitly make sure the transform is up to date in VisualServer before + // resetting. This is necessary because NOTIFICATION_TRANSFORM_CHANGED + // is normally deferred, and a client change to transform will not always be sent + // before the reset, so we need to guarantee this. + RS::get_singleton()->canvas_light_set_transform(canvas_light, get_global_transform()); + RS::get_singleton()->canvas_light_reset_physics_interpolation(canvas_light); } } break; } diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index d38fb1e45..007f3109e 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -203,7 +203,12 @@ void LightOccluder2D::_notification(int p_what) { } break; case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: { if (is_visible_in_tree() && is_physics_interpolated()) { - RenderingServer::get_singleton()->canvas_light_occluder_reset_physics_interpolation(occluder); + // Explicitly make sure the transform is up to date in VisualServer before + // resetting. This is necessary because NOTIFICATION_TRANSFORM_CHANGED + // is normally deferred, and a client change to transform will not always be sent + // before the reset, so we need to guarantee this. + RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform()); + RS::get_singleton()->canvas_light_occluder_reset_physics_interpolation(occluder); } } break; }