import { NodeIO } from "@gltf-transform/core"; import { prune } from "@gltf-transform/functions"; import { readdir } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; async function findGlbs(directory) { const entries = await readdir(directory, { withFileTypes: true }); const files = await Promise.all(entries.map(async (entry) => { const entryPath = path.join(directory, entry.name); if (entry.isDirectory()) return findGlbs(entryPath); return entry.isFile() && path.extname(entry.name).toLowerCase() === ".glb" ? [entryPath] : []; })); return files.flat(); } const directory = path.resolve( process.argv[2] ?? fileURLToPath(new URL( "../public/assets/equipment/wow335a-v1", import.meta.url, )), ); const io = new NodeIO(); const files = await findGlbs(directory); for (const file of files) { const document = await io.read(file); const root = document.getRoot(); for (const animation of root.listAnimations()) animation.dispose(); for (const node of root.listNodes()) { if (!node.getSkin()) continue; node.setSkin(null); for (const primitive of node.getMesh()?.listPrimitives() ?? []) { primitive.setAttribute("JOINTS_0", null); primitive.setAttribute("WEIGHTS_0", null); } } for (const skin of root.listSkins()) skin.dispose(); await document.transform(prune({ keepAttributes: true, keepIndices: true, keepLeaves: false, })); await io.write(file, document); } console.log(`Sanitized ${files.length} rigid equipment GLBs below ${directory}.`);