diff --git a/docs/superpowers/specs/2026-09-16-strassen-design.md b/docs/superpowers/specs/2026-09-16-strassen-design.md index 6f034de..4be01ec 100644 --- a/docs/superpowers/specs/2026-09-16-strassen-design.md +++ b/docs/superpowers/specs/2026-09-16-strassen-design.md @@ -90,6 +90,8 @@ Ein 15-cm-Bordstein hält den Spieler also nicht auf, er ist eine Stufe. Fahrzeu Zwei Dinge liegen damit fest. Erstens: Das Straßen-Kit taugt nicht für die Fahrbahn — 4,2 m gegen 13,4 m gemessene Korridorbreite, und seine Markierungen sind europäisch (gelbe Randlinien, weiße gestrichelte Mitte), also das Gegenteil des amerikanischen Schemas. Zweitens: Das Bordstein-Kit besteht aus 16 Kästen mit zusammen 351 Punkten; seine Substanz sind die Texturen, nicht die Geometrie. 177 km Bordsteinkante wären in 3-m-Modulen rund 59.000 Einzelteile. +**Korrektur (Gehwegtextur-Korrektur, 2026-09-18):** Die Zeile „Brauchbar als: Profil und Texturen für Bordstein und Gehweg" gilt nur noch für den Bordstein. `sidewalk_Diffuse.jpg` aus `modular_sidewalk_curb_kit` ist kein Betonbild, sondern das Platzhalterbild des Kits — dunkler Grund, roter Schriftzug „Tru-planar Sidewalk texture", im Browser geprüft. Solange `loadSet()` an der fehlenden Normal- und ARM-Karte scheiterte, fiel der Gehweg auf den einfarbigen Ersatz zurück und niemand bemerkte es; sobald `loadSet()` auch ohne die beiden Beiwerke lädt (s. Abschnitt „Texturen aus dem Kit" unten), kachelt der Schriftzug über die ganze Stadt. Der Gehweg benutzt deshalb `concrete_pavement` von Poly Haven (CC0), dieselbe Textur wie die Parkwege (`TEXTURES.paths`). Der Bordstein bleibt beim Kit — `curb_Diffuse.jpg` ist eine echte Betontextur mit Fugen, im Browser geprüft. + ## Entscheidungen des Nutzers | Frage | Entscheidung | @@ -203,7 +205,7 @@ Der Schritt überspringt still, was schon da ist, und meldet verständlich, wenn `sidewalk_metallicRoughness.png` ist eine 605 Byte große Einfarbfläche und wird nicht übernommen; eine Normal-Map für den Gehweg liefert das Kit nicht. -**Namensnennung:** `manifest.json` und die Zeile im Spiel bekommen „Bordstein und Gehweg: Just8 (Sketchfab, CC BY 4.0)". Das Straßen-Kit wird in dieser Arbeit nicht benutzt und deshalb auch nicht genannt. +**Namensnennung:** `manifest.json` und die Zeile im Spiel bekommen „Bordstein: Just8 (Sketchfab, CC BY 4.0)". Das Straßen-Kit wird in dieser Arbeit nicht benutzt und deshalb auch nicht genannt. Der Gehweg kommt seit der Korrektur oben (Abschnitt „Die beiden Kits") von Poly Haven (CC0) und bleibt deshalb wie die übrigen Poly-Haven-Texturen ohne eigene Namensnennung. ## Chunk-Format @@ -239,7 +241,7 @@ Die Ausgabe bleibt normalisiert und sortiert (Fixrunde 3 aus Teil 1): `shapely.n |---|---| | `carriageway` | `asphalt_02` mit `ROAD_TINT`, wie die heutige Straße | | `curb` | `curb` aus dem Kit, mit Normal- und ARM-Karte | - | `sidewalk` | `sidewalk` aus dem Kit | + | `sidewalk` | `concrete_pavement` von Poly Haven, s. Korrektur oben („Die beiden Kits") | | `markings` | unbeleuchtet, Vertexfarben, ohne Textur | - **Tiefenpuffer:** `POLYGON_OFFSET_ORDER` bekommt `sidewalk` und `lots` zwischen den Belägen und `markings` ganz vorn. `carriageway` und `curb` brauchen keinen Versatz — sie liegen 15 cm tiefer und sind echte Geometrie, keine Auflage. diff --git a/public/textures/sidewalk_Diffuse.jpg b/public/textures/sidewalk_Diffuse.jpg deleted file mode 100644 index 1e01b20..0000000 Binary files a/public/textures/sidewalk_Diffuse.jpg and /dev/null differ diff --git a/src/world/geometry.js b/src/world/geometry.js index 732acb0..16dfa13 100644 --- a/src/world/geometry.js +++ b/src/world/geometry.js @@ -270,7 +270,10 @@ export function buildChunkGeometry(chunk) { carriageway: flatPolygons((chunk.carriageway ?? []).map((c) => c.poly), { y: -CARRIAGEWAY_DEPTH, uvScale: 8 }), curb: kerbGeometry(chunk.curb ?? [], (chunk.carriageway ?? []).map((c) => c.poly)), - sidewalk: flatPolygons((chunk.sidewalk ?? []).map((s) => s.poly), { y: SURFACE_OFFSET, uvScale: 4 }), + // Korrektur: derselbe Belag wie paths (concrete_pavement), also auch dasselbe uvScale — + // Poly Haven misst die Kachel mit 1,8 × 1,8 m (s. Kommentar bei paths unten); mit 4 wären + // die Platten um mehr als das Doppelte gestreckt. + sidewalk: flatPolygons((chunk.sidewalk ?? []).map((s) => s.poly), { y: SURFACE_OFFSET, uvScale: 1.8 }), markings: markingGeometry(chunk.markings ?? [], (chunk.bridges ?? []).map((b) => b.poly)), lots: flatPolygons((chunk.lots ?? []).map((l) => l.poly), { y: SURFACE_OFFSET, uvScale: 8 }), bridges: extrudePolygons((chunk.bridges ?? []).map((b) => b.poly), diff --git a/src/world/materials.js b/src/world/materials.js index 19d2c1a..43a5600 100644 --- a/src/world/materials.js +++ b/src/world/materials.js @@ -13,11 +13,15 @@ export const TEXTURES = { // Parkplatz im Asphalt der Straßen. Beide lädt createMaterials nicht neu, sondern klont park und carriageway. field: "leafy_grass", parking: "asphalt_02", - paths: "concrete_pavement", // helle Betonplatten, auch für die Gehwege aus Teil 2 gedacht + paths: "concrete_pavement", // helle Betonplatten, seit Teil 2 auch für den Gehweg (sidewalk unten) carriageway: "asphalt_02", lots: "asphalt_02", // Parkplätze und Vorplätze: derselbe Asphalt wie die Fahrbahn curb: "curb", // modular_sidewalk_curb_kit (Just8, CC BY 4.0), s. tools/assets/textures.mjs - sidewalk: "sidewalk", + // Korrektur: sidewalk_Diffuse.jpg aus modular_sidewalk_curb_kit ist keine Betontextur, sondern + // das Platzhalterbild des Kits (roter Schriftzug "Tru-planar Sidewalk texture" auf dunklem + // Grund, im Browser geprüft) - das Kit taugt deshalb nur für den Bordstein. Derselbe Wert wie + // TEXTURES.paths, s. Entwurf Abschnitt "Die beiden Kits". + sidewalk: "concrete_pavement", // Ruling 56: eine Brücke ist in den Daten dasselbe Straßenstück, nur über Wasser — dieselbe // Textur wie die Fahrbahn, sonst zeigt jeder Straße-Brücke-Übergang eine Farbnaht. bridges: "asphalt_02", diff --git a/tests/materials.test.js b/tests/materials.test.js index f5ea8e3..2f40bb6 100644 --- a/tests/materials.test.js +++ b/tests/materials.test.js @@ -105,9 +105,13 @@ describe("Schichten aus Teil 2", () => { expect(MATERIAL_KEYS).not.toContain("roads"); }); - it("nimmt Bordstein und Gehweg aus dem Kit", () => { + it("nimmt den Bordstein aus dem Kit, den Gehweg aus den Betonplatten von Poly Haven", () => { + // Korrektur: sidewalk_Diffuse.jpg aus dem Kit ist ein Platzhalterbild (roter Schriftzug), + // keine Betontextur (im Browser geprüft) - der Gehweg benutzt deshalb denselben Belag wie + // die Parkwege, nicht den Kit-Slug. expect(TEXTURES.curb).toBe("curb"); - expect(TEXTURES.sidewalk).toBe("sidewalk"); + expect(TEXTURES.sidewalk).toBe("concrete_pavement"); + expect(TEXTURES.sidewalk).toBe(TEXTURES.paths); expect(TEXTURES.carriageway).toBe("asphalt_02"); expect(TEXTURES.lots).toBe("asphalt_02"); }); diff --git a/tools/assets/textures.mjs b/tools/assets/textures.mjs index 8b77d40..a0b144c 100644 --- a/tools/assets/textures.mjs +++ b/tools/assets/textures.mjs @@ -24,10 +24,14 @@ for (const slug of SLUGS) { } } -// Bordstein und Gehweg kommen aus modular_sidewalk_curb_kit (Just8, CC BY 4.0). Der Ordner -// gehört dem Nutzer und liegt nicht im Repo — das Skript darf deshalb nicht von ihm abhängen, -// sondern überspringt den Schritt mit einer verständlichen Meldung, wenn er fehlt. Die vier -// erzeugten Dateien sind versioniert, danach braucht niemand mehr den Ordner. +// Der Bordstein kommt aus modular_sidewalk_curb_kit (Just8, CC BY 4.0). Der Ordner gehört dem +// Nutzer und liegt nicht im Repo — das Skript darf deshalb nicht von ihm abhängen, sondern +// überspringt den Schritt mit einer verständlichen Meldung, wenn er fehlt. Die drei erzeugten +// Dateien sind versioniert, danach braucht niemand mehr den Ordner. +// Korrektur: sidewalk_baseColor.jpeg (-> sidewalk_Diffuse.jpg) ist raus. Die Datei war das +// Platzhalterbild des Kits, keine Betontextur (roter Schriftzug "Tru-planar Sidewalk texture", +// im Browser geprüft) - der Gehweg benutzt jetzt concrete_pavement von Poly Haven, s. +// src/world/materials.js. // Über CURB_KIT umstellbar, damit der Fall "Kit fehlt" geprüft werden kann, ohne den Ordner // des Nutzers zu verschieben. const KIT = `${process.env.CURB_KIT ?? "modular_sidewalk_curb_kit"}/textures`; @@ -37,7 +41,6 @@ const KIT_MAPS = [ { from: "CurbMat_baseColor.jpeg", to: "curb_Diffuse.jpg" }, { from: "CurbMat_normal.png", to: "curb_nor_gl.jpg" }, { from: "CurbMat_metallicRoughness.png", to: "curb_arm.jpg" }, - { from: "sidewalk_baseColor.jpeg", to: "sidewalk_Diffuse.jpg" }, ]; async function importCurbKit() { @@ -53,7 +56,7 @@ async function importCurbKit() { continue; } // 1024 wie alle übrigen Texturen: die 2048er des Kits wären für ein 15 cm hohes - // Wandband und einen Gehwegbelag Verschwendung. + // Wandband Verschwendung. await sharp(`${KIT}/${from}`).resize(1024, 1024).jpeg({ quality: 90 }).toFile(target); console.log(`${to} erzeugt`); } diff --git a/tools/extract/run.py b/tools/extract/run.py index da8b520..31b5a7e 100644 --- a/tools/extract/run.py +++ b/tools/extract/run.py @@ -170,7 +170,7 @@ def main() -> None: "attribution": "Kartenkacheln: GTA VI Map (CC BY 4.0) — https://map.gtadb.org, YANIS v15. " "Wahrzeichen: rolux/gtamaplib-vc (Unlicense). " "Flamingo Park: © OpenStreetMap-Mitwirkende (ODbL). " - "Bordstein und Gehweg: Just8 (Sketchfab, CC BY 4.0).", + "Bordstein: Just8 (Sketchfab, CC BY 4.0).", }) print(render_map(OUT, OUT), "->", OUT)