import * as THREE from "three"; import { computeExplodedWorldOffset, EXPLOSION_PROGRESS_MAX, } from "@/lib/3d/explosion-math"; describe("engine explosion", () => { it("progress 超过 1 时应继续增大爆炸幅度(用于更大最大值)", () => { const v = new THREE.Vector3(10, -20, 30); const offset1 = computeExplodedWorldOffset(v, 1, 0.2); const offset2 = computeExplodedWorldOffset(v, 2, 0.2); const offset3 = computeExplodedWorldOffset(v, 3, 0.2); expect(offset2.x).toBeCloseTo(offset1.x * 2, 5); expect(offset2.y).toBeCloseTo(offset1.y * 2, 5); expect(offset2.z).toBeCloseTo(offset1.z * 2, 5); // 超过最大值应被裁剪到 EXPLOSION_PROGRESS_MAX const offsetMax = computeExplodedWorldOffset(v, EXPLOSION_PROGRESS_MAX, 0.2); expect(offset3.x).toBeCloseTo(offsetMax.x, 5); expect(offset3.y).toBeCloseTo(offsetMax.y, 5); expect(offset3.z).toBeCloseTo(offsetMax.z, 5); }); it("爆炸位移应按相对中心距离同比放大,不能强制整体上抬", () => { const lowerWheel = new THREE.Vector3(0, -100, 0); const lowerBoard = new THREE.Vector3(0, -40, 0); const wheelOffset = computeExplodedWorldOffset(lowerWheel, 1, 0.2); const boardOffset = computeExplodedWorldOffset(lowerBoard, 1, 0.2); expect(wheelOffset.y).toBeLessThan(0); expect(boardOffset.y).toBeLessThan(0); expect(Math.abs(wheelOffset.y)).toBeGreaterThan(Math.abs(boardOffset.y)); }); it("相对中心更远的底部部件,爆炸后仍应保持在更下方", () => { const wheelOriginal = new THREE.Vector3(0, -100, 0); const boardOriginal = new THREE.Vector3(0, -40, 0); const wheelExploded = wheelOriginal .clone() .add(computeExplodedWorldOffset(wheelOriginal, 1, 0.2)); const boardExploded = boardOriginal .clone() .add(computeExplodedWorldOffset(boardOriginal, 1, 0.2)); expect(wheelExploded.y).toBeLessThan(boardExploded.y); }); });