Files

86 lines
2.7 KiB
JavaScript

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";
import { glassRevealAtHeight as reveal } from "../src/glass-reveal.ts";
import { decryptionFrame } from "../src/decryption.ts";
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;
}
// Subsequent ring changes are covered by check-internal-optics.mjs.
const after = await load("../public/assets/archive-assembly.glb");
let patch,
metal,
engravingDepth = -Infinity;
after.traverse((m) => {
if (!m.isMesh) return;
const name = m.material.name.replace(/\.\d+$/, "");
assert.notEqual(name, "Amber_Lightguide");
const box = new T.Box3().setFromObject(m);
if (name === "Index_Inlay") patch = box;
if (name === "Titanium_Fasteners") metal = m;
if (name.startsWith("Case_") && m.userData.assemblyPart === "cover")
engravingDepth = Math.max(engravingDepth, box.max.z);
});
assert.ok(patch && metal);
assert.ok(Math.abs(patch.max.y - 3.7) < 1e-5, "Patch flush with top");
assert.ok(Math.abs(patch.max.z - 0.206) < 1e-5, "Patch flush with front");
assert.ok(Math.abs(patch.max.x - patch.min.x - 0.25) < 1e-5);
assert.ok(
engravingDepth < 0.174,
"Every frame/boss engraving lies behind front cover",
);
const positions = metal.geometry.attributes.position;
let tr = 0,
bl = 0;
for (let i = 0; i < positions.count; i++) {
const v = new T.Vector3()
.fromBufferAttribute(positions, i)
.applyMatrix4(metal.matrixWorld);
if (v.x > 2.25 && v.y > 3.4) tr++;
else if (v.x < -2.2 && v.y < 0.23) bl++;
else assert.fail("Extra screw outside top-right / bottom-left");
}
assert.ok(tr > 0 && bl > 0);
for (let h = 0; h <= 1; h += 0.01) {
assert.equal(reveal(0, h), 0);
assert.equal(reveal(1, h), 1);
let last = 0;
for (let p = 0; p <= 1; p += 0.01) {
const next = reveal(p, h);
assert.ok(next >= last);
last = next;
}
}
assert.equal(reveal(0.5, 0.9), 1);
assert.equal(reveal(0.5, 0.1), 0);
let last = 0;
for (let t = 38.84; t <= 39.56; t += 0.001) {
const p = decryptionFrame(t).clarity;
assert.ok(p >= last);
last = p;
}
assert.equal(decryptionFrame(38.84).clarity, 0);
assert.equal(decryptionFrame(39.56).clarity, 1);
console.log(
JSON.stringify(
{
passed: true,
screwRegions: 2,
patchSize: patch.getSize(new T.Vector3()).toArray(),
engravingDepth,
reveal: "fully frosted → top to bottom → fully clear",
},
null,
2,
),
);