ADR-049 — Tiangong module pickability and scene graph
Status · Accepted Date · 2026-05-07 Closes · RFC-014 (with ADR-048, ADR-050) TA anchor · §components Related · ADR-048, ADR-041 (the ISS analogue), PRD-011
Context
RFC-014 OQ-2 + OQ-5 asked how to balance pick granularity vs draw calls for Tiangong. PRD-011 / GH-50 require 6 pick targets: 3 pressurised modules (Tianhe / Wentian / Mengtian) + Chinarm + 2 visiting vehicles (Shenzhou / Tianzhou). Solar arrays are scenery in V1. The small experimental arm (RFC OQ-5 option B) is deferred.
Decision
Hybrid mesh split (RFC OQ-2 Option C)
- Pickable: one
THREE.Mesh(or group leaf) per canonicalidintiangong-modules.jsonandtiangong-visitors.json, withuserData.moduleId === idanduserData.stationPickable === true. - Non-pickable: structural geometry (truss spurs, solar wings, MLI wraps) carries
userData.stationPickable === falseso the raycaster walk-up filters them out.
stationPickable rename
ISS V1 used userData.issPickable. Since /tiangong reuses the same raycaster + walk-up pattern, the convention is generalised to userData.stationPickable and the same key is renamed in iss-proxy-model.ts + src/routes/iss/+page.svelte. The picking convention is now station-agnostic so a third station (e.g. a future Mir route) drops in with no protocol churn.
Highlight
OutlinePass on hover (matches /iss post-V1 — ADR-041's emissive-only V1 was upgraded). Emissive scale-pulse (1 + sin(t · 2.6) · 0.04) on the selected module when its panel is open. Unselected modules render at base scale.
Draw calls
Expect ~7 pickable meshes (3 modules + Chinarm + 2 visitors + 1 merged truss-and-radiator group) — comfortably under any mobile budget.
Consequences
Positive: Identical raycaster + selection logic across /iss and /tiangong; trivial per-mesh userData.moduleId wiring from raycast → panel.
Negative: A future CMSA / Sketchfab GLB import must preserve the four module ids (tianhe, wentian, mengtian, chinarm) and two visitor ids (shenzhou, tianzhou) on its mesh names, or carry an alias table in code.
Implementation notes
Scene traversal after buildTiangongProxyStation(): register pickables in a Map keyed by userData.moduleId for raycaster + INDEX drawer + deep-link sync. Same pattern as iss-proxy-model.ts post-rename.