Reframe cockpit around industrial reference

This commit is contained in:
chindit committed 2026-10-04 09:50:41 +02:00
1 parent c2b3ac42a3
commit dffe790926
9 files changed
+146 -95

No files matched your search

@@ -6,8 +6,10 @@ const CockpitMeshFactory = preload("res://game/presentation/cockpit/cockpit_mesh
const DiveAlertLevel = preload("res://game/domain/dive/dive_alert_level.gd")
var _materials: CockpitMaterialPalette
var _oxygen_needle: Node3D
var _battery_needle: Node3D
var _pressure_needle: Node3D
var _hull_needle: Node3D
var _depth_needle: Node3D
var _indicator_materials: Array[StandardMaterial3D] = []
var _active_indicator_count := 0
@@ -15,29 +17,49 @@ var _active_indicator_count := 0
func _init(materials: CockpitMaterialPalette) -> void:
_materials = materials
name = "AnalogGauges"
_build_binnacle()
_build_instrument_cluster()
_build_indicator_bank()
_oxygen_needle = _add_gauge(
"OxygenGauge",
Vector3(-0.50, 0.12, 0.145),
"%",
0.72
)
_battery_needle = _add_gauge(
"BatteryGauge",
Vector3(-0.095, 0.315, 0.145),
"%"
Vector3(-0.22, 0.12, 0.145),
"%",
0.72
)
_pressure_needle = _add_gauge(
"PressureGauge",
Vector3(0.095, 0.315, 0.145),
"BAR"
_hull_needle = _add_gauge(
"HullGauge",
Vector3(0.05, 0.12, 0.145),
"%",
0.56
)
_add_binnacle_label("CHARGE BAT.", Vector3(-0.095, 0.235, 0.160))
_add_binnacle_label("PRESSION COQUE", Vector3(0.095, 0.235, 0.160))
_depth_needle = _add_gauge(
"DepthGauge",
Vector3(0.40, 0.12, 0.145),
"%",
0.90
)
_add_cluster_label("OXYGÈNE", Vector3(-0.50, 0.025, 0.170))
_add_cluster_label("BATTERIE", Vector3(-0.22, 0.025, 0.170))
_add_cluster_label("COQUE", Vector3(0.05, 0.045, 0.170))
_add_cluster_label("PROFONDEUR", Vector3(0.40, 0.005, 0.170))
func present(
oxygen_ratio: float,
battery_ratio: float,
pressure_ratio: float,
hull_ratio: float,
depth_ratio: float,
alert_level: DiveAlertLevel.Value
) -> void:
_set_needle_ratio(_oxygen_needle, oxygen_ratio)
_set_needle_ratio(_battery_needle, battery_ratio)
_set_needle_ratio(_pressure_needle, pressure_ratio)
_set_needle_ratio(_hull_needle, hull_ratio)
_set_needle_ratio(_depth_needle, depth_ratio)
_update_indicator_bank(alert_level)
@@ -49,23 +71,27 @@ func indicator_count() -> int:
return _indicator_materials.size()
func gauge_count() -> int:
return 4
func active_indicator_count() -> int:
return _active_indicator_count
func _build_binnacle() -> void:
func _build_instrument_cluster() -> void:
CockpitMeshFactory.add_box(
"BinnacleHousing",
"InstrumentClusterHousing",
self,
Vector3(0.0, 0.290, 0.095),
Vector3(0.40, 0.180, 0.105),
Vector3(-0.04, 0.105, 0.095),
Vector3(1.26, 0.255, 0.105),
_materials.overhead_steel
)
CockpitMeshFactory.add_box(
"BinnacleFoot",
"InstrumentClusterFoot",
self,
Vector3(0.0, 0.205, 0.075),
Vector3(0.47, 0.040, 0.14),
Vector3(-0.04, -0.025, 0.075),
Vector3(1.32, 0.040, 0.14),
_materials.dark_steel
)
@@ -81,11 +107,11 @@ func _build_indicator_bank() -> void:
]
var captions: Array[String] = ["SYS", "ATTN", "ALRM"]
for indicator_index in colors.size():
var x := -0.055 + indicator_index * 0.055
var y := 0.165 - indicator_index * 0.050
CockpitMeshFactory.add_cylinder(
"%sBezel" % captions[indicator_index],
root,
Vector3(x, 0.198, 0.156),
Vector3(0.205, y, 0.156),
0.016,
0.012,
_materials.brass,
@@ -96,7 +122,7 @@ func _build_indicator_bank() -> void:
CockpitMeshFactory.add_cylinder(
"%sLens" % captions[indicator_index],
root,
Vector3(x, 0.198, 0.165),
Vector3(0.205, y, 0.165),
0.009,
0.008,
material,
@@ -108,7 +134,7 @@ func _build_indicator_bank() -> void:
label.font_size = 8
label.pixel_size = 0.00042
label.modulate = Color(0.70, 0.67, 0.56)
label.position = Vector3(x, 0.177, 0.168)
label.position = Vector3(0.235, y, 0.168)
root.add_child(label)
@@ -136,7 +162,7 @@ func _update_indicator_bank(alert_level: DiveAlertLevel.Value) -> void:
_active_indicator_count = 1
func _add_binnacle_label(caption: String, position: Vector3) -> void:
func _add_cluster_label(caption: String, position: Vector3) -> void:
var label := Label3D.new()
label.name = "%sLabel" % caption.to_pascal_case().replace(" ", "")
label.text = caption
@@ -147,18 +173,23 @@ func _add_binnacle_label(caption: String, position: Vector3) -> void:
add_child(label)
func _add_gauge(gauge_name: String, position: Vector3, caption: String) -> Node3D:
func _add_gauge(
gauge_name: String,
position: Vector3,
caption: String,
gauge_scale: float
) -> Node3D:
var gauge := Node3D.new()
gauge.name = gauge_name
gauge.position = position
gauge.scale = Vector3(0.62, 0.62, 0.62)
gauge.scale = Vector3(gauge_scale, gauge_scale, gauge_scale)
add_child(gauge)
CockpitMeshFactory.add_box(
"MountingPlate",
gauge,
Vector3(0.0, 0.0, -0.025),
Vector3(0.225, 0.225, 0.055),
_materials.dark_steel
_materials.overhead_steel
)
for screw_position: Vector2 in [
Vector2(-0.086, -0.086),
@@ -182,7 +213,7 @@ func _add_gauge(gauge_name: String, position: Vector3, caption: String) -> Node3
bezel_mesh.height = 0.035
bezel_mesh.radial_segments = 32
bezel.mesh = bezel_mesh
bezel.material_override = _materials.brass
bezel.material_override = _materials.brushed_steel
bezel.rotation_degrees.x = 90.0
gauge.add_child(bezel)
var face := MeshInstance3D.new()
@@ -64,8 +64,8 @@ func _build_structural_frame() -> void:
CockpitMeshFactory.add_box(
"ScreenSeparator",
self,
Vector3(x, 0.015, 0.118),
Vector3(0.038, 0.39, 0.048),
Vector3(x, -0.075, 0.118),
Vector3(0.038, 0.16, 0.048),
_materials.brass
)
for screw_position: Vector2 in [
@@ -14,7 +14,6 @@ const CockpitMeshFactory = preload("res://game/presentation/cockpit/cockpit_mesh
var _materials: CockpitMaterialPalette
var _painted_steel: Material
var _dark_steel: Material
var _overhead_steel: Material
var _brass: Material
var _copper: Material
var _analog_gauges: CockpitAnalogGauges
@@ -39,10 +38,12 @@ func present(update: DiveUpdate, telemetry: VehicleTelemetry) -> void:
return
var snapshot = update.snapshot
_analog_gauges.present(
snapshot.oxygen.ratio,
snapshot.battery.ratio,
snapshot.hull.ratio,
clampf(
snapshot.hull.exterior_pressure_bar
/ maxf(snapshot.hull.certified_pressure_bar, 0.001),
snapshot.depth.current_m
/ maxf(snapshot.depth.certified_m, 0.001),
0.0,
1.0
),
@@ -89,7 +90,6 @@ func _create_materials() -> void:
_materials = CockpitMaterialPalette.new()
_painted_steel = _materials.painted_steel
_dark_steel = _materials.dark_steel
_overhead_steel = _materials.overhead_steel
_brass = _materials.brass
_copper = _materials.copper
@@ -116,7 +116,7 @@ func _apply_materials_to_existing_cockpit() -> void:
]
)
_apply_material_to_paths(
_overhead_steel,
_materials.overhead_steel,
[
"CabinShell/Ceiling",
"PortholeAssembly/TopBulkhead",
@@ -240,7 +240,7 @@ func _build_overhead_console() -> void:
root,
Vector3(0.0, 0.94, -1.06),
Vector3(0.30, 0.09, 0.12),
_overhead_steel,
_materials.overhead_steel,
Vector3(-8.0, 0.0, 0.0)
)
CockpitMeshFactory.add_box(
@@ -30,20 +30,16 @@ func present(update: DiveUpdate, telemetry: VehicleTelemetry) -> void:
return
var snapshot = update.snapshot
_resources_label.text = (
"BATTERIE\n%.1f / %.1f kWh · %.0f %%\n%.0f kW\n\nOXYGÈNE\n%.1f / %.1f L · %.0f %%\n%.1f L/min"
"BAT %.1f kWh · O₂ %.0f %%\n%.0f kW · %.1f L/min"
% [
snapshot.battery.remaining_kwh,
snapshot.battery.maximum_kwh,
snapshot.battery.ratio * 100.0,
snapshot.battery.current_power_kw,
snapshot.oxygen.remaining_l,
snapshot.oxygen.maximum_l,
snapshot.oxygen.ratio * 100.0,
snapshot.battery.current_power_kw,
snapshot.oxygen.consumption_l_per_min,
]
)
_navigation_label.text = (
"PROFONDEUR\n%.1f m\nMAX. CONSEILLÉ %.1f m\n\nVITESSE\n%.2f m/s"
"PROF. %.1f / %.1f m\nVIT. %.2f m/s"
% [
snapshot.depth.current_m,
snapshot.depth.certified_m,
@@ -51,10 +47,8 @@ func present(update: DiveUpdate, telemetry: VehicleTelemetry) -> void:
]
)
_integrity_label.text = (
"COQUE\n%.1f / %.1f · %.0f %%\n\nPRESSION\n%.2f / %.2f bar"
"COQUE %.0f %% · %.2f bar\nLIMITE %.2f bar"
% [
snapshot.hull.current_integrity,
snapshot.hull.maximum_integrity,
snapshot.hull.ratio * 100.0,
snapshot.hull.exterior_pressure_bar,
snapshot.hull.certified_pressure_bar,
+35 -35
View File
@@ -267,82 +267,82 @@ mesh = SubResource("UnitBoxMesh")
material_override = SubResource("PaintedMaterial")
[node name="ResourcesFrame" type="MeshInstance3D" parent="Dashboard"]
position = Vector3(-0.5, 0.03, 0.088)
scale = Vector3(0.45, 0.31, 0.025)
position = Vector3(-0.5, -0.075, 0.088)
scale = Vector3(0.45, 0.115, 0.025)
mesh = SubResource("UnitBoxMesh")
material_override = SubResource("BrassMaterial")
[node name="ResourcesScreen" type="MeshInstance3D" parent="Dashboard"]
position = Vector3(-0.5, 0.03, 0.102)
scale = Vector3(0.41, 0.27, 1)
position = Vector3(-0.5, -0.075, 0.102)
scale = Vector3(0.41, 0.085, 1)
mesh = SubResource("ScreenQuadMesh")
material_override = SubResource("ScreenMaterial")
[node name="ResourcesLabel" type="Label3D" parent="Dashboard"]
unique_name_in_owner = true
position = Vector3(-0.5, 0.03, 0.108)
pixel_size = 0.00115
font_size = 20
position = Vector3(-0.5, -0.075, 0.108)
pixel_size = 0.00082
font_size = 14
outline_size = 2
text = "BATTERIE\n— / — kWh\n— kW\n\nOXYGÈNE\n— / — L\n— L/min"
text = "BAT — kWh · O₂ — %\n— kW · — L/min"
modulate = Color(0.45, 0.89, 0.9, 1)
[node name="NavigationFrame" type="MeshInstance3D" parent="Dashboard"]
position = Vector3(0, 0.03, 0.088)
scale = Vector3(0.4, 0.31, 0.025)
position = Vector3(0, -0.075, 0.088)
scale = Vector3(0.4, 0.115, 0.025)
mesh = SubResource("UnitBoxMesh")
material_override = SubResource("BrassMaterial")
[node name="NavigationScreen" type="MeshInstance3D" parent="Dashboard"]
position = Vector3(0, 0.03, 0.102)
scale = Vector3(0.36, 0.27, 1)
position = Vector3(0, -0.075, 0.102)
scale = Vector3(0.36, 0.085, 1)
mesh = SubResource("ScreenQuadMesh")
material_override = SubResource("ScreenMaterial")
[node name="NavigationLabel" type="Label3D" parent="Dashboard"]
unique_name_in_owner = true
position = Vector3(0, 0.03, 0.108)
pixel_size = 0.00115
font_size = 20
position = Vector3(0, -0.075, 0.108)
pixel_size = 0.00082
font_size = 14
outline_size = 2
text = "PROFONDEUR\n— m\nMAX. — m\n\nVITESSE\n— m/s"
text = "PROF. — / — m\nVIT. — m/s"
modulate = Color(0.45, 0.89, 0.9, 1)
[node name="IntegrityFrame" type="MeshInstance3D" parent="Dashboard"]
position = Vector3(0.5, 0.03, 0.088)
scale = Vector3(0.45, 0.31, 0.025)
position = Vector3(0.5, -0.075, 0.088)
scale = Vector3(0.45, 0.115, 0.025)
mesh = SubResource("UnitBoxMesh")
material_override = SubResource("BrassMaterial")
[node name="IntegrityScreen" type="MeshInstance3D" parent="Dashboard"]
position = Vector3(0.5, 0.03, 0.102)
scale = Vector3(0.41, 0.27, 1)
position = Vector3(0.5, -0.075, 0.102)
scale = Vector3(0.41, 0.085, 1)
mesh = SubResource("ScreenQuadMesh")
material_override = SubResource("ScreenMaterial")
[node name="IntegrityLabel" type="Label3D" parent="Dashboard"]
unique_name_in_owner = true
position = Vector3(0.5, 0.03, 0.108)
pixel_size = 0.00115
font_size = 20
position = Vector3(0.5, -0.075, 0.108)
pixel_size = 0.00082
font_size = 14
outline_size = 2
text = "COQUE\n— / —\n\nPRESSION\n— / — bar"
text = "COQUE — % · — bar\nLIMITE — bar"
modulate = Color(0.45, 0.89, 0.9, 1)
[node name="ReturnLabel" type="Label3D" parent="Dashboard"]
unique_name_in_owner = true
position = Vector3(0.32, 0.205, 0.108)
pixel_size = 0.00082
font_size = 15
position = Vector3(0.61, 0.245, 0.17)
pixel_size = 0.00062
font_size = 12
outline_size = 2
text = "RETOUR · INCONNU"
modulate = Color(1, 0.75, 0.2, 1)
[node name="StatusLabel" type="Label3D" parent="Dashboard"]
unique_name_in_owner = true
position = Vector3(-0.34, 0.205, 0.108)
pixel_size = 0.00082
font_size = 15
position = Vector3(-0.61, 0.245, 0.17)
pixel_size = 0.00062
font_size = 12
outline_size = 2
text = "SYSTÈMES · NORMAL"
modulate = Color(0.45, 0.89, 0.9, 1)
@@ -413,16 +413,16 @@ text = "SONAR\nMODULE EN ATTENTE"
modulate = Color(0.34, 0.6, 0.6, 1)
[node name="EmergencyDial" type="MeshInstance3D" parent="."]
position = Vector3(-0.6, 0.39, -1.15)
scale = Vector3(0.38, 0.38, 0.38)
position = Vector3(-0.7, 0.32, -1.15)
scale = Vector3(0.18, 0.18, 0.18)
rotation_degrees = Vector3(90, 0, 0)
mesh = SubResource("DialMesh")
material_override = SubResource("RedMaterial")
[node name="EmergencyLabel" type="Label3D" parent="."]
position = Vector3(-0.6, 0.3, -1.125)
pixel_size = 0.0009
font_size = 15
position = Vector3(-0.7, 0.275, -1.125)
pixel_size = 0.00072
font_size = 12
outline_size = 2
text = "ÉJECTION · X"
modulate = Color(1, 0.48, 0.38, 1)
@@ -11,6 +11,7 @@ const GAUGE_FACE_TEXTURE_PATH := (
var painted_steel: Material
var dark_steel: Material
var overhead_steel: StandardMaterial3D
var brushed_steel: StandardMaterial3D
var brass: Material
var copper: Material
var rubber: Material
@@ -43,6 +44,7 @@ func _init() -> void:
0.56,
Vector3(1.6, 1.6, 1.6)
)
brushed_steel = _plain_material(Color(0.27, 0.30, 0.29), 0.82, 0.30)
brass = _weathered_material(
Color(0.28, 0.18, 0.045),
Color(0.08, 0.16, 0.13),
@@ -8,9 +8,10 @@ const CockpitMeshFactory = preload(
"res://game/presentation/cockpit/cockpit_mesh_factory.gd"
)
const PANEL_COUNT := 12
const ANGULAR_STEPS := 4
const RADIAL_STEPS := 3
const PANEL_COUNT := 1
const FASTENER_COUNT := 16
const ANGULAR_STEPS := 64
const RADIAL_STEPS := 4
const INNER_RADIUS := 0.72
const OUTER_RADIUS := 1.11
@@ -21,6 +22,7 @@ var _panel_count := 0
func _ready() -> void:
_materials = CockpitMaterialPalette.new()
_hide_rectangular_whitebox()
_style_existing_frame()
_build_curved_panels()
_build_outer_rib()
_build_fasteners()
@@ -45,12 +47,20 @@ func _hide_rectangular_whitebox() -> void:
whitebox.visible = false
func _style_existing_frame() -> void:
var frame := get_parent().get_node_or_null("WindowFrame") as MeshInstance3D
if frame != null:
frame.material_override = _materials.brushed_steel
for child: Node in get_parent().get_children():
if child is MeshInstance3D and child.name.begins_with("Bolt"):
(child as MeshInstance3D).material_override = _materials.dark_steel
func _build_curved_panels() -> void:
var panel_angle := TAU / float(PANEL_COUNT)
var seam_half_width := deg_to_rad(0.22)
for panel_index in PANEL_COUNT:
var start_angle := panel_index * panel_angle + seam_half_width
var end_angle := (panel_index + 1) * panel_angle - seam_half_width
var start_angle := panel_index * panel_angle
var end_angle := (panel_index + 1) * panel_angle
var panel := MeshInstance3D.new()
panel.name = "PressurePanel%02d" % (panel_index + 1)
panel.mesh = _create_curved_panel_mesh(start_angle, end_angle)
@@ -128,11 +138,23 @@ func _build_outer_rib() -> void:
rib.rotation_degrees.x = 90.0
rib.position.z = 0.025
add_child(rib)
var inner_rib := MeshInstance3D.new()
inner_rib.name = "InnerPressureRib"
var inner_torus := TorusMesh.new()
inner_torus.inner_radius = 0.695
inner_torus.outer_radius = 0.755
inner_torus.rings = 64
inner_torus.ring_segments = 12
inner_rib.mesh = inner_torus
inner_rib.material_override = _materials.brushed_steel
inner_rib.rotation_degrees.x = 90.0
inner_rib.position.z = 0.075
add_child(inner_rib)
func _build_fasteners() -> void:
for fastener_index in PANEL_COUNT:
var angle := (fastener_index + 0.5) * TAU / float(PANEL_COUNT)
for fastener_index in FASTENER_COUNT:
var angle := (fastener_index + 0.5) * TAU / float(FASTENER_COUNT)
CockpitMeshFactory.add_cylinder(
"OuterFastener",
self,