Experience fix pass: placement, selection rotation, roof gable, stairs, capture, Cmd+S, three 0.186 - #807
Conversation
|
I hit an error while handling your request (Model unavailable on AI Gateway free tier: Free tier users do not have access to this model. Upgrade to paid credits at https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%3Fmodal%3Dtop-up for unrestricted…). Please try again, rephrase, or reach out if it keeps failing. Error id: 13d2cf37-d670-4189-9d4d-bd278918139c |
2818400 to
504e546
Compare
…mera armCaptureFov stored the live camera FOV verbatim, so fractional pose FOVs printed float tails in the HUD and left the reset button enabled. Both writers now share clampCaptureFov. Alt holds the drone at 0.2x speed and look sensitivity for fine framing; Shift stays the boost. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
The CSG degeneracy guard enforced its 5 cm minimum by lowering the shell base, which for wallHeight-0 room roofs put the gable 4 cm inside the wall and z-fought its faces. Raise the eave instead; mirror the floor in the opening-placement frame and the shed inset panel. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Capture-phase, always-on listener so the page-save dialog never appears. Hosts can take the chord over via onSaveShortcut; the default flushes the autosave through the existing executeSave path. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…previews to the level Fresh (absolute) placement mapped the cursor to the node origin, so a cabinet run landed |bounds.center| away from the pointer. Subtract the rotated centre and keep it under the cursor across R/T. The registry mover's box/sphere now ride the target level's stacked Y like the other placement tools. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Level-destination stairs returned the full floor-to-floor height even when a slab lifted their base, so the top overshot the storey plane. The resolver now subtracts the elected base for both destinations. The panel exposes Follows storey / Custom rise for level stairs, and the stair tool and landing toggle seed from the storey instead of a 2.5 m constant. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…on the right storey The floor-path Y was frozen at drag start (#638), so an item pulled off a shelf kept the shelf height after reparenting. Read the live grid Y instead. The cursor group, grid surface and facing pose now add the level mesh's stacked Y, which the building-local tool group lacks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
translateGroupPatches dropped the snapshots' yaw after a mid-gesture rotation, so the layout orbited while every item kept its old facing and the commit wrote the same. Carry rotation for vec3/scalar participants, pivot every session on the shared mesh-box centre the idle shortcut uses, and engage an armed session before rotating. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
No removed export is used and every peer range admits r186. Two adjustments: Renderer.dispose() is async now, so the capability probe swallows its rejection; and r186's CommonJS entry re-exports the ES module, which Bun cannot require() while the same process imports three as ESM. A bun test preload steers fiber/drei/maath/meshline (no exports map, CJS main) to their module builds, the way bundlers already resolve them. Types stay on 0.184.1 (0.185 types OOM tsgo). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Bun's plugin onResolve does not run for static imports, so steering the
R3F packages to their module builds never applied in CI (isolated linker)
and the CJS require("three") kept racing the ESM import. Evaluating the
package's own three copy first makes the later require() a cache hit.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
The 5 cm CSG floor lifted only the outer shell, so a flat zero-height roof would have ended up with a solid cap under the deck. Compute the lift once and apply it to every volume. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…andle Cmd+S Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…s eave A shell-derived lift left overhanging deck cutters with a negative eave. Clamp each volume's top the way main did, just at 5 cm and without the base sink, so cutters stay level with the shells they carve. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
The rise-mode block already exposes the Rise field in custom mode; the geometry copy wrote totalRise behind the Follows storey toggle. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…re when R/T cannot engage The stair tool seeded the flight from the storey height alone, a slab thickness too tall until syncStairRises caught up; it now subtracts the drop point's elected base like the resolver. A failed engage() on R/T no longer tears down the pointer listeners. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
5e77007 to
5526120
Compare
…() before the WebGL fallback Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…r each R/T Rotating the previous axis-aligned fit inflated the anchors every step. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
… use the shared display name A curved stair switched to straight had no stair-segment child and drew nothing (and vanished on select). The type change now creates a default flight in the same history step and the viewer falls back to that flight for already-broken scenes. Stair and elevator panels label levels the way the level switcher does, and the rise toggle reads Follows level like walls. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Room roofs computed their elevation once at creation, so a later custom wall height left the roof at the storey plane. Roofs now remember their source walls and a core system re-derives position[1] (highest top, clamped to the level floor) on wall/slab/level edits, history-paused like the stair rise sync. Moving the roof by hand detaches it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…al rise On a follows-level stair the sync handed the edited height straight back, so the segment slider did nothing. The edit now also writes totalRise (the stair becomes Custom rise, as editing Rise on its own panel does). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Walls shorter than the level (2.5 m in a 3 m storey) left a gap because the roof elevation was clamped to its level floor. Follow the wall top. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Replace the source-wall id list with support.kind 'walls': room and conical roofs are created following, the system resolves the enclosure under the roof centre on the level below and writes the highest wall top (unclamped), an explicit Y edit or vertical handle drag flips the roof to custom, and the panel offers Follows walls / Custom like walls do. No migration; existing roofs stay custom until the user opts in. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 947c439. Configure here.
| node?.type === 'building' || | ||
| node?.type === 'site' | ||
| ) | ||
| } |
There was a problem hiding this comment.
Roof sync skips segment-only edits
Low Severity
isElevationRelevant does not treat roof-segment as relevant, but conical wall-follow matching uses each segment's position, width, and type. Resizing or moving a conical segment therefore does not reschedule elevation sync, so the roof Y can stay locked to a wall it no longer matches.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 947c439. Configure here.
…m membership A room missing a wall, or an L-room whose centre falls outside, left the roof frozen. Walls whose band overlaps a segment footprint on the level below now count; segment-less roofs keep the point-in-room lookup. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
…walls on the roof's own level too Armed on the walls' level, the tool parented the roof to that level and the follow rule only looked one storey down, so a Floor 1 roof dropped to the Level 0 wall tops. The roof now goes to the level above the walls when one exists (top floor keeps it on the walls' level), and the resolver considers walls on the roof's level and the one below. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc


What does this PR do?
Experience fix pass across placement, selection, roof, stairs, capture and shortcuts, plus the three r186 bump.
onSaveShortcutprop, the default flushes the autosave. Listed in the shortcuts dialog.armCaptureFovrounds and clamps likesetCaptureFov, which also fixes the reset button staying enabled.translateGroupPatchesnow carries the rotated yaw for vec3/scalar participants (it was dropped on re-publish and at commit). All sessions pivot on the shared mesh-box centre; R/T while armed engages the session first. 2D floorplan session ported too.Renderer.dispose()is async now (capability probe handles it). r186's CJS entry re-exports the ESM build, which Bun cannotrequire()alongside an ESM import of three, so abun testpreload evaluates three first and the R3F packages' CJSrequire("three")becomes a cache hit.@types/threestays 0.184.1.How to test
bun install && bun run test— all suites green (core 1436, viewer 308, editor 877, nodes 2370, capture-viewer 25, apps/editor 41).Screenshots / screen recording
Non-visual verification by unit tests; before/after screenshots are in the private-editor PR description.
Checklist
bun devbun checkto verify)mainbranch🤖 Generated with Claude Code
https://claude.ai/code/session_013hQVFZ62S1qJDsBM9ferYc
Note
Medium Risk
Touches scene undo/commits, roof schema v3, and widespread placement math; dependency bump affects all Three/R3F paths but is mostly mechanical with test preloads.
Overview
Broad experience fix pass across core, editor, nodes, and viewer: shortcuts, placement, multi-select transforms, roofs, stairs, capture, plus three 0.186 with Bun test preloads.
Roofs gain
support: { kind: 'walls' }: elevation resolves from walls under the footprint (or room), withRoofElevationSystemsyncing Y after wall/slab/level edits (undo-aware, coalesced). Room/conical creation defaults to wall-follow; explicit Y or handle moves switch to custom level placement. Gable wall faces keep the base at 0 and raise the eave to at least 5 cm to avoid z-fighting. Footprint/elevation helpers move into@pascal-app/core(schema v3).Stairs: level-destination
totalRisesubtracts the elected floor/slab base (matching deck stairs); tool/preview seed flight height from the storey; sharedcreateDefaultStairSegmentin core.Editor placement & selection: Cmd/Ctrl+S saves (host
onSaveShortcutorsaveNow); floor-path items use live grid Y and level mesh offset on upper storeys; modular runs use footprint-centre absolute cursor placement; group move/rotate pivots on the mesh box, preserves yaw through translate, and engages R/T before threshold. Drone Alt = slow look/move; capture FOV clamped on arm; straight stairs without segments keep the merged body visible in edit mode.Deps: monorepo
three→ 0.186.0;bunfig.tomlpreloads evaluate three before R3F CJSrequirein tests.Reviewed by Cursor Bugbot for commit fb945b1. Bugbot is set up for automated code reviews on this repo. Configure here.