Skip to content

feat(twin): Ride mode, mode hints, real navigation, multi-fragment captures#254

Merged
TortoiseWolfe merged 1 commit into
mainfrom
feat/twin-modes-nav
Jul 9, 2026
Merged

feat(twin): Ride mode, mode hints, real navigation, multi-fragment captures#254
TortoiseWolfe merged 1 commit into
mainfrom
feat/twin-modes-nav

Conversation

@TortoiseWolfe

Copy link
Copy Markdown
Owner

Every mode does something, and the twin is findable

Follows user feedback: "some of the modes seem redundant? and others don't seem to change anything at all? I don't have a direct path to chatt or the lidar house."

Modes

  • Follow → Ride: the Rig's dormant board() capability is finally wired — the trolley reports position/heading via its previously-unused onTick, and Ride mode chase-cams the vehicle around the loop. The button only appears on sites with a trolley: an unboarded follow mode just chased an invisible math-point avatar (the "does nothing" mode the dock used to ship). Verified live: trolley crossing the river with the camera trailing at 28 m (44 m put the collision-less chase cam inside downtown buildings — noted as a future item).
  • Trolley rides ON the terrain: TwinWorld hands the composition root its terrain sampler (onGroundReady, same pattern as onHouseGround); the trolley — and therefore the Ride camera — follows ground height instead of running at sea level (the camera used to go underground wherever terrain rose).
  • Walk/Ride hints: one-line HUD control cards (pointer-lock Walk read as broken without "click to look"). modesForSite() extracted pure + unit-tested per site shape.

Navigation

  • "Digital Twin" homepage demo card + "Twin" GlobalNav item → /chatt (the twin was URL-only — no card, no nav entry).
  • E2E: homepage card → twin wordmark visible.

Multi-fragment as-built captures (#234)

  • convert-scan.mjs accepts repeated --dae flags and merges a Polycam PROJECT into one GLB with named per-fragment groups (fixed a per-fragment texture-barrier race — the LoadingManager batches, so each fragment arms its own onLoad barrier).
  • house.json gains optional validated parts (pivot/yawDeg/position per GLB group); HouseModel applies them BEFORE grounding so a registered fragment can't drag the bbox and float the model. Transforms come from a voxel-overlap registration search against the primary fragment (client capture itself stays local-only as always).

Verification

3811 unit tests pass (+12 new: modes dock per site shape, Rig chase-a-moving-boarded-object, house parts validation), type-check + lint clean, CI-sim build green, live captures of Ride mode + the two-fragment house view.

🤖 Generated with Claude Code

…ptures

Every dock mode now DOES something, and the twin is findable:

- Follow → Ride: the Rig's dormant board()/unboard() capability is finally
  wired — the trolley reports position/heading via its (previously unused)
  onTick, entering Ride boards it, and the chase camera trails the vehicle.
  The button only appears on sites WITH a trolley (an unboarded follow mode
  just chased an invisible math-point avatar — the "does nothing" mode).
  Trail distance tuned live: 28 m clears the roofline without putting the
  no-collision chase cam inside downtown buildings.
- Trolley rides ON the terrain: TwinWorld hands the composition root its
  terrain sampler (onGroundReady, same pattern as onHouseGround) and the
  trolley — and therefore the Ride camera — follows ground height instead
  of running at sea level (the camera used to go underground wherever the
  terrain rose).
- Walk/Ride HUD hints: one-line control cards (pointer-lock Walk reads as
  broken without "click to look"); modesForSite() extracted pure + tested.
- Navigation: "Digital Twin" homepage demo card + "Twin" GlobalNav item →
  /chatt (the twin was URL-only). E2E covers homepage → twin.
- Multi-fragment as-built captures (#234): convert-scan.mjs accepts
  repeated --dae flags and merges a Polycam PROJECT into one GLB with named
  per-fragment groups (per-fragment texture barrier fixed — the manager
  batches, so each fragment arms its own onLoad barrier). house.json gains
  optional `parts` (pivot/yawDeg/position per group, validated) which
  HouseModel applies BEFORE grounding, so a registered fragment can't drag
  the bbox and float the model. Placement transforms come from a
  voxel-overlap registration search against the primary fragment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@TortoiseWolfe TortoiseWolfe merged commit 37b26e3 into main Jul 9, 2026
19 checks passed
@TortoiseWolfe TortoiseWolfe deleted the feat/twin-modes-nav branch July 9, 2026 23:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants