Skip to content

editor: unify walkthrough + viewer UI, crouch, screenshot pause#529

Merged
wass08 merged 8 commits into
mainfrom
fix/viewer-builder-pass
Jul 21, 2026
Merged

editor: unify walkthrough + viewer UI, crouch, screenshot pause#529
wass08 merged 8 commits into
mainfrom
fix/viewer-builder-pass

Conversation

@wass08

@wass08 wass08 commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Unifies the three divergent walkthrough/viewer UIs onto the baked-GLB design and upgrades the walkthrough controls:

  • Shared WalkthroughHud (packages/editor): the GLB-style HUD — dot/ring reticle, floor + room labels, interact prompt, bottom pills — now backs the builder first-person overlay, the baked-GLB viewer, and the parametric viewer. The old "Street View" overlay (cross-hair, exit button, hints card) is gone. FirstPersonControls feeds it via a small useFirstPersonHud store (per-frame interact target; floor/zone labels sampled from the camera against level elevations and slab/zone polygons) and gains the GLB controller's FOV-widen + perspective-forcing for parity.
  • Shared ViewerControlsBar + ViewerSceneHeader (packages/editor): the community viewer's bottom bar and header/levels cards extracted as prop-driven components; preview mode's ViewerOverlay is now a thin composition of them. The display menu gains an Edges submenu; the vestigial translucent wall mode is dropped (stale values render as cutaway).
  • Crouch: hold Ctrl — swaps to a short capsule that shrinks around its centre (works mid-air, so you can thread window openings) and lowers the float gap, for an effective 0.25–0.95 m profile that fits ~1 m openings; standing back up is gated on headroom. Frozen while the cursor pause is active (⌃⇧⌘4 must not crouch you mid-screenshot).
  • Screenshot pause: P toggles pointer-lock release without exiting the walkthrough (macOS region screenshots need a movable cursor), advertised in the HUD ("P free cursor"); while paused the pill flips to a click-through "Click or P to resume". Tracked as walkthroughSuspended on the viewer store.
  • HelperManager renders nothing in first-person mode (the Ctrl multi-select hint was popping over the walkthrough — Ctrl is crouch there).
  • WalkthroughControls (the collision-less WASD glide) is removed from packages/viewer; WALKTHROUGH_FOV and the crouch tuning constants live in the GLB controller module.

How to test

  1. bun dev, open a project, press Preview — the viewer bar should be the community design (visibility, level/wall modes, display menu incl. Edges, walkthrough, orbit/top view).
  2. Enter walkthrough from the preview bar: GLB-style HUD (reticle, floor/room labels, "P free cursor" + "Esc to exit" pills). Aim at a door → ring reticle + "E or click to open …" prompt.
  3. Hold Ctrl to crouch (eye lowers, slower walk) and walk through a ~1 m opening; release under a low ceiling — you stand up only once clear. Jump + Ctrl through a window opening.
  4. Press P — cursor frees, pill reads "Click or P to resume · Esc to exit"; take an OS screenshot (⇧⌘4 / ⌃⇧⌘4 — Ctrl must not crouch you); click or press P to resume; Esc exits.
  5. In first-person, press Ctrl — no editor "select more" hint should appear.

Screenshots / screen recording

HUD + pills (parametric viewer):

  • Walkthrough HUD with reticle and bottom pills verified via headless run; will attach a short recording on the private-editor PR where the community viewer exercises the same components.

Checklist

  • I've tested this locally with bun dev
  • My code follows the existing code style (run bun check to verify)
  • I've updated relevant documentation (if applicable)
  • This PR targets the main branch

🤖 Generated with Claude Code


Note

Medium Risk
Large UI/control refactor touching pointer lock, camera mode, and physics capsule parameters across editor and GLB walkthrough; behavior regressions in walkthrough exit, crouch, or viewer display toggles are the main concern, not security or data.

Overview
Unifies walkthrough and community-viewer UI and upgrades first-person controls across the editor and GLB viewer.

Walkthrough experience: Replaces the old Street View overlay with shared WalkthroughHud (reticle, floor/zone labels, interact prompt, bottom pills). Editor FirstPersonControls drives it via useFirstPersonHud, sampling floor/zone from camera position against level elevations and slab/zone polygons. Adds Ctrl crouch (short capsule, slower movement, headroom check to stand), P to release pointer lock for screenshots without exiting (walkthroughSuspended on the viewer store), walkthrough FOV, and forcing perspective while walking. HelperManager hides editor shortcut hints in first-person so Ctrl isn’t advertised as multi-select.

Viewer chrome: ViewerOverlay shrinks to ViewerSceneHeader + ViewerControlsBar (extracted, exported). The bar consolidates scans/guides into a visibility menu, display settings (shadows, camera, colors, render/theme/edges submenus), drops translucent wall mode (stale values treated as cutaway), and supports GLB-specific props.

Viewer package: Removes collision-less WalkthroughControls; GlbWalkthroughController gains the same crouch, P-pause, and shared tuning constants exported from @pascal-app/viewer.

Reviewed by Cursor Bugbot for commit cdbb5b1. Bugbot is set up for automated code reviews on this repo. Configure here.

wass08 and others added 7 commits July 21, 2026 15:31
… shared HUD

The builder first-person overlay (crosshair, Exit Street View button, hints
card) and the baked-GLB walkthrough HUD were two divergent UIs. Extract the
GLB-style HUD (reticle, floor/room labels, Esc pill, interact prompt) into a
shared WalkthroughHud in packages/editor, feed it from FirstPersonControls via
a small useFirstPersonHud store (interact target each frame, floor/zone labels
sampled from the camera), and align FOV/projection handling with the baked
controller. The now-unused WalkthroughControls glide controller is removed
from packages/viewer (WALKTHROUGH_FOV moves to the GLB controller module).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…view and embedders

