Files
ttstd-3d-director/src/editor/canvas/viewportCaptureLabels.test.ts

69 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Group, Scene } from "three";
import { beforeEach, describe, expect, it } from "vitest";
import type { DirectorObject } from "../schema/directorProject";
import { createDefaultDirectorProject, useDirectorStore } from "../store/directorStore";
import { getViewportCaptureLabels } from "./DirectorCanvas";
describe("getViewportCaptureLabels", () => {
beforeEach(() => {
useDirectorStore.getState().replaceProject(createDefaultDirectorProject());
});
it("places each label at the character's real scene position, not its static transform (0,0,0)", () => {
const project = createDefaultDirectorProject();
const characters = project.objects.filter((o): o is DirectorObject => o.kind === "character");
expect(characters.length).toBeGreaterThan(0);
// 把所有角色静态 transform 摆到原点,但在场景里把它们挪到别处 ——
// 截图标签必须贴着「场景里真实的位置」,而不是落回 0 点坐标。
const scene = new Scene();
const nameToPosition = new Map<string, [number, number, number]>();
characters.forEach((item, index) => {
const group = new Group();
group.userData.directorObjectId = item.id;
const position: [number, number, number] = [10 + index, 0.5, 20 + index];
group.position.set(position[0], position[1], position[2]);
scene.add(group);
nameToPosition.set(item.name, position);
item.transform.position = [0, 0, 0];
});
useDirectorStore.getState().replaceProject(project);
const labels = getViewportCaptureLabels(scene);
expect(labels.length).toBe(characters.length);
for (const label of labels) {
const expected = nameToPosition.get(label.text);
expect(expected).toBeTruthy();
// 用 x / z 验证:若误用静态 transform(原点),这里会是 0
expect(label.worldPosition.x).toBeCloseTo(expected![0], 5);
expect(label.worldPosition.z).toBeCloseTo(expected![2], 5);
// y 在角色头部高度(基础 y + 标签高度),应高于场景里摆放的 y
expect(label.worldPosition.y).toBeGreaterThan(expected![1]);
}
});
it("returns nothing when scene.showLabels is off", () => {
const project = createDefaultDirectorProject();
project.scene.showLabels = false;
useDirectorStore.getState().replaceProject(project);
expect(getViewportCaptureLabels(new Scene())).toEqual([]);
});
});
describe("captureShowGrid setting", () => {
beforeEach(() => {
useDirectorStore.getState().replaceProject(createDefaultDirectorProject());
});
it("defaults to false (grid hidden during capture) and toggles", () => {
expect(useDirectorStore.getState().project.scene.captureShowGrid).toBe(false);
useDirectorStore.getState().updateScene({ captureShowGrid: true });
expect(useDirectorStore.getState().project.scene.captureShowGrid).toBe(true);
});
});