import { BufferAttribute, BufferGeometry, Float32BufferAttribute, Group, Mesh, } from "three"; import { describe, expect, it } from "vitest"; import { preparePartyNavigationGraph } from "./partyNavigationAssetCache"; function navigationScene(): Group { const geometry = new BufferGeometry(); geometry.setAttribute("position", new Float32BufferAttribute([ 0, 0, 0, 2, 0, 0, 0, 0, 2, ], 3)); const scene = new Group(); scene.add(new Mesh(geometry)); return scene; } describe("party navigation asset cache", () => { it("reuses the graph prepared during expedition loading", () => { const first = preparePartyNavigationGraph("/navigation/cache-test.glb", navigationScene(), []); const second = preparePartyNavigationGraph("/navigation/cache-test.glb", new Group(), []); expect(second).toBe(first); expect(first.sourceTriangleCount).toBe(1); }); it("keeps navigation variants with different authored links separate", () => { const first = preparePartyNavigationGraph("/navigation/link-test.glb", navigationScene(), []); const second = preparePartyNavigationGraph("/navigation/link-test.glb", navigationScene(), [{ id: "ledge", start: [0, 0, 0], end: [2, 0, 2], bidirectional: true, authoredReason: "Test link", }]); expect(second).not.toBe(first); }); it("expands normalized quantized positions before baking the node transform", () => { const geometry = new BufferGeometry(); geometry.setAttribute("position", new BufferAttribute(new Int16Array([ 0, 0, 0, 32_767, 0, 0, 0, 0, 32_767, ]), 3, true)); const mesh = new Mesh(geometry); mesh.position.set(10, 2, -5); mesh.scale.setScalar(100); const scene = new Group(); scene.add(mesh); const graph = preparePartyNavigationGraph("/navigation/quantized-transform.glb", scene, []); expect(graph.nodes.map((node) => node.position)).toEqual([ [10, 2, -5], [110, 2, -5], [10, 2, 95], ]); }); });