Merge branch 'leonida/tribuene'
Tribüne im Park J6 statt des alten Gebäudekastens, mit Materialrollen, ersetzten Grundrissen beim Chunk-Aufbau und Asset-Test je Ort. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
commit
780e246fe5
13 files changed
+1149
-43
No files matched your search
@@ -0,0 +1,154 @@
|
||||
# Tribüne im Park J6 — Entwurf
|
||||
|
||||
**Datum:** 2026-09-14
|
||||
**Zusammenhang:** Der Nutzer hat eine Tribüne gebaut (`~/Downloads/tribuene.glb`, erzeugt mit trimesh). Sie soll 1:1 die Tribüne des Flamingo Park Baseball Stadium (1435 Michigan Ave, Miami Beach) ersetzen, die das Spiel in J6 als einfachen Gebäudekasten zeigt. Den Kasten soll es danach nicht mehr geben. Vorlage ist ein Satellitenbild des Nutzers im Gespräch. Es liegt nicht als Datei vor. Verglichen wurde deshalb mit dem Screenshot aus dem Hood Yard (`~/Desktop/Bildschirmfoto 2026-09-14 um 00.15.53.png`), auf dem die Tribüne ebenfalls zu sehen ist.
|
||||
**Baut auf:** `docs/superpowers/specs/2026-09-14-hood-yard-design.md` (Orte-Schicht, Aufbereitung, Radien, Tests). Neu ist nur, dass ein Ort ein Gebäude aus den Chunk-Daten ersetzt.
|
||||
|
||||
## Ziel
|
||||
|
||||
Die Tribüne steht im Spiel an der Stelle des alten Gebäudes, in Originalgröße, mit Schatten und Kollision. Das alte Gebäude ist weg.
|
||||
|
||||
## Befund (gemessen)
|
||||
|
||||
### Modell
|
||||
|
||||
| Punkt | Wert |
|
||||
|---|---|
|
||||
| Datei | 6,3 MB, Generator trimesh, 19 Knoten mit je eigenem Mesh, 14 Materialien, keine Erweiterungen (kein Bump, keine Texturtransformation) |
|
||||
| Texturen | 40 JPEG: 21 × 512 px, 13 × 256 px, 6 × 768 px (Grundfarbe von `Verkleidung`, `Estrich`, `Stahl`, `Trapezblech`, `Riffelblech`, `Sitzschale`), geschätzt 53 MB Grafikspeicher |
|
||||
| Dreiecke | 117 916 gezeichnet, kein Mesh wird mehrfach benutzt. Die größten: `Sitzschale` 44 256, `modular_electric_cables` 21 796, `industrial_wall_lamp` 13 845, `power_box_01` 13 398, `modular_electric_cables_boxes` 8 491, `Stahl` 6 804 |
|
||||
| Maße | x −20,8 bis 20,8 · z −14,82 bis 0,8 · y 0 bis 12,57, also 41,6 × 15,6 m und 12,6 m hoch (`getBounds`) |
|
||||
| Einheit | Meter: Sitzstufen 0,45 m hoch und 0,8 m tief |
|
||||
| Ausrichtung | Front mit der untersten Stufe bei +z, Rückwand mit Dach, Pressekabine und Tunnelportal bei −z. Ohne Drehung schaute die Tribüne nach Süden. |
|
||||
| Boden | Keine Bodenplatte. Die Unterseite des Betonkörpers (`Sichtbeton`) liegt bei y 0, die tiefsten Trittflächen bei 0,25 m (Tunnel) und 0,55 m (vorderste Stufe). |
|
||||
| Tunnel | Zwei 2 m breite Gänge (x −8 bis −6 und 6 bis 8) führen von der Rückseite mit zwölf 20-cm-Stufen auf die Sitzstufe bei y 2,85. |
|
||||
|
||||
### Stelle im Spiel (J6, `chunk_9_5`)
|
||||
|
||||
- **Altes Gebäude:**
|
||||
- Ecken (1384,5 | 1052), (1409 | 1076,5), (1422 | 1063,5), (1397,5 | 1039).
|
||||
- 34,65 × 18,38 m, 18,6 m hoch, 45° gedreht, Mitte (1403,25 | 1057,75).
|
||||
- Kein anderes Gebäude steht näher als 21 m.
|
||||
- **Nachbarschaft:**
|
||||
- Südwestlich verläuft die Michigan Ave. An ihr stehen zwei Laternen, bei (1384,17 | 1048,56) und (1382,18 | 1048,37).
|
||||
- Nördlich liegt die Straße am Parkrand.
|
||||
- Südöstlich liegt das Spielfeld (`surfaces`, `kind: "park"`).
|
||||
- **Boden unter der Tribüne:** nur Land, keine Straße und keine Bodenfläche.
|
||||
|
||||
### Satellitenbild
|
||||
|
||||
- Anker und Maßstab wie beim Hood Yard: Nordost-Ecke des Baseballfelds (1000 | 213) ↔ (1525 | 1058), 0,15 m je Pixel.
|
||||
- Die echte Tribüne (Dach und Sitzreihen) misst etwa 24 × 15 m. Sie ist ebenfalls 45° gedreht und schaut nach Südosten auf die Home Plate. Ihre Mitte liegt bei etwa (1405 | 1058,6), 2 m neben der Mitte des alten Gebäudes.
|
||||
- Das Modell ist 7 m länger als das alte Gebäude und 17 m länger als die echte Tribüne. Längs bleibt es mittig, weil an beiden Enden Straßen liegen. An der gewählten Lage steht nach 1,25 m Verschiebung nach Nordosten oder 1,8 m nach Südwesten eine Ecke auf der Fahrbahn.
|
||||
|
||||
## Entscheidungen des Nutzers
|
||||
|
||||
| Frage | Entscheidung |
|
||||
|---|---|
|
||||
| Größe | 1:1 |
|
||||
| Lage | Längs mittig auf dem alten Gebäude, 45° gedreht, Front 1 m vor dessen Feldseite (Vergleichsbild im Gespräch bestätigt) |
|
||||
| Ersetzen | `replaces` im Orte-Eintrag, der `ChunkStreamer` lässt den Grundriss beim Aufbau weg. Verworfen: ein Platzhalter-Kasten bis zum Einsetzen und eine Korrektur in der Extraktion. |
|
||||
| Materialrollen, Aufbereitung, Tests | bestätigt |
|
||||
| Arbeitsweise | Arbeitsbaum `.claude/worktrees/tribuene`, Branch `leonida/tribuene`, weil im Hauptordner nicht committete Änderungen einer anderen Sitzung liegen |
|
||||
|
||||
## Lage
|
||||
|
||||
`at = [1409.9, 1051.1]`, `rotation = 45`, `lift = 0`, `replaces = [[1403.25, 1057.75]]`.
|
||||
|
||||
Die positive Drehung bringt +x nach Nordosten und die Front (+z) nach Südosten.
|
||||
|
||||
| Nachbar | Abstand zur Außenkante |
|
||||
|---|---|
|
||||
| Straße am Parkrand | 0,8 m von der hinteren Nordost-Ecke (1414,13 \| 1076,29) |
|
||||
| Michigan Ave | 1,3 m von der hinteren Südwest-Ecke (1384,71 \| 1046,87) |
|
||||
| Laternen | 1,6 m und 2,9 m |
|
||||
| Palmen | 10,1 m |
|
||||
| Spielfeld | 3,2 m vor der Front |
|
||||
| altes Gebäude | Die Tribüne ragt an beiden Enden 3,5 m hinaus. Ihre Front liegt 1,0 m vor der Feldseite des alten Gebäudes, ihre Rückseite 3,8 m vor dessen Rückseite. |
|
||||
|
||||
**Höhe:** Es gibt keine Bodenplatte, also `lift = 0`. Keine nach oben zeigende Fläche liegt auf y 0, deshalb flackert nichts.
|
||||
|
||||
**Radien:**
|
||||
- Unter der Tribüne liegt nur J6. Seine Mitte ist 81,7 m von `at` entfernt, die Bedingungen 81,7 + 250 ≤ 400 und 81,7 + 450 ≤ 600 sind erfüllt.
|
||||
- Vom Startpunkt (1600 | 690) sind es 408 m. Die Datei lädt also schon beim Start vor, wie der Hood Yard, der 81 m entfernt steht.
|
||||
|
||||
## Altes Gebäude ersetzen
|
||||
|
||||
- **`PLACES`-Eintrag:** `replaces` ist eine Liste von Weltpunkten (x, y). Jeder Grundriss eines Chunks, in dem ein solcher Punkt liegt, entfällt. Das wirkt wie `remove_building` aus der Feinkalibrierung (`docs/superpowers/specs/2026-09-13-feinkalibrierung-design.md`), nur zur Laufzeit.
|
||||
- **`src/world/streaming.js`:** Die reine Funktion `withoutReplacedBuildings(chunk, points)` gibt den Chunk ohne diese Grundrisse zurück, als flache Kopie mit neuer `buildings`-Liste.
|
||||
- Der Punkt wird in Chunk-Koordinaten umgerechnet: u = x − origin[0], v = −y − origin[1]. Geprüft wird mit `pointInPolygon` aus `props.js`.
|
||||
- Trifft kein Punkt, kommt der Chunk selbst zurück.
|
||||
- **`ChunkStreamer`:** Neue Option `replacedBuildings` (Vorgabe `[]`). Die Geometrie entsteht aus `withoutReplacedBuildings(chunk, this.replacedBuildings)`. Gebäude liegen in der Kollisionsgruppe, mit dem Grundriss entfallen deshalb Kasten, Schatten und Kollision zugleich.
|
||||
- **`src/main.js`:** `replacedBuildings: PLACES.flatMap((place) => place.replaces ?? [])`.
|
||||
- **Folgen:**
|
||||
- Den Kasten sieht man nie. Die Stelle bleibt leer, bis die Tribüne ab 250 m eingesetzt wird, genau wie beim Hood Yard.
|
||||
- Die Minimap zeigt weiter den alten Umriss, ihr Bild kommt aus der Extraktion. Er liegt ungefähr unter der Tribüne. Ihre Begehbarkeitsmaske (`tools/extract/overview.py`) sperrt dort weiter das Landen.
|
||||
- Lädt die Tribüne nicht, steht an der Stelle gar kein Gebäude.
|
||||
|
||||
## Materialrollen
|
||||
|
||||
`SOLID_MATERIALS`, `NEAR_MATERIALS` und `SIMPLIFY_RATIOS` gelten für alle Orte und werden über den Materialnamen nachgeschlagen. Keiner der neuen Namen steht dort schon.
|
||||
|
||||
| Rolle | Materialien |
|
||||
|---|---|
|
||||
| fest (`SOLID_MATERIALS`) | `Sichtbeton`, `Estrich`, `Verkleidung`, `Stahl`, `Trapezblech`, `Riffelblech`, `Verglasung`, `utility_box_01` (Anschlusskästen am Boden, 1,1 m hoch) |
|
||||
| durchlässig | `Sitzschale`: Zwischen den Sitzreihen bleiben nur 38 cm, man läuft auf den Betonstufen. Außerdem `modular_electric_cables`, `modular_electric_cables_boxes`, `industrial_wall_lamp`, `industrial_wall_lamp_glass`, `power_box_01` (Verteilerkästen an der Wand in 1,5 m Höhe) |
|
||||
| Nahflächen, 1024 px (`NEAR_MATERIALS`) | `Sichtbeton`, `Estrich`, `Verkleidung`, `Stahl`, `Sitzschale`. Die Quelle hat höchstens 768 px, und `compressTexture` vergrößert nicht, 768 bleibt also 768. Alle übrigen Texturen gehen auf höchstens 512 px, darunter die von `Trapezblech` und `Riffelblech`. |
|
||||
| Vereinfachung 0,25 (`SIMPLIFY_RATIOS`) | `modular_electric_cables`, `modular_electric_cables_boxes`, `industrial_wall_lamp`, `industrial_wall_lamp_glass`, `power_box_01`, `utility_box_01`: 64 298 → rund 16 000 Dreiecke. Körper, Dach, Geländer und Sitze bleiben unverändert. |
|
||||
|
||||
## Budget
|
||||
|
||||
- **Gemessen an der Aufbereitung (2026-09-14):**
|
||||
- 1,7 MB, 69 557 Dreiecke, 14 Primitive (Draw Calls)
|
||||
- 39 WebP-Texturen: 4 × 768, 23 × 512, 12 × 256 px
|
||||
- geschätzt 49 MB Grafikspeicher, Außenmaße unverändert
|
||||
- Die sechs Kleinteil-Materialien haben 15 939 Dreiecke statt 64 298.
|
||||
- **Zum Vergleich der Hood Yard:** 657 653 Dreiecke, 43 Primitive, 231 MB.
|
||||
|
||||
## Tests
|
||||
|
||||
- **`tests/streaming.test.js`:**
|
||||
- `withoutReplacedBuildings` entfernt nur den Grundriss, der den Punkt enthält, und rechnet dabei mit dem Chunk-Ursprung.
|
||||
- Ohne Treffer gibt die Funktion den Chunk selbst zurück.
|
||||
- Ein `ChunkStreamer` mit `replacedBuildings` baut aus einem Chunk mit nur diesem Gebäude keine Gebäudegeometrie.
|
||||
- **`tests/placesSite.test.js`:**
|
||||
- „in keinem Gebäude“ übergeht die Grundrisse, die ein Ort ersetzt.
|
||||
- Neu: Der Punkt trifft genau einen Grundriss, liegt in den Außenmaßen, und alle Ecken dieses Grundrisses liegen höchstens 5 m außerhalb. Das fängt einen Lauf der Extraktion ab, der das Gebäude verschiebt, teilt oder mit einem Nachbarn zusammenlegt.
|
||||
- **`tests/placesAsset.test.js`** wird auf `describe.each(PLACES)` umgebaut:
|
||||
- Je Ort geprüft werden Dateigröße, meshopt und WebP, fehlende Instanzen, Texturen bis 1024 px und `bounds` auf 5 cm.
|
||||
- Die festen Materialien je Ort kommen aus einer Tabelle im Test, deren Vereinigung `SOLID_MATERIALS` ergeben muss.
|
||||
- Bump wird nur beim Hood Yard geprüft.
|
||||
- **Browser** (`.claude/skills/placing-editor-models/browser-checks.md`):
|
||||
- Über die Minimap ans Spielfeld vor der Tribüne springen, der alte Kasten ist nicht mehr da.
|
||||
- Draufsicht zum Vergleich mit dem Satellitenbild, dazu Blicke vom Spielfeld und von der Rückseite.
|
||||
- Kollision: Die Kapsel steht neben der Tribüne bei y 0,75, die Rückwand stoppt sie, die Sitze lässt sie durch. Ob der Tunnel begehbar ist, wird festgehalten.
|
||||
- Kosten mit `gl.finish` messen, mit und ohne Tribüne. Vorwärmen am Startpunkt über den Texturzähler prüfen.
|
||||
- Die Konsole zeigt keine Fehler.
|
||||
|
||||
## Fehlerfälle und Risiken
|
||||
|
||||
- **Karte neu erzeugt:** Verschiebt die Extraktion das Gebäude, trifft der Punkt nichts mehr oder ein anderes Gebäude. Dann schlägt der Datentest an.
|
||||
- **Glas wirft Schatten:** Jedes Mesh eines Orts wirft Schatten, auch `Verglasung` und das Lampenglas. Fällt das im Browser auf, wird es im Gespräch entschieden.
|
||||
- **Vereinfachte Kabel und Leuchten wirken zerrissen:** Dann wird der Anteil hochgesetzt, mit einem Vorher-Nachher-Bild.
|
||||
- **Stufen:** Die vorderste Stufe (55 cm), die Sitzstufen (45 cm) und der Tunnelboden (25 cm) sind vielleicht zu hoch für die Kapsel. Das wird im Browser festgestellt und nicht nachgebaut.
|
||||
- **Gemessen im Spiel (2026-09-14, 2560 × 1600, mit Schattenstufen):**
|
||||
- **Alter Kasten:** Er ist weg. Ein Strahl im Streifen hinter der Tribüne trifft den Boden (y 0), in der alten Mitte das Tribünendach (y 10,1) statt 18,6 m. Ein Nachbargebäude in J6 steht unverändert.
|
||||
- **Kollision:**
|
||||
- Genau die acht festen Materialien haben Float32-Positionen und kommen in den Collider, die sechs durchlässigen nicht.
|
||||
- Die Kapsel (Radius 0,15 m) steht auf dem Boden bei y 0,75. An der Rückwand bleibt ihre Mitte bei Modell-z −14,54 stehen; die Sockelfläche (Sichtbeton, y 0–1,15) liegt bei −14,39 — die Kapsel berührt die Wand also, ohne einzudringen.
|
||||
- Sie steigt über die 25-cm-Kante in den Tunnel, läuft die Treppe hinauf auf die Sitzstufe (y 3,6) und im Gang hinunter bis ans vordere Geländer.
|
||||
- Auf der Sitzstufe in 6 m Höhe läuft sie ohne Halt 5,7 m durch eine Sitzreihe.
|
||||
- **Kosten:** Median aus 60 Bildern mit `gl.finish`:
|
||||
- Blick vom Spielfeld 1,4–1,5 ms statt 1,3 ms
|
||||
- Draufsicht 2,4–2,5 ms statt 2,2 ms
|
||||
- Blick von hinten 4,5–4,6 ms statt 4,3 ms
|
||||
- Die Tribüne kostet also +0,1–0,3 ms je Bild.
|
||||
- **Vorwärmen:** Am Startpunkt hängen 112 der 139 GPU-Texturen an keinem Objekt der Szene (Hood Yard 69 und Tribüne 39, beide vorgeladen). Nach einem Rücksprung aus 511 m erscheint die Tribüne 48 ms nach dem Klick, die größte Bildlücke ist 56 ms bei 33-ms-Takt, und es kommen keine Texturen hinzu.
|
||||
- **Aussehen:** Vereinfachte Kabel und Leuchten wirken nicht zerrissen, ein Schatten des Glases fällt nicht auf.
|
||||
- **Konsole:** keine Warnung zu Orten. Nur Pointer-Lock-Fehler des verborgenen Browser-Bereichs und Fehler aus den künstlichen Mausereignissen der Prüfung.
|
||||
|
||||
## Nicht Teil dieser Arbeit
|
||||
|
||||
- Minimap-Bild, Begehbarkeitsmaske und Feinkalibrierung.
|
||||
- Kein Platzhalter-Kasten von weitem, keine eigenen Radien je Ort.
|
||||
- Das Modell wird nur verkleinert, nicht umgebaut.
|
||||
Reference in new issue
Block a user