feat(timeline): 支持角色轨迹关键帧与轨道拖拽排序

This commit is contained in:
2026-09-17 14:47:29 +08:00
parent 0794486857
commit bab92c05b8
18 changed files with 1862 additions and 135 deletions

View File

@@ -4,6 +4,7 @@ import { afterEach, beforeEach, vi } from "vitest";
import { VIEWPORT_CAMERA_VISUAL_SCALE } from "../schema/cameraGeometry";
import { degreesRotationToRadians } from "../schema/directorProject";
import { createInitialDirectorState, useDirectorStore } from "../store/directorStore";
import { usePlaybackStore } from "../runtime/playbackStore";
import { getImportedModelNormalization, getTrajectoryGroundPoint, SceneRoot } from "./SceneRoot";
import { AXIS_COLORS } from "./sceneAxes";
import { GROUND_GRID_ELEVATION, GROUND_PLANE_SIZE } from "./sceneGround";
@@ -162,6 +163,7 @@ vi.mock("../runtime/CharacterModel", async () => {
beforeEach(() => {
vi.spyOn(console, "error").mockImplementation(() => {});
mockCharacterModelShouldSuspend.current = false;
usePlaybackStore.setState({ isPlaying: false, playhead: 0, duration: 5, editingObjectId: null });
const base = createInitialDirectorState();
useDirectorStore.setState({
...useDirectorStore.getState(),
@@ -678,6 +680,17 @@ it("renders solid trajectory spheres and a smooth curve through the waypoints",
expect(container.querySelectorAll('mesh[name^="trajectory-point-"]')).toHaveLength(2);
});
it("puts a walking character at its trajectory sample for the current playhead", () => {
useDirectorStore.getState().addTrajectoryPoint("char_default_a", [8, 0, 0]);
// 单点轨迹:0s 在角色起始位置,时间轴末尾(5s)到达该轨迹点
usePlaybackStore.setState({ isPlaying: false, playhead: 5, duration: 5, editingObjectId: null });
render(<SceneRoot />);
const characterGroup = screen.getByTestId("mock-character-model").closest("group");
expect(characterGroup).toHaveAttribute("position", "8,0,0");
});
it("shows a translate gizmo on the selected trajectory point so it can be dragged", () => {
useDirectorStore.getState().addTrajectoryPoint("char_default_a", [1, 0, 2]);
const pointId = useDirectorStore