fix: 优化空格播放和截图角色标签对不上

This commit is contained in:
2026-09-17 19:39:24 +08:00
parent 8d67f17a84
commit e66e3374bf
19 changed files with 633 additions and 58 deletions

View File

@@ -0,0 +1,68 @@
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);
});
});