Merge pull request #106109 from Asaduji/fti_fix_xr_nodes

Physics Interpolation - Fix XR Nodes to work with `SceneTreeFTI`
This commit is contained in:
Thaddeus Crews
2025-05-06 08:38:09 -05:00
2 changed files with 17 additions and 58 deletions

View File

@ -72,36 +72,13 @@ void XRCamera3D::_removed_tracker(const StringName &p_tracker_name, int p_tracke
void XRCamera3D::_pose_changed(const Ref<XRPose> &p_pose) { void XRCamera3D::_pose_changed(const Ref<XRPose> &p_pose) {
if (p_pose->get_name() == pose_name) { if (p_pose->get_name() == pose_name) {
Node3D *parent = Object::cast_to<Node3D>(get_parent()); set_transform(p_pose->get_adjusted_transform());
if (is_inside_tree() && parent && parent->is_physics_interpolated_and_enabled() && !is_set_as_top_level() && !is_physics_interpolated()) {
pose_offset = p_pose->get_adjusted_transform();
} else {
set_transform(p_pose->get_adjusted_transform());
}
} }
} }
void XRCamera3D::_notification(int p_what) { void XRCamera3D::_physics_interpolated_changed() {
switch (p_what) { Camera3D::_physics_interpolated_changed();
case NOTIFICATION_ENTER_TREE: { update_configuration_warnings();
if (!Engine::get_singleton()->is_editor_hint()) {
set_desired_process_modes(true, false);
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
if (!is_inside_tree() || is_physics_interpolated() || Engine::get_singleton()->is_editor_hint()) {
break;
}
Node3D *parent = Object::cast_to<Node3D>(get_parent());
if (parent && parent->is_physics_interpolated_and_enabled() && !is_set_as_top_level()) {
set_global_transform(parent->get_global_transform_interpolated() * pose_offset);
}
} break;
}
} }
PackedStringArray XRCamera3D::get_configuration_warnings() const { PackedStringArray XRCamera3D::get_configuration_warnings() const {
@ -114,6 +91,10 @@ PackedStringArray XRCamera3D::get_configuration_warnings() const {
if (parent && origin == nullptr) { if (parent && origin == nullptr) {
warnings.push_back(RTR("XRCamera3D may not function as expected without an XROrigin3D node as its parent.")); warnings.push_back(RTR("XRCamera3D may not function as expected without an XROrigin3D node as its parent."));
}; };
if (is_physics_interpolated()) {
warnings.push_back(RTR("XRCamera3D should have physics_interpolation_mode set to OFF in order to avoid jitter."));
}
} }
return warnings; return warnings;
@ -431,13 +412,7 @@ void XRNode3D::_removed_tracker(const StringName &p_tracker_name, int p_tracker_
void XRNode3D::_pose_changed(const Ref<XRPose> &p_pose) { void XRNode3D::_pose_changed(const Ref<XRPose> &p_pose) {
if (p_pose.is_valid() && p_pose->get_name() == pose_name) { if (p_pose.is_valid() && p_pose->get_name() == pose_name) {
Node3D *parent = Object::cast_to<Node3D>(get_parent()); set_transform(p_pose->get_adjusted_transform());
if (is_inside_tree() && parent && parent->is_physics_interpolated_and_enabled() && !is_set_as_top_level() && !is_physics_interpolated()) {
pose_offset = p_pose->get_adjusted_transform();
} else {
set_transform(p_pose->get_adjusted_transform());
}
_set_has_tracking_data(p_pose->get_has_tracking_data()); _set_has_tracking_data(p_pose->get_has_tracking_data());
} }
} }
@ -477,26 +452,8 @@ void XRNode3D::_update_visibility() {
} }
} }
void XRNode3D::_notification(int p_what) { void XRNode3D::_physics_interpolated_changed() {
switch (p_what) { update_configuration_warnings();
case NOTIFICATION_ENTER_TREE: {
if (!Engine::get_singleton()->is_editor_hint()) {
set_process_internal(true);
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
if (!is_inside_tree() || is_physics_interpolated() || Engine::get_singleton()->is_editor_hint()) {
break;
}
Node3D *parent = Object::cast_to<Node3D>(get_parent());
if (parent && parent->is_physics_interpolated_and_enabled() && !is_set_as_top_level()) {
set_global_transform(parent->get_global_transform_interpolated() * pose_offset);
}
} break;
}
} }
XRNode3D::XRNode3D() { XRNode3D::XRNode3D() {
@ -540,6 +497,10 @@ PackedStringArray XRNode3D::get_configuration_warnings() const {
if (pose_name == "") { if (pose_name == "") {
warnings.push_back(RTR("No pose is set.")); warnings.push_back(RTR("No pose is set."));
} }
if (is_physics_interpolated()) {
warnings.push_back(RTR("XRNode3D should have physics_interpolation_mode set to OFF in order to avoid jitter."));
}
} }
return warnings; return warnings;

View File

@ -46,14 +46,13 @@ protected:
StringName tracker_name = "head"; StringName tracker_name = "head";
StringName pose_name = SceneStringName(default_); StringName pose_name = SceneStringName(default_);
Ref<XRPositionalTracker> tracker; Ref<XRPositionalTracker> tracker;
Transform3D pose_offset;
void _bind_tracker(); void _bind_tracker();
void _unbind_tracker(); void _unbind_tracker();
void _changed_tracker(const StringName &p_tracker_name, int p_tracker_type); void _changed_tracker(const StringName &p_tracker_name, int p_tracker_type);
void _removed_tracker(const StringName &p_tracker_name, int p_tracker_type); void _removed_tracker(const StringName &p_tracker_name, int p_tracker_type);
void _pose_changed(const Ref<XRPose> &p_pose); void _pose_changed(const Ref<XRPose> &p_pose);
void _notification(int p_what); virtual void _physics_interpolated_changed() override;
public: public:
PackedStringArray get_configuration_warnings() const override; PackedStringArray get_configuration_warnings() const override;
@ -81,7 +80,6 @@ private:
StringName pose_name = SceneStringName(default_); StringName pose_name = SceneStringName(default_);
bool has_tracking_data = false; bool has_tracking_data = false;
bool show_when_tracked = false; bool show_when_tracked = false;
Transform3D pose_offset;
protected: protected:
Ref<XRPositionalTracker> tracker; Ref<XRPositionalTracker> tracker;
@ -98,7 +96,7 @@ protected:
void _set_has_tracking_data(bool p_has_tracking_data); void _set_has_tracking_data(bool p_has_tracking_data);
void _update_visibility(); void _update_visibility();
void _notification(int p_what); virtual void _physics_interpolated_changed() override;
public: public:
void _validate_property(PropertyInfo &p_property) const; void _validate_property(PropertyInfo &p_property) const;