# Radiation canister station, game-ready A machine after the user's picture (2026-10-21, `reference/ref_user.png`; the user: *"create me a 3d model of this picture"*): a black frame with dark green panels and cream trim, a tower with a grey head, a short green piston and a cable on its side, a round hub with a key slot on the base, a small status screen between two cream handles on the front column, and a big dark green canister with a radiation sign leaning at 47 degrees, standing in a cream cup, held by a cream cradle rail with two clamps, closed by a black cap with a glowing ring and four cream latches. "Canister station" is a working name; the user gave none. Not in Unreal yet. Built **headless** by script (`build/`), nothing in anyone's open Blender. Nothing is a boolean: chamfered prisms with quad caps, lathes, curved boxes and tubes (`build/cs_lib.py`). ## How it was made from one picture The picture is one product shot. Its camera was estimated from things that do not depend on depth: the cap's ellipse, the hub's ellipse, the foot plate's end edge. About 10 degrees off the side, 8 degrees from above, a long lens (the model keeps it as `CS_PictureCamera`, 100 mm at 5 m). Every outline was traced in the picture's pixels from ruler crops (`reference/z_*.png`, `z3_*.png`, `build/zoom.py`) and put on the plane of its front face through that camera, so the render from `CS_PictureCamera` lands on the picture. The canister's axis and diameter were measured by scanning the picture across it at 1 px steps (lower edge at 46.5 degrees, 268 px wide = 0.40 m). Fitting overlays: `previews/fit/overlay_*.png` (`build/cs_overlay.py`). **Chosen, not in the picture:** all depths (the picture has none); the back half. The picture shows one side, so the side's detail (panels, strips, bracket, piston, cable, hub, the base's fittings, the green box, the cream pillar and plate) is **copied onto the far side**; the screen, its handles and the saddle under the canister are on the front side only. The top of the canister's cup is hidden in the picture (the screen column is in front of it). ## Files - `CanisterStation.blend` (Blender 5.2): collections `CanisterStation` → `CS | static`, `CS | moving`, `CS | collision` (UCX hulls, excluded from the view layer); `Studio` (cyclorama, lights, `CS_PictureCamera`, `CS_View`; not exported). - `fbx/SM_CanisterStation_Body.fbx` (with its 9 `UCX_` hulls), `fbx/SM_CanisterStation_Canister.fbx` (one hull, at its pivot), `fbx/CanisterStation_Assembled.fbx` (both, canister seated), `fbx/verify_report.json` (the re-import check). - `CanisterStation_layout.json`: pivots, motion, materials, sizes in Unreal units. - `textures/`: `T_CS_Body_Masks.png` (4096) and `T_CS_Canister_Masks.png` (2048), baked (R occlusion, G edges, B crevices); `T_CS_Radiation.png` (the sign, RGBA), `T_CS_Screen_UI.png` (the status screen), `T_CS_GlowRing.png` (the ring's colours round the circumference), drawn by `build/cs_textures.py`. 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 `CanisterStation_v01_*` (the picture's view, two three-quarter views, from the canister's end, the cap, the screen and hub, the canister slid out) and the sheet; `wire_*` (topology); `compare/lookalike_v01.png` (the picture left, the model right, same camera); `fit/` (working renders and overlays). - `reference/`: the picture, ruler crops, `check_textures.png`. ## Scale, axes, size 1 unit = 1 m, Z up. The picture's side (with the screen) faces −Y; the canister leans toward +X. **Origin: on the ground under the middle of the base's footprint, in the machine's middle plane.** In Unreal: **ue_cm = (x, −y, z) × 100** (the project's FBX pair; the data is turned −90° about Z on export). | | | |---|---| | body | 115 cm long (foot plate to green box), 72 cm deep with the pistons (the frame 34 cm), 150 cm high (the head) | | canister | 40 cm across, 103.5 cm long with its cap, axis 47 degrees up; its top 148 cm over the ground | | scale | from the picture: about 1.5 mm per pixel at the machine's middle plane (the canister 268 px = 40 cm) | ## Parts and pivots | Mesh | Pivot | Motion | |---|---|---| | `SM_CanisterStation_Body` | origin | static: frame, head, panels, bolts, bracket, both pistons, cables, hubs, base, screen column, screen, handles, saddle, the column's cradle, the cup, the cradle rail and clamps | | `SM_CanisterStation_Canister` | on its axis at its bottom end | **slides 32 cm up its own axis**, out of the cup, along the rail; body, glow ring, cap, four latches, the radiation sign (a decal patch 0.6 mm off the surface) | The screen is the body's material slot `M_CS_Screen` (UV0 0..1 over the glass), so Unreal can swap it for a live screen. The glow ring's colour comes from `T_CS_GlowRing` along UV0 u. ## Rig (Blender) One slider: `CanisterStation_Root["eject"]` (0 seated as in the picture, 1 slid out), eased (`smoothstep`). Drivers are simple expressions. Timeline, 30 fps: seated at frame 1, out at 60, held to 120, seated at 180. The canister keeps `["closed_location"]` and `["open_location"]`. ## Checked `build/cs_check.py` runs the slider through 101 steps and tests the canister against the body (triangle overlap): **no clash anywhere in the slide; smallest clearance 3.1 mm** (the radiation sign passing under the upper clamp). The canister's foot stands 5 cm deep in the cup, 4.5 mm clear of its bore and 5 mm over its floor; the clamps and the column's cradle are 4 mm off it. Topology: body 6,472 quads, 420 triangles (flat caps of concave outlines, bolt and button tips), no n-gons, no non-manifold edges; the open edges are the flat bottoms of bolts, buttons and hubs against their faces. Canister 1,928 quads, no triangles; its open edges are the decal patch's border. The FBX files re-import at scale 1 on their pivots with both UV layers, their materials and the hulls; nothing under the ground. ## Surfaces Two UV layers on each mesh: `UVMap` (UV0, a unique unwrap into its own mask map; screen, decal and glow ring take their textures' 0..1) and `UV_Tile` (UV1, metres, box-projected, for the tiling sets). Tints sampled from the picture. Low wear (the ship is clean). | Material | What it is | Set | |---|---|---| | `M_CS_Green` | the dark teal-green paint of panels, canister, boxes | ScratchedMetal under the tint | | `M_CS_Black` | frame, cap, rims | ScratchedMetal | | `M_CS_Grey` | the tower's head | ScratchedMetal | | `M_CS_Cream` | trim, rail, clamps, latches, cup, handles | ScratchedMetal | | `M_CS_Steel` | foot plate, wedge, channel, hub disc | ScratchedMetal | | `M_CS_Chrome` | bolts, fittings, the button | BrushedMetal + scratch normal | | `M_CS_Rubber` | cables | — | | `M_CS_Gap` | slots, the cup's bore | — | | `M_CS_PanelDark` | the panel under the screen | ScratchedMetal | | `M_CS_Screen` | the screen (emissive UI) | `T_CS_Screen_UI` | | `M_CS_Glow` | the cap's ring (emissive) | `T_CS_GlowRing` | | `M_CS_Decal` | the radiation sign (alpha-masked) | `T_CS_Radiation` | Paints used on both meshes have a copy on the canister (`*_Can`) that reads the canister's mask map. ## Collision Body: nine `UCX_SM_CanisterStation_Body_NN` boxes (tower top, head, tower column, base left of the cup, base under it, the screen column's core, the green boxes and plates, the foot plate, the rail over the canister), all kept out of the canister's path. Canister: one 16-sided hull round it, from its foot to its latches. ## Triangles Body 13,364, canister 3,856: **17.2k**. ## Not done / open - Unreal: not imported. The layout JSON has what an import and an actor for the slide need. - The cap's end (its mechanism) and the cup's top are my design where the picture shows little or nothing. - The far side is a copy of the near side (see above); the user has not said what the machine's other side looks like. - No game role decided: the lore has the carrier's reactors, but the user has not said what this machine is for. ## Rebuild `sh build/run_all.sh` (Git Bash) runs the whole chain headless, one Blender at a time, all threads (the user allows full CPU since 2026-10-19); the GPU (HIP) does the bake and the renders. About 2 minutes. `cs_build.py` rewrites `CanisterStation.blend` from scratch, so run the rest of the chain after it.