// Lädt die Poly-Haven-Straßenlaterne in 1k (gltf + zugehörige Texturen/`.bin`) nach // public/models/props/raw/ und vereinfacht sie danach mit @gltf-transform/cli zu einer // kompakten .glb unter public/models/props/. Gleiches Muster wie textures.mjs, aber Modelle // stehen unter dem Schlüssel "gltf" statt unter den Map-Namen ("Diffuse", "nor_gl", "arm"), // und die 1k-Auflösung liefert neben der .gltf-Datei selbst noch eine `include`-Liste mit den // referenzierten Texturen und der gemeinsamen `.bin`-Geometriedatei — ohne die kann // gltf-transform die .gltf-Datei nicht öffnen. // // Ruling 61 (Fix-Runde 1): ursprünglich fünf Requisiten (Laterne, Bank, Mülleimer, Hydrant, // Absperrung), aber nur street_lamp_02 hat in den Chunk-Daten eine Platzierungsquelle // (chunk.centerlines) — für die anderen vier gibt es weder ein Feld im Chunk-Schema noch // einen Aufrufer irgendwo im Plan. Sie lagen ungenutzt mit rund 18 MB im Arbeitsverzeichnis // (1,2 MB davon versioniert); erfundene Platzierungsdaten wären reines Raten gewesen (siehe // Bericht). Wieder aufnehmen, sobald eine echte Platzierungsquelle für sie entsteht. import { execFileSync } from "node:child_process"; import { mkdir, writeFile } from "node:fs/promises"; import { dirname, join } from "node:path"; const UA = { "User-Agent": "leonida-assets/0.1 (local hobby project)" }; const SLUGS = ["street_lamp_02"]; const RAW_DIR = "public/models/props/raw"; const OUT_DIR = "public/models/props"; async function fetchTo(url, path) { const buf = Buffer.from(await (await fetch(url, { headers: UA })).arrayBuffer()); await mkdir(dirname(path), { recursive: true }); await writeFile(path, buf); return buf.length; } await mkdir(OUT_DIR, { recursive: true }); for (const slug of SLUGS) { const files = await (await fetch(`https://api.polyhaven.com/files/${slug}`, { headers: UA })).json(); const entry = files.gltf?.["1k"]?.gltf; if (!entry) { console.warn(`${slug}: keine 1k-gltf-Datei gefunden`); continue; } const gltfPath = join(RAW_DIR, slug, `${slug}_1k.gltf`); const gltfSize = await fetchTo(entry.url, gltfPath); console.log(`${slug}_1k.gltf ${(gltfSize / 1e6).toFixed(2)} MB`); for (const [relPath, include] of Object.entries(entry.include ?? {})) { const size = await fetchTo(include.url, join(RAW_DIR, slug, relPath)); console.log(` ${relPath} ${(size / 1e6).toFixed(2)} MB`); } const outPath = join(OUT_DIR, `${slug}.glb`); execFileSync("npx", ["--yes", "@gltf-transform/cli@4.5.0", "optimize", gltfPath, outPath, "--texture-size", "512", "--simplify-error", "0.01", "--compress", "meshopt"], { stdio: "inherit" }); }