# Nutrition vat, game-ready A standing pod after the user's picture (2026-10-21, `reference/ref_user.jpg`; the user: *"Create 3d model for nutrition vat in blender. build exactly as the image"*). The picture shows one pod from three sides (front three-quarter, right side with hoses, an elevated right side). The model: a pale sage shell; a two-chamber glass tank of dark teal liquid with bright bubbles at the front, a glowing disc under its lid, a mid band and a bottom bezel with cyan light rings; a C-frame round the tank whose lower part steps forward; a raised middle panel, a rear column with two pills, a vertical rod in the C-groove; hex knobs in round bezels, a grille, a slot, a keypad; six ribbed hose ports on the head; a U handle at the head's front left corner and a rail round the lower housing's front left corner; a cyan strip along the lower housing's front; a C-shaped arm with five windows behind the pod that sweeps down into the plinth; a cartridge at each rear corner in two clamp rings; and (optional) the middle view's bundle of 18 hoses falling behind the pod. Built **headless** by script (`build/`), nothing in anyone's open Blender. Nothing is a boolean. ## Files - `NutritionVat.blend` (Blender 5.2): collections `NutritionVat` → `NV | static` (body), `NV | movable` (liquid, the two cartridges), `NV | optional` (hoses), `NV | collision` (UCX hulls, excluded from the view layer); `Studio` (floor, lights, camera; not exported). All parented to the empty `NutritionVat_Root`. - `fbx/SM_NutritionVat_.fbx`: one file per mesh at its own pivot, with its `UCX_` hulls (body 17, cartridge 1). `fbx/NutritionVat_Assembled.fbx`: everything. `fbx/verify_report.json`: the re-import check. - `NutritionVat_layout.json`: pivots, the cartridges' two placements, materials, the liquid's fill heights, in Unreal units. - `textures/`: `T_NV_Masks.png` (4096, baked: R occlusion, G edges, B crevices), `T_NV_Decals.png` (side label, warning sticker, keypad digits), `T_NV_CanLabel.png` (the cartridge's wrap), `T_NV_Bubbles.png` (the liquid), `T_NV_Perforation.png` (the grille); drawn by `build/nv_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 `NutritionVat_v01_*` (hero = front right, front_left, side_hoses, rear, tank, top) and `wire_*` (topology). `previews/compare/v01.png`: for each of the picture's three views, the picture left and the model right, rendered from a camera fitted to that view (`_overlay` adds the model's outline over the picture); `previews/cycles/` holds those renders. - `reference/`: the picture and its ruler crops `z_*.png` (`build/zoom.py`). - `build/`: `nv_lib.py` (geometry: rounded polygons with offset rings, slabs, Coons caps relaxed into a Tutte grid, lathes, tubes, cell solids, decals), `nv_build.py` (the parts; measured numbers in its docstring), `nv_textures.py`, `nv_surfaces.py`, `nv_check.py`, `nv_export.py`, `nv_verify_fbx.py`, `nv_render.py`, `nv_wire.py`, `nv_compare.py`; `nv_fit.py` fits a camera to each of the picture's views from landmarks (`cams.json`), `nv_preview.py` makes quick Workbench looks from those cameras. `run_all.sh` runs the chain in order (one Blender at a time). ## Scale, axes, size Measured in pixels of the picture's middle (side) view; **1 px = 4.62 mm**, chosen so the head's top stands **2.00 m** over the floor (the picture has no person; the knobs, keypad, handles and ports all read right at that size). The width (110 px, 50.8 cm) is from the front three-quarter view. 1 unit = 1 m, Z up, the tank faces −Y, the picture's visible side (label, knobs, grille) is +X. **The origin is on the floor under the body's middle.** In Unreal: **ue_cm = (x, −y, z) × 100** (the project's FBX pair; the data is turned −90° about Z on export). | | | |---|---| | height | 200 cm to the head's top, 214 cm with the ports | | width | 50.8 cm body, 66.4 cm at the plinth and handles | | depth | 118.7 cm from the front rail to the plinth's back; the optional hoses lie up to 65 cm further back on the floor | | tank | glass r 20.3 cm, two chambers 33 and 68 cm tall, liquid from 58 to 163 cm above the floor | ## Parts and pivots | Mesh | Pivot | Note | |---|---|---| | `SM_NutritionVat_Body` | origin | everything static, glass and decals included (glass and decals are their own material slots) | | `SM_NutritionVat_Fluid` | the bottom of the liquid on the tank's axis | static; for the fill level cut it in the material by world height (58.0 cm empty, 162.9 cm full above the origin). Scaling it would push its rounded bottom through the glass | | `SM_NutritionVat_Canister` | its foot on its axis | one mesh, placed twice: right corner as built, left corner turned 180° (`NutritionVat_Canister_L`), label out on both | | `SM_NutritionVat_Hoses` | origin | optional dressing (the picture's middle view only), no collision | No rig: nothing in the picture moves. ## Checked `build/nv_check.py` tests every pair of separate meshes for triangle overlap, and the hoses tube against tube: **no clash**. Smallest gaps: liquid to glass 2.1 mm, cartridges to the body (their clamp rings) 4.6 mm, hoses to anything 9.7 mm. The hoses were relaxed apart from each other, the body and the cartridges (`relax_hoses` in `nv_build.py`). The C-frame's lower part wraps the glass (its inner side follows the tank's cylinder 2.8 mm off it) instead of cutting into it. Topology: body 18,997 quads and **4 triangles** (two corners where a bevelled edge meets an unbevelled one), no n-gons, no non-manifold edges, no zero-area faces; liquid, cartridges and hoses all quads. Open edges are where parts sit on each other (their contact faces are left out). The FBX files re-import at scale 1 on their pivots with both UV layers, their materials and hulls (`fbx/verify_report.json`). Wireframes: `previews/wire_*`. ## Surfaces Two UV layers on every mesh: `UVMap` (UV0: a unique unwrap into the mask atlas; decals take their atlas, the cartridge's glass its wrap, the liquid a cylinder) and `UV_Tile` (UV1, metres, box-projected, for the tiling sets). Clean, low wear. | Material | What it is | Set | |---|---|---| | `M_NV_Shell` | the pale sage paint (body, arm, plinth) | ScratchedMetal under the tint, faint | | `M_NV_ShellDark` | the plinth's toe | ScratchedMetal | | `M_NV_Gap` | port bores, the lid's dark ring | — | | `M_NV_Glass` | the tank's two chambers: clear, thin walls | Glass_DirtRough as smudges | | `M_NV_Fluid` | dark teal liquid, bubbles emissive | `T_NV_Bubbles` | | `M_NV_Glow` | the lid's disc, the light rings, the front strip (emissive cyan) | — | | `M_NV_Rubber`, `M_NV_Hose` | ports, cartridge caps; the hoses (black, glossy) | ScratchedMetal | | `M_NV_Chrome`, `M_NV_Brass` | handles, rod, clamp rings; the valve lever | BrushedMetal + scratch normal | | `M_NV_Keypad`, `M_NV_Grille` | the keypad's panel; the grille (holes every 4 mm) | `T_NV_Perforation` | | `M_NV_Decal` | label, warning sticker, keypad digits (alpha), 0.25 mm off the surface | `T_NV_Decals` | | `M_NV_CanGlass` | the cartridge's glass with its label | `T_NV_CanLabel` | ## Collision Body: 17 `UCX_SM_NutritionVat_Body_NN` hulls (head, lip, tank, body, lower housing, plinth, rear block, the ports' crown, the arm in seven pieces, the two handles). Cartridge: one 12-sided prism. Liquid and hoses: none. ## Triangles Body 38.0k, liquid 3.7k, cartridge 1.6k (×2): **45k** without the hoses; the hoses add 26.4k. ## Against the picture - The three views are not one pod in every detail: the front three-quarter view has no arm, no hoses, no second cartridge and a shorter base. The model follows the side and elevated views there (where views disagree the side view rules). - The second cartridge (left rear corner) is placed from the elevated view, where only its cap shows above the arm. - The picture's lettering "medpod", the "gen:LOCK" logo and the artist's watermark are not on the model (no names in textures); the side label reads **"nutrivat"** (my word, in `nv_textures.py`, `LABEL_WORD`). The warning sticker and the cartridge label are generic. - The picture is concept art for the series gen:LOCK (its watermarks name the artist, Ian Llanas). The model follows its design closely; whether a game that ships may use it that way is the user's call. - The left side (−X) is not in the picture: its plates mirror the right side; knobs, grille, label and slot are on +X only. ## Not done / open - Unreal: not imported. `NutritionVat_layout.json` has what the import and a vat actor need. - The liquid's level and the bubbles' rise are material work in Unreal (a height cut and a panning UV); the textures are here. - Hoses: one fixed arrangement (seeded); they end lying on the floor behind the pod. ## 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 two minutes. `nv_build.py` rewrites `NutritionVat.blend` from scratch, so run the rest of the chain after it. `nv_fit.py` (the cameras for the comparison) is not in the chain: re-run it only if the landmarks in it change.