-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add OpenXR demo project showing off local reference space
- Loading branch information
1 parent
b74261c
commit d256e73
Showing
14 changed files
with
580 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Normalize EOL for all files that Git considers text files. | ||
* text=auto eol=lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Godot 4+ specific ignores | ||
.godot/ |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="CompressedTexture2D" | ||
uid="uid://rek0t7kubpx4" | ||
path.s3tc="res://.godot/imported/pattern.png-cf6f03dfd1cdd4bc35da3414e912103d.s3tc.ctex" | ||
metadata={ | ||
"imported_formats": ["s3tc_bptc"], | ||
"vram_texture": true | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://assets/pattern.png" | ||
dest_files=["res://.godot/imported/pattern.png-cf6f03dfd1cdd4bc35da3414e912103d.s3tc.ctex"] | ||
|
||
[params] | ||
|
||
compress/mode=2 | ||
compress/high_quality=false | ||
compress/lossy_quality=0.7 | ||
compress/hdr_compression=1 | ||
compress/normal_map=0 | ||
compress/channel_pack=0 | ||
mipmaps/generate=true | ||
mipmaps/limit=-1 | ||
roughness/mode=0 | ||
roughness/src_normal="" | ||
process/fix_alpha_border=true | ||
process/premult_alpha=false | ||
process/normal_map_invert_y=false | ||
process/hdr_as_srgb=false | ||
process/hdr_clamp_exposure=false | ||
process/size_limit=0 | ||
detect_3d/compress_to=0 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="CompressedTexture2D" | ||
uid="uid://d1s6lsinmhdj5" | ||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" | ||
metadata={ | ||
"vram_texture": false | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://icon.svg" | ||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] | ||
|
||
[params] | ||
|
||
compress/mode=0 | ||
compress/high_quality=false | ||
compress/lossy_quality=0.7 | ||
compress/hdr_compression=1 | ||
compress/normal_map=0 | ||
compress/channel_pack=0 | ||
mipmaps/generate=false | ||
mipmaps/limit=-1 | ||
roughness/mode=0 | ||
roughness/src_normal="" | ||
process/fix_alpha_border=true | ||
process/premult_alpha=false | ||
process/normal_map_invert_y=false | ||
process/hdr_as_srgb=false | ||
process/hdr_clamp_exposure=false | ||
process/size_limit=0 | ||
detect_3d/compress_to=1 | ||
svg/scale=1.0 | ||
editor/scale_with_editor_scale=false | ||
editor/convert_colors_with_editor_theme=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
[gd_scene load_steps=11 format=3 uid="uid://db1q04xf4urua"] | ||
|
||
[ext_resource type="Texture2D" uid="uid://rek0t7kubpx4" path="res://assets/pattern.png" id="1_sbpla"] | ||
[ext_resource type="PackedScene" uid="uid://dkdk37kpjui3q" path="res://vehicle.tscn" id="2_x0meh"] | ||
[ext_resource type="Script" path="res://start_vr.gd" id="3_d042y"] | ||
[ext_resource type="PackedScene" uid="uid://du5twm6cwhq6j" path="res://track.tscn" id="4_ddbiu"] | ||
|
||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_t0uks"] | ||
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) | ||
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) | ||
|
||
[sub_resource type="Sky" id="Sky_f7epq"] | ||
sky_material = SubResource("ProceduralSkyMaterial_t0uks") | ||
|
||
[sub_resource type="Environment" id="Environment_ctbfb"] | ||
background_mode = 2 | ||
sky = SubResource("Sky_f7epq") | ||
tonemap_mode = 2 | ||
|
||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jptbt"] | ||
albedo_color = Color(0.211765, 0.717647, 0.160784, 1) | ||
albedo_texture = ExtResource("1_sbpla") | ||
uv1_scale = Vector3(100, 100, 100) | ||
|
||
[sub_resource type="PlaneMesh" id="PlaneMesh_judwf"] | ||
size = Vector2(1000, 1000) | ||
subdivide_width = 10 | ||
subdivide_depth = 10 | ||
|
||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_k6vqu"] | ||
|
||
[node name="Main" type="Node3D"] | ||
|
||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."] | ||
environment = SubResource("Environment_ctbfb") | ||
|
||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] | ||
transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) | ||
|
||
[node name="Floor" type="StaticBody3D" parent="."] | ||
|
||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Floor"] | ||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.01, 0) | ||
material_override = SubResource("StandardMaterial3D_jptbt") | ||
mesh = SubResource("PlaneMesh_judwf") | ||
|
||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor"] | ||
shape = SubResource("WorldBoundaryShape3D_k6vqu") | ||
|
||
[node name="Vehicle" parent="." instance=ExtResource("2_x0meh")] | ||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.54837, 0.2, 0) | ||
|
||
[node name="StartVR" type="Node3D" parent="."] | ||
script = ExtResource("3_d042y") | ||
maximum_refresh_rate = 144 | ||
|
||
[node name="Track" parent="." instance=ExtResource("4_ddbiu")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[gd_resource type="OpenXRActionMap" load_steps=7 format=3 uid="uid://b6o1742qdpkht"] | ||
|
||
[sub_resource type="OpenXRAction" id="OpenXRAction_bxnsb"] | ||
resource_name = "default_pose" | ||
localized_name = "Default pose" | ||
action_type = 3 | ||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right") | ||
|
||
[sub_resource type="OpenXRAction" id="OpenXRAction_e4g8i"] | ||
resource_name = "haptic" | ||
localized_name = "Haptic" | ||
action_type = 4 | ||
toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right") | ||
|
||
[sub_resource type="OpenXRActionSet" id="OpenXRActionSet_ucgoy"] | ||
resource_name = "godot" | ||
localized_name = "Godot action set" | ||
actions = [SubResource("OpenXRAction_bxnsb"), SubResource("OpenXRAction_e4g8i")] | ||
|
||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_xbpfq"] | ||
action = SubResource("OpenXRAction_bxnsb") | ||
paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose") | ||
|
||
[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7tlrk"] | ||
action = SubResource("OpenXRAction_e4g8i") | ||
paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic") | ||
|
||
[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_1xkvk"] | ||
interaction_profile_path = "/interaction_profiles/khr/simple_controller" | ||
bindings = [SubResource("OpenXRIPBinding_xbpfq"), SubResource("OpenXRIPBinding_7tlrk")] | ||
|
||
[resource] | ||
action_sets = [SubResource("OpenXRActionSet_ucgoy")] | ||
interaction_profiles = [SubResource("OpenXRInteractionProfile_1xkvk")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
; Engine configuration file. | ||
; It's best edited using the editor UI and not directly, | ||
; since the parameters that go here are not all obvious. | ||
; | ||
; Format: | ||
; [section] ; section goes between [] | ||
; param=value ; assign values to parameters | ||
|
||
config_version=5 | ||
|
||
[application] | ||
|
||
config/name="OpenXR Vehicle Movement" | ||
run/main_scene="res://main.tscn" | ||
config/features=PackedStringArray("4.1", "GL Compatibility") | ||
config/icon="res://icon.svg" | ||
|
||
[input] | ||
|
||
turn_left={ | ||
"deadzone": 0.5, | ||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) | ||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null) | ||
] | ||
} | ||
turn_right={ | ||
"deadzone": 0.5, | ||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) | ||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) | ||
] | ||
} | ||
accelerate={ | ||
"deadzone": 0.5, | ||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) | ||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null) | ||
] | ||
} | ||
brake={ | ||
"deadzone": 0.5, | ||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) | ||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null) | ||
] | ||
} | ||
|
||
[rendering] | ||
|
||
renderer/rendering_method="gl_compatibility" | ||
renderer/rendering_method.mobile="gl_compatibility" | ||
|
||
[xr] | ||
|
||
openxr/enabled=true | ||
openxr/reference_space=0 | ||
shaders/enabled=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
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") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
@tool | ||
extends Path3D | ||
|
||
@export var tire_spacing : float = 0.5: | ||
set(value): | ||
tire_spacing = value | ||
if is_inside_tree(): | ||
_update_tires() | ||
|
||
func _update_tires(): | ||
var multimesh : MultiMesh = $Tirewall.multimesh | ||
|
||
# Cheap and dirty approach, need to improve this! | ||
var track_length = curve.get_baked_length() | ||
var tires_per_side = floor(track_length / tire_spacing) | ||
var offset = 0.0 | ||
|
||
multimesh.instance_count = tires_per_side * 2 | ||
for tire in range(tires_per_side): | ||
var t : Transform3D = curve.sample_baked_with_rotation(offset) | ||
|
||
var t_adj : Transform3D = t | ||
t_adj.origin += t_adj.basis.x * 5.0 | ||
multimesh.set_instance_transform(tire, t_adj) | ||
|
||
t_adj = t | ||
t_adj.origin -= t_adj.basis.x * 5.0 | ||
multimesh.set_instance_transform(tires_per_side + tire, t_adj) | ||
|
||
offset += tire_spacing | ||
|
||
# Called when the node enters the scene tree for the first time. | ||
func _ready(): | ||
_update_tires() | ||
|
||
if Engine.is_editor_hint(): | ||
curve_changed.connect(_update_tires) |
Oops, something went wrong.