Commit Graph
7 Commits
Author SHA1 Message Date
knsoandClaude Sonnet 5 ca4f7161af feat(world): Fahrbahnmulde, Bordsteinwand und Markierungen bauen
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 21:02:14 +02:00
knsoandClaude Haiku 4.5 8f80c020c8 test(world): Bodenplatte-Test absichern und console.log entfernen
Fixrunde 1: Der Test „lässt kein Loch verschwinden" konnte nicht fehlschlagen,
weil er nur position.count prüfte, das vor der Triangulierung gefüllt wird.
Jetzt absichert footprintArea(geo) die tatsächliche Restfläche (18400 m²);
das console.log ist entfernt.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-17 00:05:55 +02:00
knsoandClaude Haiku 4.5 f301d39ea0 test(world): Bodenplatte mit vielen Löchern messen
Erstes Risiko des Entwurfs: die Fahrbahn wird als Loch aus der Bodenplatte
geschnitten, und ShapeUtils.triangulateShape läuft beim Nachladen im
Hauptthread. Der Test hält fest, dass 100 Löcher je Chunk unter 50 ms
bleiben und keines verschwindet.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-16 23:50:34 +02:00
knsoandClaude Sonnet 5 b736afb7ff feat(world): Parkwege, Felder, Plätze, Pool und Parkplatz als eigene Schichten
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 08:34:43 +02:00
knsoandClaude Sonnet 5 5c8df78246 fix(world): Flackernden Boden behoben (Tiefenpuffer-Versatz je Schicht, Brücke angehoben)
Downtown aus der Luft: Boden, Stadtfläche, Park, Strand und Straße lagen 1-2 cm
auseinander (geometry.js: SURFACE_OFFSET=0.02 für alle drei Flächen gleich,
ROAD_OFFSET=0.03), bei 150-300 m Kameraabstand unter der Auflösung eines
24-Bit-Tiefenpuffers (~1,3 cm bei 150 m, ~5 cm bei 300 m, gemessen mit dem alten
Nahwert 0.1) — Strand/Park/Stadtfläche lagen zusätzlich exakt aufeinander und
fighteten unabhängig von der Entfernung. Die Brückenoberkante lag exakt auf der
Bodenoberkante (beide y=0).

Vier Änderungen, freigegebener Entwurf:
- Kamera-Nahwert 0.1 -> 0.5 m (src/main.js): fünffache Tiefenauflösung auf jede
  Entfernung, far bleibt 2500.
- src/world/materials.js: POLYGON_OFFSETS/POLYGON_OFFSET_ORDER, eine feste,
  streng zunehmend negative Stufe je Schicht (Boden 0, Stadt -1, Park -2, Strand -3,
  Straße -4, für Faktor und Units gleich) — wirkt im Tiefenpuffer selbst, hält die
  Rangfolge deshalb auf jede Entfernung, unabhängig vom geometrischen Abstand.
  applyPolygonOffsets() ist eine separate, reine Funktion, damit sie ohne
  createMaterials()/Texturladen testbar ist und beweisbar nur diese fünf Materialien
  trifft (Brücken/Gebäude/Wasser/Meeresboden bleiben unberührt).
- Strand, Park und Stadtfläche bekommen dabei je eine eigene Stufe, statt sich wie
  bisher (SURFACE_OFFSET) eine zu teilen.
- src/world/geometry.js: Brückendeck-Oberkante jetzt BRIDGE_OFFSET (=SURFACE_OFFSET,
  0.02 m) statt 0 — derselbe Größenordnungsentscheid wie bei den Flächen, klein genug
  für einen unbemerkten Schritt, groß genug für die Tiefenpuffer-Auflösung bei 300 m.

TDD: Rangfolge/Kein-Teilen-Regeln sind rein und zuerst als fehlschlagende Tests
geschrieben (tests/materials.test.js, 5 neue), ebenso die Brückenanhebung
(tests/geometry.test.js, 1 neu) — beide zunächst rot, dann grün. 65 -> 71 Tests,
alle grün.

Browser-Verifikation (Downtown, Chunk 2_9, gleiche Kameraposition vorher/nachher):
das zuvor durchgängig zackige/zerstückelte Straßen-/Flächenbild ist jetzt glatt und
durchgängig lesbar. Ego-Perspektive dicht an einer Gebäudewand zeigt mit near=0.5
kein sichtbares Durchsehen. Details, Screenshot-Pfade und offene Punkte (Brücken-
Nahaufnahme nicht separat bestätigt) im Bericht:
.superpowers/sdd/2026-09-12-leonida-vice-slice/schichten-report.md

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 09:01:36 +02:00
knsoandClaude Sonnet 5 962bfef778 fix(world): openRing() stürzt bei leerem oder fehlendem Außenring nicht mehr ab
Ruling 47 (Fix-Runde 1, Befund A): Die Längenprüfung stand erst im return,
destrukturiert wurde davor. extrudePolygons/flatPolygons warfen dadurch bei
einem Polygon mit leerem Außenring ([[]]) oder ganz ohne Ringe ([]), statt wie
der Rest des Moduls zu null zu degradieren. Längenprüfung nach vorn gezogen
und zusätzlich raw[0] am Aufrufort auf [] defaultet, da ein Polygon ganz ohne
Ringe openRing() ein undefined statt eines leeren Rings übergibt — die
Prüfung allein in openRing() fängt diesen zweiten Fall nicht ab.

Dazu Ruling 49: Regressionstest für die Wickelrichtung (Außenwände nach
außen, Lochwände nach innen, Dach nach oben) anhand von COURTYARD. Bestand
beim ersten Lauf unverändert, keine Anpassung am Modul nötig.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 19:43:46 +02:00
knsoandClaude Sonnet 5 dce90a2263 feat(world): Geometrie-Baustein für Land, Straßen, Brücken und Gebäude
Normalisiert Ringe vor der Triangulierung: ShapeUtils.triangulateShape
verlangt echte Vector2 (nicht {x,y}-Objekte) wegen des internen
Vector2#equals-Aufrufs, und jeder extrahierte Ring schließt sich selbst
(letzter Punkt == erster). Ohne vorheriges Entfernen dieses Schlusspunkts
verschieben sich ab dem ersten Loch alle Dreiecksindizes um eins gegenüber
der von ShapeUtils intern neu vergebenen Nummerierung — Häuser und Straßen
mit Innenhof bekämen an genau der Stelle falsch verdrahtete Dreiecke, ohne
dass die Dreieckszahl sich ändert. Beide Fehler traten mit den Testquadraten
aus dem Task-Brief nicht auf, weil deren Ringe offen sind; die echten
Chunk-Dateien schließen aber ausnahmslos jeden Ring.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 19:23:30 +02:00