From a4b64f8275a19d82aa2170e67b2a3b889873f8f6 Mon Sep 17 00:00:00 2001
From: RubberDuckShobe <64215152+CLfamilaris@users.noreply.github.com>
Date: Thu, 3 Aug 2023 21:15:54 +0200
Subject: [PATCH] Oh, I think a heart always learns to come through
---
.gitattributes | 2 +
.gitignore | 8 +
Main.tscn | 144 ++++++
README.md | 9 +
VRDOM.csproj | 9 +
VRDOM.sln | 19 +
controller.tres | 4 +
controller_collisionshape.tres | 4 +
icon.svg | 1 +
icon.svg.import | 37 ++
openxr_action_map.tres | 835 +++++++++++++++++++++++++++++++++
project.godot | 25 +
scripts/DisplayCapture.cs | 66 +++
scripts/FootSensor.cs | 81 ++++
scripts/GameConnection.cs | 95 ++++
scripts/GameInfo.cs | 24 +
scripts/RootInit.cs | 25 +
scripts/SensorTrigger.cs | 17 +
shaders/ColorSwap.gdshader | 9 +
shaders/FootSensor.gdshader | 19 +
20 files changed, 1433 insertions(+)
create mode 100644 .gitattributes
create mode 100644 .gitignore
create mode 100644 Main.tscn
create mode 100644 README.md
create mode 100644 VRDOM.csproj
create mode 100644 VRDOM.sln
create mode 100644 controller.tres
create mode 100644 controller_collisionshape.tres
create mode 100644 icon.svg
create mode 100644 icon.svg.import
create mode 100644 openxr_action_map.tres
create mode 100644 project.godot
create mode 100644 scripts/DisplayCapture.cs
create mode 100644 scripts/FootSensor.cs
create mode 100644 scripts/GameConnection.cs
create mode 100644 scripts/GameInfo.cs
create mode 100644 scripts/RootInit.cs
create mode 100644 scripts/SensorTrigger.cs
create mode 100644 shaders/ColorSwap.gdshader
create mode 100644 shaders/FootSensor.gdshader
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..8ad74f7
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Normalize EOL for all files that Git considers text files.
+* text=auto eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9b17fa7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+# Godot 4+ specific ignores
+.godot/
+*.dblite
+
+*.dll
+*.lib
+*.exp
+*.obj
\ No newline at end of file
diff --git a/Main.tscn b/Main.tscn
new file mode 100644
index 0000000..4579228
--- /dev/null
+++ b/Main.tscn
@@ -0,0 +1,144 @@
+[gd_scene load_steps=20 format=3 uid="uid://bq81xxba71cxw"]
+
+[ext_resource type="Script" path="res://scripts/RootInit.cs" id="1_i51wy"]
+[ext_resource type="BoxMesh" uid="uid://c86k0m3ggdn76" path="res://controller.tres" id="2_d3qf6"]
+[ext_resource type="Shader" path="res://shaders/ColorSwap.gdshader" id="2_xru62"]
+[ext_resource type="Script" path="res://scripts/FootSensor.cs" id="3_6061f"]
+[ext_resource type="Script" path="res://scripts/SensorTrigger.cs" id="4_thw0t"]
+[ext_resource type="Shader" path="res://shaders/FootSensor.gdshader" id="4_xuw0l"]
+[ext_resource type="Script" path="res://scripts/GameConnection.cs" id="5_44hhi"]
+[ext_resource type="Shape3D" uid="uid://rd2eoar5f4gj" path="res://controller_collisionshape.tres" id="5_py4o4"]
+[ext_resource type="Script" path="res://scripts/DisplayCapture.cs" id="7_ffs0h"]
+
+[sub_resource type="PlaneMesh" id="PlaneMesh_j2hdc"]
+size = Vector2(1.77, 1)
+
+[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_phccb"]
+size = Vector2(1920, 1080)
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_y0wys"]
+render_priority = 0
+shader = ExtResource("2_xru62")
+shader_parameter/texture_albedo = SubResource("PlaceholderTexture2D_phccb")
+
+[sub_resource type="PlaneMesh" id="PlaneMesh_1s0mo"]
+size = Vector2(1.28, 1.65)
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_41fau"]
+render_priority = 0
+shader = ExtResource("4_xuw0l")
+shader_parameter/led_data = null
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_r3gxn"]
+size = Vector3(1.3, 0.08, 1.7)
+
+[sub_resource type="BoxMesh" id="BoxMesh_a5ph8"]
+size = Vector3(0.04, 0.045, 0.05)
+
+[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_cxmum"]
+sky_top_color = Color(0.141176, 0.454902, 0.764706, 1)
+sky_horizon_color = Color(0.901961, 0.65098, 0.678431, 1)
+ground_bottom_color = Color(0.909804, 0.909804, 0.909804, 1)
+
+[sub_resource type="Sky" id="Sky_ifkyq"]
+sky_material = SubResource("ProceduralSkyMaterial_cxmum")
+
+[sub_resource type="Environment" id="Environment_jj1ls"]
+background_mode = 2
+sky = SubResource("Sky_ifkyq")
+ambient_light_source = 3
+ssil_intensity = 3.38
+sdfgi_read_sky_light = false
+glow_enabled = true
+
+[node name="Node3D" type="Node3D"]
+script = ExtResource("1_i51wy")
+
+[node name="XROrigin3D" type="XROrigin3D" parent="."]
+
+[node name="Screen" type="CSGMesh3D" parent="XROrigin3D"]
+transform = Transform3D(0.95, 0, 0, 0, -4.37114e-08, -0.95, 0, 1, -4.15258e-08, 0, 1.22575, -1.19404)
+mesh = SubResource("PlaneMesh_j2hdc")
+material = SubResource("ShaderMaterial_y0wys")
+script = ExtResource("7_ffs0h")
+
+[node name="Foot Sensor Pad" type="CSGMesh3D" parent="XROrigin3D" node_paths=PackedStringArray("_gameConnection")]
+gi_mode = 2
+use_collision = true
+collision_layer = 4
+collision_mask = 4
+mesh = SubResource("PlaneMesh_1s0mo")
+material = SubResource("ShaderMaterial_41fau")
+script = ExtResource("3_6061f")
+_gameConnection = NodePath("../../Game Connection")
+
+[node name="Sensor" type="Area3D" parent="XROrigin3D/Foot Sensor Pad"]
+collision_layer = 3
+collision_mask = 2
+
+[node name="MinMarker" type="Marker3D" parent="XROrigin3D/Foot Sensor Pad/Sensor"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.64, 0, -0.824933)
+
+[node name="MaxMarker" type="Marker3D" parent="XROrigin3D/Foot Sensor Pad/Sensor"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.640241, 0, 0.825155)
+
+[node name="CollisionPolygon3D" type="CollisionShape3D" parent="XROrigin3D/Foot Sensor Pad/Sensor"]
+shape = SubResource("BoxShape3D_r3gxn")
+
+[node name="XRCamera3D" type="XRCamera3D" parent="XROrigin3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.7, 0)
+
+[node name="LeftHand" type="XRController3D" parent="XROrigin3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1, -0.5)
+tracker = &"left_hand"
+
+[node name="Sensor" type="Area3D" parent="XROrigin3D/LeftHand"]
+collision_layer = 2
+collision_mask = 2
+script = ExtResource("4_thw0t")
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="XROrigin3D/LeftHand/Sensor"]
+shape = ExtResource("5_py4o4")
+
+[node name="RayCast3D" type="RayCast3D" parent="XROrigin3D/LeftHand/Sensor"]
+collision_mask = 4
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="XROrigin3D/LeftHand"]
+mesh = ExtResource("2_d3qf6")
+
+[node name="MeshInstance3D2" type="MeshInstance3D" parent="XROrigin3D/LeftHand"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0740553, 0)
+mesh = SubResource("BoxMesh_a5ph8")
+
+[node name="RightHand" type="XRController3D" parent="XROrigin3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 1, -0.5)
+tracker = &"right_hand"
+
+[node name="Sensor" type="Area3D" parent="XROrigin3D/RightHand"]
+collision_layer = 2
+collision_mask = 2
+script = ExtResource("4_thw0t")
+sensorId = 1
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="XROrigin3D/RightHand/Sensor"]
+shape = ExtResource("5_py4o4")
+
+[node name="RayCast3D" type="RayCast3D" parent="XROrigin3D/RightHand/Sensor"]
+collision_mask = 4
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="XROrigin3D/RightHand"]
+mesh = ExtResource("2_d3qf6")
+
+[node name="MeshInstance3D2" type="MeshInstance3D" parent="XROrigin3D/RightHand"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0740553, 0)
+mesh = SubResource("BoxMesh_a5ph8")
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 0.445432, 0.895316, 0, -0.895316, 0.445432, 0, 5.43573, -0.011737)
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_jj1ls")
+
+[node name="Game Connection" type="Node" parent="." node_paths=PackedStringArray("_footSensor")]
+script = ExtResource("5_44hhi")
+_footSensor = NodePath("../XROrigin3D/Foot Sensor Pad")
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1893076
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+# VRDOM
+For the people who
+- spent money on VR
+- live in the middle of bumfuck nowhere and can't just drive 5h to and from the nearest arcade
+
+This is for that one funny 573 dance game with all those pretty lights. Still pretty WIP, the most basic stuff *should* work though.
+
+# Building
+Grab [Godot 4.1 with .NET support](https://godotengine.org/download/windows) and open the project. You may need to install the NuGet packages yourself.
\ No newline at end of file
diff --git a/VRDOM.csproj b/VRDOM.csproj
new file mode 100644
index 0000000..61defb2
--- /dev/null
+++ b/VRDOM.csproj
@@ -0,0 +1,9 @@
+
+
+ net6.0
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/VRDOM.sln b/VRDOM.sln
new file mode 100644
index 0000000..0e3b69b
--- /dev/null
+++ b/VRDOM.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VRDOM", "VRDOM.csproj", "{D520E313-A4E5-4815-81C5-801581B0C76E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ ExportDebug|Any CPU = ExportDebug|Any CPU
+ ExportRelease|Any CPU = ExportRelease|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D520E313-A4E5-4815-81C5-801581B0C76E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D520E313-A4E5-4815-81C5-801581B0C76E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D520E313-A4E5-4815-81C5-801581B0C76E}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
+ {D520E313-A4E5-4815-81C5-801581B0C76E}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
+ {D520E313-A4E5-4815-81C5-801581B0C76E}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
+ {D520E313-A4E5-4815-81C5-801581B0C76E}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/controller.tres b/controller.tres
new file mode 100644
index 0000000..efb2121
--- /dev/null
+++ b/controller.tres
@@ -0,0 +1,4 @@
+[gd_resource type="BoxMesh" format=3 uid="uid://c86k0m3ggdn76"]
+
+[resource]
+size = Vector3(0.1, 0.1, 0.1)
diff --git a/controller_collisionshape.tres b/controller_collisionshape.tres
new file mode 100644
index 0000000..b8a1d79
--- /dev/null
+++ b/controller_collisionshape.tres
@@ -0,0 +1,4 @@
+[gd_resource type="BoxShape3D" format=3 uid="uid://rd2eoar5f4gj"]
+
+[resource]
+size = Vector3(0.1, 0.1, 0.1)
diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000..b370ceb
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1 @@
+
diff --git a/icon.svg.import b/icon.svg.import
new file mode 100644
index 0000000..a610e23
--- /dev/null
+++ b/icon.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dwcpcngsrs8dm"
+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
diff --git a/openxr_action_map.tres b/openxr_action_map.tres
new file mode 100644
index 0000000..f3d1b65
--- /dev/null
+++ b/openxr_action_map.tres
@@ -0,0 +1,835 @@
+[gd_resource type="OpenXRActionMap" load_steps=197 format=3 uid="uid://6jacgy3u6pau"]
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_y062n"]
+resource_name = "trigger"
+localized_name = "Trigger"
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_seerx"]
+resource_name = "trigger_click"
+localized_name = "Trigger click"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_s8iuk"]
+resource_name = "trigger_touch"
+localized_name = "Trigger touching"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_4fliw"]
+resource_name = "grip"
+localized_name = "Grip"
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_vtkrt"]
+resource_name = "grip_click"
+localized_name = "Grip click"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_a4qke"]
+resource_name = "grip_touch"
+localized_name = "Grip touching"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_gtsy0"]
+resource_name = "grip_force"
+localized_name = "Grip force"
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_4t61h"]
+resource_name = "primary"
+localized_name = "Primary joystick/thumbstick/trackpad"
+action_type = 2
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_mbh41"]
+resource_name = "primary_click"
+localized_name = "Primary joystick/thumbstick/trackpad click"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_2b35x"]
+resource_name = "primary_touch"
+localized_name = "Primary joystick/thumbstick/trackpad touching"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_wc4bs"]
+resource_name = "secondary"
+localized_name = "Secondary joystick/thumbstick/trackpad"
+action_type = 2
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_3meys"]
+resource_name = "secondary_click"
+localized_name = "Secondary joystick/thumbstick/trackpad click"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_leb4v"]
+resource_name = "secondary_touch"
+localized_name = "Secondary joystick/thumbstick/trackpad touching"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_ds8ku"]
+resource_name = "menu_button"
+localized_name = "Menu button"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_54yne"]
+resource_name = "select_button"
+localized_name = "Select button"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_3ajip"]
+resource_name = "ax_button"
+localized_name = "A/X button"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_2v5hd"]
+resource_name = "ax_touch"
+localized_name = "A/X touching"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_expdw"]
+resource_name = "by_button"
+localized_name = "B/Y button"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_0138q"]
+resource_name = "by_touch"
+localized_name = "B/Y touching"
+action_type = 0
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_1seqp"]
+resource_name = "default_pose"
+localized_name = "Default pose"
+action_type = 3
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right", "/user/vive_tracker_htcx/role/left_foot", "/user/vive_tracker_htcx/role/right_foot", "/user/vive_tracker_htcx/role/left_shoulder", "/user/vive_tracker_htcx/role/right_shoulder", "/user/vive_tracker_htcx/role/left_elbow", "/user/vive_tracker_htcx/role/right_elbow", "/user/vive_tracker_htcx/role/left_knee", "/user/vive_tracker_htcx/role/right_knee", "/user/vive_tracker_htcx/role/waist", "/user/vive_tracker_htcx/role/chest", "/user/vive_tracker_htcx/role/camera", "/user/vive_tracker_htcx/role/keyboard")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_4cghg"]
+resource_name = "aim_pose"
+localized_name = "Aim pose"
+action_type = 3
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_rvi8w"]
+resource_name = "grip_pose"
+localized_name = "Grip pose"
+action_type = 3
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_sv3of"]
+resource_name = "palm_pose"
+localized_name = "Palm pose"
+action_type = 3
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right")
+
+[sub_resource type="OpenXRAction" id="OpenXRAction_fei5o"]
+resource_name = "haptic"
+localized_name = "Haptic"
+action_type = 4
+toplevel_paths = PackedStringArray("/user/hand/left", "/user/hand/right", "/user/vive_tracker_htcx/role/left_foot", "/user/vive_tracker_htcx/role/right_foot", "/user/vive_tracker_htcx/role/left_shoulder", "/user/vive_tracker_htcx/role/right_shoulder", "/user/vive_tracker_htcx/role/left_elbow", "/user/vive_tracker_htcx/role/right_elbow", "/user/vive_tracker_htcx/role/left_knee", "/user/vive_tracker_htcx/role/right_knee", "/user/vive_tracker_htcx/role/waist", "/user/vive_tracker_htcx/role/chest", "/user/vive_tracker_htcx/role/camera", "/user/vive_tracker_htcx/role/keyboard")
+
+[sub_resource type="OpenXRActionSet" id="OpenXRActionSet_qs6q3"]
+resource_name = "godot"
+localized_name = "Godot action set"
+actions = [SubResource("OpenXRAction_y062n"), SubResource("OpenXRAction_seerx"), SubResource("OpenXRAction_s8iuk"), SubResource("OpenXRAction_4fliw"), SubResource("OpenXRAction_vtkrt"), SubResource("OpenXRAction_a4qke"), SubResource("OpenXRAction_gtsy0"), SubResource("OpenXRAction_4t61h"), SubResource("OpenXRAction_mbh41"), SubResource("OpenXRAction_2b35x"), SubResource("OpenXRAction_wc4bs"), SubResource("OpenXRAction_3meys"), SubResource("OpenXRAction_leb4v"), SubResource("OpenXRAction_ds8ku"), SubResource("OpenXRAction_54yne"), SubResource("OpenXRAction_3ajip"), SubResource("OpenXRAction_2v5hd"), SubResource("OpenXRAction_expdw"), SubResource("OpenXRAction_0138q"), SubResource("OpenXRAction_1seqp"), SubResource("OpenXRAction_4cghg"), SubResource("OpenXRAction_rvi8w"), SubResource("OpenXRAction_sv3of"), SubResource("OpenXRAction_fei5o")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1lr1w"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_mkvmr"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pm370"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_g8wiw"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_upisp"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_375vj"]
+action = SubResource("OpenXRAction_54yne")
+paths = PackedStringArray("/user/hand/left/input/select/click", "/user/hand/right/input/select/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_h7a33"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_l83nv"]
+interaction_profile_path = "/interaction_profiles/khr/simple_controller"
+bindings = [SubResource("OpenXRIPBinding_1lr1w"), SubResource("OpenXRIPBinding_mkvmr"), SubResource("OpenXRIPBinding_pm370"), SubResource("OpenXRIPBinding_g8wiw"), SubResource("OpenXRIPBinding_upisp"), SubResource("OpenXRIPBinding_375vj"), SubResource("OpenXRIPBinding_h7a33")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1dxdc"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gr4le"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7x18d"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_x1gd5"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_eojnc"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_f83ke"]
+action = SubResource("OpenXRAction_54yne")
+paths = PackedStringArray("/user/hand/left/input/system/click", "/user/hand/right/input/system/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_f5b8j"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_iq2bx"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_bpfx6"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5laq6"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jegcb"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_akuse"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/trackpad/click", "/user/hand/right/input/trackpad/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7vqhb"]
+action = SubResource("OpenXRAction_2b35x")
+paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_edu20"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_m56k4"]
+interaction_profile_path = "/interaction_profiles/htc/vive_controller"
+bindings = [SubResource("OpenXRIPBinding_1dxdc"), SubResource("OpenXRIPBinding_gr4le"), SubResource("OpenXRIPBinding_7x18d"), SubResource("OpenXRIPBinding_x1gd5"), SubResource("OpenXRIPBinding_eojnc"), SubResource("OpenXRIPBinding_f83ke"), SubResource("OpenXRIPBinding_f5b8j"), SubResource("OpenXRIPBinding_iq2bx"), SubResource("OpenXRIPBinding_bpfx6"), SubResource("OpenXRIPBinding_5laq6"), SubResource("OpenXRIPBinding_jegcb"), SubResource("OpenXRIPBinding_akuse"), SubResource("OpenXRIPBinding_7vqhb"), SubResource("OpenXRIPBinding_edu20")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_0rios"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ms761"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_hk0al"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_h1ir5"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_blqf0"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1awhh"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_wsxge"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_6xld6"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_vmqoo"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ehcrx"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_vet2g"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_q2dcl"]
+action = SubResource("OpenXRAction_wc4bs")
+paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pdwus"]
+action = SubResource("OpenXRAction_3meys")
+paths = PackedStringArray("/user/hand/left/input/trackpad/click", "/user/hand/right/input/trackpad/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_758rk"]
+action = SubResource("OpenXRAction_leb4v")
+paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ve1pp"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_0nr80"]
+interaction_profile_path = "/interaction_profiles/microsoft/motion_controller"
+bindings = [SubResource("OpenXRIPBinding_0rios"), SubResource("OpenXRIPBinding_ms761"), SubResource("OpenXRIPBinding_hk0al"), SubResource("OpenXRIPBinding_h1ir5"), SubResource("OpenXRIPBinding_blqf0"), SubResource("OpenXRIPBinding_1awhh"), SubResource("OpenXRIPBinding_wsxge"), SubResource("OpenXRIPBinding_6xld6"), SubResource("OpenXRIPBinding_vmqoo"), SubResource("OpenXRIPBinding_ehcrx"), SubResource("OpenXRIPBinding_vet2g"), SubResource("OpenXRIPBinding_q2dcl"), SubResource("OpenXRIPBinding_pdwus"), SubResource("OpenXRIPBinding_758rk"), SubResource("OpenXRIPBinding_ve1pp")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fum5p"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_xbfgg"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qtuq8"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_hwaoo"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_61hx0"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/system/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_6i1a7"]
+action = SubResource("OpenXRAction_3ajip")
+paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_0ensj"]
+action = SubResource("OpenXRAction_2v5hd")
+paths = PackedStringArray("/user/hand/left/input/x/touch", "/user/hand/right/input/a/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qkpjp"]
+action = SubResource("OpenXRAction_expdw")
+paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_g73pc"]
+action = SubResource("OpenXRAction_0138q")
+paths = PackedStringArray("/user/hand/left/input/y/touch", "/user/hand/right/input/b/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_cfodb"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_aa4pf"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_uoek2"]
+action = SubResource("OpenXRAction_s8iuk")
+paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_wh0qn"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_sbuho"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qq2je"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_w0olk"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qcnqk"]
+action = SubResource("OpenXRAction_2b35x")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pb6tx"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_coslu"]
+interaction_profile_path = "/interaction_profiles/oculus/touch_controller"
+bindings = [SubResource("OpenXRIPBinding_fum5p"), SubResource("OpenXRIPBinding_xbfgg"), SubResource("OpenXRIPBinding_qtuq8"), SubResource("OpenXRIPBinding_hwaoo"), SubResource("OpenXRIPBinding_61hx0"), SubResource("OpenXRIPBinding_6i1a7"), SubResource("OpenXRIPBinding_0ensj"), SubResource("OpenXRIPBinding_qkpjp"), SubResource("OpenXRIPBinding_g73pc"), SubResource("OpenXRIPBinding_cfodb"), SubResource("OpenXRIPBinding_aa4pf"), SubResource("OpenXRIPBinding_uoek2"), SubResource("OpenXRIPBinding_wh0qn"), SubResource("OpenXRIPBinding_sbuho"), SubResource("OpenXRIPBinding_qq2je"), SubResource("OpenXRIPBinding_w0olk"), SubResource("OpenXRIPBinding_qcnqk"), SubResource("OpenXRIPBinding_pb6tx")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_wavuv"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qg0bj"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_3b2hc"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nbnpu"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fx2n0"]
+action = SubResource("OpenXRAction_54yne")
+paths = PackedStringArray("/user/hand/left/input/system/click", "/user/hand/right/input/system/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_cnjem"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/back/click", "/user/hand/right/input/back/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_17m8t"]
+action = SubResource("OpenXRAction_3ajip")
+paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_2d0nq"]
+action = SubResource("OpenXRAction_2v5hd")
+paths = PackedStringArray("/user/hand/left/input/x/touch", "/user/hand/right/input/a/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_2btaf"]
+action = SubResource("OpenXRAction_expdw")
+paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_oo1jo"]
+action = SubResource("OpenXRAction_0138q")
+paths = PackedStringArray("/user/hand/left/input/y/touch", "/user/hand/right/input/b/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_mcxpd"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_dt10d"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_da06j"]
+action = SubResource("OpenXRAction_s8iuk")
+paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_8mcic"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ej0ux"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1l68r"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1c8ws"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pk2h5"]
+action = SubResource("OpenXRAction_2b35x")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_0g3ls"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_dwef8"]
+interaction_profile_path = "/interaction_profiles/pico/neo3_controller"
+bindings = [SubResource("OpenXRIPBinding_wavuv"), SubResource("OpenXRIPBinding_qg0bj"), SubResource("OpenXRIPBinding_3b2hc"), SubResource("OpenXRIPBinding_nbnpu"), SubResource("OpenXRIPBinding_fx2n0"), SubResource("OpenXRIPBinding_cnjem"), SubResource("OpenXRIPBinding_17m8t"), SubResource("OpenXRIPBinding_2d0nq"), SubResource("OpenXRIPBinding_2btaf"), SubResource("OpenXRIPBinding_oo1jo"), SubResource("OpenXRIPBinding_mcxpd"), SubResource("OpenXRIPBinding_dt10d"), SubResource("OpenXRIPBinding_da06j"), SubResource("OpenXRIPBinding_8mcic"), SubResource("OpenXRIPBinding_ej0ux"), SubResource("OpenXRIPBinding_1l68r"), SubResource("OpenXRIPBinding_1c8ws"), SubResource("OpenXRIPBinding_pk2h5"), SubResource("OpenXRIPBinding_0g3ls")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_vrpj5"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ryr8e"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_og7cr"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_oukxt"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7sojt"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/system/click", "/user/hand/right/input/system/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_j2vfe"]
+action = SubResource("OpenXRAction_3ajip")
+paths = PackedStringArray("/user/hand/left/input/a/click", "/user/hand/right/input/a/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ee1qf"]
+action = SubResource("OpenXRAction_2v5hd")
+paths = PackedStringArray("/user/hand/left/input/a/touch", "/user/hand/right/input/a/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ywty5"]
+action = SubResource("OpenXRAction_expdw")
+paths = PackedStringArray("/user/hand/left/input/b/click", "/user/hand/right/input/b/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_g0yxg"]
+action = SubResource("OpenXRAction_0138q")
+paths = PackedStringArray("/user/hand/left/input/b/touch", "/user/hand/right/input/b/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_vlagd"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_hlhwq"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_k2pgv"]
+action = SubResource("OpenXRAction_s8iuk")
+paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gq6rk"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_3n3gf"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1ky72"]
+action = SubResource("OpenXRAction_gtsy0")
+paths = PackedStringArray("/user/hand/left/input/squeeze/force", "/user/hand/right/input/squeeze/force")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_x06h7"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jr3bv"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_x4v5r"]
+action = SubResource("OpenXRAction_2b35x")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5jh43"]
+action = SubResource("OpenXRAction_wc4bs")
+paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_xj2ji"]
+action = SubResource("OpenXRAction_3meys")
+paths = PackedStringArray("/user/hand/left/input/trackpad/force", "/user/hand/right/input/trackpad/force")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_t3c1u"]
+action = SubResource("OpenXRAction_leb4v")
+paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ld2y0"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_orejf"]
+interaction_profile_path = "/interaction_profiles/valve/index_controller"
+bindings = [SubResource("OpenXRIPBinding_vrpj5"), SubResource("OpenXRIPBinding_ryr8e"), SubResource("OpenXRIPBinding_og7cr"), SubResource("OpenXRIPBinding_oukxt"), SubResource("OpenXRIPBinding_7sojt"), SubResource("OpenXRIPBinding_j2vfe"), SubResource("OpenXRIPBinding_ee1qf"), SubResource("OpenXRIPBinding_ywty5"), SubResource("OpenXRIPBinding_g0yxg"), SubResource("OpenXRIPBinding_vlagd"), SubResource("OpenXRIPBinding_hlhwq"), SubResource("OpenXRIPBinding_k2pgv"), SubResource("OpenXRIPBinding_gq6rk"), SubResource("OpenXRIPBinding_3n3gf"), SubResource("OpenXRIPBinding_1ky72"), SubResource("OpenXRIPBinding_x06h7"), SubResource("OpenXRIPBinding_jr3bv"), SubResource("OpenXRIPBinding_x4v5r"), SubResource("OpenXRIPBinding_5jh43"), SubResource("OpenXRIPBinding_xj2ji"), SubResource("OpenXRIPBinding_t3c1u"), SubResource("OpenXRIPBinding_ld2y0")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nwe24"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_62a71"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_flxka"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_07yjo"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7aoxy"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_mrwqd"]
+action = SubResource("OpenXRAction_3ajip")
+paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_onpfa"]
+action = SubResource("OpenXRAction_expdw")
+paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_0664x"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_w807y"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fra6p"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_sb4na"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/value", "/user/hand/right/input/squeeze/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_8rtwo"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qrr2e"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_gnbgw"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_jcpt7"]
+interaction_profile_path = "/interaction_profiles/hp/mixed_reality_controller"
+bindings = [SubResource("OpenXRIPBinding_nwe24"), SubResource("OpenXRIPBinding_62a71"), SubResource("OpenXRIPBinding_flxka"), SubResource("OpenXRIPBinding_07yjo"), SubResource("OpenXRIPBinding_7aoxy"), SubResource("OpenXRIPBinding_mrwqd"), SubResource("OpenXRIPBinding_onpfa"), SubResource("OpenXRIPBinding_0664x"), SubResource("OpenXRIPBinding_w807y"), SubResource("OpenXRIPBinding_fra6p"), SubResource("OpenXRIPBinding_sb4na"), SubResource("OpenXRIPBinding_8rtwo"), SubResource("OpenXRIPBinding_qrr2e"), SubResource("OpenXRIPBinding_gnbgw")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_kdnwj"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_smeve"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fglyf"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_yc6jt"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_8fwi4"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click", "/user/hand/right/input/menu/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7nkhk"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jy8rl"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_hpgo7"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_4q5ub"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_nelm6"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ph4wk"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1661t"]
+action = SubResource("OpenXRAction_wc4bs")
+paths = PackedStringArray("/user/hand/left/input/trackpad", "/user/hand/right/input/trackpad")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_l5otv"]
+action = SubResource("OpenXRAction_3meys")
+paths = PackedStringArray("/user/hand/left/input/trackpad/click", "/user/hand/right/input/trackpad/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pvix6"]
+action = SubResource("OpenXRAction_leb4v")
+paths = PackedStringArray("/user/hand/left/input/trackpad/touch", "/user/hand/right/input/trackpad/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_wc3gb"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_vdhpc"]
+interaction_profile_path = "/interaction_profiles/samsung/odyssey_controller"
+bindings = [SubResource("OpenXRIPBinding_kdnwj"), SubResource("OpenXRIPBinding_smeve"), SubResource("OpenXRIPBinding_fglyf"), SubResource("OpenXRIPBinding_yc6jt"), SubResource("OpenXRIPBinding_8fwi4"), SubResource("OpenXRIPBinding_7nkhk"), SubResource("OpenXRIPBinding_jy8rl"), SubResource("OpenXRIPBinding_hpgo7"), SubResource("OpenXRIPBinding_4q5ub"), SubResource("OpenXRIPBinding_nelm6"), SubResource("OpenXRIPBinding_ph4wk"), SubResource("OpenXRIPBinding_1661t"), SubResource("OpenXRIPBinding_l5otv"), SubResource("OpenXRIPBinding_pvix6"), SubResource("OpenXRIPBinding_wc3gb")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_6pq45"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_q21y2"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_fxbve"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_x82yu"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_dfgrh"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ldgwr"]
+action = SubResource("OpenXRAction_54yne")
+paths = PackedStringArray("/user/hand/right/input/system/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_7mbc0"]
+action = SubResource("OpenXRAction_3ajip")
+paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_8puxy"]
+action = SubResource("OpenXRAction_expdw")
+paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ogvyw"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_662xs"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_0gpqb"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_64uy7"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_no5tl"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_stsrw"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_rhl1w"]
+action = SubResource("OpenXRAction_2b35x")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_awhlk"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_ymb65"]
+interaction_profile_path = "/interaction_profiles/htc/vive_cosmos_controller"
+bindings = [SubResource("OpenXRIPBinding_6pq45"), SubResource("OpenXRIPBinding_q21y2"), SubResource("OpenXRIPBinding_fxbve"), SubResource("OpenXRIPBinding_x82yu"), SubResource("OpenXRIPBinding_dfgrh"), SubResource("OpenXRIPBinding_ldgwr"), SubResource("OpenXRIPBinding_7mbc0"), SubResource("OpenXRIPBinding_8puxy"), SubResource("OpenXRIPBinding_ogvyw"), SubResource("OpenXRIPBinding_662xs"), SubResource("OpenXRIPBinding_0gpqb"), SubResource("OpenXRIPBinding_64uy7"), SubResource("OpenXRIPBinding_no5tl"), SubResource("OpenXRIPBinding_stsrw"), SubResource("OpenXRIPBinding_rhl1w"), SubResource("OpenXRIPBinding_awhlk")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_r45x1"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_v3j5x"]
+action = SubResource("OpenXRAction_4cghg")
+paths = PackedStringArray("/user/hand/left/input/aim/pose", "/user/hand/right/input/aim/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_i5lfi"]
+action = SubResource("OpenXRAction_rvi8w")
+paths = PackedStringArray("/user/hand/left/input/grip/pose", "/user/hand/right/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_je57r"]
+action = SubResource("OpenXRAction_sv3of")
+paths = PackedStringArray("/user/hand/left/input/palm_ext/pose", "/user/hand/right/input/palm_ext/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_pikjn"]
+action = SubResource("OpenXRAction_ds8ku")
+paths = PackedStringArray("/user/hand/left/input/menu/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_wkuva"]
+action = SubResource("OpenXRAction_54yne")
+paths = PackedStringArray("/user/hand/right/input/system/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_llgws"]
+action = SubResource("OpenXRAction_3ajip")
+paths = PackedStringArray("/user/hand/left/input/x/click", "/user/hand/right/input/a/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_6fk1c"]
+action = SubResource("OpenXRAction_expdw")
+paths = PackedStringArray("/user/hand/left/input/y/click", "/user/hand/right/input/b/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_o3tve"]
+action = SubResource("OpenXRAction_y062n")
+paths = PackedStringArray("/user/hand/left/input/trigger/value", "/user/hand/right/input/trigger/value")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_kcw08"]
+action = SubResource("OpenXRAction_seerx")
+paths = PackedStringArray("/user/hand/left/input/trigger/click", "/user/hand/right/input/trigger/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_1rhrb"]
+action = SubResource("OpenXRAction_s8iuk")
+paths = PackedStringArray("/user/hand/left/input/trigger/touch", "/user/hand/right/input/trigger/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_qigcd"]
+action = SubResource("OpenXRAction_4fliw")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_l883a"]
+action = SubResource("OpenXRAction_vtkrt")
+paths = PackedStringArray("/user/hand/left/input/squeeze/click", "/user/hand/right/input/squeeze/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_5si61"]
+action = SubResource("OpenXRAction_4t61h")
+paths = PackedStringArray("/user/hand/left/input/thumbstick", "/user/hand/right/input/thumbstick")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_481oo"]
+action = SubResource("OpenXRAction_mbh41")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/click", "/user/hand/right/input/thumbstick/click")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_o480n"]
+action = SubResource("OpenXRAction_2b35x")
+paths = PackedStringArray("/user/hand/left/input/thumbstick/touch", "/user/hand/right/input/thumbstick/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_ynweh"]
+action = SubResource("OpenXRAction_leb4v")
+paths = PackedStringArray("/user/hand/left/input/thumbrest/touch", "/user/hand/right/input/thumbrest/touch")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_mtx5n"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/hand/left/output/haptic", "/user/hand/right/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_mbvhu"]
+interaction_profile_path = "/interaction_profiles/htc/vive_focus3_controller"
+bindings = [SubResource("OpenXRIPBinding_r45x1"), SubResource("OpenXRIPBinding_v3j5x"), SubResource("OpenXRIPBinding_i5lfi"), SubResource("OpenXRIPBinding_je57r"), SubResource("OpenXRIPBinding_pikjn"), SubResource("OpenXRIPBinding_wkuva"), SubResource("OpenXRIPBinding_llgws"), SubResource("OpenXRIPBinding_6fk1c"), SubResource("OpenXRIPBinding_o3tve"), SubResource("OpenXRIPBinding_kcw08"), SubResource("OpenXRIPBinding_1rhrb"), SubResource("OpenXRIPBinding_qigcd"), SubResource("OpenXRIPBinding_l883a"), SubResource("OpenXRIPBinding_5si61"), SubResource("OpenXRIPBinding_481oo"), SubResource("OpenXRIPBinding_o480n"), SubResource("OpenXRIPBinding_ynweh"), SubResource("OpenXRIPBinding_mtx5n")]
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_3xtv4"]
+action = SubResource("OpenXRAction_1seqp")
+paths = PackedStringArray("/user/vive_tracker_htcx/role/left_foot/input/grip/pose", "/user/vive_tracker_htcx/role/right_foot/input/grip/pose", "/user/vive_tracker_htcx/role/left_shoulder/input/grip/pose", "/user/vive_tracker_htcx/role/right_shoulder/input/grip/pose", "/user/vive_tracker_htcx/role/left_elbow/input/grip/pose", "/user/vive_tracker_htcx/role/right_elbow/input/grip/pose", "/user/vive_tracker_htcx/role/left_knee/input/grip/pose", "/user/vive_tracker_htcx/role/right_knee/input/grip/pose", "/user/vive_tracker_htcx/role/waist/input/grip/pose", "/user/vive_tracker_htcx/role/chest/input/grip/pose", "/user/vive_tracker_htcx/role/camera/input/grip/pose", "/user/vive_tracker_htcx/role/keyboard/input/grip/pose")
+
+[sub_resource type="OpenXRIPBinding" id="OpenXRIPBinding_jsp5c"]
+action = SubResource("OpenXRAction_fei5o")
+paths = PackedStringArray("/user/vive_tracker_htcx/role/left_foot/output/haptic", "/user/vive_tracker_htcx/role/right_foot/output/haptic", "/user/vive_tracker_htcx/role/left_shoulder/output/haptic", "/user/vive_tracker_htcx/role/right_shoulder/output/haptic", "/user/vive_tracker_htcx/role/left_elbow/output/haptic", "/user/vive_tracker_htcx/role/right_elbow/output/haptic", "/user/vive_tracker_htcx/role/left_knee/output/haptic", "/user/vive_tracker_htcx/role/right_knee/output/haptic", "/user/vive_tracker_htcx/role/waist/output/haptic", "/user/vive_tracker_htcx/role/chest/output/haptic", "/user/vive_tracker_htcx/role/camera/output/haptic", "/user/vive_tracker_htcx/role/keyboard/output/haptic")
+
+[sub_resource type="OpenXRInteractionProfile" id="OpenXRInteractionProfile_5qrmo"]
+interaction_profile_path = "/interaction_profiles/htc/vive_tracker_htcx"
+bindings = [SubResource("OpenXRIPBinding_3xtv4"), SubResource("OpenXRIPBinding_jsp5c")]
+
+[resource]
+action_sets = [SubResource("OpenXRActionSet_qs6q3")]
+interaction_profiles = [SubResource("OpenXRInteractionProfile_l83nv"), SubResource("OpenXRInteractionProfile_m56k4"), SubResource("OpenXRInteractionProfile_0nr80"), SubResource("OpenXRInteractionProfile_coslu"), SubResource("OpenXRInteractionProfile_dwef8"), SubResource("OpenXRInteractionProfile_orejf"), SubResource("OpenXRInteractionProfile_jcpt7"), SubResource("OpenXRInteractionProfile_vdhpc"), SubResource("OpenXRInteractionProfile_ymb65"), SubResource("OpenXRInteractionProfile_mbvhu"), SubResource("OpenXRInteractionProfile_5qrmo")]
diff --git a/project.godot b/project.godot
new file mode 100644
index 0000000..ca370cc
--- /dev/null
+++ b/project.godot
@@ -0,0 +1,25 @@
+; 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="VRDOM"
+run/main_scene="res://Main.tscn"
+config/features=PackedStringArray("4.1", "C#", "Forward Plus")
+config/icon="res://icon.svg"
+
+[dotnet]
+
+project/assembly_name="VRDOM"
+
+[xr]
+
+openxr/enabled=true
+shaders/enabled=true
diff --git a/scripts/DisplayCapture.cs b/scripts/DisplayCapture.cs
new file mode 100644
index 0000000..81c2379
--- /dev/null
+++ b/scripts/DisplayCapture.cs
@@ -0,0 +1,66 @@
+using System.Threading;
+using System.Collections.Generic;
+using System.Linq;
+using Godot;
+using ScreenCapture.NET;
+
+public partial class DisplayCapture : CsgMesh3D
+{
+ private IScreenCapture _screenCapture;
+ private CaptureZone _capZone;
+ private ImageTexture _texture;
+ private Image _image;
+ private Thread _capThread;
+ private CancellationTokenSource cancel = new CancellationTokenSource();
+
+ public override void _Ready()
+ {
+ // Create a screen-capture service
+ IScreenCaptureService screenCaptureService = new DX11ScreenCaptureService();
+
+ // Get all available graphics cards
+ IEnumerable graphicsCards = screenCaptureService.GetGraphicsCards();
+
+ // Get the displays from the graphics card(s) you are interested in
+ IEnumerable displays = screenCaptureService.GetDisplays(graphicsCards.First());
+
+ // Create a screen-capture for all screens you want to capture
+ _screenCapture = screenCaptureService.GetScreenCapture(displays.First());
+
+ // Register the regions you want to capture on the screen
+ // Capture the whole screen
+ _capZone = _screenCapture.RegisterCaptureZone(0, 0, _screenCapture.Display.Width, _screenCapture.Display.Height);
+
+ _image = Image.Create(_capZone.Width, _capZone.Height, false, Image.Format.Rgba8);
+ _image.Fill(Color.Color8(0, 0, 0, 255));
+ _texture = ImageTexture.CreateFromImage(_image);
+
+ _capThread = new(new ThreadStart(RefreshCaptureThread));
+ _capThread.Start();
+ }
+
+ void RefreshCaptureThread()
+ {
+ while (!cancel.IsCancellationRequested)
+ {
+ _screenCapture.CaptureScreen();
+ lock (_capZone.Buffer)
+ {
+ _image.SetData(_capZone.Width, _capZone.Height, false, Image.Format.Rgba8, _capZone.Buffer);
+ _texture.CallDeferred(ImageTexture.MethodName.Update, _image);
+ Thread.Sleep(16);
+ }
+ }
+ }
+
+ public override void _ExitTree()
+ {
+ cancel.Cancel();
+ _screenCapture.Dispose();
+ }
+
+ public override void _Process(double delta)
+ {
+ (Material as ShaderMaterial).SetShaderParameter("texture_albedo", _texture);
+ }
+}
\ No newline at end of file
diff --git a/scripts/FootSensor.cs b/scripts/FootSensor.cs
new file mode 100644
index 0000000..d982236
--- /dev/null
+++ b/scripts/FootSensor.cs
@@ -0,0 +1,81 @@
+using System.Collections.Generic;
+using Godot;
+using VRDOM;
+
+public partial class FootSensor : CsgMesh3D
+{
+ [Export]
+ private GameConnection _gameConnection;
+
+ private Area3D _sensor;
+ private Marker3D MinMarker;
+ private Marker3D MaxMarker;
+ private Dictionary _activeSensors = new Dictionary();
+ public Vector3[] gpu_led_data = new Vector3[1862];
+ private Vector2 defaultTouchSize = new Vector2(0.15f, 0.15f);
+
+ public override void _PhysicsProcess(double delta)
+ {
+ List touchCommands = new List();
+
+ foreach (var pair in _activeSensors)
+ _activeSensors[pair.Key] = false;
+
+ foreach (Area3D area in _sensor.GetOverlappingAreas())
+ {
+ var sensorTrigger = area as SensorTrigger;
+ RayCast3D raycast = area.GetNode("RayCast3D") as RayCast3D;
+ if (raycast.IsColliding())
+ {
+ if (_activeSensors.ContainsKey(sensorTrigger.sensorId))
+ {
+ _activeSensors[sensorTrigger.sensorId] = true;
+ //GD.Print($"move event on {sensorTrigger.sensorId}!");
+ //move event!
+ touchCommands.Add(new TouchCommand(sensorTrigger.sensorId, (int)TouchEvents.TOUCH_MOVE, GetLocalTouchPosition(new Vector2(raycast.GetCollisionPoint().X, raycast.GetCollisionPoint().Z)), defaultTouchSize));
+
+ }
+ else
+ {
+ _activeSensors.Add(sensorTrigger.sensorId, true);
+ //GD.Print($"down event on {sensorTrigger.sensorId}!");
+ //down event!
+ touchCommands.Add(new TouchCommand(sensorTrigger.sensorId, (int)TouchEvents.TOUCH_DOWN, GetLocalTouchPosition(new Vector2(raycast.GetCollisionPoint().X, raycast.GetCollisionPoint().Z)), defaultTouchSize));
+ }
+ }
+ }
+
+ foreach (var pair in _activeSensors)
+ {
+ if (pair.Value == false)
+ {
+ _activeSensors.Remove(pair.Key);
+ //GD.Print($"up event on {pair.Key}!");
+ //up event!
+ touchCommands.Add(new TouchCommand(pair.Key, (int)TouchEvents.TOUCH_UP, new Vector2(0, 0), defaultTouchSize));
+ }
+ }
+ _gameConnection.setTouch(touchCommands);
+ }
+
+ public Vector2 GetLocalTouchPosition(Vector2 vec)
+ {
+ float x = 1 - (vec.X - MinMarker.GlobalPosition.X) / (MaxMarker.GlobalPosition.X - MinMarker.GlobalPosition.X);
+ float y = 1 - (vec.Y - MinMarker.GlobalPosition.Z) / (MaxMarker.GlobalPosition.Z - MinMarker.GlobalPosition.Z);
+ return new Vector2(1 - x, 1 - y);
+ }
+
+ // Called when the node enters the scene tree for the first time.
+ public override void _Ready()
+ {
+ _sensor = GetNode("Sensor") as Area3D;
+ MinMarker = GetNode("Sensor/MinMarker") as Marker3D;
+ MaxMarker = GetNode("Sensor/MaxMarker") as Marker3D;
+ }
+
+ // Called every frame. 'delta' is the elapsed time since the previous frame.
+ public override void _Process(double delta)
+ {
+ (Material as ShaderMaterial).SetShaderParameter("led_data", gpu_led_data);
+ }
+}
diff --git a/scripts/GameConnection.cs b/scripts/GameConnection.cs
new file mode 100644
index 0000000..7c46b8c
--- /dev/null
+++ b/scripts/GameConnection.cs
@@ -0,0 +1,95 @@
+using Godot;
+using System.Collections.Generic;
+using System.Text;
+using VRDOM;
+
+public partial class GameConnection : Node
+{
+ [Export]
+ private string _websocket_url = "ws://localhost:9002";
+ [Export]
+ private FootSensor _footSensor;
+
+ private WebSocketPeer wsPeer = new WebSocketPeer();
+ double lightingGetInterval = 0.0166;
+ double lightingGetTimer = 0;
+
+ public void getLighting()
+ {
+ if (wsPeer.GetReadyState() == WebSocketPeer.State.Open)
+ wsPeer.Send(Encoding.UTF8.GetBytes("{\"id\":0,\"module\":\"drs\",\"function\":\"tapeled_get\",\"params\":[]}"));
+ }
+
+ public void setTouch(List touchCommands)
+ {
+ if (touchCommands.Count == 0)
+ return;
+
+ if (wsPeer.GetReadyState() == WebSocketPeer.State.Open)
+ {
+ string touchCommandString = "{\"id\":1,\"module\":\"drs\",\"function\":\"touch_set\",\"params\":[";
+ foreach (var touchCommand in touchCommands)
+ {
+ touchCommandString += "[" + touchCommand.touchEvent + "," + touchCommand.sensorId + "," + touchCommand.touchPosition.X.ToString("0.0000") + "," + touchCommand.touchPosition.Y.ToString("0.0000") + "," + touchCommand.touchSize.X + "," + touchCommand.touchSize.Y + "],";
+ }
+ touchCommandString = touchCommandString.Remove(touchCommandString.Length - 1);
+ touchCommandString += "]}";
+ wsPeer.Send(Encoding.UTF8.GetBytes(touchCommandString));
+ }
+ }
+
+ // Called when the node enters the scene tree for the first time.
+ public override void _Ready()
+ {
+ GD.Print("Connecting WebSocket...");
+ wsPeer.ConnectToUrl(_websocket_url);
+ wsPeer.EncodeBufferMaxSize = 16 * 1024 * 1024;
+ wsPeer.InboundBufferSize = 16 * 1024 * 1024;
+ wsPeer.OutboundBufferSize = 16 * 1024 * 1024;
+ }
+
+ // Called every frame. 'delta' is the elapsed time since the previous frame.
+ public override void _Process(double delta)
+ {
+ lightingGetTimer += delta;
+ wsPeer.Poll();
+ var state = wsPeer.GetReadyState();
+ switch (state)
+ {
+ case WebSocketPeer.State.Open:
+ if (lightingGetTimer >= lightingGetInterval)
+ {
+ getLighting();
+ lightingGetTimer = 0;
+ }
+
+ for (int i = 0; i < wsPeer.GetAvailablePacketCount(); i++)
+ {
+ string packetText = Encoding.UTF8.GetString(wsPeer.GetPacket());
+ if (packetText.Contains("id"))
+ {
+ var dict = Json.ParseString(packetText).AsGodotDictionary();
+ if (dict.ContainsKey("data") && dict["id"].AsInt32() == 0)
+ {
+ int[] ledData = dict["data"].AsGodotArray()[0].AsInt32Array();
+ //The LED data is in the format of [r, g, b, r, g, b, ...]
+ //We need to turn that into an array of Vector3s and then push that to the shader
+ for (int j = 0; j < ledData.Length; j += 3)
+ {
+ _footSensor.gpu_led_data[j / 3] = new Vector3(ledData[j], ledData[j + 1], ledData[j + 2]);
+ }
+ }
+ }
+ }
+ break;
+ case WebSocketPeer.State.Closed:
+ GD.Print("WebSocket closed.");
+ var code = wsPeer.GetCloseCode();
+ var reason = wsPeer.GetCloseReason();
+ GD.Print("WebSocket closed with code: %d, reason %s. Clean: %s", code, reason, code != -1);
+
+ SetProcess(false);
+ break;
+ }
+ }
+}
diff --git a/scripts/GameInfo.cs b/scripts/GameInfo.cs
new file mode 100644
index 0000000..d2474cb
--- /dev/null
+++ b/scripts/GameInfo.cs
@@ -0,0 +1,24 @@
+using Godot;
+
+namespace VRDOM;
+
+public enum TouchEvents
+{
+ TOUCH_DOWN = 0,
+ TOUCH_UP = 1,
+ TOUCH_MOVE = 2,
+}
+
+public class TouchCommand {
+ public int sensorId;
+ public int touchEvent;
+ public Vector2 touchPosition;
+ public Vector2 touchSize;
+
+ public TouchCommand(int sensorId, int touchEvent, Vector2 touchPosition, Vector2 touchSize) {
+ this.sensorId = sensorId;
+ this.touchEvent = touchEvent;
+ this.touchPosition = touchPosition;
+ this.touchSize = touchSize;
+ }
+}
\ No newline at end of file
diff --git a/scripts/RootInit.cs b/scripts/RootInit.cs
new file mode 100644
index 0000000..6b9d8f8
--- /dev/null
+++ b/scripts/RootInit.cs
@@ -0,0 +1,25 @@
+using Godot;
+
+public partial class RootInit : Node3D
+{
+ private XRInterface _xrInterface;
+
+ public override void _Ready()
+ {
+ _xrInterface = XRServer.FindInterface("OpenXR");
+ if(_xrInterface != null && _xrInterface.IsInitialized())
+ {
+ GD.Print("OpenXR initialized successfully");
+
+ // Turn off v-sync!
+ DisplayServer.WindowSetVsyncMode(DisplayServer.VSyncMode.Disabled);
+
+ // Change our main viewport to output to the HMD
+ GetViewport().UseXR = true;
+ }
+ else
+ {
+ GD.Print("OpenXR not initialized, please check if your headset is connected");
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/SensorTrigger.cs b/scripts/SensorTrigger.cs
new file mode 100644
index 0000000..e57621a
--- /dev/null
+++ b/scripts/SensorTrigger.cs
@@ -0,0 +1,17 @@
+using Godot;
+
+public partial class SensorTrigger : Area3D
+{
+ [Export]
+ public int sensorId;
+
+ // Called when the node enters the scene tree for the first time.
+ public override void _Ready()
+ {
+ }
+
+ // Called every frame. 'delta' is the elapsed time since the previous frame.
+ public override void _Process(double delta)
+ {
+ }
+}
diff --git a/shaders/ColorSwap.gdshader b/shaders/ColorSwap.gdshader
new file mode 100644
index 0000000..1a20d8f
--- /dev/null
+++ b/shaders/ColorSwap.gdshader
@@ -0,0 +1,9 @@
+shader_type spatial;
+render_mode unshaded;
+uniform sampler2D texture_albedo : source_color;
+void fragment()
+{
+ vec4 albedo_tex = texture(texture_albedo, UV);
+ ALBEDO = albedo_tex.bgr;
+ ALPHA = albedo_tex.a;
+}
\ No newline at end of file
diff --git a/shaders/FootSensor.gdshader b/shaders/FootSensor.gdshader
new file mode 100644
index 0000000..2de7d49
--- /dev/null
+++ b/shaders/FootSensor.gdshader
@@ -0,0 +1,19 @@
+shader_type spatial;
+uniform vec3 led_data[1862];
+const int SIZE_Y = 49;
+const int SIZE_X = 38;
+void fragment() {
+ int coord_y = int(floor(float(SIZE_Y) * UV.y));
+ int coord_x = int(floor(float(SIZE_X) * UV.x));
+
+ vec3 coord_color = led_data[(coord_y * SIZE_X + coord_x)];
+
+ vec2 local_UV = vec2((UV.x - float(coord_x) * 1.0/float(SIZE_X))*float(SIZE_X),
+ (UV.y - float(coord_y) * 1.0/float(SIZE_Y))*float(SIZE_Y));
+
+ float dist = ((local_UV.x - 0.5)*(local_UV.x - 0.5) + (local_UV.y - 0.5)*(local_UV.y - 0.5));
+ float factor = exp(-25.0*dist);
+
+ ALBEDO = factor*coord_color;
+ EMISSION = ALBEDO;
+}
\ No newline at end of file