Redo main scene

Much simpler XR setup based on Bastiaan Olij's Dev stream 58
Correctly applied bone deformation in Mi-2 model
This commit is contained in:
attila-vr 2025-02-18 11:34:59 +01:00
parent 9ebb025f8a
commit 4ddccdaf62
15 changed files with 181 additions and 104 deletions

View file

@ -1 +0,0 @@
uid://46i64f2dmonl

View file

@ -1 +0,0 @@
uid://c086s0jrgaiwi

View file

@ -1,6 +0,0 @@
extends Node3D
@export var connector: MarshConnector
func _process(_delta: float) -> void:
transform = connector.get_aircraft()

View file

@ -0,0 +1,19 @@
extends Node3D
@onready var connector = $MarshConnector
@onready var skeleton = $"Mi-2/Armature/Skeleton3D"
@onready var attitude_root = $AttitudeRoot
@onready var bone_cg: int = skeleton.find_bone("BodyCG")
func _process(_delta: float) -> void:
var target: Transform3D = connector.get_aircraft()
position = target.origin
# Add the rotation to the bone
var rest = skeleton.get_bone_rest(bone_cg).basis.get_rotation_quaternion()
var attitude = target.basis.get_rotation_quaternion()
skeleton.set_bone_pose_rotation(bone_cg, attitude * rest)
# Rotate other children (not using BoneAttachment3D due to jitter)
attitude_root.rotation = target.basis.get_euler()

View file

