ecspresso
Version:
A minimal Entity-Component-System library for typescript and javascript.
114 lines (113 loc) • 4.12 kB
TypeScript
/**
* 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 {};