193 lines
5.5 KiB
GDScript
193 lines
5.5 KiB
GDScript
class_name CockpitPressureBulkhead
|
|
extends Node3D
|
|
|
|
const CockpitMaterialPalette = preload(
|
|
"res://game/presentation/cockpit/cockpit_material_palette.gd"
|
|
)
|
|
const CockpitMeshFactory = preload(
|
|
"res://game/presentation/cockpit/cockpit_mesh_factory.gd"
|
|
)
|
|
|
|
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
|
|
|
|
var _materials: CockpitMaterialPalette
|
|
var _panel_count := 0
|
|
|
|
|
|
func _ready() -> void:
|
|
_materials = CockpitMaterialPalette.new()
|
|
_hide_rectangular_whitebox()
|
|
_style_existing_frame()
|
|
_build_curved_panels()
|
|
_build_outer_rib()
|
|
_build_fasteners()
|
|
_build_clamp_plates()
|
|
|
|
|
|
func panel_count() -> int:
|
|
return _panel_count
|
|
|
|
|
|
func rectangular_whitebox_is_hidden() -> bool:
|
|
for node_name: String in ["LeftBulkhead", "RightBulkhead", "TopBulkhead", "BottomBulkhead"]:
|
|
var whitebox := get_parent().get_node_or_null(node_name) as MeshInstance3D
|
|
if whitebox != null and whitebox.visible:
|
|
return false
|
|
return true
|
|
|
|
|
|
func _hide_rectangular_whitebox() -> void:
|
|
for node_name: String in ["LeftBulkhead", "RightBulkhead", "TopBulkhead", "BottomBulkhead"]:
|
|
var whitebox := get_parent().get_node_or_null(node_name) as MeshInstance3D
|
|
if whitebox != null:
|
|
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.brass
|
|
|
|
|
|
func _build_curved_panels() -> void:
|
|
var panel_angle := TAU / float(PANEL_COUNT)
|
|
for panel_index in PANEL_COUNT:
|
|
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)
|
|
panel.material_override = _materials.overhead_steel
|
|
panel.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_ON
|
|
add_child(panel)
|
|
_panel_count += 1
|
|
|
|
|
|
func _create_curved_panel_mesh(start_angle: float, end_angle: float) -> ArrayMesh:
|
|
var surface := SurfaceTool.new()
|
|
surface.begin(Mesh.PRIMITIVE_TRIANGLES)
|
|
for angular_index in ANGULAR_STEPS:
|
|
var angle_ratio_0 := float(angular_index) / float(ANGULAR_STEPS)
|
|
var angle_ratio_1 := float(angular_index + 1) / float(ANGULAR_STEPS)
|
|
var angle_0 := lerpf(start_angle, end_angle, angle_ratio_0)
|
|
var angle_1 := lerpf(start_angle, end_angle, angle_ratio_1)
|
|
for radial_index in RADIAL_STEPS:
|
|
var radial_ratio_0 := float(radial_index) / float(RADIAL_STEPS)
|
|
var radial_ratio_1 := float(radial_index + 1) / float(RADIAL_STEPS)
|
|
_add_panel_quad(
|
|
surface,
|
|
angle_0,
|
|
angle_1,
|
|
angle_ratio_0,
|
|
angle_ratio_1,
|
|
radial_ratio_0,
|
|
radial_ratio_1
|
|
)
|
|
surface.generate_normals()
|
|
return surface.commit()
|
|
|
|
|
|
func _add_panel_quad(
|
|
surface: SurfaceTool,
|
|
angle_0: float,
|
|
angle_1: float,
|
|
angle_ratio_0: float,
|
|
angle_ratio_1: float,
|
|
radial_ratio_0: float,
|
|
radial_ratio_1: float
|
|
) -> void:
|
|
_add_panel_vertex(surface, angle_0, angle_ratio_0, radial_ratio_0)
|
|
_add_panel_vertex(surface, angle_1, angle_ratio_1, radial_ratio_0)
|
|
_add_panel_vertex(surface, angle_0, angle_ratio_0, radial_ratio_1)
|
|
_add_panel_vertex(surface, angle_0, angle_ratio_0, radial_ratio_1)
|
|
_add_panel_vertex(surface, angle_1, angle_ratio_1, radial_ratio_0)
|
|
_add_panel_vertex(surface, angle_1, angle_ratio_1, radial_ratio_1)
|
|
|
|
|
|
func _add_panel_vertex(
|
|
surface: SurfaceTool,
|
|
angle: float,
|
|
angle_ratio: float,
|
|
radial_ratio: float
|
|
) -> void:
|
|
var radius := lerpf(INNER_RADIUS, OUTER_RADIUS, radial_ratio)
|
|
var convex_depth := sin(radial_ratio * PI) * 0.075
|
|
surface.set_uv(Vector2(angle_ratio, radial_ratio))
|
|
surface.add_vertex(
|
|
Vector3(cos(angle) * radius, sin(angle) * radius, 0.045 + convex_depth)
|
|
)
|
|
|
|
|
|
func _build_outer_rib() -> void:
|
|
var rib := MeshInstance3D.new()
|
|
rib.name = "OuterPressureRib"
|
|
var torus := TorusMesh.new()
|
|
torus.inner_radius = 1.055
|
|
torus.outer_radius = 1.125
|
|
torus.rings = 64
|
|
torus.ring_segments = 12
|
|
rib.mesh = torus
|
|
rib.material_override = _materials.dark_steel
|
|
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 FASTENER_COUNT:
|
|
var angle := (fastener_index + 0.5) * TAU / float(FASTENER_COUNT)
|
|
var fastener_position := Vector3(
|
|
cos(angle) * 0.96,
|
|
sin(angle) * 0.96,
|
|
0.12
|
|
)
|
|
CockpitMeshFactory.add_cylinder(
|
|
"OuterFastener",
|
|
self,
|
|
fastener_position,
|
|
0.020,
|
|
0.018,
|
|
_materials.brass,
|
|
Vector3(90.0, 0.0, 0.0)
|
|
)
|
|
CockpitMeshFactory.add_sphere(
|
|
"FastenerCap",
|
|
self,
|
|
fastener_position + Vector3(0.0, 0.0, 0.012),
|
|
0.017,
|
|
_materials.brushed_steel
|
|
)
|
|
|
|
|
|
func _build_clamp_plates() -> void:
|
|
for plate_index in 12:
|
|
var angle := (plate_index + 0.5) * TAU / 12.0
|
|
var plate := CockpitMeshFactory.add_box(
|
|
"PressureClamp",
|
|
self,
|
|
Vector3(cos(angle) * 0.88, sin(angle) * 0.88, 0.105),
|
|
Vector3(0.11, 0.055, 0.028),
|
|
_materials.brushed_steel
|
|
)
|
|
plate.rotation_degrees.z = rad_to_deg(angle) + 90.0
|