/**
 * 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 {};
