// Lädt die benötigten Poly-Haven-Texturen in 1k nach public/textures/. Vorhandene Dateien bleiben // unangetastet, damit ein neuer Eintrag die übrigen Texturen nicht still ändert. import { existsSync } from "node:fs"; import { mkdir, writeFile } from "node:fs/promises"; import sharp from "sharp"; const UA = { "User-Agent": "leonida-assets/0.1 (local hobby project)" }; const SLUGS = ["asphalt_02", "concrete_pavement_03", "white_stucco", "sand_01", "leafy_grass", "grass_path_2", "palm_bark", "concrete_pavement"]; const MAPS = ["Diffuse", "nor_gl", "arm"]; await mkdir("public/textures", { recursive: true }); for (const slug of SLUGS) { if (MAPS.every((map) => existsSync(`public/textures/${slug}_${map}.jpg`))) continue; const files = await (await fetch(`https://api.polyhaven.com/files/${slug}`, { headers: UA })).json(); for (const map of MAPS) { const target = `public/textures/${slug}_${map}.jpg`; if (existsSync(target)) continue; const entry = files[map]?.["1k"]?.jpg; if (!entry) { console.warn(`${slug}: ${map} fehlt`); continue; } const buf = Buffer.from(await (await fetch(entry.url, { headers: UA })).arrayBuffer()); await writeFile(target, buf); console.log(`${slug}_${map}.jpg ${(buf.length / 1e6).toFixed(1)} MB`); } } // 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`; const KIT_MAPS = [ // glTF packt Rauheit nach G und Metall nach B — dasselbe Schema wie die arm-Karten von // Poly Haven, deshalb ist die metallicRoughness-Karte hier direkt das arm-Ziel. { 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" }, ]; async function importCurbKit() { if (!existsSync(KIT)) { console.log(`${KIT} fehlt — Bordstein-Texturen übersprungen. Das Kit gehört dem Nutzer ` + "und ist nicht im Repo; die erzeugten Dateien liegen bereits unter public/textures."); return; } for (const { from, to } of KIT_MAPS) { const target = `public/textures/${to}`; if (existsSync(target)) { console.log(`${to} ist schon da`); continue; } // 1024 wie alle übrigen Texturen: die 2048er des Kits wären für ein 15 cm hohes // Wandband Verschwendung. await sharp(`${KIT}/${from}`).resize(1024, 1024).jpeg({ quality: 90 }).toFile(target); console.log(`${to} erzeugt`); } } await importCurbKit();