mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-04 15:00:09 +01:00
105 lines
3.1 KiB
GDScript
105 lines
3.1 KiB
GDScript
extends Node3D
|
|
|
|
signal focus_lost
|
|
signal focus_gained
|
|
signal pose_recentered
|
|
|
|
@export var maximum_refresh_rate : int = 90
|
|
|
|
var xr_interface : OpenXRInterface
|
|
var xr_is_focussed = false
|
|
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready():
|
|
xr_interface = XRServer.find_interface("OpenXR")
|
|
if xr_interface and xr_interface.is_initialized():
|
|
print("OpenXR instantiated successfully.")
|
|
var vp : Viewport = get_viewport()
|
|
|
|
# Enable XR on our viewport
|
|
vp.use_xr = true
|
|
|
|
# Make sure v-sync is off, v-sync is handled by OpenXR
|
|
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
|
|
|
|
# Connect the OpenXR events
|
|
xr_interface.connect("session_begun", _on_openxr_session_begun)
|
|
xr_interface.connect("session_visible", _on_openxr_visible_state)
|
|
xr_interface.connect("session_focussed", _on_openxr_focused_state)
|
|
xr_interface.connect("session_stopping", _on_openxr_stopping)
|
|
xr_interface.connect("pose_recentered", _on_openxr_pose_recentered)
|
|
else:
|
|
# We couldn't start OpenXR.
|
|
print("OpenXR not instantiated!")
|
|
get_tree().quit()
|
|
|
|
|
|
# Handle OpenXR session ready
|
|
func _on_openxr_session_begun() -> void:
|
|
# Get the reported refresh rate
|
|
var current_refresh_rate = xr_interface.get_display_refresh_rate()
|
|
if current_refresh_rate > 0:
|
|
print("OpenXR: Refresh rate reported as ", str(current_refresh_rate))
|
|
else:
|
|
print("OpenXR: No refresh rate given by XR runtime")
|
|
|
|
# See if we have a better refresh rate available
|
|
var new_rate = current_refresh_rate
|
|
var available_rates : Array = xr_interface.get_available_display_refresh_rates()
|
|
if available_rates.size() == 0:
|
|
print("OpenXR: Target does not support refresh rate extension")
|
|
elif available_rates.size() == 1:
|
|
# Only one available, so use it
|
|
new_rate = available_rates[0]
|
|
else:
|
|
for rate in available_rates:
|
|
if rate > new_rate and rate <= maximum_refresh_rate:
|
|
new_rate = rate
|
|
|
|
# Did we find a better rate?
|
|
if current_refresh_rate != new_rate:
|
|
print("OpenXR: Setting refresh rate to ", str(new_rate))
|
|
xr_interface.set_display_refresh_rate(new_rate)
|
|
current_refresh_rate = new_rate
|
|
|
|
# Now match our physics rate
|
|
Engine.physics_ticks_per_second = current_refresh_rate
|
|
|
|
|
|
# Handle OpenXR visible state
|
|
func _on_openxr_visible_state() -> void:
|
|
# We always pass this state at startup,
|
|
# but the second time we get this it means our player took off their headset
|
|
if xr_is_focussed:
|
|
print("OpenXR lost focus")
|
|
|
|
xr_is_focussed = false
|
|
|
|
# pause our game
|
|
process_mode = Node.PROCESS_MODE_DISABLED
|
|
|
|
emit_signal("focus_lost")
|
|
|
|
|
|
# Handle OpenXR focused state
|
|
func _on_openxr_focused_state() -> void:
|
|
print("OpenXR gained focus")
|
|
xr_is_focussed = true
|
|
|
|
# unpause our game
|
|
process_mode = Node.PROCESS_MODE_INHERIT
|
|
|
|
emit_signal("focus_gained")
|
|
|
|
# Handle OpenXR stopping state
|
|
func _on_openxr_stopping() -> void:
|
|
# Our session is being stopped.
|
|
print("OpenXR is stopping")
|
|
|
|
# Handle OpenXR pose recentered signal
|
|
func _on_openxr_pose_recentered() -> void:
|
|
# User recentered view, we have to react to this by recentering the view.
|
|
# This is game implementation dependent.
|
|
emit_signal("pose_recentered")
|