From 4781f146fbf889aecba0bf8ab08a5dcb47470bcf Mon Sep 17 00:00:00 2001 From: Relintai Date: Wed, 27 Jul 2022 17:43:40 +0200 Subject: [PATCH] Ported: Physics Interpolation - optimize hidden nodes In order to prevent glitches when unhiding nodes, set_transform() is still called to the VisualServer even for hidden nodes when the node is interpolated. This activates a lot of logic which is not necessary just to keep the previous transform updated. This PR adds an early out which misses out on the unnecessary logic when instances are invisible. - lawnjelly https://github.com/godotengine/godot/commit/ec9a17cfadd9eef603d5cc14604ca37c876edc1a --- servers/visual/visual_server_scene.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 8825e4a2c..2d3ba6601 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -748,9 +748,6 @@ void VisualServerScene::instance_set_transform(RID p_instance, const Transform & instance->transform_curr = p_transform; - // decide on the interpolation method .. slerp if possible - instance->interpolation_method = TransformInterpolator::find_method(instance->transform_prev.basis, instance->transform_curr.basis); - // keep checksums up to date instance->transform_checksum_curr = new_checksum; @@ -761,6 +758,17 @@ void VisualServerScene::instance_set_transform(RID p_instance, const Transform & DEV_ASSERT(instance->scenario->_interpolation_data.instance_transform_update_list_curr->size()); } + // If the instance is invisible, then we are simply updating the data flow, there is no need to calculate the interpolated + // transform or anything else. + // Ideally we would not even call the VisualServer::set_transform() when invisible but that would entail having logic + // to keep track of the previous transform on the SceneTree side. The "early out" below is less efficient but a lot cleaner codewise. + if (!instance->visible) { + return; + } + + // decide on the interpolation method .. slerp if possible + instance->interpolation_method = TransformInterpolator::find_method(instance->transform_prev.basis, instance->transform_curr.basis); + if (!instance->on_interpolate_list) { instance->scenario->_interpolation_data.instance_interpolate_update_list.push_back(p_instance); instance->on_interpolate_list = true;