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