import assert from "node:assert/strict"; import {readFile} from "node:fs/promises"; import * as T from "three"; import {GLTFLoader} from "three/addons/loaders/GLTFLoader.js"; async function load(path) { const b=await readFile(new URL(path,import.meta.url)); const s=(await new GLTFLoader().parseAsync(b.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength),"")).scene; s.updateMatrixWorld(true);return s; } const [chosen,previous,current]=await Promise.all([ load("../reference/internal-study/assembly-before.glb"), load("../reference/ring-study/assembly-before.glb"), load("../public/assets/archive-assembly.glb"), ]); function collect(scene,interior) { const result=new Map(); scene.traverse(m=>{ if(!m.isMesh)return; const isInterior=["optical-core","optical-lenses"].includes(m.userData.assemblyPart); if(isInterior!==interior)return; const p=m.geometry.attributes.position,n=m.geometry.attributes.normal,nm=new T.Matrix3().getNormalMatrix(m.matrixWorld),rows=[]; for(let i=0;i