Remove orbit-visitor-navigation-controller
This commit is contained in:
@@ -1,184 +0,0 @@
|
||||
import { Vector3 } from "three";
|
||||
|
||||
import type { Vec3 } from "../core/vector";
|
||||
|
||||
import type {
|
||||
NavigationControllerDeactivateOptions,
|
||||
NavigationController,
|
||||
RuntimeControllerContext
|
||||
} from "./navigation-controller";
|
||||
|
||||
const MIN_DISTANCE = 2;
|
||||
const MAX_DISTANCE = 48;
|
||||
const MIN_PITCH = 0.15;
|
||||
const MAX_PITCH = Math.PI * 0.48;
|
||||
|
||||
function clampDistance(distance: number): number {
|
||||
return Math.max(MIN_DISTANCE, Math.min(MAX_DISTANCE, distance));
|
||||
}
|
||||
|
||||
function clampPitch(pitchRadians: number): number {
|
||||
return Math.max(MIN_PITCH, Math.min(MAX_PITCH, pitchRadians));
|
||||
}
|
||||
|
||||
function cloneVec3(vector: Vec3): Vec3 {
|
||||
return {
|
||||
x: vector.x,
|
||||
y: vector.y,
|
||||
z: vector.z
|
||||
};
|
||||
}
|
||||
|
||||
export class OrbitVisitorNavigationController implements NavigationController {
|
||||
readonly id = "orbitVisitor" as const;
|
||||
|
||||
private context: RuntimeControllerContext | null = null;
|
||||
private readonly lookAtVector = new Vector3();
|
||||
private target: Vec3 = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
private distance = 8;
|
||||
private yawRadians = Math.PI * 0.25;
|
||||
private pitchRadians = Math.PI * 0.35;
|
||||
private dragging = false;
|
||||
private lastPointerClientX = 0;
|
||||
private lastPointerClientY = 0;
|
||||
private initializedFromScene = false;
|
||||
|
||||
activate(ctx: RuntimeControllerContext): void {
|
||||
this.context = ctx;
|
||||
|
||||
if (!this.initializedFromScene) {
|
||||
const runtimeScene = ctx.getRuntimeScene();
|
||||
const focusPoint =
|
||||
runtimeScene.playerStart?.position ??
|
||||
runtimeScene.sceneBounds?.center ??
|
||||
this.target;
|
||||
const focusDistance = runtimeScene.sceneBounds
|
||||
? Math.max(
|
||||
runtimeScene.sceneBounds.size.x,
|
||||
runtimeScene.sceneBounds.size.y,
|
||||
runtimeScene.sceneBounds.size.z
|
||||
) * 1.1
|
||||
: 8;
|
||||
|
||||
this.target = cloneVec3(focusPoint);
|
||||
this.distance = clampDistance(focusDistance);
|
||||
this.initializedFromScene = true;
|
||||
}
|
||||
|
||||
ctx.domElement.addEventListener("pointerdown", this.handlePointerDown);
|
||||
ctx.domElement.addEventListener("wheel", this.handleWheel, {
|
||||
passive: false
|
||||
});
|
||||
ctx.domElement.addEventListener("contextmenu", this.handleContextMenu);
|
||||
window.addEventListener("pointermove", this.handlePointerMove);
|
||||
window.addEventListener("pointerup", this.handlePointerUp);
|
||||
|
||||
ctx.setRuntimeMessage(
|
||||
"Orbit Visitor active. Drag to orbit around the scene and use the mouse wheel to zoom."
|
||||
);
|
||||
ctx.setFirstPersonTelemetry(null);
|
||||
this.updateCameraTransform();
|
||||
}
|
||||
|
||||
deactivate(
|
||||
ctx: RuntimeControllerContext,
|
||||
_options: NavigationControllerDeactivateOptions = {}
|
||||
): void {
|
||||
void _options;
|
||||
ctx.domElement.removeEventListener("pointerdown", this.handlePointerDown);
|
||||
ctx.domElement.removeEventListener("wheel", this.handleWheel);
|
||||
ctx.domElement.removeEventListener("contextmenu", this.handleContextMenu);
|
||||
window.removeEventListener("pointermove", this.handlePointerMove);
|
||||
window.removeEventListener("pointerup", this.handlePointerUp);
|
||||
ctx.setRuntimeMessage(null);
|
||||
this.dragging = false;
|
||||
this.context = null;
|
||||
}
|
||||
|
||||
resetSceneState(): void {
|
||||
this.target = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
this.distance = 8;
|
||||
this.yawRadians = Math.PI * 0.25;
|
||||
this.pitchRadians = Math.PI * 0.35;
|
||||
this.dragging = false;
|
||||
this.lastPointerClientX = 0;
|
||||
this.lastPointerClientY = 0;
|
||||
this.initializedFromScene = false;
|
||||
}
|
||||
|
||||
update(_dt: number): void {
|
||||
void _dt;
|
||||
this.updateCameraTransform();
|
||||
}
|
||||
|
||||
setFocusPoint(target: Vec3): void {
|
||||
this.target = cloneVec3(target);
|
||||
this.updateCameraTransform();
|
||||
}
|
||||
|
||||
private updateCameraTransform() {
|
||||
if (this.context === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const horizontalDistance = Math.cos(this.pitchRadians) * this.distance;
|
||||
const cameraPosition = {
|
||||
x: this.target.x + Math.sin(this.yawRadians) * horizontalDistance,
|
||||
y: this.target.y + Math.sin(this.pitchRadians) * this.distance,
|
||||
z: this.target.z + Math.cos(this.yawRadians) * horizontalDistance
|
||||
};
|
||||
|
||||
this.context.camera.position.set(
|
||||
cameraPosition.x,
|
||||
cameraPosition.y,
|
||||
cameraPosition.z
|
||||
);
|
||||
this.lookAtVector.set(this.target.x, this.target.y, this.target.z);
|
||||
this.context.camera.lookAt(this.lookAtVector);
|
||||
}
|
||||
|
||||
private handlePointerDown = (event: PointerEvent) => {
|
||||
if (event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dragging = true;
|
||||
this.lastPointerClientX = event.clientX;
|
||||
this.lastPointerClientY = event.clientY;
|
||||
};
|
||||
|
||||
private handlePointerMove = (event: PointerEvent) => {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
const deltaX = event.clientX - this.lastPointerClientX;
|
||||
const deltaY = event.clientY - this.lastPointerClientY;
|
||||
this.lastPointerClientX = event.clientX;
|
||||
this.lastPointerClientY = event.clientY;
|
||||
|
||||
this.yawRadians -= deltaX * 0.008;
|
||||
this.pitchRadians = clampPitch(this.pitchRadians + deltaY * 0.008);
|
||||
};
|
||||
|
||||
private handlePointerUp = () => {
|
||||
this.dragging = false;
|
||||
};
|
||||
|
||||
private handleWheel = (event: WheelEvent) => {
|
||||
event.preventDefault();
|
||||
this.distance = clampDistance(this.distance + event.deltaY * 0.01);
|
||||
};
|
||||
|
||||
private handleContextMenu = (event: MouseEvent) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user