# Pressure hatch, game-ready A round, hinged pressure hatch in a wall plate, after the user's reference sheet "PRESSURE HATCH" (2026-10-14): a grey plate with rounded corners, one long cut corner bottom left, a round lamp top right and two triangular pockets bottom right; a black seal ring with light slots; a white leaf with a blue window, an orange indicator, a release valve and labels; a dark hinge block on the right with a grey latch plate. Opened, the leaf's back shows the locking mechanism: a cam ring round the window hub, eight white dogs on guide rails and amber pads. Palette as on the sheet: three greys and amber. The sheet's "UAC" lettering is left out (no brand names on the project's assets). **A stand-alone model for now**, at the user's word (2026-10-14: *"I'll say later where it goes"*): not placed in the ship and not in the Unreal project until they say where. Built in the live Blender through the MCP, by script. Nothing is a boolean; every surface is quads except the fans at the centres of turned parts and the flat caps of the small parts (triangulated). ## Files - `PressureHatch.blend` (Blender 5.2): the hatch, rigged. Collections: `PressureHatch` → `PH | static`, `PH | moving`, `PH | collision` (UCX hulls, excluded from the view layer); `Studio` (camera and lights, not exported). - `fbx/SM_PressureHatch_.fbx`: one file per mesh at its own pivot, with its `UCX_` hulls. `fbx/PressureHatch_Assembled.fbx`: everything shut, for a quick look. - `PressureHatch_layout.json`: pivots, motion, timing, materials, in Unreal units. - `textures/T_PH_Masks.png` (4096, baked: R occlusion, G edges, B crevices), `T_PH_Hazard_BaseColor.png` (seamless amber and black stripes). The tiling sets are the Season 2 pack's own files, read in place from `../vessel-interior/textures/ModSci_Engineer/Textures` (**relative paths: keep the .blend here**). - `previews/`: Cycles pictures (`PressureHatch_01..`); `wip_*` are working shots. - `build/`: `ph_lib.py` (geometry helpers, copied from the pressure door), `ph_build.py` (the parts), `ph_rig.py`, `ph_check.py` (travel check), `ph_surfaces.py` (UVs, bake, materials), `ph_export.py` (UCX, FBX, layout), `ph_studio.py`. Run one in the open Blender with `ns = {}; exec(compile(open(p).read(), p, "exec"), ns)` and call its function; `build_all()` rebuilds every mesh (then run `rig()`, the surfaces and the export again). ## Scale, axes, size 1 unit = 1 m, Z up. **The origin is on the hatch axis in the wall's front face** (not at the floor): the axis is Y, the wall's front face is y = 0, the hatch is seen from −Y. +X is right; the hinge is on the right and the leaf swings out toward −Y. In Unreal: **ue_cm = (x, −y, z) × 100** (the project's FBX pair, as for the pressure door; the data is turned −90° about Z on export). | | | |---|---| | clear opening | Ø 1.00 m (R 0.50) through the seat lip and the bore | | leaf | Ø 1.12 m; its face sits 3 cm below the seal ring, its gasket 5 mm off the seat | | seal ring | Ø 1.66 m | | wall plate | 2.10 × 1.90 m, 6 cm thick | | wall | 0.20 m (bore and back flange); the optional bulkhead piece is 3.0 × 2.8 m | | mounting | not given; for a crouch-through hatch put the axis about 0.85 m above the floor | ## Parts and pivots | Mesh | Pivot | Motion | |---|---|---| | `SM_PressureHatch_Frame` | origin | static: plate, seal ring with slots, seat lip, the groove behind the lip that the dogs lock into, bore, back flange, hinge block with pin and nuts, lamp, pockets, foot plate, screws | | `SM_PressureHatch_Bulkhead` | origin | static, optional: a piece of 0.20 m wall with a hole of R 0.64 (the frame's bore lines the opening). Leave it out where the ship's wall is | | `SM_PressureHatch_Leaf` | hinge pin (0.72, −0.16, 0) | leaf, arm, knuckle, handle: **yaw +105° about Z** (Unreal −105°) | | `SM_PressureHatch_Cam` | (0, 0.004, 0), child of the leaf | ring with eight lobes round the window hub: **turns 20° about Y**, counter-clockwise seen from the front | | `SM_PressureHatch_Dog` ×8 | its centre; children of the leaf at 0, 45 … 315° | **slides 0.08 m along its local −X** (inward, out of the groove) | ## Rig (Blender) One slider: `PressureHatch_Root["open"]` (0 shut and locked, 1 open). Cam and dogs 0–0.30, swing 0.35–1.00, each eased. Drivers are simple expressions (they run with Python auto-run off). The timeline plays it: shut at frame 1, open at 90, held to 150, shut at 240, 30 fps; action `PressureHatch | OPEN_CLOSE`. Each moving part keeps `["closed_location"]` and `["closed_rotation"]`. **To render a state, set the frame**: the timeline keys drive the slider. ## Checked `ph_check.py` runs the slider through 101 steps and tests every moving part against every static mesh and the other moving parts (triangle overlap in world space), and measures the gaps: **no clash anywhere in the travel.** Smallest gaps: 5 mm (knuckle to the hinge housings, pin in its bore, dogs to the lip and the groove), cam 3 mm over the back plate, dogs 1 mm over their beds. One clash found on the way and fixed: the arm's knuckle sat 15 mm inside the seal ring, so the pin moved 15 mm forward and the knuckle got slimmer. ## Surfaces Two UV layers on every mesh: `UVMap` (UV0, a unique unwrap into the shared mask atlas) and `UV_Tile` (UV1, metres, box-projected, for the tiling sets). | Material | What it is | Set | |---|---|---| | `M_PH_Grey` | mid grey plate paint | ScratchedMetal under the tint, a few chips on exposed edges | | `M_PH_Light` | light grey trim: seal ring edges, slots, cover plates, arm, wall | as above | | `M_PH_White` | the leaf's white paint | as above | | `M_PH_Dark` | near-black: seal ring, bore, hinge block, mechanism | ScratchedMetal, matte | | `M_PH_Steel` | bright steel: band, bezel, cam, pin, screws, handle | StainedSteel + scratch normal | | `M_PH_Rubber` | the leaf's gasket | ScratchedMetal roughness | | `M_PH_Amber` | amber paint: pads, label, pill, valve centre | ScratchedMetal | | `M_PH_Hazard` | amber and black stripes on the latch plate | `T_PH_Hazard_BaseColor`, 0.12 m a repeat | | `M_PH_Glass` | the blue window, opaque coated glass with a faint glow (as on the sheet) | Glass_DirtRough smudges | | `M_PH_Orange`, `M_PH_Lens` | the indicator and the lamp, emissive | — | ## Collision `UCX__NN` convex hulls (in `PH | collision`, exported inside each part's FBX): 21 for the frame (16 ring segments from the opening to the seal ring and through the wall, four pieces of the plate clear of the opening, the hinge block), 2 for the leaf (disc with hub and front parts, the arm with knuckle and handle; in the leaf's frame, so they swing with it), 4 for the optional wall round its hole. Cam and dogs have none. The opening stays clear: Ø 1.00 m. ## Triangles Frame 19.2k, leaf 29.3k, cam 3.7k, dog 0.65k ×8: about 57k for the working hatch; the optional wall adds 2.6k. ## Checked after export `build/ph_verify_fbx.py` (headless: `blender.exe -b --factory-startup --python ph_verify_fbx.py`) re-imports every FBX and writes `fbx/verify_report.json`: each part comes back at scale 1 on its own pivot, with both UV layers, its materials and its hulls, and no n-gons. ## Not done - Placing it: kept stand-alone until the user says where the hatch goes (a wall, a deck or a ceiling) and at what height. - Unreal: not imported. `PressureHatch_layout.json` has what the import and a hatch actor need (pivots, motion, timing, materials); the materials there would be rebuilt from the same texture sets.