67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { createBoxBrush } from "../../src/document/brushes";
|
|
import { createEmptySceneDocument } from "../../src/document/scene-document";
|
|
import { createPlayerStartEntity } from "../../src/entities/entity-instances";
|
|
import { RapierCollisionWorld } from "../../src/runtime-three/rapier-collision-world";
|
|
import { buildRuntimeSceneFromDocument } from "../../src/runtime-three/runtime-scene-build";
|
|
|
|
describe("RapierCollisionWorld", () => {
|
|
it("clamps a third-person camera boom before it clips through world geometry", async () => {
|
|
const wall = createBoxBrush({
|
|
id: "brush-third-person-camera-wall",
|
|
center: {
|
|
x: 0,
|
|
y: 1.5,
|
|
z: -2.25
|
|
},
|
|
size: {
|
|
x: 6,
|
|
y: 3,
|
|
z: 0.5
|
|
}
|
|
});
|
|
const playerStart = createPlayerStartEntity({
|
|
id: "entity-player-start-third-person",
|
|
navigationMode: "thirdPerson"
|
|
});
|
|
const runtimeScene = buildRuntimeSceneFromDocument({
|
|
...createEmptySceneDocument({ name: "Third Person Camera Collision" }),
|
|
brushes: {
|
|
[wall.id]: wall
|
|
},
|
|
entities: {
|
|
[playerStart.id]: playerStart
|
|
}
|
|
});
|
|
const collisionWorld = await RapierCollisionWorld.create(
|
|
runtimeScene.colliders,
|
|
runtimeScene.playerCollider
|
|
);
|
|
|
|
try {
|
|
const desiredCameraPosition = {
|
|
x: 0,
|
|
y: 1.5,
|
|
z: -4
|
|
};
|
|
const resolvedCameraPosition =
|
|
collisionWorld.resolveThirdPersonCameraCollision(
|
|
{
|
|
x: 0,
|
|
y: 1.5,
|
|
z: 0
|
|
},
|
|
desiredCameraPosition,
|
|
0.2
|
|
);
|
|
|
|
expect(resolvedCameraPosition.z).toBeGreaterThan(desiredCameraPosition.z);
|
|
expect(resolvedCameraPosition.z).toBeGreaterThan(-2.05);
|
|
expect(resolvedCameraPosition.z).toBeLessThan(-1.6);
|
|
} finally {
|
|
collisionWorld.dispose();
|
|
}
|
|
});
|
|
});
|