Preview mode's ViewerOverlay was an older copy of the community viewer UI
(separate scan/guide/camera buttons, own render/theme/edges menus, 4-state
wall mode). Extract the community design into shared prop-driven components:
ViewerControlsBar (visibility, level/wall modes, display menu, walkthrough,
orbit/top view) and ViewerSceneHeader (back, project info, optional stats
slot, breadcrumb, levels card). ViewerOverlay is now a thin composition of
them. The display menu gains the edges submenu everywhere; the vestigial
translucent wall mode is dropped (a stale value renders as cutaway).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rollers

Crouch swaps the capsule for a short one (shrinks around the centre, so a
mid-jump crouch lowers the head and raises the feet — enough to thread window
openings), lowers the eye with a short lerp, and slows movement; standing back
up is gated on headroom via an upward raycast against the collider world.
Tuning constants live in the GLB controller module and are shared with the
editor first-person controller.

P releases the pointer lock without leaving the walkthrough so the cursor is
free for an OS screenshot (macOS region capture needs a movable pointer);
clicking the canvas re-locks and resumes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The float gap counts toward the effective obstacle height — the capsule rides
floatHeight (0.5 m) above the ground, so the old crouch spanned 0.5–1.3 m and
a 1.14 m opening still blocked it. Crouching now also lowers the float gap
(0.25 m) and uses a shorter capsule (0.7 m), for an effective 0.25–0.95 m
span; the stand-up headroom check grows to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ock on ⌘

Replace the P shortcut: macOS swallows the full ⇧⌘4 but the ⌘-down keystroke
still reaches the page, so the moment ⌘ (or PrintScreen) goes down while
locked the cursor is released without leaving the walkthrough — the native
screenshot flow just works, no user education. The HUD pill flips to "Click
to resume" (click-through, so the resuming click lands on the canvas) via a
new walkthroughSuspended flag on the viewer store, reset on lock/exit/unmount.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The ⌘ auto-release fired on every command combo and felt broken. Back to an
explicit P toggle, now discoverable: the HUD bottom shows a "P free cursor"
pill next to "Esc to exit", and while paused it flips to "Click or P to
resume · Esc to exit" (click-through so the resuming click lands on the
canvas). P re-locks as well as releasing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…in first person

While the P pause is active, Ctrl no longer toggles crouch — ⌃⇧⌘4 (clipboard
screenshot) was crouching the player mid-capture; the held state stays frozen
until resume. HelperManager now renders nothing in first-person mode, so the
Ctrl multi-select hint no longer pops over the walkthrough HUD (Ctrl is
crouch there).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

// E or click activates the openable in view. The click also re-locks the
// pointer via WalkthroughControls — harmless overlap; no selection happens.
// pointer through the walkthrough controller; no selection happens.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resume click toggles GLB door

Medium Severity

After pressing P to free the cursor, a canvas click re-locks via GlbWalkthroughController and also runs activateWalkDoor on every walkthrough click. Resuming from screenshot pause can open or close the door in view instead of only restoring pointer lock.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6996256. Configure here.

const modes: ('cutaway' | 'up' | 'down')[] = ['cutaway', 'up', 'down']
const nextIndex = (modes.indexOf(safeWallMode) + 1) % modes.length
useViewer.getState().setWallMode(modes[nextIndex] ?? 'cutaway')
}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Translucent walls UI only

Medium Severity

Persisted wallMode translucent is mapped to cutaway only in the controls bar (safeWallMode), while the viewer still renders translucent walls via wall-cutout.tsx. The bar label, icon, and cycle skip the real mode until the user clicks walls.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6996256. Configure here.

!suspendRef.current
) {
crouchKeyRef.current = false
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ctrl state stuck after pause

Low Severity

While walkthroughSuspended is active, Control keyup is ignored so crouch is not toggled by screenshot shortcuts. If the user releases Ctrl during pause, crouchKeyRef can stay true after resume, keeping crouch until Ctrl is pressed and released again.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6996256. Configure here.

flushSync(() => useEditor.getState().setFirstPersonMode(true))
requestWalkthroughPointerLock()
}}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preview walkthrough state not shown

Low Severity

ViewerControlsBar exposes walkthroughActive so the footprints control can show walkthrough as on, but preview’s ViewerOverlay never passes it while first-person mode is active. The bar keeps showing walkthrough off even after entering walkthrough from preview.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6996256. Configure here.

levelMode === 'stacked'
? 'hover:bg-white/5 hover:text-amber-400'
: 'bg-amber-500/20 text-amber-400'
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual level mode highlighted wrongly

Low Severity

The level-mode control treats only stacked as the inactive styling; manual now gets the same amber “active” highlight as exploded and solo. Previously manual was grouped with stacked as the default, inactive appearance.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6996256. Configure here.

…anel

The wall-panel lint error predates this branch (#526); fixed here to unblock
the quality gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 6 total unresolved issues (including 5 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cdbb5b1. Configure here.

worldPoint.x <= hudLevelBounds.max.x &&
worldPoint.z >= hudLevelBounds.min.z &&
worldPoint.z <= hudLevelBounds.max.z
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HUD footprint mixes coordinate spaces

Medium Severity

When a level has no slab or zone polygons, pointIsInLevelFootprint tests the camera’s world X/Z against a world-axis bounding box, while slab and zone checks use building-local X/Z. Rotated or offset buildings can show wrong floor or room labels in walkthrough HUD.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit cdbb5b1. Configure here.

@wass08
wass08 merged commit cb6fadb into main Jul 21, 2026
2 checks passed
@wass08
wass08 deleted the fix/viewer-builder-pass branch July 21, 2026 21:04
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.

1 participant