fix(2.5D): prove the sun beam is cut by bodies; review r1 lows (#649)

CODE-REVIEW-649-r1 M1: the 2.5D beam's cut by physical bodies (AC7) had no
witness. Unit: a column in the beam leaves the floor between window and
column lit and shades it behind the column; smoke: a Solid partition across
the south beam removes floor from the rendered wash. Mutants: occluders
extruded toward the sun, occluders ignored, card drops occluders.

Lows: L1 stale alpha wording (DEVELOPMENT, ARCHITECTURE, card comment,
benchmark); L3 dark-theme state edges computed per theme; L4 Alert beats a
plain Hover and a plain Selected; L5 a virtual marker has no dashed ring;
L6 tiles and shadows stay without walls (show_borders off).

Issue: #649
User-Visible: no
This commit is contained in:
Claude
2026-09-25 18:55:28 +03:00
parent e1f1c7d908
commit 106fdc096d
73 changed files with 624 additions and 496 deletions
+20
View File
@@ -3523,6 +3523,26 @@ const MUTANT_DEFINITIONS = [
replace: " const isoSun = this._renderProjection === 'iso' && this._editing ? this._isoSceneRuntime : null;",
}],
},
{
id: 'iso-sun-occluders-toward-sun',
guard: "npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs && node --test --test-name-pattern=\"AC7 the 2.5D beam is cut\" test/iso-stage6.test.mjs",
because: '#649 AC7 (CODE-REVIEW-649-r1 M1): a body shades the floor behind it, away from the sun — '
+ 'extruded toward the sun it darkens the lit floor between window and body',
patches: [{ file: 'src/iso-sun.ts', find: " const shadows = directionalOccluders(input.occluders, away, travel);", replace: " const shadows = directionalOccluders(input.occluders, toSun, travel);" }],
},
{
id: 'iso-sun-occluders-ignored',
guard: "npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs && node --test --test-name-pattern=\"AC7 the 2.5D beam is cut\" test/iso-stage6.test.mjs",
because: '#649 AC7 (CODE-REVIEW-649-r1 M1): the 2.5D beam is cut by the same physical bodies as Flat',
patches: [{ file: 'src/iso-sun.ts', find: " if (polys.length && input.occluders?.length) {", replace: " if (polys.length && input.occluders?.length && input.elevation > 90) {" }],
},
{
id: 'iso-sun-card-drops-occluders',
guard: 'node demo/smoke_iso_sun.mjs',
because: '#649 AC7 (CODE-REVIEW-649-r1 M1): the card hands the 2.5D beam the same physical bodies '
+ 'as the Flat wedges (`_sunInputs`); without them light passes through a partition',
patches: [{ file: 'src/houseplan-card.ts', find: "beams: isoSun.computeIsoSunBeams({ ...inputs, azimuth:", replace: "beams: isoSun.computeIsoSunBeams({ ...inputs, occluders: [], azimuth:" }],
},
{
id: 'iso-theme-dark-wall-rule-returns',
guard: 'node demo/smoke_iso_theme_walls.mjs',