# Tender docking carousel (three arms), game-ready A ceiling-hung turret with three booms 120° apart. Each boom carries a folding two-link hoist (shoulder, elbow, wrist, built like an industrial robot arm) and a clamp head with four claws that closes on the Tender's hatch collar. It is the modelled version of the carousel blockout in the Unreal port (`Vehicles/CarrierCarousel.cpp`, DESIGN_UE.md 3.5). **It is not in the Unreal project yet.** ## Files - `DockArm_Carousel.blend` (Blender 5.2): the assembly in the stowed pose. `DockArm_Parts` (the three shared meshes at their own origin) and `DockArm_Collision` (UCX hulls) are excluded from the view layer; `Studio` is camera and lights only. - `fbx/SM_DockArm_.fbx`: one file per unique mesh, at its own pivot, with its `UCX_` hulls. `fbx/DockArm_Carousel_Assembled.fbx`: the whole thing stowed, for a quick look. - `dockarm_layout.json`: pivots, parents and the hoist formula in Unreal units. `textures/T_DockArm_Decals_BaseColor.png`: decal atlas (arm numbers, hazard chevrons, generic labels; no brand names). `previews/`: renders. `build/`: the scripts. ## What comes from the Unreal blockout | Blockout | Model | |---|---| | hub at `ArmsRoot`, bay ceiling at z 1.20 | origin = hub axis at carrier z 0; the mount flange sits on z 1.20, nothing is higher | | three arms 120° apart, cradle radius 6.0 | three booms; tips at radius 6.0007, turned 0.86° so the head is centred on the hatch collar (9 cm ahead of the Tender origin) | | arm 1 over the pool at hub angle 0 (Unreal +Y) | `Arm1` points to Blender −Y | | Tender origin z −1.0 STOWED, −6.3 BOARD | links lie flat beside the boom at STOWED; `lower_m` 5.3 is BOARD | | clamp plate on the hatch collar | head with landing feet on the collar flange and four claws on the collar wall | | carriage moved in z, mast scaled | **changed:** a two-link knee hoist. The blockout leaves 9 cm between beam and clamp when stowed and 0.64 m under the ceiling, so a rigid mast cannot exist there | ## Scale, axes, pivots - 1 unit = 1 m, Z up. Unreal = (x, −y, z) × 100 cm. Span 13.4 m across the heads, 1.0 m tall stowed, reaches 5.3 m down. - Moving parts are separate objects with the origin on their axis, scale 1: | Mesh | Count | Pivot | Motion | |---|---|---|---| | `SM_DockArm_Mount` | 1 | hub axis | fixed to the carrier | | `SM_DockArm_Turret` (drum + three booms) | 1 | hub axis | yaw = carousel angle | | `SM_DockArm_UpperLink` (both side plates) | 3 | shoulder axis at the boom tip (6.0007, 0, 0.94 in the boom frame) | pitch | | `SM_DockArm_LowerLink` (both plates, elbow servos) | 3 | elbow axis, 3.0 m from the shoulder | pitch | | `SM_DockArm_Head` | 3 | wrist axis, 3.0 m from the elbow, 1.94 m above the Tender origin | pitch (stays level) | | `SM_DockArm_Claw` | 12 | its hinge under the head rim, at 45/135/225/315° | swings out 25° to open | - Hoist: `phi = asin((StowedZ − TenderOriginZ) / 6.0)`. In Blender: upper link Y rotation −phi, lower +2·phi, head −phi (Unreal pitch +phi, −2·phi, +phi). 0 at STOWED, 62.05° at BOARD. The wrist stays exactly under the shoulder. - In the .blend the empties `Arm1..3` have two custom properties that drive this: `lower_m` (0..5.3) and `claw_open` (0..1). ## Mesh notes - No booleans. Quads plus triangle fans on the ends of turned parts and a few bevel corners; no n-gons, no open edges, no zero-area faces, outward normals. 6 unique meshes, 19.6k triangles; 41.3k for the whole assembly (23 mesh objects). - UVs on every mesh (smart project per mesh; hand-set on the decal quads). 8 materials: flat PBR values plus the one decal atlas. **No baked texture sets.** - Collision: `UCX__NN` convex boxes, coarse (the blockout has no collision on the carousel at all). ## Checked - No two parts intersect in 12 poses (0, 0.25, 1.0, 2.5, 4.0, 5.3 m lowered × claws closed/open), all three arms present. - Against the real Kazah mesh (`models/Kazah-stern-cavity-fixedv4.blend`, linked only for the check and the renders): no crossing triangles; smallest gaps 17 mm (landing feet over the flange) and 20 mm (claw pads to the collar wall); links stay 0.24 m or more from the hull; the canopy opened 55° clears the arm at BOARD. - Every FBX re-imported and compared with the .blend (bounds, triangle counts, materials, hulls, placement): `build/verify_fbx.py`. ## Rebuild ``` python build\make_decals.py textures blender -b --python build\build_dockarm.py # model, .blend, layout json, fbx blender -b --python build\verify_fbx.py blender -b --python build\render_previews.py # fit check against the Kazah + previews ``` ## Open - Putting it into Unreal: `CarrierCarousel.cpp` drives one carriage z and a mast scale per arm; with this model it sets three pitches per arm instead (formula above). The clearance obstacle list there would also get the booms. - No LODs, no baked textures, emissive values are placeholders. Per-part FBX use the project's export pair (forward −Y, up Z, data turned −90° about Z; import with "convert scene" + "force front X axis", as `Tools/ue/assets_12_arm.py` does).