Skip to content

Fix non-rectangular furniture light masks - #266

Merged
nicosandller merged 14 commits into
nicosandller:mainfrom
jjj120:fix/furniture-lighting
Sep 21, 2026
Merged

nicosandller merged 14 commits into
nicosandller:mainfrom
jjj120:fix/furniture-lighting

Conversation

@jjj120

@jjj120 jjj120 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Implements option (b) from #248

image

This leaves the sunlight implementation alone, since it already ignored furniture. Now furniture also gets ignored and light gets just drawn on top.

I think this is not the best option, I think on the long run it should mask out furniture exactly. And then also use this mask on the sunlight layer, since sunlight and normal lamp light should not differ.

jjj120 and others added 3 commits September 5, 2026 10:17
it does not render a mask for furniture anymore, so it does not have to
get tested
@jjj120
jjj120 marked this pull request as draft September 5, 2026 08:31
@jjj120

This comment was marked as resolved.

@nicosandller
nicosandller self-requested a review September 7, 2026 02:32
@nicosandller nicosandller linked an issue Sep 11, 2026 that may be closed by this pull request
jjj120 and others added 3 commits September 15, 2026 17:02
The mask uses all the closed geometry in furniture as light masks, so
rectangles, polygons, ...
@jjj120
jjj120 force-pushed the fix/furniture-lighting branch from 2718f99 to 82ccd42 Compare September 15, 2026 15:50
@jjj120

jjj120 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

I have changed the mask system to now just draw the furniture onto the masking layer too. This now looks like this:

image

This now fixes the issue and also preserves the look of the lightbulb light hitting the floor, rather than just being painted over everything

@jjj120
jjj120 marked this pull request as ready for review September 15, 2026 15:52
@jjj120

This comment was marked as resolved.

@jjj120

jjj120 commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor Author

Found the problem, I indeed changed something in the sunlight rendering logic. No clue why, I just changed it back with e51bfdc now.

@jjj120 jjj120 changed the title Remove furniture light masks Fix non-rectangular furniture light masks Sep 16, 2026
@nicosandller
nicosandller requested a lite review from Copilot September 21, 2026 05:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Unresolved moderate issues remain in mask opacity, geometry compatibility, path/fill handling, and regression coverage.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 3 Medium severity · 1 Low severity

Open (4)
What changed in this PR

Updates furniture light masks to follow each symbol’s geometry, improving lighting for non-rectangular furniture.

Changes:

  • Adds fill-color overrides for symbol rendering.
  • Renders furniture masks from symbol geometry.
  • Updates regression tests and authoring guidance.
File Summary and final review findings
src/​symbols.ts Supports fill-color overrides. Moderate (1 vote): Preserve none when applying color overrides. Moderate (1 vote): Use fillC in the path template so path-based shapes honor overrideFill.
src/​render.ts Renders furniture glow masks from symbol geometry. Moderate (3 votes): Handle overrideOp: 0 correctly. Nit (2 votes): Fix fo to of. Moderate (2 votes): Avoid filling open paths unless they contain Z. Moderate (1 vote): Preserve or update the documented footprint contract. Moderate (1 vote): Suppress or attenuate mask strokes.
src/​render.test.ts Updates glow-mask expectations. Moderate (3 votes): Add sectional/L-shaped geometry assertions that verify the notch rather than only the transform and primitive type.
furniture/​README.md Documents closed-shape requirements. Nit (1 vote): Replace correct displaying with clearer wording such as the lighting mask to display correctly.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/render.test.ts
Comment thread src/render.ts Outdated
Comment thread src/render.ts Outdated
Comment thread src/render.ts Outdated
- Honor overrideOp: 0 (was skipped by a truthiness check).
- Only closed geometry dims in the mask: an open path's fill was
  implicitly closing in SVG and smearing a wedge the glyph never draws.
- Let a sealed path carry overrideFill; unsealed paths keep fill="none".
- Update the stale renderGlowMask docs and test the sectional's L notch.
@nicosandller

Copy link
Copy Markdown
Owner

