Add fallback camera with mouse controls

This commit is contained in:
Marek S. Łukasiewicz 2025-03-03 10:01:54 +01:00
parent 2824f77450
commit ad4bb45951
6 changed files with 79 additions and 1 deletions

View file

@ -1,5 +1,7 @@
extends Node3D
signal use_fallback(active: bool)
## Rotation of cyclic stick model for full control deflection, in degrees
@export var range_cyclic: float = 30
## Main rotor speed, in revolutions per minute
@ -16,6 +18,7 @@ var _rotor_azimuth: float = 0
@onready var tracker_mount_platform: Node3D = $AttitudeRoot/PilotEyes/PilotFloor/TrackerMountPlatform
@onready var xr_origin: XROrigin3D = $AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D
@onready var tracker: XRController3D = $AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D/ViveTracker
@onready var xr_camera: XRCamera3D = $AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D/XRCamera3D
@onready var bone_cg: int = skeleton.find_bone("BodyCG")
@onready var bone_cyclic: int = skeleton.find_bone("Cyclic")
@ -53,3 +56,7 @@ func _process(delta: float) -> void:
xr_origin.transform = tracker_mount.transform * tracker.transform.affine_inverse()
else:
xr_origin.transform = Transform3D.IDENTITY
func _on_vr_setup_failed() -> void:
xr_camera.current = false
use_fallback.emit(true)

View file

@ -1,9 +1,10 @@
[gd_scene load_steps=6 format=3 uid="uid://bj1s0g7ixjw71"]
[gd_scene load_steps=7 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"]
[ext_resource type="PackedScene" uid="uid://fmygcraoturj" path="res://reference_axes.tscn" id="3_2bi7g"]
[ext_resource type="PackedScene" uid="uid://cis4s43ubuynp" path="res://instruments.tscn" id="3_5w717"]
[ext_resource type="Script" uid="uid://bt32fse84itrp" path="res://aircraft/fallback_input.gd" id="3_gf6ud"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mrxe8"]
@ -22,6 +23,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.4, 0)
[node name="PilotEyes" type="Node3D" parent="AttitudeRoot"]
editor_description = "Target position for Local XR tracking"
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0.214, -0.7, 1.594)
script = ExtResource("3_gf6ud")
[node name="PilotFloor" type="Node3D" parent="AttitudeRoot/PilotEyes"]
editor_description = "Required for floor tracking
@ -44,6 +46,7 @@ visible = false
[node name="XROrigin3D" type="XROrigin3D" parent="AttitudeRoot/PilotEyes/PilotFloor"]
[node name="XRCamera3D" type="XRCamera3D" parent="AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D"]
current = true
[node name="ViveTracker" type="XRController3D" parent="AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D"]
tracker = &"/user/vive_tracker_htcx/role/camera"
@ -52,9 +55,14 @@ tracker = &"/user/vive_tracker_htcx/role/camera"
transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0, 0)
visible = false
[node name="FallbackCamera" type="Camera3D" parent="AttitudeRoot/PilotEyes"]
transform = Transform3D(1, 0, 0, 0, 0.980955, 0.194234, 0, -0.194234, 0.980955, 0, 0, 0)
[node name="Instruments" parent="AttitudeRoot" instance=ExtResource("3_5w717")]
transform = Transform3D(-0.5, -1.27582e-08, 7.43353e-08, 4.33325e-10, 0.4923, 0.0874084, -7.5421e-08, 0.0874084, -0.4923, 0.00724897, -1.1581, 2.40391)
[node name="MarshConnector" type="MarshConnector" parent="."]
[connection signal="use_fallback" from="." to="AttitudeRoot/PilotEyes" method="_on_aircraft_use_fallback"]
[editable path="Mi-2"]

View file

@ -0,0 +1,58 @@
# Based on Godot Engine Third Person Shooter Demo, used under MIT License
# Copyright (c) 2018-2021 Juan Linietsky, Godot Engine contributors
# https://github.com/godotengine/tps-demo/blob/master/player/player_input.gd
extends Node3D
const CAMERA_MOUSE_ROTATION_SPEED := 0.001
const CAMERA_X_ROT_MIN := deg_to_rad(-85)
const CAMERA_X_ROT_MAX := deg_to_rad(70)
var active: bool = false
var initial_rotation: Vector3
@onready var camera_base = $"."
@onready var camera = $FallbackCamera
func _ready() -> void:
set_process(false)
set_process_input(false)
initial_rotation = camera.rotation
func _on_aircraft_use_fallback(active_in: bool) -> void:
if active_in:
set_process(true)
set_process_input(true)
camera.make_current()
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
else:
set_process(false)
set_process_input(false)
camera.current = false
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) # default value
# Reset the rotation
camera_base.rotation = Vector3.ZERO
camera.rotation = initial_rotation
active = active_in
func _input(event):
# Make mouse aiming speed resolution-independent
# (required when using the `canvas_items` stretch mode).
var scale_factor: float = min(
(float(get_viewport().size.x) / get_viewport().get_visible_rect().size.x),
(float(get_viewport().size.y) / get_viewport().get_visible_rect().size.y)
)
if event is InputEventMouseMotion:
var camera_speed_this_frame = CAMERA_MOUSE_ROTATION_SPEED
rotate_camera(event.relative * camera_speed_this_frame * scale_factor)
func rotate_camera(move):
camera_base.rotate_y(-move.x)
# After relative transforms, camera needs to be renormalized.
camera_base.orthonormalize()
camera.rotation.x = clamp(camera.rotation.x - move.y, CAMERA_X_ROT_MIN, CAMERA_X_ROT_MAX)

View file

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