85 lines
2.8 KiB
JavaScript
85 lines
2.8 KiB
JavaScript
import { readFile } from "node:fs/promises";
|
|
import { performance } from "node:perf_hooks";
|
|
import { fileURLToPath } from "node:url";
|
|
import { dirname, resolve } from "node:path";
|
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
import { DoubleSide, Raycaster, Vector3 } from "three";
|
|
|
|
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 visualPath = resolve(
|
|
here,
|
|
"../src/assets/game/dungeons/wailing-caverns/wailing-caverns-visual.glb",
|
|
);
|
|
const bytes = await readFile(visualPath);
|
|
const arrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
const started = performance.now();
|
|
const gltf = await new Promise((resolveLoad, rejectLoad) => {
|
|
new GLTFLoader().parse(arrayBuffer, "", resolveLoad, rejectLoad);
|
|
});
|
|
|
|
let meshes = 0;
|
|
let instancedMeshes = 0;
|
|
let representedInstances = 0;
|
|
gltf.scene.traverse((object) => {
|
|
if (object.isMesh) meshes += 1;
|
|
if (object.isMesh) {
|
|
const materials = Array.isArray(object.material) ? object.material : [object.material];
|
|
for (const material of materials) material.side = DoubleSide;
|
|
}
|
|
if (object.isInstancedMesh) {
|
|
instancedMeshes += 1;
|
|
representedInstances += object.count;
|
|
}
|
|
});
|
|
gltf.scene.updateMatrixWorld(true);
|
|
|
|
const camera = new Vector3(168.4397730700396, -69.7455139484265, 135.3106010044644);
|
|
const lookAt = new Vector3(162.366, -72.29, 132.353);
|
|
const raycaster = new Raycaster(camera, lookAt.clone().sub(camera).normalize(), 0, 115);
|
|
const visibleHits = raycaster.intersectObject(gltf.scene, true).slice(0, 5).map((hit) => ({
|
|
distance: hit.distance,
|
|
object: hit.object.name,
|
|
point: hit.point.toArray(),
|
|
materials: (Array.isArray(hit.object.material) ? hit.object.material : [hit.object.material]).map((material) => ({
|
|
name: material.name,
|
|
color: material.color?.getHexString(),
|
|
opacity: material.opacity,
|
|
transparent: material.transparent,
|
|
alphaTest: material.alphaTest,
|
|
map: material.map?.name ?? null,
|
|
})),
|
|
}));
|
|
|
|
console.log(JSON.stringify({
|
|
parseMs: Math.round(performance.now() - started),
|
|
sceneTransform: {
|
|
position: gltf.scene.position.toArray(),
|
|
quaternion: gltf.scene.quaternion.toArray(),
|
|
scale: gltf.scene.scale.toArray(),
|
|
},
|
|
firstChildTransforms: gltf.scene.children.slice(0, 5).map((child) => ({
|
|
name: child.name,
|
|
position: child.position.toArray(),
|
|
quaternion: child.quaternion.toArray(),
|
|
scale: child.scale.toArray(),
|
|
})),
|
|
sceneChildren: gltf.scene.children.length,
|
|
meshes,
|
|
instancedMeshes,
|
|
representedInstances,
|
|
visibleHits,
|
|
}, null, 2));
|