UNPKG

ecspresso

Version:

A minimal Entity-Component-System library for typescript and javascript.

114 lines (113 loc) 4.12 kB
/** * Camera 3D Plugin for ECSpresso * * Orbit/follow/shake camera controls for a Three.js PerspectiveCamera or * OrthographicCamera managed by renderer3D. Purely resource-based (no camera * entity). The renderer3D `camera` resource is the single camera target. * Orbit via pointer drag + scroll wheel, follow via entity tracking, shake * via trauma-based offsets. * * The plugin's `projection` option must match the underlying camera's kind; * a mismatch throws at init. State is a discriminated union — perspective * cameras expose `fov` / `setFov`, orthographic cameras expose `zoom` / `setZoom`. * * Import from 'ecspresso/plugins/spatial/camera3D' */ import type { SystemPhase } from 'ecspresso'; import type { ComponentsConfig, ResourcesConfig } from '../../type-utils'; import type { Transform3DComponentTypes } from './transform3D'; import type { Renderer3DResourceTypes } from '../rendering/renderer3D'; type Camera3DRequiredConfig = ComponentsConfig<Transform3DComponentTypes> & ResourcesConfig<Renderer3DResourceTypes>; export interface Camera3DFollowOptions { smoothing?: number; offsetX?: number; offsetY?: number; offsetZ?: number; } export interface Camera3DShakeOptions { traumaDecay?: number; maxOffsetX?: number; maxOffsetY?: number; maxOffsetZ?: number; } export interface Camera3DBaseState { targetX: number; targetY: number; targetZ: number; azimuth: number; elevation: number; distance: number; followTarget: number; followSmoothing: number; followOffsetX: number; followOffsetY: number; followOffsetZ: number; trauma: number; shakeOffsetX: number; shakeOffsetY: number; shakeOffsetZ: number; follow(target: number | { id: number; }, options?: Camera3DFollowOptions): void; unfollow(): void; setTarget(x: number, y: number, z: number): void; setOrbit(azimuth: number, elevation: number, distance: number): void; setDistance(distance: number): void; addTrauma(amount: number): void; } export interface PerspectiveCamera3DState extends Camera3DBaseState { projection: 'perspective'; fov: number; setFov(fov: number): void; } export interface OrthographicCamera3DState extends Camera3DBaseState { projection: 'orthographic'; zoom: number; setZoom(zoom: number): void; } export type Camera3DState = PerspectiveCamera3DState | OrthographicCamera3DState; export interface Camera3DResourceTypes { camera3DState: Camera3DState; } export type Camera3DWorldConfig = ResourcesConfig<Camera3DResourceTypes>; export interface Camera3DBasePluginOptions<G extends string = 'camera3d'> { systemGroup?: G; phase?: SystemPhase; azimuth?: number; elevation?: number; distance?: number; target?: { x: number; y: number; z: number; }; minDistance?: number; maxDistance?: number; minElevation?: number; maxElevation?: number; orbitSensitivity?: number; dollySensitivity?: number; enableOrbit?: boolean; follow?: Camera3DFollowOptions; shake?: boolean | Partial<Camera3DShakeOptions>; randomFn?: () => number; } export type Camera3DPluginOptions<G extends string = 'camera3d'> = Camera3DBasePluginOptions<G> & ({ projection?: 'perspective'; fov?: number; } | { projection: 'orthographic'; zoom?: number; }); export type Camera3DLabels = 'camera3d-init' | 'camera3d-follow' | 'camera3d-shake' | 'camera3d-sync'; /** * Convert spherical coordinates to cartesian. Y-up convention (Three.js default). * Azimuth rotates in the XZ plane; elevation goes from XZ plane toward +Y. */ export declare function sphericalToCartesian(azimuth: number, elevation: number, distance: number, out: { x: number; y: number; z: number; }): void; export declare function createCamera3DPlugin<G extends string = 'camera3d'>(options?: Camera3DPluginOptions<G>): import("ecspresso").Plugin<import("ecspresso").WithResources<import("ecspresso").EmptyConfig, Camera3DResourceTypes>, Camera3DRequiredConfig, Camera3DLabels, G, never, never>; export {};