class_name CockpitPressureBulkhead extends Node3D ## Imported pressure hull (end cap, knuckle and barrel in one shell) and the ## porthole bolted into it. Both models are instanced by `cockpit_interior.tscn`. ## The porthole glass lives alone on render layer 2 so interior lights that ## sit right behind it (the cool porthole fill) can leave it out of their cull ## mask instead of mirroring themselves as a hard specular point. const PORTHOLE_GLASS_RENDER_LAYER_BIT := 1 << 1 ## Imported glass is near-mirror smooth; a little roughness turns the remaining ## lamp reflections into soft smears rather than pinpoints. const PORTHOLE_GLASS_ROUGHNESS := 0.45 const CockpitMeshFactory = preload( "res://game/presentation/cockpit/cockpit_mesh_factory.gd" ) const WHITEBOX_NAMES: Array[String] = [ "LeftBulkhead", "RightBulkhead", "TopBulkhead", "BottomBulkhead", ] var _hull_shells: Array[Node] = [] var _porthole_frame: MeshInstance3D var _porthole_glass: MeshInstance3D func _ready() -> void: var hull := get_node_or_null("HullWall") if hull != null: _hull_shells = hull.find_children("*", "MeshInstance3D", true, false) _porthole_frame = _find_mesh("Porthole") _porthole_glass = _find_mesh("PortholeGlass") if _hull_shells.is_empty() or _porthole_frame == null or _porthole_glass == null: push_error("Pressure hull or porthole model is missing a node") return _porthole_glass.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF _porthole_glass.layers = PORTHOLE_GLASS_RENDER_LAYER_BIT var glass_material := CockpitMeshFactory.own_surface_material(_porthole_glass) if glass_material != null: glass_material.roughness = PORTHOLE_GLASS_ROUGHNESS func glass_is_on_dedicated_layer() -> bool: return _porthole_glass != null and _porthole_glass.layers == PORTHOLE_GLASS_RENDER_LAYER_BIT func glass_roughness() -> float: if _porthole_glass == null: return 0.0 var material := _porthole_glass.get_active_material(0) as BaseMaterial3D return 0.0 if material == null else material.roughness func panel_count() -> int: return _hull_shells.size() func hull_shell() -> MeshInstance3D: return null if _hull_shells.is_empty() else _hull_shells[0] as MeshInstance3D func porthole_frame() -> MeshInstance3D: return _porthole_frame func porthole_glass() -> MeshInstance3D: return _porthole_glass func rectangular_whitebox_is_hidden() -> bool: for node_name: String in WHITEBOX_NAMES: var whitebox := get_parent().get_node_or_null(node_name) as MeshInstance3D if whitebox != null and whitebox.visible: return false return true func _find_mesh(mesh_name: String) -> MeshInstance3D: var matches := find_children(mesh_name, "MeshInstance3D", true, false) return null if matches.is_empty() else matches[0] as MeshInstance3D