Initial commit.
This commit is contained in:
commit
907695442f
28 changed files with 717 additions and 0 deletions
4
.editorconfig
Normal file
4
.editorconfig
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Normalize EOL for all files that Git considers text files.
|
||||||
|
* text=auto eol=lf
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Godot 4+ specific ignores
|
||||||
|
.godot/
|
||||||
|
/android/
|
26
demo/airfoils/symmetric.tres
Normal file
26
demo/airfoils/symmetric.tres
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
[gd_resource type="Resource" script_class="Airfoil" load_steps=5 format=3 uid="uid://dpk3bgq54ajul"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://jts0c0xrwc8q" path="res://scripts/aircraft/resources/airfoil.gd" id="1_bnq8l"]
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_bnq8l"]
|
||||||
|
_limits = [0.0, 0.25, -20.0, 20.0]
|
||||||
|
_data = [Vector2(-20, 0.25), 0.0, -0.0451077, 0, 0, Vector2(-15.2, 0.106742), -0.0196947, -0.0196947, 0, 0, Vector2(-10.2128, 0.0337079), -0.00684561, -0.00684561, 0, 0, Vector2(0, 0.011236), 0.0, 0.0, 0, 0, Vector2(10, 0.0337079), 0.00560095, 0.00560095, 0, 0, Vector2(14.8936, 0.0983146), 0.0198034, 0.0198034, 0, 0, Vector2(20, 0.25), 0.0490369, 0.0, 0, 0]
|
||||||
|
point_count = 7
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_fbf5p"]
|
||||||
|
_limits = [-1.5, 1.5, -20.0, 20.0]
|
||||||
|
bake_resolution = 80
|
||||||
|
_data = [Vector2(-13, -0.7), 0.0, 0.0, 0, 0, Vector2(-12, -1.1), 0.0, 0.0, 0, 0, Vector2(12, 1.1), 0.0, 0.0, 0, 0, Vector2(13, 0.7), 0.0, 0.0, 0, 0]
|
||||||
|
point_count = 4
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_iphra"]
|
||||||
|
_limits = [0.0, 1.0, -20.0, 20.0]
|
||||||
|
_data = [Vector2(-20, 0), 0.0, 0.0, 0, 0, Vector2(20, 0), 0.0, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_bnq8l")
|
||||||
|
lift_curve = SubResource("Curve_fbf5p")
|
||||||
|
drag_curve = SubResource("Curve_bnq8l")
|
||||||
|
moment_curve = SubResource("Curve_iphra")
|
||||||
|
metadata/_custom_type_script = "uid://jts0c0xrwc8q"
|
138
demo/demo.tscn
Normal file
138
demo/demo.tscn
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
[gd_scene load_steps=18 format=3 uid="uid://d20jwlre5rc5m"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bruwqvb6qrsfn" path="res://demo/textures/untexture.png" id="1_ytiva"]
|
||||||
|
[ext_resource type="Script" uid="uid://bddnsq0h2tpf" path="res://scripts/aircraft/nodes/fixed_wing_aircraft.gd" id="2_dar0o"]
|
||||||
|
[ext_resource type="Resource" uid="uid://dpk3bgq54ajul" path="res://demo/airfoils/symmetric.tres" id="3_u10mr"]
|
||||||
|
[ext_resource type="Script" uid="uid://qjdma7j2qrns" path="res://scripts/aircraft/resources/fixed_wing_aircraft_performance.gd" id="4_onu7k"]
|
||||||
|
[ext_resource type="Resource" uid="uid://p2i7a806s6gs" path="res://demo/propulsion/electric_motor.tres" id="4_s1s6j"]
|
||||||
|
[ext_resource type="Script" uid="uid://pc3j1c6e1ra7" path="res://scripts/aircraft/nodes/flight_sim_controller.gd" id="5_s1s6j"]
|
||||||
|
[ext_resource type="Script" uid="uid://tgj0rvn5wj8t" path="res://demo/hud.gd" id="6_onu7k"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_j5lb4"]
|
||||||
|
albedo_texture = ExtResource("1_ytiva")
|
||||||
|
uv1_scale = Vector3(100, 100, 100)
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_5hjng"]
|
||||||
|
material = SubResource("StandardMaterial3D_j5lb4")
|
||||||
|
size = Vector2(2000, 2000)
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_s1s6j"]
|
||||||
|
_limits = [0.0, 0.5, 0.0, 20.0]
|
||||||
|
_data = [Vector2(0, 0.5), 0.0, 0.0, 0, 0, Vector2(20, 0), -0.082397, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_onvmd"]
|
||||||
|
_limits = [0.0, 2.0, 0.0, 30.0]
|
||||||
|
_data = [Vector2(0, 2), 0.0, 0.0, 0, 0, Vector2(30, 0), -0.199316, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_oeqrt"]
|
||||||
|
_limits = [0.0, 0.202247, 0.0, 10.0]
|
||||||
|
_data = [Vector2(0, 0.202247), 0.0, 0.0, 0, 0, Vector2(10, 0), -0.0393259, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_onu7k"]
|
||||||
|
script = ExtResource("4_onu7k")
|
||||||
|
horizontal_surface = ExtResource("3_u10mr")
|
||||||
|
horizontal_area = 21.8
|
||||||
|
horizontal_aspect_ratio = 5.83
|
||||||
|
horizontal_sweep = 0.0
|
||||||
|
vertical_surface = ExtResource("3_u10mr")
|
||||||
|
vertical_area = 5.0
|
||||||
|
vertical_aspect_ratio = 5.0
|
||||||
|
vertical_sweep = 0.0
|
||||||
|
propultion = ExtResource("4_s1s6j")
|
||||||
|
base_thrust = 100000.0
|
||||||
|
base_drag = 0.0
|
||||||
|
empty_mass = 3463.0
|
||||||
|
yaw_axis = Vector3(0, -1, 0)
|
||||||
|
roll_axis = Vector3(0, 0.1, -1)
|
||||||
|
pitch_stability = 0.0
|
||||||
|
yaw_stability = 0.0
|
||||||
|
roll_stability = 0.0
|
||||||
|
reference_ias_mps = 100.0
|
||||||
|
braking_power = 0.0
|
||||||
|
pitch_power = SubResource("Curve_s1s6j")
|
||||||
|
yaw_power = SubResource("Curve_oeqrt")
|
||||||
|
roll_power = SubResource("Curve_onvmd")
|
||||||
|
metadata/_custom_type_script = "uid://qjdma7j2qrns"
|
||||||
|
|
||||||
|
[sub_resource type="SphereShape3D" id="SphereShape3D_u10mr"]
|
||||||
|
radius = 8.0
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_onu7k"]
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_s1s6j"]
|
||||||
|
sky_material = SubResource("ProceduralSkyMaterial_onu7k")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_onvmd"]
|
||||||
|
background_mode = 2
|
||||||
|
sky = SubResource("Sky_s1s6j")
|
||||||
|
ambient_light_source = 3
|
||||||
|
ambient_light_color = Color(1, 1, 1, 1)
|
||||||
|
|
||||||
|
[node name="Demo" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="Ground" type="MeshInstance3D" parent="."]
|
||||||
|
mesh = SubResource("PlaneMesh_5hjng")
|
||||||
|
|
||||||
|
[node name="FixedWingAircraft" type="CharacterBody3D" parent="." node_paths=PackedStringArray("controller")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0)
|
||||||
|
script = ExtResource("2_dar0o")
|
||||||
|
performance = SubResource("Resource_onu7k")
|
||||||
|
controller = NodePath("FlightSimController")
|
||||||
|
initial_speed = 100.0
|
||||||
|
metadata/_custom_type_script = "uid://bddnsq0h2tpf"
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="FixedWingAircraft"]
|
||||||
|
shape = SubResource("SphereShape3D_u10mr")
|
||||||
|
|
||||||
|
[node name="FlightSimController" type="Node" parent="FixedWingAircraft"]
|
||||||
|
script = ExtResource("5_s1s6j")
|
||||||
|
pitch_speed = 4.0
|
||||||
|
yaw_speed = 4.0
|
||||||
|
roll_speed = 3.0
|
||||||
|
metadata/_custom_type_script = "uid://pc3j1c6e1ra7"
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="FixedWingAircraft"]
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="HUD" type="Control" parent="CanvasLayer" node_paths=PackedStringArray("source")]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("6_onu7k")
|
||||||
|
source = NodePath("../../FixedWingAircraft")
|
||||||
|
|
||||||
|
[node name="TAS_Label" type="Label" parent="CanvasLayer/HUD"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 32.0
|
||||||
|
|
||||||
|
[node name="AOA_Label" type="Label" parent="CanvasLayer/HUD"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_top = 32.0
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 64.0
|
||||||
|
|
||||||
|
[node name="SideslipLabel" type="Label" parent="CanvasLayer/HUD"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_top = 64.0
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 96.0
|
||||||
|
|
||||||
|
[node name="RelativeVelocityLabel" type="Label" parent="CanvasLayer/HUD"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_top = 96.0
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 128.0
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_onvmd")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(-4.37114e-08, -0.984808, 0.173648, 0, 0.173648, 0.984808, -1, 4.30473e-08, -7.5904e-09, 0, 0, 0)
|
15
demo/hud.gd
Normal file
15
demo/hud.gd
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
class_name HUD
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
@export var source: FixedWingAircraft
|
||||||
|
|
||||||
|
@onready var tas_label := $TAS_Label as Label
|
||||||
|
@onready var aoa_label := $AOA_Label as Label
|
||||||
|
@onready var sideslip_label := $SideslipLabel as Label
|
||||||
|
@onready var relative_velocity_label := $RelativeVelocityLabel as Label
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
tas_label.text = "TAS: %s" % source.m_tas
|
||||||
|
aoa_label.text = "AOA: %s" % rad_to_deg(source.m_aoa)
|
||||||
|
sideslip_label.text = "Sideslip: %s" % rad_to_deg(source.m_sideslip)
|
||||||
|
relative_velocity_label.text = "V: %s" % source.m_relative_velocity
|
1
demo/hud.gd.uid
Normal file
1
demo/hud.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://tgj0rvn5wj8t
|
22
demo/propulsion/electric_motor.tres
Normal file
22
demo/propulsion/electric_motor.tres
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
[gd_resource type="Resource" script_class="Propultion" load_steps=5 format=3 uid="uid://p2i7a806s6gs"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://8fsi1mq555uj" path="res://scripts/aircraft/resources/propultion.gd" id="1_idr77"]
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_idr77"]
|
||||||
|
_data = [Vector2(0, 0), 0.0, 2.81648, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_sw002"]
|
||||||
|
_data = [Vector2(0, 1), 0.0, -2.57766, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_jnvlh"]
|
||||||
|
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_idr77")
|
||||||
|
propultion_speed_curve = SubResource("Curve_sw002")
|
||||||
|
propultion_density_curve = SubResource("Curve_idr77")
|
||||||
|
propultion_temperature_curve = SubResource("Curve_jnvlh")
|
||||||
|
metadata/_custom_type_script = "uid://8fsi1mq555uj"
|
BIN
demo/textures/untexture.png
Normal file
BIN
demo/textures/untexture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 128 B |
35
demo/textures/untexture.png.import
Normal file
35
demo/textures/untexture.png.import
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bruwqvb6qrsfn"
|
||||||
|
path.s3tc="res://.godot/imported/untexture.png-e9b4c6dd107bfceece0daf5f5dd4fe66.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://demo/textures/untexture.png"
|
||||||
|
dest_files=["res://.godot/imported/untexture.png-e9b4c6dd107bfceece0daf5f5dd4fe66.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
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=0
|
1
icon.svg
Normal file
1
icon.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>
|
After Width: | Height: | Size: 994 B |
37
icon.svg.import
Normal file
37
icon.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bw3c6f8nrg5q7"
|
||||||
|
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
|
80
project.godot
Normal file
80
project.godot
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
; 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="SparkyGD"
|
||||||
|
run/main_scene="uid://d20jwlre5rc5m"
|
||||||
|
config/features=PackedStringArray("4.4", "Forward Plus")
|
||||||
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
Atmosphere="*res://scripts/aircraft/nodes/atmosphere.gd"
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
|
||||||
|
gdscript/warnings/untyped_declaration=2
|
||||||
|
gdscript/warnings/unsafe_property_access=2
|
||||||
|
gdscript/warnings/unsafe_method_access=2
|
||||||
|
gdscript/warnings/unsafe_cast=1
|
||||||
|
gdscript/warnings/unsafe_call_argument=2
|
||||||
|
gdscript/warnings/return_value_discarded=1
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
pitch_down={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
pitch_up={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
yaw_left={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
yaw_right={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
roll_left={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
roll_right={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
throttle_down={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":true,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
throttle_up={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null)
|
||||||
|
]
|
||||||
|
}
|
6
scenes/aircraft/fixed_wing_aircraft.tscn
Normal file
6
scenes/aircraft/fixed_wing_aircraft.tscn
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://duwkogb01nnwa"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://bddnsq0h2tpf" path="res://scripts/aircraft/nodes/fixed_wing_aircraft.gd" id="1_6x31w"]
|
||||||
|
|
||||||
|
[node name="FixedWingAircraft" type="CharacterBody3D"]
|
||||||
|
script = ExtResource("1_6x31w")
|
8
scripts/aircraft/nodes/aircraft_controller.gd
Normal file
8
scripts/aircraft/nodes/aircraft_controller.gd
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
class_name AircraftController
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
@export var pitch: float # Negative: down, positive: up
|
||||||
|
@export var yaw: float # Negative: left, positive: right
|
||||||
|
@export var roll: float # Negative: left, positive: right
|
||||||
|
@export var throttle: float # 0: minimum, 1: maximum
|
||||||
|
@export var brake: float # 0: fully released, 1: fully applied
|
1
scripts/aircraft/nodes/aircraft_controller.gd.uid
Normal file
1
scripts/aircraft/nodes/aircraft_controller.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://b2k35mmv3g82l
|
55
scripts/aircraft/nodes/atmosphere.gd
Normal file
55
scripts/aircraft/nodes/atmosphere.gd
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
@export var pressure_ASL := 101.325 # 1 atm. in kPa
|
||||||
|
@export var density_ASL := 1.225 # at 288.15k in kg/m^3
|
||||||
|
@export var temperature_ASL := 288.15 # surface temperature in Kelvin (288.15K = 15C)
|
||||||
|
@export var tropopause_altitude := 11000.0 # meters above ASL
|
||||||
|
@export var tropopause_temp := 216.65 # (216.65K = -56.5C)
|
||||||
|
@export var gravity := 9.8 # here until I figure out the best way to get the project's default gravity.
|
||||||
|
|
||||||
|
const AIR_MOLAR_MASS := 0.029 # kg/mol
|
||||||
|
const GAS_CONSTANT := 8.31447
|
||||||
|
const MACH_COEFF := 20.02948
|
||||||
|
|
||||||
|
var pressure_constant: float
|
||||||
|
var density_constant: float
|
||||||
|
var temp_lapse_at_tropo: float # temperature lapse at troposphere, in K or C
|
||||||
|
|
||||||
|
# Use this for initialization
|
||||||
|
func _ready() -> void:
|
||||||
|
_recalculate()
|
||||||
|
|
||||||
|
func _recalculate() -> void:
|
||||||
|
pressure_constant = (gravity * AIR_MOLAR_MASS) / (GAS_CONSTANT * temperature_ASL)
|
||||||
|
density_constant = 1 / density_ASL
|
||||||
|
temp_lapse_at_tropo = (temperature_ASL - tropopause_temp) / tropopause_altitude
|
||||||
|
|
||||||
|
func pressure_by_alt(altitude: float, atm := false) -> float: # returns the pressure at altitude in kPa (default) or atm.
|
||||||
|
var ret := exp(pressure_constant * altitude)
|
||||||
|
if !atm:
|
||||||
|
ret *= pressure_ASL
|
||||||
|
return ret
|
||||||
|
|
||||||
|
func density_by_alt(altitude: float, relative := false) -> float: # returns the density at altitude in kg/m^3 (default), or relative.
|
||||||
|
var ret := pressure_by_alt(altitude) / (0.287058 * temperature_by_alt(altitude))
|
||||||
|
if relative:
|
||||||
|
ret *= density_constant
|
||||||
|
return ret
|
||||||
|
|
||||||
|
func temperature_by_alt(altitude: float) -> float:
|
||||||
|
if altitude < tropopause_altitude:
|
||||||
|
return temperature_ASL - altitude * temp_lapse_at_tropo
|
||||||
|
else: # mesopause coming soon!
|
||||||
|
return tropopause_temp
|
||||||
|
|
||||||
|
func speed_of_sound_by_alt(altitude: float) -> float:
|
||||||
|
return sqrt(temperature_by_alt(altitude)) * MACH_COEFF
|
||||||
|
|
||||||
|
func mach_by_alt(altitude: float, speed: float) -> float:# a little bit expensive - use with caution
|
||||||
|
return speed / speed_of_sound_by_alt(altitude)
|
||||||
|
|
||||||
|
func atm_to_kPa(pressure: float) -> float:
|
||||||
|
return pressure * pressure_ASL
|
||||||
|
|
||||||
|
func kPa_to_atm(pressure: float) -> float:
|
||||||
|
return pressure / pressure_ASL
|
1
scripts/aircraft/nodes/atmosphere.gd.uid
Normal file
1
scripts/aircraft/nodes/atmosphere.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://0nphoxplw624
|
201
scripts/aircraft/nodes/fixed_wing_aircraft.gd
Normal file
201
scripts/aircraft/nodes/fixed_wing_aircraft.gd
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
class_name FixedWingAircraft
|
||||||
|
extends CharacterBody3D
|
||||||
|
|
||||||
|
@export var performance: FixedWingAircraftPerformance
|
||||||
|
@export var controller: AircraftController
|
||||||
|
|
||||||
|
@export var initial_speed: float
|
||||||
|
|
||||||
|
#var acceleration := Vector3
|
||||||
|
#var angular_velocity := Vector3
|
||||||
|
#var angular_acceleration := Vector3
|
||||||
|
var m_aoa: float
|
||||||
|
var m_sideslip: float
|
||||||
|
var m_tas: float
|
||||||
|
var m_ias: float
|
||||||
|
var m_relative_velocity: Vector3
|
||||||
|
|
||||||
|
var m_is_landed := false
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
velocity = -global_basis.z * initial_speed
|
||||||
|
m_relative_velocity = transform.basis.inverse() * velocity
|
||||||
|
m_tas = _tas()
|
||||||
|
m_ias = _ias()
|
||||||
|
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
|
||||||
|
m_relative_velocity = transform.basis.inverse() * velocity
|
||||||
|
m_aoa = -atan2(m_relative_velocity.y, -m_relative_velocity.z)
|
||||||
|
if m_aoa > PI:
|
||||||
|
m_aoa -= TAU
|
||||||
|
m_sideslip = -atan2(m_relative_velocity.x, -m_relative_velocity.z)
|
||||||
|
if m_sideslip > PI:
|
||||||
|
m_sideslip -= TAU
|
||||||
|
m_tas = _tas()
|
||||||
|
m_ias = _ias()
|
||||||
|
|
||||||
|
# aero
|
||||||
|
var vel_forward := m_relative_velocity.normalized()
|
||||||
|
var vel_right := vel_forward.cross(Vector3.UP).normalized()
|
||||||
|
var vel_up := vel_right.cross(vel_forward).normalized()
|
||||||
|
#var vel_basis := Basis(vel_right, vel_up, vel_forward)
|
||||||
|
var linear_forces := Vector3.ZERO
|
||||||
|
|
||||||
|
var horiz_lift := _lift(performance.horizontal_surface,
|
||||||
|
performance.horizontal_area,
|
||||||
|
performance.horizontal_aspect_ratio,
|
||||||
|
performance.horizontal_sweep,
|
||||||
|
m_aoa, m_tas)
|
||||||
|
var horiz_drag := _drag(performance.horizontal_surface,
|
||||||
|
performance.horizontal_area,
|
||||||
|
performance.horizontal_aspect_ratio,
|
||||||
|
performance.horizontal_sweep,
|
||||||
|
m_aoa, m_tas)
|
||||||
|
var vert_lift := _lift(performance.vertical_surface,
|
||||||
|
performance.vertical_area,
|
||||||
|
performance.vertical_aspect_ratio,
|
||||||
|
performance.vertical_sweep,
|
||||||
|
m_sideslip, m_tas)
|
||||||
|
var vert_drag := _drag(performance.vertical_surface,
|
||||||
|
performance.vertical_area,
|
||||||
|
performance.vertical_aspect_ratio,
|
||||||
|
performance.vertical_sweep,
|
||||||
|
m_sideslip, m_tas)
|
||||||
|
|
||||||
|
linear_forces += vel_up * horiz_lift
|
||||||
|
linear_forces += vel_right * vert_lift
|
||||||
|
linear_forces -= vel_forward * horiz_drag
|
||||||
|
linear_forces -= vel_forward * vert_drag
|
||||||
|
linear_forces += Vector3.FORWARD * _thrust()
|
||||||
|
m_relative_velocity += linear_forces * delta / performance.empty_mass
|
||||||
|
velocity = (transform.basis * m_relative_velocity) + (get_gravity() * delta)
|
||||||
|
|
||||||
|
# steering
|
||||||
|
var steering_axis := _get_steering_axis() * delta
|
||||||
|
if (steering_axis.length_squared() > 0.0):
|
||||||
|
rotate_object_local(steering_axis.normalized(), steering_axis.length())
|
||||||
|
|
||||||
|
move_and_slide()
|
||||||
|
#if !is_landed:
|
||||||
|
# _fly()
|
||||||
|
#else:
|
||||||
|
# taxi()
|
||||||
|
#ResetControls()
|
||||||
|
|
||||||
|
#func _sync()
|
||||||
|
|
||||||
|
func _get_steering_axis() -> Vector3:
|
||||||
|
var pitch_effect := Vector3.RIGHT * performance.pitch_power.sample(absf(rad_to_deg(m_aoa))) * controller.pitch
|
||||||
|
var yaw_effect := performance.yaw_axis.normalized() * performance.yaw_power.sample(absf(rad_to_deg(m_sideslip))) * controller.yaw
|
||||||
|
var roll_effect := performance.roll_axis.normalized() * performance.roll_power.sample(absf(rad_to_deg(m_aoa))) * controller.roll
|
||||||
|
return (pitch_effect + yaw_effect + roll_effect) * m_ias / performance.reference_ias_mps
|
||||||
|
|
||||||
|
func _lift(foil: Airfoil,
|
||||||
|
area: float,
|
||||||
|
aspect_ratio: float,
|
||||||
|
_sweep: float,
|
||||||
|
aoa: float,
|
||||||
|
tas: float) -> float:
|
||||||
|
# https://www1.grc.nasa.gov/beginners-guide-to-aeronautics/downwash-effects-on-lift/
|
||||||
|
var Cl0: float
|
||||||
|
if absf(aoa) < PI / 9:
|
||||||
|
Cl0 = foil.lift_curve.sample(rad_to_deg(aoa))
|
||||||
|
else:
|
||||||
|
Cl0 = sin(aoa * 2.0) * 2.0
|
||||||
|
var Cl := Cl0 / (1.0 + Cl0 / (PI * aspect_ratio))
|
||||||
|
return Cl * area * tas * tas * Atmosphere.density_by_alt(position.y) * 0.5
|
||||||
|
|
||||||
|
func _drag(foil: Airfoil,
|
||||||
|
area: float,
|
||||||
|
_aspect_ratio: float,
|
||||||
|
_sweep: float,
|
||||||
|
aoa: float,
|
||||||
|
tas: float) -> float:
|
||||||
|
var Dl0: float
|
||||||
|
if absf(aoa) < PI / 9:
|
||||||
|
Dl0 = foil.drag_curve.sample(rad_to_deg(aoa))
|
||||||
|
else:
|
||||||
|
Dl0 = sin(aoa) * sin(aoa) * 10.0
|
||||||
|
#var Dl := Dl0 / (1.0 + Dl0 / (PI * aspect_ratio))
|
||||||
|
return Dl0 * area * tas * tas * Atmosphere.density_by_alt(position.y) * 0.5
|
||||||
|
|
||||||
|
func _moment(foil: Airfoil,
|
||||||
|
area: float,
|
||||||
|
aspect_ratio: float,
|
||||||
|
_sweep: float,
|
||||||
|
aoa: float,
|
||||||
|
tas: float) -> float:
|
||||||
|
var Ml0 := foil.lift_curve.sample(rad_to_deg(aoa))
|
||||||
|
#var Ml := Ml0 / (1.0 + Ml0 / (PI * aspect_ratio))
|
||||||
|
var mean_chord := sqrt(area / aspect_ratio)
|
||||||
|
return Ml0 * area * tas * tas * Atmosphere.density_by_alt(position.y) * 0.5 * mean_chord
|
||||||
|
|
||||||
|
func _thrust() -> float:
|
||||||
|
var speed_contrib := performance.propultion.propultion_speed_curve.sample(Atmosphere.mach_by_alt(position.y, m_tas))
|
||||||
|
var density_contrib := performance.propultion.propultion_density_curve.sample(Atmosphere.density_by_alt(position.y, true))
|
||||||
|
var temp_contrib := performance.propultion.propultion_temperature_curve.sample(Atmosphere.temperature_by_alt(position.y))
|
||||||
|
return speed_contrib * density_contrib * temp_contrib * performance.base_thrust * controller.throttle
|
||||||
|
|
||||||
|
#func _fly() -> void:
|
||||||
|
#acceleration = Vector3.DOWN * global_basis * gravity
|
||||||
|
#if controller.brake > 0.0:
|
||||||
|
# mThrust -= performance.braking_power * _ias()
|
||||||
|
#acceleration += Vector3.FORWARD * mThrust / mass;
|
||||||
|
#lift();
|
||||||
|
#control();
|
||||||
|
#velocity += mAcceleration * Time.fixedDeltaTime;
|
||||||
|
#transform.Translate(velocity * Time.fixedDeltaTime * iScale);
|
||||||
|
#Vector3 prevVel = transform.TransformDirection(velocity);
|
||||||
|
#transform.Rotate(mAngularVelocity * Time.fixedDeltaTime);
|
||||||
|
#velocity = transform.InverseTransformDirection(prevVel);
|
||||||
|
# Check to see if we've landed
|
||||||
|
#if (isLandingGearDeployed)
|
||||||
|
#{
|
||||||
|
# RaycastHit ground;
|
||||||
|
# Physics.Raycast(transform.position, -transform.up, out ground, rideHeight, 0xFF, QueryTriggerInteraction.Ignore);
|
||||||
|
# if (ground.collider != null && ground.distance < rideHeight)
|
||||||
|
# {
|
||||||
|
# AttemptLanding(ref ground);
|
||||||
|
# }
|
||||||
|
#}
|
||||||
|
|
||||||
|
#func lift() -> void:
|
||||||
|
# var speed_sqr_YZ := velocity.y * velocity.y + velocity.z * velocity.z
|
||||||
|
# var speed_sqr_XZ := velocity.x * velocity.x + velocity.z * velocity.z
|
||||||
|
# var altitude := Atmosphere.altitude(position.y)
|
||||||
|
# float horizLiftPerCoeff = speed_sqr_YZ * horizWingArea * Atmosphere.Density(altitude, true) * 0.5f / mass;
|
||||||
|
# float vertLiftPerCoeff = speed_sqr_XZ * vertWingArea * Atmosphere.Density(altitude, true) * 0.5f / mass;
|
||||||
|
# float degAoA = AoA * Mathf.Rad2Deg;
|
||||||
|
# float degSideslip = sideslip * Mathf.Rad2Deg;
|
||||||
|
# float wingDrag = horizAirfoil.getDrag(degAoA) * horizWingArea + vertAirfoil.getDrag(degSideslip) * vertWingArea;
|
||||||
|
# float mach = Atmosphere.Mach(altitude, velocity.magnitude);
|
||||||
|
# if (mach > 0.7f) # No need to do expensive calculations unless we're going fast enough for them to matter.
|
||||||
|
# {
|
||||||
|
# wingDrag += 3 * wingDrag * Mathf.Min(Mathf.Exp(16 * (mach - 1.0f + Mathf.Log10(1 - wingSweep / 90.0f))), Mathf.Exp(-mach + 1.0f));
|
||||||
|
# }
|
||||||
|
# float totalDrag = indicatedVelocity.sqrMagnitude * Atmosphere.Density(altitude, true) * 0.5f * (wingDrag + bodyDragCoeff * frontalArea) / mass;
|
||||||
|
# Vector3 relativeAccel = new Vector3(-vertAirfoil.getLift(degSideslip) * vertLiftPerCoeff, horizAirfoil.getLift(degAoA) * horizLiftPerCoeff, -totalDrag);
|
||||||
|
# Vector3 fixedAcceleration = TransformR(relativeAccel);
|
||||||
|
# if ((velocity.x + mAcceleration.x * Time.fixedDeltaTime) * velocity.x < 0.0f)
|
||||||
|
# {
|
||||||
|
# fixedAcceleration.x = -velocity.x / Time.fixedDeltaTime;
|
||||||
|
# }
|
||||||
|
# if ((velocity.y + mAcceleration.y * Time.fixedDeltaTime) * velocity.y < 0.0f)
|
||||||
|
# {
|
||||||
|
# fixedAcceleration.y = -velocity.y / Time.fixedDeltaTime;
|
||||||
|
# }
|
||||||
|
# acceleration += fixedAcceleration;
|
||||||
|
# mAngularVelocity = new Vector3(horizAirfoil.getMoment(degAoA) * horizLiftPerCoeff, vertAirfoil.getMoment(degSideslip) * vertLiftPerCoeff, 0f);
|
||||||
|
# mAngularVelocity += new Vector3(-moment * Mathf.Cos(Vector3.Angle(Physics.gravity, transform.up) * Mathf.Deg2Rad) * horizLiftPerCoeff, 0.0f, 0.0f)
|
||||||
|
|
||||||
|
func _tas() -> float:
|
||||||
|
return sqrt(m_relative_velocity.z * m_relative_velocity.z + m_relative_velocity.y * m_relative_velocity.y) * -sign(m_relative_velocity.z)
|
||||||
|
|
||||||
|
func _ias() -> float:
|
||||||
|
return _tas() * sqrt(Atmosphere.density_by_alt(position.y, true))
|
||||||
|
|
||||||
|
#func _
|
||||||
|
|
||||||
|
#func _g_force() -> Vector3:
|
||||||
|
# return (acceleration - transform.inverse(get_gravity())) / get_gravity().length()
|
1
scripts/aircraft/nodes/fixed_wing_aircraft.gd.uid
Normal file
1
scripts/aircraft/nodes/fixed_wing_aircraft.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://bddnsq0h2tpf
|
37
scripts/aircraft/nodes/flight_sim_controller.gd
Normal file
37
scripts/aircraft/nodes/flight_sim_controller.gd
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
class_name FlightSimController
|
||||||
|
extends AircraftController
|
||||||
|
|
||||||
|
@export var pitch_down := &"pitch_down"
|
||||||
|
@export var pitch_up := &"pitch_up"
|
||||||
|
@export var yaw_left := &"yaw_left"
|
||||||
|
@export var yaw_right := &"yaw_right"
|
||||||
|
@export var roll_left := &"roll_left"
|
||||||
|
@export var roll_right := &"roll_right"
|
||||||
|
@export var throttle_down := &"throttle_down"
|
||||||
|
@export var throttle_up := &"throttle_up"
|
||||||
|
|
||||||
|
@export var pitch_speed := 1.0
|
||||||
|
@export var yaw_speed := 1.0
|
||||||
|
@export var roll_speed := 1.0
|
||||||
|
@export var throttle_speed := 1.0
|
||||||
|
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
if get_multiplayer_authority() == multiplayer.get_unique_id():
|
||||||
|
var pitch_target := Input.get_axis(pitch_down, pitch_up)
|
||||||
|
var pitch_diff := pitch_target - pitch
|
||||||
|
pitch += signf(pitch_diff) * minf(absf(pitch_diff), pitch_speed * delta)
|
||||||
|
|
||||||
|
var yaw_target := Input.get_axis(yaw_left, yaw_right)
|
||||||
|
var yaw_diff := yaw_target - yaw
|
||||||
|
yaw += signf(yaw_diff) * minf(absf(yaw_diff), yaw_speed * delta)
|
||||||
|
|
||||||
|
var roll_target := Input.get_axis(roll_left, roll_right)
|
||||||
|
var roll_diff := roll_target - roll
|
||||||
|
roll += signf(roll_diff) * minf(absf(roll_diff), roll_speed * delta)
|
||||||
|
|
||||||
|
var throttle_target := Input.get_axis(throttle_down, throttle_up) * 0.5 + 0.5
|
||||||
|
if throttle_target > throttle:
|
||||||
|
throttle = minf(throttle_target, throttle + throttle_speed * delta)
|
||||||
|
elif throttle_target < throttle:
|
||||||
|
throttle = maxf(throttle_target, throttle - throttle_speed * delta)
|
||||||
|
brake = 1.0 if throttle < 0.05 else 0.0
|
1
scripts/aircraft/nodes/flight_sim_controller.gd.uid
Normal file
1
scripts/aircraft/nodes/flight_sim_controller.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://pc3j1c6e1ra7
|
6
scripts/aircraft/resources/airfoil.gd
Normal file
6
scripts/aircraft/resources/airfoil.gd
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
class_name Airfoil
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
@export var lift_curve: Curve
|
||||||
|
@export var drag_curve: Curve
|
||||||
|
@export var moment_curve: Curve
|
1
scripts/aircraft/resources/airfoil.gd.uid
Normal file
1
scripts/aircraft/resources/airfoil.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://jts0c0xrwc8q
|
|
@ -0,0 +1,27 @@
|
||||||
|
class_name FixedWingAircraftPerformance
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
@export var horizontal_surface: Airfoil
|
||||||
|
@export var horizontal_area: float
|
||||||
|
@export var horizontal_aspect_ratio: float
|
||||||
|
@export var horizontal_sweep: float
|
||||||
|
@export var vertical_surface: Airfoil
|
||||||
|
@export var vertical_area: float
|
||||||
|
@export var vertical_aspect_ratio: float
|
||||||
|
@export var vertical_sweep: float
|
||||||
|
@export var propultion: Propultion
|
||||||
|
@export var base_thrust: float
|
||||||
|
@export var base_drag: float
|
||||||
|
@export var empty_mass: float
|
||||||
|
@export var yaw_axis: Vector3 = Vector3.DOWN
|
||||||
|
@export var roll_axis: Vector3 = Vector3.FORWARD
|
||||||
|
@export var pitch_stability: float
|
||||||
|
@export var yaw_stability: float
|
||||||
|
@export var roll_stability: float
|
||||||
|
|
||||||
|
# Below are factors designed around the reference IAS.
|
||||||
|
@export var reference_ias_mps: float = 100.0
|
||||||
|
@export var braking_power: float
|
||||||
|
@export var pitch_power: Curve
|
||||||
|
@export var yaw_power: Curve
|
||||||
|
@export var roll_power: Curve
|
|
@ -0,0 +1 @@
|
||||||
|
uid://qjdma7j2qrns
|
6
scripts/aircraft/resources/propultion.gd
Normal file
6
scripts/aircraft/resources/propultion.gd
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
class_name Propultion
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
@export var propultion_speed_curve: Curve
|
||||||
|
@export var propultion_density_curve: Curve
|
||||||
|
@export var propultion_temperature_curve: Curve
|
1
scripts/aircraft/resources/propultion.gd.uid
Normal file
1
scripts/aircraft/resources/propultion.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://8fsi1mq555uj
|
Loading…
Add table
Add a link
Reference in a new issue