# Nutrition feeding device, game-ready A wall unit after the user's picture (2026-10-21, `reference/ref_user.png`; the user: *"Create me 3d model for nutrition feeding device in the game descent exactly as the image"*): a light grey panel with a rolled aluminium rim; a status screen ("NUTRIENT STATUS", four bars, "INFUSION READY") in a dark bezel; below it on the right a raised, mid-grey cavity frame round a recess whose back opens into a tunnel for the hand; a rounded lip at the tunnel's mouth with a blue light bar on each side and a cradle under it for the wrist; an injector over the mouth (light shoulders, a dark sleeve, a chrome cylinder with a blue ring, a dark collar) whose nozzle and needle come down to the palm. Not in the model: the hand and arm of the picture (no scale figures in the assets). Not in Unreal yet. Built **headless** by script (`build/`), nothing in anyone's open Blender. Nothing is a boolean; every surface is quads except the needle's tip (a 12-triangle cone point). ## Files - `NutritionFeeder.blend` (Blender 5.2): collections `NutritionFeeder` → `NF | static`, `NF | moving`, `NF | collision` (UCX hulls, excluded from the view layer); `Studio` (wall, lights, camera; not exported). - `fbx/SM_NutritionFeeder_.fbx`: one file per mesh at its own pivot, the body with its `UCX_` hulls. `fbx/NutritionFeeder_Assembled.fbx`: everything, needle away. `fbx/verify_report.json`: the re-import check. - `NutritionFeeder_layout.json`: pivots, motion, timing, materials, mounting, in Unreal units. - `textures/T_NF_Masks.png` (4096, baked: R occlusion, G edges, B crevices), `textures/T_NF_Screen_UI.png` (2048 x 1024, the screen, drawn after the picture by `build/nf_screen_ui.py`, font Bahnschrift). 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 `NutritionFeeder_v01_*` (front at the picture's framing, two three-quarter views, the cavity, the injector out and away, the edge), `wire_*` (topology), `wb_*` (quick Workbench looks). `previews/compare/lookalike_v01.png`: the picture left, the model right, same framing; `_bloom` adds a bloom pass on the blue lights like the picture's (and Unreal's) glow; `cavity_v01*.png` the same, close on the cavity. - `reference/`: the picture, ruler crops `z_*.png` (from `build/zoom.py`), `check_screen_ui.png`. - `build/`: `nf_lib.py` (geometry helpers), `nf_build.py` (the parts, measured numbers in its docstring), `nf_rig.py`, `nf_surfaces.py`, `nf_check.py`, `nf_export.py`, `nf_verify_fbx.py`, `nf_render.py`, `nf_preview.py`, `nf_compare.py`, `nf_screen_ui.py`; `run_all.sh` runs everything in order (one Blender at a time). ## Scale, axes, size Scale from the hand in the picture: **1 picture pixel = 0.5 mm**. 1 unit = 1 m, Z up, the front faces −Y. **The origin is the panel's bottom edge, centred, on the wall's face.** In Unreal: **ue_cm = (x, −y, z) × 100** (the project's FBX pair; the data is turned −90° about Z on export). | | | |---|---| | panel | 46.7 × 62.3 cm; its face 5.5 cm off the wall, the rolled rim 5.2 cm | | cavity frame | 26.3 × 30.3 cm outside, 7.1 cm off the wall | | tunnel | about 21 cm wide (a squircle, exponent 2.5, fitted to the mouth's edges in the picture), narrowing inward | | into the wall | the recess's back is the wall's face; the tunnel goes **12.3 cm into the wall**: set the unit into a wall at least that thick or behind a lining | | mounting | not given; for a standing person put the origin about 85 cm above the floor (cavity centre at about 1.03 m) | Depths are not in the picture (it is a front view); they were chosen and checked by rendering at the picture's framing. ## Parts and pivots | Mesh | Pivot | Motion | |---|---|---| | `SM_NutritionFeeder_Body` | origin | static: panel, screen with glass, cavity frame, recess, tunnel and its lip, light bars, cradle, injector mount, chrome cylinder and collar | | `SM_NutritionFeeder_Nozzle` | its top, on the injector axis | **slides 4.7 cm straight down** out of the collar | | `SM_NutritionFeeder_Needle` | its top; child of the nozzle | **slides 3.6 cm straight down** out of the nozzle | The screen is the body's material slot `M_NF_Screen`; its glass takes the whole UI texture in UV0, so a live screen in Unreal only swaps that slot's material. ## Rig (Blender) One slider: `NutritionFeeder_Root["inject"]` (0 needle away, 1 as in the picture). Nozzle 0–0.55, needle 0.55–1, each eased (`smoothstep`). Drivers are simple expressions (they run with Python auto-run off). Timeline, 30 fps: away at frame 1, out at 60, held to 120, away at 180. Each moving part keeps `["closed_location"]` and `["open_location"]`. ## Checked `build/nf_check.py` runs the slider through 101 steps and tests the nozzle and the needle against the body and each other (triangle overlap in world space): **no clash anywhere in the travel.** Smallest gaps: nozzle 0.75 mm in the collar's bore, needle 8.5 mm from the body. Topology (body): 11,617 quads, no triangles, no n-gons, no non-manifold edges; the open edges are the panel's back edge on the wall and the mount's back on the recess. The FBX files re-import at scale 1 on their pivots with both UV layers, their materials and the hulls (`fbx/verify_report.json`). ## Surfaces Two UV layers on every mesh: `UVMap` (UV0, a unique unwrap into the shared mask atlas; the glass takes the UI) and `UV_Tile` (UV1, metres, box-projected, for the tiling sets). Clean, low wear (the ship is clean). | Material | What it is | Set | |---|---|---| | `M_NF_Shell` | the panel's light grey satin paint | ScratchedMetal under the tint, faint | | `M_NF_Trim` | the rolled rim, the frame's inner edge: satin aluminium | BrushedMetal | | `M_NF_Frame` | the cavity frame: darker anodised metal | BrushedMetal | | `M_NF_Bezel` | screen bezel, injector sleeve and cheeks: matte near-black | ScratchedMetal | | `M_NF_Screen` | the glass: UI as emission, matte anti-glare | `T_NF_Screen_UI` | | `M_NF_Cavity` | recess walls and back: dark grey paint | ScratchedMetal | | `M_NF_Tunnel` | the tunnel: matte blue-black | ScratchedMetal | | `M_NF_Rim` | the tunnel's lip, the cradle, the injector's shoulders: mid grey satin | BrushedMetal | | `M_NF_Steel`, `M_NF_SteelDark` | the chrome cylinder, nozzle, needle; the darker collar | BrushedMetal + scratch normal | | `M_NF_Gap` | grooves, bores | — | | `M_NF_Glow` | light bars, ledges under the shoulders, injector rings, needle tip (emissive cyan) | — | ## Collision Nine `UCX_SM_NutritionFeeder_Body_NN` boxes (exported inside the body's FBX): the panel above, left, right and under the cavity, the cavity frame's four bars, and the injector. The cavity and the tunnel are left open (the hand goes in). The nozzle and needle have none. ## Triangles Body 23,234, nozzle 960, needle 150: **24.3k** in all. ## Used by - **Anchorage** (2026-10-21, the user: *"add and place nutrition feeder to the facility walls to the meaningfully"*): six feeders on the station's walls (`models/anchorage/build/furnish.py`). It uses a copy made then, `models/anchorage/source_fab/nutrition_feeder/nutrition_feeder.blend` (`props_prepare.py -- nutrition_feeder`: no collision hulls, no studio, inject 0). It relies on the origin on the wall's face at the panel's bottom edge, the front to -Y, the 12.3 cm tunnel behind the face and the 85 cm mounting height. After a change to those, re-run that command and `furnish.apply()` in the station. ## Not done / open - Unreal: not imported. `NutritionFeeder_layout.json` has what the import and a feeder actor need. - The picture's thin light from the needle's tip to the palm is an effect, not geometry. - The screen shows the picture's text and numbers as they are, including its date "2026-05-16". - Lore note, not acted on: `GameLore.txt` puts the feeding port in the convict's side and gives him metal arms; the picture's needle goes into a human palm. Built as the picture shows, as asked. ## 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. `nf_build.py` rewrites `NutritionFeeder.blend` from scratch, so run the rest of the chain after it.