Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added frame rate control. #364

Merged
merged 1 commit into from
Feb 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 44 additions & 9 deletions addons/godot-xr-tools/xr/start_xr.gd
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ export var enable_passthrough : bool = false setget _set_enable_passthrough
## Physics rate multiplier compared to HMD frame rate
export var physics_rate_multiplier : int = 1

## If non-zero, specifies the target refresh rate
export var target_refresh_rate : float = 0


## Current XR interface
var xr_interface : ARVRInterface
Expand All @@ -51,6 +54,9 @@ var _openxr_configuration
# OpenXR enabled extensions
var _openxr_enabled_extensions : Array

# Current refresh rate
var _current_refresh_rate : float = 0


# Handle auto-initialization when ready
func _ready() -> void:
Expand Down Expand Up @@ -136,18 +142,31 @@ func _on_openxr_session_begun() -> void:
# Our interface will tell us whether we should keep our render buffer in linear color space
get_viewport().keep_3d_linear = _openxr_configuration.keep_3d_linear()

# increase our physics engine update speed
var refresh_rate : float = _openxr_configuration.get_refresh_rate()
if refresh_rate > 0:
# Report provided frame rare
print("OpenXR: HMD refresh rate is set to ", str(refresh_rate))
# Get the reported refresh rate
_current_refresh_rate = _openxr_configuration.get_refresh_rate()
if _current_refresh_rate > 0:
print("OpenXR: Refresh rate reported as ", str(_current_refresh_rate))
else:
# None provided, assume a standard rate
print("OpenXR: No refresh rate given by XR runtime")
refresh_rate = 144

# Pick a physics rate
var physics_rate := int(round(refresh_rate * physics_rate_multiplier))
# Pick a desired refresh rate
var desired_rate := target_refresh_rate if target_refresh_rate > 0 else _current_refresh_rate
var available_rates : Array = _openxr_configuration.get_available_refresh_rates()
if available_rates.size() == 0:
print("OpenXR: Target does not support refresh rate extension")
elif available_rates.size() == 1:
print("OpenXR: Target supports only one refresh rate")
elif desired_rate > 0:
print("OpenXR: Available refresh rates are ", str(available_rates))
var rate = _find_closest(available_rates, desired_rate)
if rate > 0:
print("OpenXR: Setting refresh rate to ", str(rate))
_openxr_configuration.set_refresh_rate(rate)
_current_refresh_rate = rate

# increase our physics engine update speed
var active_rate := _current_refresh_rate if _current_refresh_rate > 0 else 144.0
var physics_rate := int(round(active_rate * physics_rate_multiplier))
print("Setting physics rate to ", physics_rate)
Engine.iterations_per_second = physics_rate

Expand Down Expand Up @@ -290,3 +309,19 @@ func _on_enter_webxr_button_pressed() -> void:
# or _on_webxr_session_failed
if not xr_interface.initialize():
OS.alert("Failed to initialize WebXR")


# Find the closest value in the array to the target
func _find_closest(values : Array, target : float) -> float:
# Return 0 if no values
if values.size() == 0:
return 0.0

# Find the closest value to the target
var best : float = values.front()
for v in values:
if abs(target - v) < abs(target - best):
best = v

# Return the best value
return best