Skip to content

Commit 6db1062

Browse files
BastiaanOlijCalinouaaronfranke
authored
Fix recenter code in OpenXR Character Centric Movement (#1131)
Co-authored-by: Hugo Locurcio <[email protected]> Co-authored-by: Aaron Franke <[email protected]>
1 parent adf6d7e commit 6db1062

File tree

1 file changed

+36
-23
lines changed
  • xr/openxr_character_centric_movement

1 file changed

+36
-23
lines changed

xr/openxr_character_centric_movement/player.gd

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
1818
func 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.
4457
func _get_movement_input() -> Vector2:

0 commit comments

Comments
 (0)