浏览代码

Merge pull request #95835 from BastiaanOlij/xrnode_visibility_43

[4.3] XRNode - fix visibility issue
Rémi Verschelde 1 年之前
父节点
当前提交
d40fc50f08
共有 3 个文件被更改,包括 24 次插入4 次删除
  1. 3 3
      modules/openxr/extensions/openxr_hand_tracking_extension.cpp
  2. 19 1
      scene/3d/xr_nodes.cpp
  3. 2 0
      scene/3d/xr_nodes.h

+ 3 - 3
modules/openxr/extensions/openxr_hand_tracking_extension.cpp

@@ -225,6 +225,7 @@ void OpenXRHandTrackingExtension::on_process() {
 				// not successful? then we do nothing.
 				print_line("OpenXR: Failed to get tracking for hand", i, "[", OpenXRAPI::get_singleton()->get_error_string(result), "]");
 				godot_tracker->set_has_tracking_data(false);
+				godot_tracker->invalidate_pose("default");
 				continue;
 			}
 
@@ -235,8 +236,6 @@ void OpenXRHandTrackingExtension::on_process() {
 			}
 
 			if (hand_trackers[i].locations.isActive) {
-				godot_tracker->set_has_tracking_data(true);
-
 				// SKELETON_RIG_HUMANOID bone adjustment. This rotation performs:
 				// OpenXR Z+ -> Godot Humanoid Y-  (Back along the bone)
 				// OpenXR Y+ -> Godot Humanoid Z- (Out the back of the hand)
@@ -293,7 +292,8 @@ void OpenXRHandTrackingExtension::on_process() {
 						}
 
 						godot_tracker->set_hand_tracking_source(source);
-						if (location.locationFlags & XR_SPACE_LOCATION_POSITION_TRACKED_BIT) {
+						if (location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) {
+							godot_tracker->set_has_tracking_data(true);
 							godot_tracker->set_pose("default", transform, linear_velocity, angular_velocity);
 						} else {
 							godot_tracker->set_has_tracking_data(false);

+ 19 - 1
scene/3d/xr_nodes.cpp

@@ -303,6 +303,8 @@ StringName XRNode3D::get_pose_name() const {
 
 void XRNode3D::set_show_when_tracked(bool p_show) {
 	show_when_tracked = p_show;
+
+	_update_visibility();
 }
 
 bool XRNode3D::get_show_when_tracked() const {
@@ -361,6 +363,9 @@ void XRNode3D::_bind_tracker() {
 		if (pose.is_valid()) {
 			set_transform(pose->get_adjusted_transform());
 			_set_has_tracking_data(pose->get_has_tracking_data());
+		} else {
+			// Pose has been invalidated or was never set.
+			_set_has_tracking_data(false);
 		}
 	}
 }
@@ -407,6 +412,10 @@ void XRNode3D::_pose_lost_tracking(const Ref<XRPose> &p_pose) {
 }
 
 void XRNode3D::_set_has_tracking_data(bool p_has_tracking_data) {
+	// Always update our visibility, we may have set our tracking data
+	// when conditions weren't right.
+	_update_visibility();
+
 	// Ignore if the has_tracking_data state isn't changing.
 	if (p_has_tracking_data == has_tracking_data) {
 		return;
@@ -415,10 +424,19 @@ void XRNode3D::_set_has_tracking_data(bool p_has_tracking_data) {
 	// Handle change of has_tracking_data.
 	has_tracking_data = p_has_tracking_data;
 	emit_signal(SNAME("tracking_changed"), has_tracking_data);
+}
 
+void XRNode3D::_update_visibility() {
 	// If configured, show or hide the node based on tracking data.
 	if (show_when_tracked) {
-		set_visible(has_tracking_data);
+		// Only react to this if we have a primary interface.
+		XRServer *xr_server = XRServer::get_singleton();
+		if (xr_server != nullptr) {
+			Ref<XRInterface> xr_interface = xr_server->get_primary_interface();
+			if (xr_interface.is_valid()) {
+				set_visible(has_tracking_data);
+			}
+		}
 	}
 }
 

+ 2 - 0
scene/3d/xr_nodes.h

@@ -95,6 +95,8 @@ protected:
 	void _pose_lost_tracking(const Ref<XRPose> &p_pose);
 	void _set_has_tracking_data(bool p_has_tracking_data);
 
+	void _update_visibility();
+
 public:
 	void _validate_property(PropertyInfo &p_property) const;
 	void set_tracker(const StringName &p_tracker_name);