viewer: honour node.visible on buildings, levels, zones and ceilings - #908
Merged
Merged
Conversation
The sidebar eye on a building, level, zone or ceiling wrote a flag that
only half the app read. Selection candidates, first-person collision,
the 2D plan and every export already prune a hidden node; the 3D
viewport did not, because these kinds ship custom renderers and none of
them applied the flag to its root. Hiding a building left it drawn but
unclickable; hiding a level left a floor you fell through in
walkthrough; hiding a zone or ceiling left it on screen but out of the
plan and the export.
Each of those renderers now sets `visible={node.visible !== false}` the
way ParametricNodeRenderer does. Two per-frame systems used to overwrite
that prop and now fold the flag in instead: LevelSystem's solo decision
moves to a pure `resolveLevelVisibility` in level-utils (a level the
author hid is hidden outright and never becomes a shadow-caster), and
both zone systems, which force the group visible to keep the <Html>
label alive, exempt a hidden zone and drop its label with it.
snapLevelsToTruePositions no longer un-hides those levels for thumbnail
and bake captures, so the capture matches the export.
The Site keeps the rule settled on the export side: its flag hides its
own ground fill, sculpted terrain and boundary line, nothing beneath it,
and the horizon disc is a world backdrop that renders either way.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
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: 0a1ad139-34f7-4627-b94a-f03f5eb067be |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
The sidebar's Hide/Show eye on a building or level was honoured by selection, first-person collision, the 2D plan and every export, but not by the 3D viewport:
BuildingRendererandLevelRendererrendered a bare<group>, and the level system overwroteobj.visibleevery frame from solo-mode state. Hide a building and it kept drawing but could no longer be clicked; hide a level and walkthrough fell through its floor. Zones and ceilings had the same gap (theirfloorplan.tshonour the flag, their renderers did not), and two zone systems forced the zone group visible every frame.Now:
visible={node.visible !== false}on their root, the same wayparametric-node-renderer.tsxdoes for parametric kinds.resolveLevelVisibility(new, inlevel-utils.ts) combines the author's flag with solo mode: solo behaviour is unchanged for visible levels, and a hidden level never enters the shadow-caster-only branch, so it stops shadowing the floor below.snapLevelsToTruePositionsno longer forces hidden levels visible during capture, matching the export, which prunes them.ZoneSystemandViewerZoneSystemdrive the zone group and its<Html>label from the node flag instead of forcing the group visible.SiteRendererhides its own ground fill, sculpted terrain and lot line when the Site is hidden, while everything standing on the site keeps its own flag and the horizon disc stays. This is the rule editor: stop a hidden Site from emptying exports and the 2D plan #907 gives the exporter and the 2D plan: the Site is the parcel reference, not a container.wiki/architecture/renderers.mdstates the rule for custom renderers.Independent of #907 (no shared files); together they make
visiblemean the same thing in the viewport, the 2D plan, selection, collision and exports.How to test
cd packages/viewer && bun test src/systems/level—resolveLevelVisibilitycases plus threeLevelSystemcases: a hidden level outside solo, a hidden level excluded from the shadow-caster branch, a hidden level staying hidden throughsnapLevelsToTruePositions.packages/nodes3422 pass,packages/viewer362 pass,packages/editor1099 pass.tsc --buildclean in viewer and nodes,tsgo --noEmitclean in editor, Biome clean.visible: falsethrough MCP — the parcel fill and lot line disappear, the house stays.Screenshots / screen recording
N/A — the change is what the sidebar eye already promised; no new UI.
Checklist
bun devbun checkto verify)mainbranchNot ticked: the viewport behaviour was not exercised in a browser from this checkout; coverage is the unit suites above.
Note
Medium Risk
Changes per-frame visibility on levels and zones (including solo shadow casting and snapshot snap), so regressions could show wrong floors, shadows, or capture output—but behavior is meant to match existing export/plan semantics.
Overview
The sidebar Hide/Show eye now drives the 3D viewport the same way it already did for selection, collision, 2D plan, and exports.
Building, level, zone, and ceiling renderers set
visible={node.visible !== false}on their root. Site is special: hiding it drops parcel surfaces (ground, terrain, lot line) only; buildings/items and the horizon disc stay governed by their own rules.ZoneSystem and ViewerZoneSystem no longer force every zone group visible each frame—they sync group visibility, mesh display, and HTML labels with
node.visible, so per-frame writes do not undo the renderer prop.Level presentation uses new
resolveLevelVisibility: author-hidden levels stay off in all modes and never enter solo’s shadow-caster-only path; visible levels keep existing solo behavior.snapLevelsToTruePositionsstill clears presentation hiding for capture but leaves author-hidden levels hidden so snapshots match export.Tests cover
resolveLevelVisibilityand level-system integration;wiki/architecture/renderers.mddocuments the renderer + per-frame system rule.Reviewed by Cursor Bugbot for commit 2f683ad. Bugbot is set up for automated code reviews on this repo. Configure here.