@@ -16,29 +16,42 @@ var gravity := float(ProjectSettings.get_setting("physics/3d/default_gravity"))
1616
1717## Called when the user has requested their view to be recentered.
1818func recenter () -> void :
19- # The code here assumes the player has walked into an area they shouldn't be
20- # and we return the player back to the character body.
21- # But other strategies can be applied here as well such as returning the player
22- # to a starting position or a checkpoint.
23-
24- # Calculate where our camera should be, we start with our global transform.
25- var new_camera_transform : Transform3D = global_transform
26-
27- # Set to the height of our neck joint.
28- new_camera_transform .origin .y = neck_position_node .global_position .y
29-
30- # Apply transform our our next position to get our desired camera transform.
31- new_camera_transform = new_camera_transform * neck_position_node .transform .inverse ()
32-
33- # Remove tilt from camera transform.
34- var camera_transform : Transform3D = camera_node .transform
35- var forward_dir : Vector3 = camera_transform .basis .z
36- forward_dir .y = 0.0
37- camera_transform = camera_transform .looking_at (camera_transform .origin + forward_dir .normalized (), Vector3 .UP , true )
38-
39- # Update our XR location.
40- origin_node .global_transform = new_camera_transform * camera_transform .inverse ()
41-
19+ var xr_interface : OpenXRInterface = XRServer .find_interface ("OpenXR" )
20+ if not xr_interface :
21+ push_error ("Couldn't access OpenXR interface!" )
22+ return
23+
24+ var play_area_mode : XRInterface .PlayAreaMode = xr_interface .get_play_area_mode ()
25+ if play_area_mode == XRInterface .XR_PLAY_AREA_SITTING :
26+ push_warning ("Sitting play space is not suitable for this setup." )
27+ elif play_area_mode == XRInterface .XR_PLAY_AREA_ROOMSCALE :
28+ # This is already handled by the headset.
29+ pass
30+ else :
31+ # Use Godot's own logic.
32+ XRServer .center_on_hmd (XRServer .RESET_BUT_KEEP_TILT , true )
33+
34+ # XRCamera3D node won't be updated yet, so go straight to the source!
35+ var head_tracker : XRPositionalTracker = XRServer .get_tracker ("head" )
36+ if not head_tracker :
37+ push_error ("Couldn't locate head tracker!" )
38+ return
39+
40+ var pose : XRPose = head_tracker .get_pose ("default" )
41+ var head_transform : Transform3D = pose .get_adjusted_transform ()
42+
43+ # Get neck transform in XROrigin3D space
44+ var neck_transform : Transform3D = neck_position_node .transform * head_transform
45+
46+ # Reset our XROrigin transform and apply the inverse of the neck position.
47+ var new_origin_transform : Transform3D = Transform3D ()
48+ new_origin_transform .origin .x = - neck_transform .origin .x
49+ new_origin_transform .origin .y = 0.0
50+ new_origin_transform .origin .z = - neck_transform .origin .z
51+ origin_node .transform = new_origin_transform
52+
53+ # Finally reset character orientation
54+ transform .basis = Basis ()
4255
4356# Returns our move input by querying the move action on each controller.
4457func _get_movement_input () -> Vector2 :
0 commit comments