Files
webeditor3d/src/runtime-three/navigation-controller.ts

178 lines
4.4 KiB
TypeScript

import type { PerspectiveCamera } from "three";
import type { Vec3 } from "../core/vector";
import type {
FirstPersonPlayerShape,
PlayerGroundProbeResult,
ResolvedPlayerMotion
} from "./player-collision";
import type {
RuntimeNavigationMode,
RuntimePlayerMovement,
RuntimeSceneDefinition,
RuntimeSpawnPoint
} from "./runtime-scene-build";
export interface RuntimeMovementTransitionSignals {
jumpStarted: boolean;
leftGround: boolean;
startedFalling: boolean;
landed: boolean;
enteredWater: boolean;
exitedWater: boolean;
wallContactStarted: boolean;
headBump: boolean;
}
export interface RuntimePlayerCameraHookState {
jumping: boolean;
falling: boolean;
landing: boolean;
swimming: boolean;
underwaterAmount: number;
}
export interface RuntimePlayerAudioHookState {
underwaterAmount: number;
enteredWater: boolean;
exitedWater: boolean;
}
export interface RuntimePlayerAnimationHookState {
locomotionMode: RuntimeLocomotionMode;
airborneKind: RuntimeAirborneKind;
gait: RuntimeLocomotionGait;
moving: boolean;
movementAmount: number;
grounded: boolean;
crouched: boolean;
sprinting: boolean;
inWater: boolean;
signals: RuntimeMovementTransitionSignals;
}
export interface RuntimePlayerMovementHooks {
camera: RuntimePlayerCameraHookState;
audio: RuntimePlayerAudioHookState;
animation: RuntimePlayerAnimationHookState;
}
export interface PlayerControllerTelemetry {
feetPosition: Vec3;
eyePosition: Vec3;
yawDegrees: number;
grounded: boolean;
locomotionState: RuntimeLocomotionState;
movement: RuntimePlayerMovement;
inWaterVolume: boolean;
cameraSubmerged: boolean;
inFogVolume: boolean;
pointerLocked: boolean;
spawn: RuntimeSpawnPoint;
signals: RuntimeMovementTransitionSignals;
hooks: RuntimePlayerMovementHooks;
}
export type FirstPersonTelemetry = PlayerControllerTelemetry;
export type RuntimeLocomotionMode =
| "grounded"
| "airborne"
| "flying"
| "swimming"
| "diving";
export type RuntimeAirborneKind = "jumping" | "falling" | null;
export type RuntimeLocomotionGait =
| "idle"
| "walk"
| "sprint"
| "crouch";
export interface RuntimeLocomotionContactState {
collisionCount: number;
collidedAxes: {
x: boolean;
y: boolean;
z: boolean;
};
groundNormal: Vec3 | null;
groundDistance: number | null;
slopeDegrees: number | null;
}
export interface RuntimeLocomotionState {
locomotionMode: RuntimeLocomotionMode;
airborneKind: RuntimeAirborneKind;
gait: RuntimeLocomotionGait;
grounded: boolean;
crouched: boolean;
sprinting: boolean;
inputMagnitude: number;
requestedPlanarSpeed: number;
planarSpeed: number;
verticalVelocity: number;
contact: RuntimeLocomotionContactState;
}
export interface RuntimePlayerVolumeState {
inWater: boolean;
inFog: boolean;
waterSurfaceHeight: number | null;
}
export interface RuntimeThirdPersonTargetAssist {
targetPosition: Vec3;
strength: number;
}
export interface RuntimeControllerContext {
camera: PerspectiveCamera;
domElement: HTMLCanvasElement;
getRuntimeScene(): RuntimeSceneDefinition;
resolveFirstPersonMotion(
feetPosition: Vec3,
motion: Vec3,
shape: FirstPersonPlayerShape
): ResolvedPlayerMotion | null;
probePlayerGround(
feetPosition: Vec3,
shape: FirstPersonPlayerShape,
maxDistance: number
): PlayerGroundProbeResult;
canOccupyPlayerShape(
feetPosition: Vec3,
shape: FirstPersonPlayerShape
): boolean;
resolvePlayerVolumeState(feetPosition: Vec3): RuntimePlayerVolumeState;
resolveThirdPersonCameraCollision(
pivot: Vec3,
desiredCameraPosition: Vec3,
radius: number
): Vec3;
resolveThirdPersonTargetAssist?(): RuntimeThirdPersonTargetAssist | null;
handleRuntimeTargetLookInput?(horizontalIntent: -1 | 0 | 1): boolean;
isCameraDrivenExternally(): boolean;
getCameraYawRadians(): number;
isInputSuspended(): boolean;
setRuntimeMessage(message: string | null): void;
setPlayerControllerTelemetry(
telemetry: PlayerControllerTelemetry | null
): void;
}
export interface NavigationControllerDeactivateOptions {
releasePointerLock?: boolean;
}
export interface NavigationController {
id: RuntimeNavigationMode;
activate(ctx: RuntimeControllerContext): void;
deactivate(
ctx: RuntimeControllerContext,
options?: NavigationControllerDeactivateOptions
): void;
resetSceneState(): void;
update(dt: number): void;
}