Addressed the review feedback from the Copilot review (commit bc03888):

  • Honor zero opacity overrides — if (overrideOp) → overrideOp !== undefined, so 0 is applied rather than skipped.
  • No filling open paths — the mask only dims sealed, closed geometry (rect/circle/ellipse, closed polygon, path sealed with Z). partTemplate also renders an unsealed path as fill="none", so the tub's rim and a stair's rail block only their strokes instead of smearing a wedge the glyph never draws. (Behavior for all built-in symbols' normal rendering is unchanged — verified against the furniture JSONs.)
  • Geometry regression coverage — added a test asserting the sectional's L polygon reaches the notch vertex 18.4, which the old bounding-box mask could never produce; also rewrote the now-misnamed "footprint" test, which was passing for the wrong reason.
  • Comment typo + docs — fixed fo → of, added a doc comment to renderFurnitureMask, and updated renderGlowMask's stale "rect/ellipse footprint" docstring to describe the symbol-geometry mask (Light is not correctly drawn onto couch #248).

One finding I deliberately did not change: "suppress/attenuate mask strokes". Line art in the mask blocks light at full strength under the stroke while the body blocks 0.5 × — the screenshots in this PR show that look, it matches the furniture's own line art drawn above the glow, and making it uniform would need a stroke-opacity override for a purely cosmetic gain. Happy to switch if you disagree.

Verified locally: typecheck, full vitest suite (1676 passed), and vite build.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Unresolved rendering and path-handling issues can affect ordinary furniture rendering and produce incorrect light masks.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 2 Medium severity

Open (3)
Resolved since last review (4)

Comment thread src/symbols.ts Outdated
Comment thread src/render.ts
Comment thread src/symbols.ts Outdated
The sealed-path fill logic in partTemplate changed ordinary furniture
rendering, not just the mask: a custom symbol with a filled open path
used to render its fill and silently lost it. The mask never needed it
either - renderFurnitureMask already limits its dim to closed geometry.
Revert partTemplate to fill=${fill} and keep all mask decisions in
closedGeometry.

closedGeometry checks the last path command now: SVG fills an open
subpath by closing it implicitly, so a path like "M .. Z M .." must
count as open or it still smears a wedge.

Document that SymbolDef.footprint is parsed but unused by the mask.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Unresolved critical findings and a failing test assertion block approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 4 High severity

Open (4)
Resolved since last review (3)

Comment thread src/render.test.ts Outdated
Comment thread src/render.ts Outdated
Comment thread src/render.ts
Comment thread src/render.ts Outdated
Three things Copilot caught on the mask geometry:

`closedGeometry` read only the last command, so `M … M … Z` passed as
sealed while its first subpath was still open — SVG closes that one
implicitly and fills it. Walk the commands instead and reject a fresh
`M` while a subpath is open.

An open path with a filled role (`body`, `solid`, an explicit
`fillOpacity`) still reached `partTemplate` with a fill, so the mask
painted the black wedge the closed-geometry check was meant to prevent.
The mask now zeroes those parts' fill opacity, which leaves ordinary
furniture rendering untouched.

The mask group carried `data-id`/`data-entity`. Those are card-mod's
styling hooks, and this group is mask *source* geometry: an unscoped
`[data-entity="light.kitchen"] { filter: … }` would repaint the mask
and bend the pool it cuts. They stay on `renderFurniture` only.

The L-notch assertion now parses the polygon coordinate instead of
matching float printing.

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Three moderate findings remain in src/render.ts affecting mask opacity and fill behavior.

Review effort: Lite
Findings: None

Resolved since last review (4)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Preserve fill intent for closed outline parts

src/​render.ts:1271

This predicate only checks whether the primitive is geometrically closed, so it turns every closed outline/detail into a filled mask area. That overrides the symbol role contract: for example, stove.json's burner circles and toilet.json's bowl ellipse use line, and custom parts may explicitly set fillOpacity: 0; the mask will now dim their interiors instead of only their strokes. Preserve the original fill intent when deciding whether a closed part should be filled.

@nicosandller
nicosandller merged commit fd1dcde into nicosandller:main Sep 21, 2026
3 checks passed
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.

Light is not correctly drawn onto couch

3 participants