Files
healer-man/scripts/audit-creature-glbs.mjs
2026-08-14 15:56:39 -04:00

67 lines
2.2 KiB
JavaScript

import { readdir, readFile } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import { Box3, Vector3 } from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
globalThis.self = globalThis;
globalThis.createImageBitmap = async () => ({ width: 1, height: 1, close() {} });
globalThis.ProgressEvent ??= class ProgressEvent {
constructor(type, init = {}) {
this.type = type;
Object.assign(this, init);
}
};
const here = dirname(fileURLToPath(import.meta.url));
const assetDirectory = resolve(here, "../public/assets/creatures/wailing-caverns");
const files = (await readdir(assetDirectory)).filter((file) => file.endsWith(".glb")).sort();
const reports = [];
for (const file of files) {
const bytes = await readFile(resolve(assetDirectory, file));
const arrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
const gltf = await new Promise((resolveLoad, rejectLoad) => {
new GLTFLoader().parse(arrayBuffer, "", resolveLoad, rejectLoad);
});
gltf.scene.updateMatrixWorld(true);
const bounds = new Box3().setFromObject(gltf.scene);
const size = bounds.getSize(new Vector3());
const materials = [];
const seen = new Set();
let meshes = 0;
let triangles = 0;
gltf.scene.traverse((object) => {
if (!object.isMesh) return;
meshes += 1;
const geometry = object.geometry;
triangles += geometry.index
? geometry.index.count / 3
: (geometry.getAttribute("position")?.count ?? 0) / 3;
const objectMaterials = Array.isArray(object.material) ? object.material : [object.material];
for (const material of objectMaterials) {
if (seen.has(material.uuid)) continue;
seen.add(material.uuid);
materials.push({
name: material.name,
transparent: material.transparent,
opacity: material.opacity,
alphaTest: material.alphaTest,
depthWrite: material.depthWrite,
side: material.side,
});
}
});
reports.push({
file,
meshes,
triangles,
bounds: { min: bounds.min.toArray(), max: bounds.max.toArray(), size: size.toArray() },
materials,
});
}
console.log(JSON.stringify(reports, null, 2));