54 lines
2.0 KiB
TypeScript
54 lines
2.0 KiB
TypeScript
import { expect, it } from "vitest";
|
||
import { DEFAULT_GROUND_COLOR, type SceneSettings } from "../schema/directorProject";
|
||
import { getSceneGroupTransform } from "./sceneTransform";
|
||
|
||
function createScene(patch: Partial<SceneSettings> = {}): SceneSettings {
|
||
return {
|
||
scale: 1,
|
||
position: [0, 0, 0],
|
||
rotation: [0, 0, 0],
|
||
backgroundColor: "#000000",
|
||
panoramaYaw: 0,
|
||
panoramaRadius: 60,
|
||
showLabels: true,
|
||
captureShowGrid: false,
|
||
snapToGrid: false,
|
||
showGround: true,
|
||
groundColor: DEFAULT_GROUND_COLOR,
|
||
groundOpacity: 0.4,
|
||
groundHeight: 0,
|
||
...patch,
|
||
};
|
||
}
|
||
|
||
it("maps the scene scale onto all three axes", () => {
|
||
expect(getSceneGroupTransform(createScene({ scale: 2.5 }))).toEqual({
|
||
position: [0, 0, 0],
|
||
rotation: [0, 0, 0],
|
||
scale: [2.5, 2.5, 2.5],
|
||
});
|
||
});
|
||
|
||
it("converts the scene rotation from degrees to radians for the Three.js group", () => {
|
||
const transform = getSceneGroupTransform(createScene({ position: [1, 3, -2], rotation: [0, 90, 180] }));
|
||
|
||
expect(transform.position).toEqual([1, 3, -2]);
|
||
expect(transform.rotation[0]).toBeCloseTo(0);
|
||
expect(transform.rotation[1]).toBeCloseTo(Math.PI / 2);
|
||
expect(transform.rotation[2]).toBeCloseTo(Math.PI);
|
||
expect(transform.scale).toEqual([1, 1, 1]);
|
||
});
|
||
|
||
it("keeps the ground plane and the viewport grid on the same world height", () => {
|
||
const scene = createScene({ scale: 1.5, position: [0, 2, 0], groundHeight: 1.2 });
|
||
const transform = getSceneGroupTransform(scene);
|
||
const gridElevation = 0.002;
|
||
|
||
// 地面:局部 y = groundHeight;网格:局部 y = groundHeight + 抬升
|
||
// 两者共用同一个场景组 → 世界高度只差 抬升 × 场景缩放,永远不会分叉成两层地面
|
||
const groundWorldY = transform.position[1] + scene.groundHeight * transform.scale[1];
|
||
const gridWorldY = transform.position[1] + (scene.groundHeight + gridElevation) * transform.scale[1];
|
||
|
||
expect(gridWorldY - groundWorldY).toBeCloseTo(gridElevation * scene.scale, 6);
|
||
});
|