diff --git a/kestrel_driver.gd b/kestrel_driver.gd index 31b0691a..160f471c 100644 --- a/kestrel_driver.gd +++ b/kestrel_driver.gd @@ -80,6 +80,10 @@ func _ready() -> void: if _aborts.is_empty(): _fallback_abort() _collect_cabin() + _gear_shown = gear_deploy + _crew_shown = hatch_crew_open + _dock_shown = hatch_dock_open + _ladder_shown = hatch_ladder_deploy _apply_clips() var clips := PackedStringArray() if _player: @@ -98,6 +102,7 @@ func _process(delta: float) -> void: _time += delta if listen_keys and not Engine.is_editor_hint(): _read_keys() + _ease_poses(delta) _apply_clips() _apply_cabin() _burn(_wish(), delta) @@ -151,6 +156,13 @@ func _wish() -> Vector3: var _anim_root: Node = null +var _hinge_report: bool = false +var _gear_shown: float = 1.0 +var _crew_shown: float = 0.0 +var _dock_shown: float = 0.0 +var _ladder_shown: float = 0.0 +const GEAR_SECONDS: float = 4.0 +const HATCH_SECONDS: float = 2.5 func _split_clips() -> void: @@ -164,12 +176,76 @@ func _split_clips() -> void: print("Kestrel clips root=", _anim_root.name, " list=", _player.get_animation_list()) + func _apply_clips() -> void: - _pose("gear_deploy", gear_deploy) - _pose("hatch_crew_open", hatch_crew_open) - _pose("hatch_ladder_deploy", hatch_ladder_deploy) - _pose("hatch_dock_open", hatch_dock_open) - _pose("instruments_demo", instruments_demo) + _hard_pose() + + +func _hinge(node_name: String) -> Node3D: + var n := find_child(node_name, true, false) as Node3D + if n == null and get_parent() != null: + n = get_parent().find_child(node_name, true, false) as Node3D + return n + + +func _q(x: float, y: float, z: float, w: float) -> Quaternion: + return Quaternion(x, y, z, w) + + +func _ease_poses(delta: float) -> void: + _gear_shown = move_toward(_gear_shown, gear_deploy, delta / GEAR_SECONDS) + _crew_shown = move_toward(_crew_shown, hatch_crew_open, delta / HATCH_SECONDS) + _dock_shown = move_toward(_dock_shown, hatch_dock_open, delta / HATCH_SECONDS) + _ladder_shown = move_toward(_ladder_shown, hatch_ladder_deploy, delta / HATCH_SECONDS) + + +func _hard_pose() -> void: + var g := clampf(_gear_shown, 0.0, 1.0) + var hip0 := _q(0.572867, 0.0, 0.0, 0.819648) + var hip1 := _q(0.470626, 0.0, 0.0, 0.882333) + var knee0 := _q(0.998152, 0.0, 0.0, 0.060759) + var knee1 := _q(0.208460, 0.0, 0.0, 0.978031) + var hit := 0 + for side in ["FR", "FL", "RR", "RL"]: + hit += _swing("Gear_%s_Hip" % side, hip0, hip1, g) + hit += _slide_z("Gear_%s_UpperStrut" % side, 0.0138, 0.46, g) + hit += _stretch_y("Gear_%s_UpperStrut" % side, 0.16, 1.0, g) + hit += _slide_z("Gear_%s_Knee" % side, 0.0276, 0.92, g) + hit += _swing("Gear_%s_Knee" % side, knee0, knee1, g) + hit += _slide_z("Gear_%s_Shock" % side, 0.0147, 0.49, g) + hit += _stretch_y("Gear_%s_Shock" % side, 0.16, 1.0, g) + hit += _slide_z("Gear_%s_Foot" % side, 0.0294, 0.98, g) + hit += _swing("CrewHatch_Hinge", Quaternion.IDENTITY, _q(0.0, -0.854714, 0.0, 0.519099), _crew_shown) + hit += _swing("DockHatch_Hinge", Quaternion.IDENTITY, _q(0.0, 0.0, -0.854714, 0.519099), _dock_shown) + hit += _swing("CrewStep_Hinge", _q(0.0, 0.0, 0.02, 0.9998), _q(0.0, 0.0, 0.305059, 0.952334), _ladder_shown) + hit += _stretch_y("CrewStep_Ladder", 0.12, 1.0, _ladder_shown) + if not _hinge_report: + _hinge_report = true + print("Kestrel hinges hit=", hit, " crew=", _hinge("CrewHatch_Hinge"), " gear=", _hinge("Gear_FR_Hip")) + + +func _swing(node_name: String, a: Quaternion, b: Quaternion, t: float) -> int: + var n := _hinge(node_name) + if n == null: + return 0 + n.quaternion = a.slerp(b, clampf(t, 0.0, 1.0)) + return 1 + + +func _slide_z(node_name: String, a: float, b: float, t: float) -> int: + var n := _hinge(node_name) + if n == null: + return 0 + n.position.z = lerpf(a, b, clampf(t, 0.0, 1.0)) + return 1 + + +func _stretch_y(node_name: String, a: float, b: float, t: float) -> int: + var n := _hinge(node_name) + if n == null: + return 0 + n.scale.y = lerpf(a, b, clampf(t, 0.0, 1.0)) + return 1 func _pose(clip: StringName, t: float) -> void: