91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
import { PerspectiveCamera } from "three";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import { createEmptySceneDocument } from "../../src/document/scene-document";
|
|
import { createPlayerStartEntity } from "../../src/entities/entity-instances";
|
|
import { buildRuntimeSceneFromDocument } from "../../src/runtime-three/runtime-scene-build";
|
|
import { FirstPersonNavigationController } from "../../src/runtime-three/first-person-navigation-controller";
|
|
|
|
function createRuntimeControllerContext() {
|
|
const runtimeScene = buildRuntimeSceneFromDocument(
|
|
{
|
|
...createEmptySceneDocument({ name: "Pointer Lock Scene" }),
|
|
entities: {
|
|
"entity-player-start-main": createPlayerStartEntity({
|
|
id: "entity-player-start-main"
|
|
})
|
|
}
|
|
},
|
|
{
|
|
navigationMode: "firstPerson"
|
|
}
|
|
);
|
|
const domElement = document.createElement("canvas");
|
|
|
|
return {
|
|
domElement,
|
|
context: {
|
|
camera: new PerspectiveCamera(70, 1, 0.05, 1000),
|
|
domElement,
|
|
getRuntimeScene: () => runtimeScene,
|
|
resolveFirstPersonMotion: () => null,
|
|
resolvePlayerVolumeState: () => ({
|
|
inWater: false,
|
|
inFog: false
|
|
}),
|
|
setRuntimeMessage: vi.fn(),
|
|
setFirstPersonTelemetry: vi.fn()
|
|
}
|
|
};
|
|
}
|
|
|
|
describe("FirstPersonNavigationController", () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("can deactivate during a scene transition without releasing pointer lock", () => {
|
|
const { context, domElement } = createRuntimeControllerContext();
|
|
const controller = new FirstPersonNavigationController();
|
|
const exitPointerLockSpy = vi.fn();
|
|
|
|
Object.defineProperty(document, "exitPointerLock", {
|
|
configurable: true,
|
|
value: exitPointerLockSpy
|
|
});
|
|
|
|
Object.defineProperty(document, "pointerLockElement", {
|
|
configurable: true,
|
|
get: () => domElement
|
|
});
|
|
|
|
controller.activate(context);
|
|
controller.deactivate(context, {
|
|
releasePointerLock: false
|
|
});
|
|
|
|
expect(exitPointerLockSpy).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("still releases pointer lock for a normal deactivation", () => {
|
|
const { context, domElement } = createRuntimeControllerContext();
|
|
const controller = new FirstPersonNavigationController();
|
|
const exitPointerLockSpy = vi.fn();
|
|
|
|
Object.defineProperty(document, "exitPointerLock", {
|
|
configurable: true,
|
|
value: exitPointerLockSpy
|
|
});
|
|
|
|
Object.defineProperty(document, "pointerLockElement", {
|
|
configurable: true,
|
|
get: () => domElement
|
|
});
|
|
|
|
controller.activate(context);
|
|
controller.deactivate(context);
|
|
|
|
expect(exitPointerLockSpy).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|