diff --git a/.gitattributes b/.gitattributes index aa8aed0..8ad74f7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,2 @@ # Normalize EOL for all files that Git considers text files. * text=auto eol=lf -*.glb filter=lfs diff=lfs merge=lfs -text -*.fbx filter=lfs diff=lfs merge=lfs -text -*.webp filter=lfs diff=lfs merge=lfs -text -*.png filter=lfs diff=lfs merge=lfs -text diff --git a/.godot-version b/.godot-version deleted file mode 100644 index 80ef135..0000000 --- a/.godot-version +++ /dev/null @@ -1 +0,0 @@ -4.4-beta3 diff --git a/README.md b/README.md index c9831c4..cfed8ed 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ git clone --recurse-submodules
git submodule update --init --recursive ``` -Using Godot v4.4 beta3 (expect it to change often until 4.4 is released) +Using Godot v4.4.beta1.official [d33da79d3](https://github.com/godotengine/godot/commit/d33da79d3f8fe84be2521d25b9ba8e440cf25a88). Install SCons with `pipx install scons`. You will need a C++ compiler, you might have one already on Linux, see below for Windows, otherwise in [Godot documentation](https://docs.godotengine.org/en/stable/contributing/development/compiling/index.html). @@ -29,9 +29,9 @@ Some files are generated, run the following commands on first setup and when dep ```sh godot --dump-extension-api # after updating Godot +scons compile_commands # after modifying SConstruct python update_mavlink.py # after updating MAVLink dialect python update_addons.py # after changing any addon submodules -scons compile_commands # after modifying SConstruct ``` ### Windows setup diff --git a/project/CREDITS.txt b/project/CREDITS.txt deleted file mode 100644 index 5e84675..0000000 --- a/project/CREDITS.txt +++ /dev/null @@ -1,6 +0,0 @@ -Programming: - Marek S. Łukasiewicz - -3D models: - Igor Samek - Marek S. Łukasiewicz diff --git a/project/addons/godot-xr-tools/plugin.gd.uid b/project/addons/godot-xr-tools/plugin.gd.uid new file mode 100644 index 0000000..6116563 --- /dev/null +++ b/project/addons/godot-xr-tools/plugin.gd.uid @@ -0,0 +1 @@ +uid://46i64f2dmonl diff --git a/project/addons/godot-xr-tools/xr_tools.gd.uid b/project/addons/godot-xr-tools/xr_tools.gd.uid new file mode 100644 index 0000000..ee86026 --- /dev/null +++ b/project/addons/godot-xr-tools/xr_tools.gd.uid @@ -0,0 +1 @@ +uid://c086s0jrgaiwi diff --git a/project/aircraft.gd b/project/aircraft.gd new file mode 100644 index 0000000..ce15b7a --- /dev/null +++ b/project/aircraft.gd @@ -0,0 +1,6 @@ +extends Node3D + +@export var connector: MarshConnector + +func _process(_delta: float) -> void: + transform = connector.get_aircraft() diff --git a/project/aircraft/aircraft.gd.uid b/project/aircraft.gd.uid similarity index 100% rename from project/aircraft/aircraft.gd.uid rename to project/aircraft.gd.uid diff --git a/project/aircraft/aircraft.gd b/project/aircraft/aircraft.gd deleted file mode 100644 index f8c9918..0000000 --- a/project/aircraft/aircraft.gd +++ /dev/null @@ -1,19 +0,0 @@ -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() diff --git a/project/aircraft/aircraft.tscn b/project/aircraft/aircraft.tscn deleted file mode 100644 index 867edc0..0000000 --- a/project/aircraft/aircraft.tscn +++ /dev/null @@ -1,26 +0,0 @@ -[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"] diff --git a/project/assets/cone/Cone80cm.fbx b/project/assets/cone/Cone80cm.fbx deleted file mode 100644 index cce66e4..0000000 --- a/project/assets/cone/Cone80cm.fbx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:53604872f79dd1e52a8144811eef77179d66313b7d1cba8b2ed6bee691203b1f -size 32252 diff --git a/project/assets/cone/Cone80cm.fbx.import b/project/assets/cone/Cone80cm.fbx.import deleted file mode 100644 index d252069..0000000 --- a/project/assets/cone/Cone80cm.fbx.import +++ /dev/null @@ -1,38 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://b6gpwum12u52w" -path="res://.godot/imported/Cone80cm.fbx-d949dbbc55b52604489414c5f9df328e.scn" - -[deps] - -source_file="res://assets/cone/Cone80cm.fbx" -dest_files=["res://.godot/imported/Cone80cm.fbx-d949dbbc55b52604489414c5f9df328e.scn"] - -[params] - -nodes/root_type="" -nodes/root_name="" -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=true -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -_subresources={} -fbx/importer=0 -fbx/allow_geometry_helper_nodes=false -fbx/embedded_image_handling=1 diff --git a/project/assets/cone/Cone_DefaultMaterial_BaseColor.webp b/project/assets/cone/Cone_DefaultMaterial_BaseColor.webp deleted file mode 100644 index f1d1788..0000000 --- a/project/assets/cone/Cone_DefaultMaterial_BaseColor.webp +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fda4c784b19821b8de716bfebfe58c5a138baca15269328fec68389b5b5a6910 -size 74366 diff --git a/project/assets/cone/Cone_DefaultMaterial_BaseColor.webp.import b/project/assets/cone/Cone_DefaultMaterial_BaseColor.webp.import deleted file mode 100644 index 25e24c5..0000000 --- a/project/assets/cone/Cone_DefaultMaterial_BaseColor.webp.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://8d1ovbs1uls5" -path="res://.godot/imported/Cone_DefaultMaterial_BaseColor.webp-bad00f3f7b1863582144eaca57549c7d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/cone/Cone_DefaultMaterial_BaseColor.webp" -dest_files=["res://.godot/imported/Cone_DefaultMaterial_BaseColor.webp-bad00f3f7b1863582144eaca57549c7d.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 diff --git a/project/assets/cone/Cone_DefaultMaterial_Normal.webp b/project/assets/cone/Cone_DefaultMaterial_Normal.webp deleted file mode 100644 index b60f821..0000000 --- a/project/assets/cone/Cone_DefaultMaterial_Normal.webp +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac629f1490250708b020f94be6dcd9b6d8562ca4a1d62af55e0ec596e374857b -size 126732 diff --git a/project/assets/cone/Cone_DefaultMaterial_Normal.webp.import b/project/assets/cone/Cone_DefaultMaterial_Normal.webp.import deleted file mode 100644 index 5bea403..0000000 --- a/project/assets/cone/Cone_DefaultMaterial_Normal.webp.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cq5sci0t8q0hy" -path="res://.godot/imported/Cone_DefaultMaterial_Normal.webp-6a67b945c81f799997551ce26f4f31c8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/cone/Cone_DefaultMaterial_Normal.webp" -dest_files=["res://.godot/imported/Cone_DefaultMaterial_Normal.webp-6a67b945c81f799997551ce26f4f31c8.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 diff --git a/project/assets/cone/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp b/project/assets/cone/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp deleted file mode 100644 index 17e7a65..0000000 --- a/project/assets/cone/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:812432b6750ab8f6391534efa2036aa5c192052672fcf7c4f63c292d63f944a7 -size 148532 diff --git a/project/assets/cone/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp.import b/project/assets/cone/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp.import deleted file mode 100644 index 9c84306..0000000 --- a/project/assets/cone/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://0x0t6mks64wj" -path="res://.godot/imported/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp-1a5b8b1d7a0eb8a9d7d6e168dd7479db.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/cone/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp" -dest_files=["res://.godot/imported/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp-1a5b8b1d7a0eb8a9d7d6e168dd7479db.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 diff --git a/project/assets/cone/cone.tscn b/project/assets/cone/cone.tscn deleted file mode 100644 index d17839b..0000000 --- a/project/assets/cone/cone.tscn +++ /dev/null @@ -1,9 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://7tddcx4u26w4"] - -[ext_resource type="PackedScene" uid="uid://b6gpwum12u52w" path="res://assets/cone/Cone80cm.fbx" id="1_caoip"] -[ext_resource type="Material" uid="uid://8my138hapqp8" path="res://assets/cone/cone_material.tres" id="2_pk7h2"] - -[node name="Cone80cm" instance=ExtResource("1_caoip")] - -[node name="Cylinder" parent="." index="0"] -surface_material_override/0 = ExtResource("2_pk7h2") diff --git a/project/assets/cone/cone_material.tres b/project/assets/cone/cone_material.tres deleted file mode 100644 index 2a52f25..0000000 --- a/project/assets/cone/cone_material.tres +++ /dev/null @@ -1,28 +0,0 @@ -[gd_resource type="StandardMaterial3D" load_steps=6 format=3 uid="uid://8my138hapqp8"] - -[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_2wwbo"] -load_path = "res://.godot/imported/Cone_DefaultMaterial_BaseColor.webp-bad00f3f7b1863582144eaca57549c7d.ctex" - -[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_86lm8"] -load_path = "res://.godot/imported/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp-1a5b8b1d7a0eb8a9d7d6e168dd7479db.ctex" - -[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_c2qq7"] -load_path = "res://.godot/imported/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp-1a5b8b1d7a0eb8a9d7d6e168dd7479db.ctex" - -[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_f28vr"] -load_path = "res://.godot/imported/Cone_DefaultMaterial_Normal.webp-6a67b945c81f799997551ce26f4f31c8.ctex" - -[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_tpcsw"] -load_path = "res://.godot/imported/Cone_DefaultMaterial_OcclusionRoughnessMetallic.webp-1a5b8b1d7a0eb8a9d7d6e168dd7479db.ctex" - -[resource] -albedo_texture = SubResource("CompressedTexture2D_2wwbo") -metallic = 1.0 -metallic_texture = SubResource("CompressedTexture2D_c2qq7") -metallic_texture_channel = 2 -roughness_texture = SubResource("CompressedTexture2D_tpcsw") -roughness_texture_channel = 1 -normal_enabled = true -normal_texture = SubResource("CompressedTexture2D_f28vr") -ao_enabled = true -ao_texture = SubResource("CompressedTexture2D_86lm8") diff --git a/project/assets/mi2/Mi-2.glb b/project/assets/mi2/Mi-2.glb deleted file mode 100644 index 9c72d04..0000000 --- a/project/assets/mi2/Mi-2.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:12565394be73ddc6c5150deaa400bbfc29ca3911dd36315fec59cd96eb3b838b -size 524076 diff --git a/project/assets/mi2/Mi-2.glb.import b/project/assets/mi2/Mi-2.glb.import deleted file mode 100644 index 1503c35..0000000 --- a/project/assets/mi2/Mi-2.glb.import +++ /dev/null @@ -1,37 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://cux4tju0ovvly" -path="res://.godot/imported/Mi-2.glb-12197697bde557481ecf457851b9e618.scn" - -[deps] - -source_file="res://assets/mi2/Mi-2.glb" -dest_files=["res://.godot/imported/Mi-2.glb-12197697bde557481ecf457851b9e618.scn"] - -[params] - -nodes/root_type="" -nodes/root_name="" -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -_subresources={} -gltf/naming_version=1 -gltf/embedded_image_handling=1 diff --git a/project/assets/splash/splash.png b/project/assets/splash/splash.png index a6d9376..32960db 100644 Binary files a/project/assets/splash/splash.png and b/project/assets/splash/splash.png differ diff --git a/project/main-xr.tscn b/project/main-xr.tscn new file mode 100644 index 0000000..38d8ce1 --- /dev/null +++ b/project/main-xr.tscn @@ -0,0 +1,42 @@ +[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"] +process_mode = 0 + +[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="Camera3D" type="Camera3D" parent="." index="3"] +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="DirectionalLight3D" type="DirectionalLight3D" parent="." index="4"] +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="5"] +environment = SubResource("Environment_jdgxj") +camera_attributes = SubResource("CameraAttributesPractical_fpvso") diff --git a/project/main.tscn b/project/main.tscn index 9b40194..6163934 100644 --- a/project/main.tscn +++ b/project/main.tscn @@ -1,27 +1,38 @@ -[gd_scene load_steps=6 format=3 uid="uid://crq3o0eu4y8ya"] +[gd_scene load_steps=7 format=3 uid="uid://cjrkxv8ix1h8s"] -[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"] +[ext_resource type="Script" uid="uid://cx30pr7kn4c74" path="res://aircraft.gd" id="1_ig7tw"] -[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_7dm0k"] +[sub_resource type="BoxMesh" id="BoxMesh_0xm2m"] -[sub_resource type="Sky" id="Sky_ig7tw"] -sky_material = SubResource("ProceduralSkyMaterial_7dm0k") +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_ig7tw"] -[sub_resource type="Environment" id="Environment_0xm2m"] +[sub_resource type="Sky" id="Sky_0xm2m"] +sky_material = SubResource("ProceduralSkyMaterial_ig7tw") + +[sub_resource type="Environment" id="Environment_ig7tw"] background_mode = 2 -sky = SubResource("Sky_ig7tw") +sky = SubResource("Sky_0xm2m") + +[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_0xm2m"] [node name="Main" type="Node3D"] -[node name="WorldEnvironment" type="WorldEnvironment" parent="."] -environment = SubResource("Environment_0xm2m") +[node name="MarshConnector" type="MarshConnector" parent="."] +process_mode = 0 + +[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="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="StartVR" type="Node3D" parent="."] -script = ExtResource("1_ig7tw") -maximum_refresh_rate = 144 - -[node name="Aircraft" parent="." instance=ExtResource("2_0xm2m")] +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_ig7tw") +camera_attributes = SubResource("CameraAttributesPractical_0xm2m") diff --git a/project/openxr_action_map.tres b/project/openxr_action_map.tres index 1adcca3..035ca38 100644 --- a/project/openxr_action_map.tres +++ b/project/openxr_action_map.tres @@ -1,4 +1,4 @@ -[gd_resource type="OpenXRActionMap" load_steps=417 format=3 uid="uid://5a62ftnefy7o"] +[gd_resource type="OpenXRActionMap" load_steps=417 format=3 uid="uid://c52lwapbt6wt2"] [sub_resource type="OpenXRAction" id="OpenXRAction_6ivru"] resource_name = "trigger" diff --git a/project/project.godot b/project/project.godot index 561ce7d..7d875dc 100644 --- a/project/project.godot +++ b/project/project.godot @@ -11,13 +11,18 @@ config_version=5 [application] config/name="Visualisation for MARSH" -run/main_scene="uid://crq3o0eu4y8ya" +run/main_scene="uid://ba764fx7hx8ei" 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() +enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg") [physics] @@ -31,6 +36,4 @@ renderer/rendering_method.mobile="gl_compatibility" [xr] openxr/enabled=true -openxr/reference_space=0 -openxr/foveation_level=3 shaders/enabled=true diff --git a/project/start-xr.tscn b/project/start-xr.tscn new file mode 100644 index 0000000..adc9b83 --- /dev/null +++ b/project/start-xr.tscn @@ -0,0 +1,11 @@ +[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") diff --git a/project/start_vr.gd b/project/start_vr.gd deleted file mode 100644 index c610b4c..0000000 --- a/project/start_vr.gd +++ /dev/null @@ -1,112 +0,0 @@ -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() diff --git a/project/start_vr.gd.uid b/project/start_vr.gd.uid deleted file mode 100644 index 036f8dc..0000000 --- a/project/start_vr.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dfcjdxesyn3l0 diff --git a/src/marshconnector.cpp b/src/marshconnector.cpp index 0d171a6..f11e62e 100644 --- a/src/marshconnector.cpp +++ b/src/marshconnector.cpp @@ -2,7 +2,6 @@ #include "godot_cpp/classes/engine.hpp" #include "godot_cpp/classes/font_file.hpp" -#include "godot_cpp/classes/global_constants.hpp" #include "godot_cpp/classes/packet_peer_udp.hpp" #include "godot_cpp/core/math.hpp" #include "godot_cpp/core/memory.hpp" @@ -13,29 +12,18 @@ #include "godot_cpp/variant/transform3d.hpp" #include "godot_cpp/variant/vector3.hpp" #include "mavlink/all/mavlink.h" // IWYU pragma: keep; always include the mavlink.h file for selected dialect -#include "mavlink/common/mavlink_msg_command_long.h" -#include "mavlink/common/mavlink_msg_manual_control.h" #include "mavlink/common/mavlink_msg_sim_state.h" #include "mavlink/mavlink_helpers.h" -#include "mavlink/mavlink_types.h" + +// How much extra bytes are needed on top of message payload length +#define MAVLINK_OVERHEAD 12 using namespace godot; void MarshConnector::_bind_methods() { - // Data access - ClassDB::bind_method(D_METHOD("get_aircraft"), &MarshConnector::get_aircraft); - ClassDB::bind_method(D_METHOD("get_cyclic"), &MarshConnector::get_cyclic); - ClassDB::bind_method(D_METHOD("get_collective"), - &MarshConnector::get_collective); - ClassDB::bind_method(D_METHOD("get_pedals"), &MarshConnector::get_pedals); - - // Timer callbacks ClassDB::bind_method(D_METHOD("send_heartbeat"), &MarshConnector::send_heartbeat); - ClassDB::bind_method(D_METHOD("manager_timeout"), - &MarshConnector::manager_timeout); - // ClassDB::bind_method(D_METHOD("model_timeout"), - // &MarshConnector::model_timeout); + ClassDB::bind_method(D_METHOD("get_aircraft"), &MarshConnector::get_aircraft); } MarshConnector::MarshConnector() { @@ -51,14 +39,10 @@ MarshConnector::MarshConnector() { socket = memnew(PacketPeerUDP); - manager_connected = false; - - manager_timer = memnew(Timer); - add_child(manager_timer); - manager_timer->set_wait_time(5.0); - manager_timer->set_one_shot(true); - manager_timer->set_autostart(false); - manager_timer->connect("timeout", Callable(this, "manager_timeout")); + if (Engine::get_singleton()->is_editor_hint()) { + // Don't run _process() in the editor + set_process_mode(Node::ProcessMode::PROCESS_MODE_DISABLED); + } } MarshConnector::~MarshConnector() { @@ -81,7 +65,7 @@ void MarshConnector::_process(double delta) { } Error MarshConnector::send_heartbeat() { - // print_line("Sending HEARTBEAT at ", time_passed, " seconds"); + print_line("Sending HEARTBEAT at ", time_passed, " seconds"); mavlink_heartbeat_t heartbeat; heartbeat.type = MAV_TYPE_HELICOPTER; @@ -93,19 +77,17 @@ Error MarshConnector::send_heartbeat() { mavlink_message_t message; mavlink_msg_heartbeat_encode_chan(1, MARSH_COMP_ID_VISUALISATION, MAVLINK_COMM_0, &message, &heartbeat); - return send_message(message); -} - -Error MarshConnector::send_message(mavlink_message_t message) { - uint8_t send_buffer[MAVLINK_MAX_PACKET_LEN]; + uint8_t send_buffer[MAVLINK_OVERHEAD + MAVLINK_MSG_ID_HEARTBEAT_LEN]; mavlink_msg_to_send_buffer(send_buffer, &message); PackedByteArray array; for (int i = 0; i < sizeof(send_buffer); i++) { array.append(send_buffer[i]); } + print_line("Data array ", array); const auto result = socket->put_packet(array); + print_line("Send result ", result); return result; } @@ -132,12 +114,6 @@ void MarshConnector::receive_data(const PackedByteArray &data) { case MAVLINK_MSG_ID_PARAM_SET: handle_param(message); break; - case MAVLINK_MSG_ID_MANUAL_CONTROL: - handle_manual_control(message); - break; - case MAVLINK_MSG_ID_HEARTBEAT: - handle_heartbeat(message); - break; default: break; } @@ -159,13 +135,6 @@ Transform3D MarshConnector::get_aircraft() { return Transform3D{Basis{last_rotation}, last_location}; } -Vector2 MarshConnector::get_cyclic() { - return Vector2{last_controls.x, last_controls.y}; -} - -float MarshConnector::get_collective() { return last_controls.w; } -float MarshConnector::get_pedals() { return last_controls.z; } - Vector2 MarshConnector::local_meters_from_global_degrees(double latitude, double longitude) { @@ -226,86 +195,13 @@ Quaternion MarshConnector::godot_rotation_from_mavlink(float roll_rad, } void MarshConnector::handle_local_position(mavlink_message_t message) { - if (message.msgid != MAVLINK_MSG_ID_LOCAL_POSITION_NED) - return; - - mavlink_local_position_ned_t local_pos; - mavlink_msg_local_position_ned_decode(&message, &local_pos); - last_location = - godot_location_from_mavlink(local_pos.x, local_pos.y, -local_pos.z); + print_line("Implement handle_local_position"); } void MarshConnector::handle_attitude(mavlink_message_t message) { - if (message.msgid != MAVLINK_MSG_ID_ATTITUDE) - return; - - mavlink_attitude_t attitude; - mavlink_msg_attitude_decode(&message, &attitude); - last_rotation = - godot_rotation_from_mavlink(attitude.roll, attitude.pitch, attitude.yaw); + print_line("Implement handle_attitude"); } void MarshConnector::handle_param(mavlink_message_t message) { print_line("Implement handle_param"); } - -void MarshConnector::handle_manual_control(mavlink_message_t message) { - if (message.msgid != MAVLINK_MSG_ID_MANUAL_CONTROL) - return; - - mavlink_manual_control_t manual_control; - mavlink_msg_manual_control_decode(&message, &manual_control); - const int16_t invalid = 0x7FFF; - if (manual_control.y != invalid) - last_controls.x = manual_control.y / 1000.0f; - if (manual_control.x != invalid) - last_controls.y = manual_control.x / -1000.0f; - if (manual_control.r != invalid) - last_controls.z = manual_control.r / 1000.0f; - if (manual_control.z != invalid) - last_controls.w = manual_control.z / 1000.0f; -} - -void MarshConnector::handle_heartbeat(mavlink_message_t message) { - if (message.msgid != MAVLINK_MSG_ID_HEARTBEAT) - return; - - // mavlink_heartbeat_t heartbeat; - // mavlink_msg_heartbeat_decode(&message, &heartbeat); - if (message.compid == MARSH_COMP_ID_MANAGER) { - if (!manager_connected) { - print_line("Connected to MARSH Manager"); - - // subscribe to messages not sent to visualisation node by default - mavlink_command_long_t command; - command.target_system = 1; - command.target_component = MARSH_COMP_ID_MANAGER; - command.command = MAV_CMD_SET_MESSAGE_INTERVAL; - command.confirmation = 0; - command.param1 = static_cast