fix(world): geteilte Requisiten-Geometrie beim Chunk-Abbau verschonen

Ruling 62: PropLayer-Geometrien (Palme, Laternenteile, Stammkollider) sind
Singletons über alle Chunks; #unload gab bei jedem Nachbarabbau ihre
GPU-Puffer frei. mesh.userData.sharedGeometry markiert sie, #unload
überspringt sie jetzt beim Entsorgen. Ruling 63: geschlossene Ringe
(Laufzeitform) waren in keiner Testvorrichtung gepinnt, obwohl der Code sie
bereits korrekt behandelte. Ruling 64: der Zweig `if (this.props)` bekommt
direkte Testabdeckung statt nur der manuellen Probe aus Fix-Runde 1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Sonnet 5 committed 2026-09-13 01:58:06 +02:00
1 parent d6a2f6d269
commit 02d0f36580
4 files changed
+152 -25

No files matched your search

+23
View File
@@ -52,6 +52,18 @@ describe("pointInPolygon", () => {
it("Punkt im Loch (im Außenring, aber auch im Loch)", () => {
expect(pointInPolygon(10, 10, [outer, hole])).toBe(false);
});
// Fix-Runde 2, Befund B / Ruling 63: bis hierher benutzte jede Vorrichtung offene Ringe;
// die echten Chunk-Daten schließen ihre Ringe ausnahmslos (letzter Punkt = erster, siehe
// Kommentar oben und in props.js) — dieser Fall stand bisher in keinem Test. Ein künftiger
// Umbau, der das Schließen kaputt macht, ginge sonst durch alle Tests.
it("behandelt geschlossene Ringe genauso wie offene (Laufzeitdaten schließen ihre Ringe)", () => {
const closedOuter = [...outer, outer[0]];
const closedHole = [...hole, hole[0]];
expect(pointInPolygon(2, 2, [closedOuter, closedHole])).toBe(true);
expect(pointInPolygon(25, 25, [closedOuter, closedHole])).toBe(false);
expect(pointInPolygon(10, 10, [closedOuter, closedHole])).toBe(false);
});
});
describe("vergeLampPoints", () => {
@@ -81,4 +93,15 @@ describe("vergeLampPoints", () => {
expect(out[0].z).toBeCloseTo(6);
expect(out[1].z).toBeCloseTo(-6);
});
// Fix-Runde 2, Befund B / Ruling 63: siehe Kommentar bei pointInPolygon — derselbe
// ungeprüfte Fall (offene statt geschlossene Ringe) steckte auch hier in jeder Vorrichtung.
it("versetzt eine Laterne auch dann, wenn der Straßenring geschlossen ist", () => {
const points = [{ x: 0, z: 0, angle: 0 }];
const ring = [[-50, -5], [50, -5], [50, 5], [-50, 5]];
const roads = [{ poly: [[...ring, ring[0]]], bridge: false }];
const out = vergeLampPoints(points, roads);
expect(out).toHaveLength(1);
expect(out[0].z).toBeCloseTo(6);
});
});