{
  "what": "Three-armed Tender docking carousel. Meshes are in each part's own frame; assemble them by this table.",
  "axes": "Blender metres here are (bx, by, bz); Unreal = (bx, -by, bz) * 100 cm. Root frame = ArmsRoot of UCarrierCarouselComponent (hub axis, carrier z 0).",
  "from_unreal_blockout": {
    "cradle_radius_m": 6.0,
    "stowed_z_m": -1.0,
    "board_z_m": -6.3,
    "ceiling_z_m": 1.2,
    "arm_yaw_deg_unreal": "90 + AngleDeg + 120 * Arm (ArmYawDeg)"
  },
  "boom_aim": {
    "note": "each boom is turned 0.8594 deg from its nominal yaw so its tip is over the hatch collar centre (Tender x +0.09), not the Tender origin",
    "unreal_yaw_deg": [
      89.1406,
      209.1406,
      329.1406
    ],
    "tip_radius_cm": 600.067
  },
  "parts": [
    {
      "mesh": "SM_DockArm_Mount",
      "parent": "carrier (does not turn)",
      "location_cm": [
        0,
        0,
        0
      ],
      "moves": "never"
    },
    {
      "mesh": "SM_DockArm_Turret",
      "parent": "ArmsRoot",
      "location_cm": [
        0,
        0,
        0
      ],
      "moves": "yaw = hub AngleDeg (the three booms are part of this mesh)"
    },
    {
      "mesh": "SM_DockArm_UpperLink",
      "count": 3,
      "parent": "Turret, in the boom frame (yaw from boom_aim)",
      "location_cm": [
        600.067,
        0,
        94.0
      ],
      "moves": "Unreal pitch = +phi"
    },
    {
      "mesh": "SM_DockArm_LowerLink",
      "count": 3,
      "parent": "UpperLink",
      "location_cm": [
        -300.0,
        0,
        0
      ],
      "moves": "Unreal pitch = -2 * phi"
    },
    {
      "mesh": "SM_DockArm_Head",
      "count": 3,
      "parent": "LowerLink",
      "location_cm": [
        300.0,
        0,
        0
      ],
      "moves": "Unreal pitch = +phi (stays level)"
    },
    {
      "mesh": "SM_DockArm_Claw",
      "count": 12,
      "parent": "Head",
      "moves": "Unreal pitch = +open * 25 deg",
      "instances": [
        {
          "location_cm": [
            46.315,
            -46.315,
            -43.0
          ],
          "unreal_yaw_deg": -45.0
        },
        {
          "location_cm": [
            -46.316,
            -46.315,
            -43.0
          ],
          "unreal_yaw_deg": -135.0
        },
        {
          "location_cm": [
            -46.316,
            46.315,
            -43.0
          ],
          "unreal_yaw_deg": -225.0
        },
        {
          "location_cm": [
            46.315,
            46.316,
            -43.0
          ],
          "unreal_yaw_deg": -315.0
        }
      ]
    }
  ],
  "hoist": {
    "phi": "asin((StowedZ - TenderOriginZ) / 6.0), radians; 0 at STOWED, 62.047 deg at BOARD",
    "link_length_cm": 300.0,
    "wrist_axis_above_tender_origin_cm": 194.0
  },
  "tender_origin_in_head_frame_cm": [
    -0.135,
    8.999,
    -194.0
  ],
  "tender_yaw_relative_to_head_deg_unreal": -89.1406,
  "ore_hose": {
    "what": "SM_DockArm_OreHose: a film duct of 11 cm radius per arm, built in the boom frame (rest = stowed), every ring skinned to ONE bone with weight 1",
    "route": "hub pod port (22 deg off the arm) -> beside the boom root -> top of the boom -> flat U-turn round the tip -> lane beside the arm -> over the shoulder -> down the upper link -> U-turn round the elbow -> down the lower link -> through the wrist -> coupling on the head",
    "lane": "the hose runs beside the arm at Unreal y = +86 cm of the boom frame (Blender y -0.86 m); the middle of the arm is taken by the boom when the arm is folded",
    "bones": {
      "Boom": "rigid with the turret, in the boom frame",
      "Upper / Lower / Head": "follow the arm's upper link, lower link and head (pivots in 'parts' above)",
      "S1..S8": "at the shoulder pivot: i/9 of the upper link's rotation",
      "E1..E9": "at the elbow pivot, carried by the upper link: plus i/10 of the lower link's rotation relative to it",
      "W1..W4": "at the wrist pivot, carried by the lower link: plus i/5 of the head's rotation relative to it"
    },
    "material": "M_DockArm_OreHose: clear ducting with a spiral rib (T_DockArm_Duct_BaseColor with the opacity in its alpha: film about 0.2 to 0.3, rib 1; T_DockArm_Duct_Roughness; T_DockArm_Duct_Normal is OpenGL, flip green for Unreal). Two-sided, translucent, reflections by Fresnel. One texture repeat = one circumference (0.69 m) of hose, 14 rib turns in it. Clamp bands are M_DockArm_HoseBand",
    "needs_headroom": "top of the hose is at z 1.37 m in the root frame when stowed: above the old blockout bay's ceiling (1.20), fine under the vessel interior's roof"
  },
  "surfaces": {
    "uv0": "UVMap: a unique unwrap in the shared 4096 px atlas (the two baked maps). Turret and mount unwrap one sector; their other sectors lie whole tiles further along U, so these samplers must wrap. Decal quads carry decal-sheet coordinates here",
    "uv1": "UV_Tile: metres. Tiling sets are sampled at uv1 / repeat_m",
    "masks": "T_DockArm_Masks (linear): R ambient occlusion, G edge (1 on a hard edge, 0 from 20 mm away), B crevice (1 open, lower in a gap)",
    "bevel_normal": "T_DockArm_BevelNormal: tangent space on UV0, OpenGL (flip green for Unreal); rounds every hard edge by 12 mm",
    "sets_from": "ModSci_Engineer/Textures (Modular SciFi Season 2, already in the Unreal project); smudge mask Base/Glass/T_Glass_DirtRough.png",
    "materials": [
      {
        "material": "M_DockArm_Paint",
        "diffuse": "Base/ScratchedMetal/T_ScratchedMetal_Diff.png",
        "roughness": "Base/ScratchedMetal/T_ScratchedMetal_Rough.png",
        "normal": "Base/ScratchedMetal/T_ScratchedMetal_Normal.png",
        "repeat_m": 0.9,
        "tint_linear": [
          0.64,
          0.65,
          0.65
        ],
        "metallic": 0.0,
        "shade_range": [
          0.88,
          1.05
        ],
        "roughness_range": [
          0.6,
          0.34
        ],
        "normal_strength": 0.35,
        "smudge_added_to_roughness": 0.05,
        "smudge_repeat_m": 2.6,
        "crevice_shade": 0.22,
        "edge_chips": 0.45
      },
      {
        "material": "M_DockArm_Graphite",
        "diffuse": "Base/StainedSteel/T_StainSteeled_Diff.png",
        "roughness": "Base/ScratchedMetal/T_ScratchedMetal_Rough.png",
        "normal": "Base/ScratchedMetal/T_ScratchedMetal_Normal.png",
        "repeat_m": 0.7,
        "tint_linear": [
          0.04,
          0.043,
          0.048
        ],
        "metallic": 0.0,
        "shade_range": [
          0.87,
          1.13
        ],
        "roughness_range": [
          0.66,
          0.42
        ],
        "normal_strength": 0.3,
        "smudge_added_to_roughness": 0.06,
        "smudge_repeat_m": 1.9,
        "crevice_shade": 0.15,
        "edge_chips": 0.5
      },
      {
        "material": "M_DockArm_Steel",
        "diffuse": "Base/StainedSteel/T_StainSteeled_Diff.png",
        "roughness": "Base/StainedSteel/T_StainSteeled_Rough.png",
        "normal": "Base/Glass/T_Scratch_Norm.png",
        "repeat_m": 0.5,
        "tint_linear": [
          0.6,
          0.61,
          0.63
        ],
        "metallic": 1.0,
        "shade_range": [
          0.8,
          1.15
        ],
        "roughness_range": [
          0.22,
          0.36
        ],
        "normal_strength": 0.5,
        "smudge_added_to_roughness": 0.05,
        "smudge_repeat_m": 0.9,
        "crevice_shade": 0.2,
        "edge_chips": 0.0
      },
      {
        "material": "M_DockArm_Rubber",
        "diffuse": null,
        "roughness": "Base/ScratchedMetal/T_ScratchedMetal_Rough.png",
        "normal": null,
        "repeat_m": 0.4,
        "tint_linear": [
          0.017,
          0.017,
          0.018
        ],
        "metallic": 0.0,
        "shade_range": [
          1.0,
          1.0
        ],
        "roughness_range": [
          0.86,
          0.62
        ],
        "normal_strength": 0.0,
        "smudge_added_to_roughness": 0.08,
        "smudge_repeat_m": 1.2,
        "crevice_shade": 0.1,
        "edge_chips": 0.0
      },
      {
        "material": "M_DockArm_SafetyOrange",
        "diffuse": "Base/ScratchedMetal/T_ScratchedMetal_Diff.png",
        "roughness": "Base/ScratchedMetal/T_ScratchedMetal_Rough.png",
        "normal": "Base/ScratchedMetal/T_ScratchedMetal_Normal.png",
        "repeat_m": 0.6,
        "tint_linear": [
          0.78,
          0.19,
          0.02
        ],
        "metallic": 0.0,
        "shade_range": [
          0.84,
          1.06
        ],
        "roughness_range": [
          0.62,
          0.36
        ],
        "normal_strength": 0.4,
        "smudge_added_to_roughness": 0.06,
        "smudge_repeat_m": 1.4,
        "crevice_shade": 0.25,
        "edge_chips": 0.7
      },
      {
        "material": "M_DockArm_HoseBand",
        "diffuse": "Base/StainedSteel/T_StainSteeled_Diff.png",
        "roughness": "Base/StainedSteel/T_StainSteeled_Rough.png",
        "normal": "Base/Glass/T_Scratch_Norm.png",
        "repeat_m": 0.35,
        "tint_linear": [
          0.6,
          0.61,
          0.63
        ],
        "metallic": 1.0,
        "shade_range": [
          0.8,
          1.15
        ],
        "roughness_range": [
          0.22,
          0.36
        ],
        "normal_strength": 0.5,
        "smudge_added_to_roughness": 0.05,
        "smudge_repeat_m": 0.6,
        "crevice_shade": 0.0,
        "edge_chips": 0.0
      }
    ],
    "glow": {
      "M_DockArm_GlowCyan": {
        "color": [
          0.1,
          0.85,
          1.0
        ],
        "strength": 1.2
      },
      "M_DockArm_GlowAmber": {
        "color": [
          1.0,
          0.55,
          0.08
        ],
        "strength": 1.2
      }
    },
    "lens": "M_DockArm_LensGlass: near-black smoked glass, roughness 0.16 to 0.24 by the smudge mask",
    "value_range_of_each_map": {
      "T_StainSteeled_Diff.png": [
        0.1735,
        0.2741
      ],
      "T_StainSteeled_Rough.png": [
        0.3608,
        0.8784
      ],
      "T_ScratchedMetal_Diff.png": [
        0.6172,
        0.6724
      ],
      "T_ScratchedMetal_Rough.png": [
        0.6314,
        0.8196
      ]
    },
    "recipe": "base colour = tint * lerp(shade_range, luminance of the diffuse map over its value range); roughness = lerp(roughness_range, roughness map over its value range) + smudge * amount; crevice shade = (1 - B)^1.4 * amount toward near-black, + 0.35 of it on the roughness; edge chips = smoothstep(0.38, 0.72, G * lerp(1.25, 0.55, roughness map) * smoothstep(0.72, 0.93, R) * amount) toward the bare-metal colour with metallic 1"
  }
}