diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 9e3c445c65d..d607dc9a4c5 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -164,6 +164,7 @@ void Camera3D::_update_camera() { void Camera3D::_physics_interpolated_changed() { _update_process_mode(); + Node3D::_physics_interpolated_changed(); } void Camera3D::set_desired_process_modes(bool p_process_internal, bool p_physics_process_internal) { diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index a00bdab66de..99f8812977c 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -1157,9 +1157,21 @@ Vector3 Node3D::to_global(Vector3 p_local) const { return get_global_transform().xform(p_local); } +void Node3D::_physics_interpolated_changed() { + ERR_THREAD_GUARD; + data.notify_transform = data.notify_transform_requested || (data.notify_transform_when_fti_off && !is_physics_interpolated_and_enabled()); +} + +void Node3D::_set_notify_transform_when_fti_off(bool p_enable) { + ERR_THREAD_GUARD; + data.notify_transform_when_fti_off = p_enable; + data.notify_transform = data.notify_transform_requested || (data.notify_transform_when_fti_off && !is_physics_interpolated_and_enabled()); +} + void Node3D::set_notify_transform(bool p_enabled) { ERR_THREAD_GUARD; - data.notify_transform = p_enabled; + data.notify_transform_requested = p_enabled; + data.notify_transform = data.notify_transform_requested || (data.notify_transform_when_fti_off && !is_physics_interpolated_and_enabled()); } bool Node3D::is_transform_notification_enabled() const { @@ -1441,6 +1453,8 @@ Node3D::Node3D() : data.ignore_notification = false; data.notify_local_transform = false; data.notify_transform = false; + data.notify_transform_requested = false; + data.notify_transform_when_fti_off = false; data.visible = true; data.disable_scale = false; diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index d03884b09cd..930a174136d 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -134,6 +134,9 @@ private: bool notify_local_transform : 1; bool notify_transform : 1; + bool notify_transform_requested : 1; + bool notify_transform_when_fti_off : 1; + bool visible : 1; bool disable_scale : 1; @@ -199,6 +202,9 @@ protected: // (e.g. changing Camera zoom even if position hasn't changed). void fti_notify_node_changed(bool p_transform_changed = true); + void _set_notify_transform_when_fti_off(bool p_enable); + virtual void _physics_interpolated_changed() override; + // Opportunity after FTI to update the servers // with global_transform_interpolated, // and any custom interpolated data in derived classes. diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 41903f208a1..32844531e35 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -88,7 +88,9 @@ void VisualInstance3D::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - // ToDo : Can we turn off notify transform for physics interpolated cases? + // NOTIFICATION normally turned off for physics interpolated cases (via + // `notify_transform_when_fti_off`), however derived classes can still turn this back on, + // so always wrap with is_physics_interpolation_enabled(). if (_is_vi_visible() && !(is_inside_tree() && get_tree()->is_physics_interpolation_enabled()) && !_is_using_identity_transform()) { // Physics interpolation global off, always send. RenderingServer::get_singleton()->instance_set_transform(instance, get_global_transform()); @@ -204,7 +206,7 @@ RID VisualInstance3D::get_base() const { VisualInstance3D::VisualInstance3D() { instance = RenderingServer::get_singleton()->instance_create(); RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id()); - set_notify_transform(true); + _set_notify_transform_when_fti_off(true); } VisualInstance3D::~VisualInstance3D() {