@ -0,0 +1,26 @@
[gd_scene load_steps=4 format=3 uid="uid://bj1s0g7ixjw71"]
[ext_resource type="Script" uid="uid://cx30pr7kn4c74" path="res://aircraft/aircraft.gd" id="1_l4uib"]
[ext_resource type="PackedScene" uid="uid://cux4tju0ovvly" path="res://assets/mi2/Mi-2.glb" id="1_mrxe8"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mrxe8"]
[node name="Aircraft" type="Node3D"]
script = ExtResource("1_l4uib")
[node name="Mi-2" parent="." instance=ExtResource("1_mrxe8")]
[node name="Łopata" parent="Mi-2/Armature/Skeleton3D" index="16"]
material_override = SubResource("StandardMaterial3D_mrxe8")
[node name="AttitudeRoot" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.4, 0)
[node name="XROrigin3D" type="XROrigin3D" parent="AttitudeRoot"]
transform = Transform3D(-1, 0, -8.74227e-08, 0, 0.999999, 0, 8.74228e-08, 0, -0.999999, 0.214, -0.721897, 1.53478)
[node name="XRCamera3D" type="XRCamera3D" parent="AttitudeRoot/XROrigin3D"]
[node name="MarshConnector" type="MarshConnector" parent="."]
[editable path="Mi-2"]

BIN
project/assets/mi2/Mi-2.glb (Stored with Git LFS)

Binary file not shown.

View file

@ -1,38 +0,0 @@
[gd_scene load_steps=8 format=3 uid="uid://cx82op4eecbwr"]
[ext_resource type="Script" uid="uid://cx30pr7kn4c74" path="res://aircraft.gd" id="1_hips3"]
[ext_resource type="PackedScene" uid="uid://qbmx03iibuuu" path="res://addons/godot-xr-tools/staging/scene_base.tscn" id="1_k0lu6"]
[sub_resource type="BoxMesh" id="BoxMesh_2w36v"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_4tcqf"]
[sub_resource type="Sky" id="Sky_0xm2m"]
sky_material = SubResource("ProceduralSkyMaterial_4tcqf")
[sub_resource type="Environment" id="Environment_jdgxj"]
background_mode = 2
sky = SubResource("Sky_0xm2m")
[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_fpvso"]
[node name="SceneBase" instance=ExtResource("1_k0lu6")]
[node name="XROrigin3D" parent="." index="0"]
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, -3)
[node name="MarshConnector" type="MarshConnector" parent="." index="1"]
[node name="Aircraft" type="Node3D" parent="." index="2" node_paths=PackedStringArray("connector")]
script = ExtResource("1_hips3")
connector = NodePath("../MarshConnector")
[node name="MeshInstance3D" type="MeshInstance3D" parent="Aircraft" index="0"]
mesh = SubResource("BoxMesh_2w36v")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." index="3"]
transform = Transform3D(-0.707107, -0.683013, 0.183013, 0, 0.258819, 0.965926, -0.707107, 0.683013, -0.183013, 3, 3, 3)
[node name="WorldEnvironment" type="WorldEnvironment" parent="." index="4"]
environment = SubResource("Environment_jdgxj")
camera_attributes = SubResource("CameraAttributesPractical_fpvso")

View file

@ -1,37 +1,27 @@
[gd_scene load_steps=7 format=3 uid="uid://cjrkxv8ix1h8s"]
[gd_scene load_steps=6 format=3 uid="uid://crq3o0eu4y8ya"]
[ext_resource type="Script" uid="uid://cx30pr7kn4c74" path="res://aircraft.gd" id="1_ig7tw"]
[ext_resource type="Script" path="res://start_vr.gd" id="1_ig7tw"]
[ext_resource type="PackedScene" uid="uid://bj1s0g7ixjw71" path="res://aircraft/aircraft.tscn" id="2_0xm2m"]
[sub_resource type="BoxMesh" id="BoxMesh_0xm2m"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_7dm0k"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_ig7tw"]
[sub_resource type="Sky" id="Sky_ig7tw"]
sky_material = SubResource("ProceduralSkyMaterial_7dm0k")
[sub_resource type="Sky" id="Sky_0xm2m"]
sky_material = SubResource("ProceduralSkyMaterial_ig7tw")
[sub_resource type="Environment" id="Environment_ig7tw"]
[sub_resource type="Environment" id="Environment_0xm2m"]
background_mode = 2
sky = SubResource("Sky_0xm2m")
[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_0xm2m"]
sky = SubResource("Sky_ig7tw")
[node name="Main" type="Node3D"]
[node name="MarshConnector" type="MarshConnector" parent="."]
[node name="Aircraft" type="Node3D" parent="." node_paths=PackedStringArray("connector")]
script = ExtResource("1_ig7tw")
connector = NodePath("../MarshConnector")
[node name="MeshInstance3D" type="MeshInstance3D" parent="Aircraft"]
mesh = SubResource("BoxMesh_0xm2m")
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(-1, -2.26267e-08, 8.44439e-08, 0, 0.965926, 0.258819, -8.74228e-08, 0.258819, -0.965926, 0, 1, -3)
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_0xm2m")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(-0.707107, -0.683013, 0.183013, 0, 0.258819, 0.965926, -0.707107, 0.683013, -0.183013, 3, 3, 3)
transform = Transform3D(0.707107, 0.683013, -0.183013, 0, 0.258819, 0.965926, 0.707107, -0.683013, 0.183013, -3, 3, -3)
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_ig7tw")
camera_attributes = SubResource("CameraAttributesPractical_0xm2m")
[node name="StartVR" type="Node3D" parent="."]
script = ExtResource("1_ig7tw")
maximum_refresh_rate = 144
[node name="Aircraft" parent="." instance=ExtResource("2_0xm2m")]

View file

@ -1,4 +1,4 @@
[gd_resource type="OpenXRActionMap" load_steps=417 format=3 uid="uid://c52lwapbt6wt2"]
[gd_resource type="OpenXRActionMap" load_steps=417 format=3 uid="uid://5a62ftnefy7o"]
[sub_resource type="OpenXRAction" id="OpenXRAction_6ivru"]
resource_name = "trigger"

View file

@ -11,18 +11,13 @@ config_version=5
[application]
config/name="Visualisation for MARSH"
run/main_scene="uid://ba764fx7hx8ei"
run/main_scene="uid://crq3o0eu4y8ya"
config/features=PackedStringArray("4.4", "GL Compatibility")
config/icon="res://icon.svg"
[autoload]
XRToolsUserSettings="*res://addons/godot-xr-tools/user_settings/user_settings.gd"
XRToolsRumbleManager="*res://addons/godot-xr-tools/rumble/rumble_manager.gd"
[editor_plugins]
enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg")
enabled=PackedStringArray()
[physics]
@ -36,4 +31,6 @@ renderer/rendering_method.mobile="gl_compatibility"
[xr]
openxr/enabled=true
openxr/reference_space=0
openxr/foveation_level=3
shaders/enabled=true

View file

@ -1,11 +0,0 @@
[gd_scene load_steps=3 format=3 uid="uid://ba764fx7hx8ei"]
[ext_resource type="PackedScene" uid="uid://bnqnnnet4dw12" path="res://addons/godot-xr-tools/staging/staging.tscn" id="1_hips3"]
[ext_resource type="Texture2D" uid="uid://ftrrxm7sxndi" path="res://assets/splash/splash.png" id="2_k0lu6"]
[node name="Staging" instance=ExtResource("1_hips3")]
main_scene = "uid://cx82op4eecbwr"
prompt_for_continue = false
[node name="LoadingScreen" parent="." index="2"]
splash_screen = ExtResource("2_k0lu6")

112
project/start_vr.gd Normal file
View file

@ -0,0 +1,112 @@
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_focused := false
func _ready() -> void:
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, as V-Sync is handled by OpenXR.
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
# Enable variable rate shading.
if RenderingServer.get_rendering_device():
vp.vrs_mode = Viewport.VRS_XR
elif int(ProjectSettings.get_setting("xr/openxr/foveation_level")) == 0:
push_warning("OpenXR: Recommend setting Foveation level to High in Project Settings")
# Connect the OpenXR events.
xr_interface.session_begun.connect(_on_openxr_session_begun)
xr_interface.session_visible.connect(_on_openxr_visible_state)
xr_interface.session_focussed.connect(_on_openxr_focused_state)
xr_interface.session_stopping.connect(_on_openxr_stopping)
xr_interface.pose_recentered.connect(_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.is_empty():
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. This is currently needed to avoid jittering,
# due to physics interpolation not being used.
Engine.physics_ticks_per_second = roundi(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_focused:
print("OpenXR lost focus")
xr_is_focused = false
# Pause our game.
process_mode = Node.PROCESS_MODE_DISABLED
focus_lost.emit()
# Handle OpenXR focused state
func _on_openxr_focused_state() -> void:
print("OpenXR gained focus")
xr_is_focused = true
# Unpause our game.
process_mode = Node.PROCESS_MODE_INHERIT
focus_gained.emit()
# 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.
pose_recentered.emit()

1
project/start_vr.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://dfcjdxesyn3l0