Files
healer-man/src/game/paspersShrineNavigationAsset.test.ts
T
2026-08-14 15:56:39 -04:00

41 lines
1.7 KiB
TypeScript

import { NodeIO } from "@gltf-transform/core";
import { BufferAttribute, BufferGeometry } from "three";
import { describe, expect, it } from "vitest";
import {
buildPartyNavigationGraph,
findNearestPartyNavigationSurface,
findPartyNavigationPath,
} from "./partyNavigation";
const PASPERS_ENTRANCE = [-0.181739, 0.349067, -11.472769] as const;
const BLACKHORN_NISORN = [80.518555, 0.448065, -115.173169] as const;
describe("shipping Pasper's Shrine party navigation", () => {
it("routes from the entrance to the first source-authored boss", async () => {
const document = await new NodeIO().read(
"src/assets/game/dungeons/paspers-shrine/paspers-shrine-navigation.glb",
);
const primitive = document.getRoot().listMeshes()[0]?.listPrimitives()[0];
const positions = primitive?.getAttribute("POSITION")?.getArray();
const indices = primitive?.getIndices()?.getArray();
if (!positions || !indices) throw new Error("Pasper navigation asset is not indexed.");
const geometry = new BufferGeometry();
geometry.setAttribute("position", new BufferAttribute(new Float32Array(positions), 3));
geometry.setIndex(new BufferAttribute(new Uint32Array(indices), 1));
const graph = buildPartyNavigationGraph(geometry);
const approach = findNearestPartyNavigationSurface(graph, BLACKHORN_NISORN, 6);
expect(approach?.distance).toBeGreaterThan(5);
expect(approach?.distance).toBeLessThan(6);
const route = findPartyNavigationPath(graph, PASPERS_ENTRANCE, approach!.position, {
maxStartSnapDistance: 3,
maxEndSnapDistance: 5,
simplifyTolerance: 0.01,
});
geometry.dispose();
expect(route).not.toBeNull();
expect(route!.length).toBeGreaterThan(1);
});
});