import type { WeaponHandlingFrame } from "./weaponHandling.js"; /** Camera-space position `[x, y, z]` in metres: `+x` right, `+y` up, `-z` forward. */ export type ViewmodelOffset = readonly [number, number, number]; /** * How one weapon sits in first person. Offsets are camera-space metres, angles are radians, FOVs are * degrees. Every field is optional; two weapons differ by the ones they set. */ export interface WeaponPresentationTuning { /** Viewmodel anchor at the hip (default `[0.34, -0.26, -0.72]`). */ hip?: ViewmodelOffset; /** Viewmodel anchor fully aimed; put the sight on the camera axis (default `[0, -0.07, -0.55]`). */ ads?: ViewmodelOffset; /** Viewmodel FOV in degrees, independent of the world FOV; omit to draw the viewmodel at the world FOV. */ viewmodelFov?: { hip?: number; ads?: number; }; /** World FOV multiplier at full ADS, e.g. `0.8` for a light zoom (default `1`). */ adsZoom?: number; /** Viewmodel lag behind look motion. */ sway?: { /** Radians of lag per rad/s of look speed (default `0.02`). */ perRadPerSec?: number; /** Largest lag, rad (default `0.08`). */ max?: number; /** How fast lag follows its target, 1/s (default `12`). */ response?: number; /** Lag multiplier at full ADS (default `0.3`). */ adsScale?: number; }; /** Walk bob driven by the movement probe's speed and `bobPhase`. */ bob?: { /** Side and vertical amplitude in metres at `fullSpeed` (default `[0.012, 0.01]`). */ amplitude?: readonly [number, number]; /** Ground speed that gives the full amplitude, m/s (default `4`). */ fullSpeed?: number; /** Bob multiplier at full ADS (default `0.25`). */ adsScale?: number; }; /** Viewmodel reaction to the handling's recoil offset. */ kick?: { /** Metres pushed back per radian of recoil (default `1.2`). */ back?: number; /** Viewmodel muzzle rise per radian of recoil (default `1.5`). */ rise?: number; }; } /** One frame of inputs: look motion, the movement probe, and the weapon's handling readout. */ export interface WeaponPresentationInput { /** Look yaw speed, rad/s, positive turning left (the same sign as a camera yaw that grows left). */ lookYawRate: number; /** Look pitch speed, rad/s, positive looking up. */ lookPitchRate: number; /** Horizontal ground speed, m/s (e.g. `EntityRenderCues.speed`). */ speed: number; /** `0..1` walk-cycle phase (e.g. `EntityRenderCues.bobPhase`). */ bobPhase: number; handling: WeaponHandlingFrame; } /** * Where the viewmodel and camera go this frame. First person applies all of it; third person and * over-the-shoulder read `lookPitch`/`lookYaw`, `aimPitch`/`aimYaw` and `adsProgress` from the same frame. */ export interface WeaponPose { /** Viewmodel anchor, camera-space metres. */ offset: [number, number, number]; /** Viewmodel rotation about its anchor, rad: `pitch > 0` muzzle up, `yaw > 0` muzzle left, `roll > 0` tilts left. */ pitch: number; yaw: number; roll: number; /** Viewmodel FOV in degrees, or `null` to use the world FOV. */ viewmodelFov: number | null; /** Multiplier for the world FOV (ADS zoom). */ fovScale: number; /** Offset to add to the camera look, rad: aim kick plus view punch. `lookYaw > 0` pulls right. */ lookPitch: number; lookYaw: number; /** Offset shots follow, rad; a third-person rig or upper-body aim reads this. */ aimPitch: number; aimYaw: number; /** `0` hip … `1` fully aimed. */ adsProgress: number; } /** Serializable presentation state: the current sway lag. */ export interface WeaponPresentationState { swayPitch: number; swayYaw: number; } /** Turns a {@link WeaponHandlingFrame} plus look and movement into a viewmodel and camera pose. */ export interface WeaponPresentation { /** Advance sway by `dt` and return the pose. The returned object is reused between calls. */ update(dt: number, input: WeaponPresentationInput): WeaponPose; pose(): WeaponPose; retune(next: WeaponPresentationTuning): void; snapshot(): WeaponPresentationState; restore(state: WeaponPresentationState): void; reset(): void; } /** Default hip anchor, matching the shell's built-in viewmodel. */ export declare const DEFAULT_VIEWMODEL_HIP: ViewmodelOffset; /** Default ADS anchor: the built-in viewmodel's top rail on the camera axis. */ export declare const DEFAULT_VIEWMODEL_ADS: ViewmodelOffset; /** * Creates a {@link WeaponPresentation}: per-weapon viewmodel offset, ADS pose and viewmodel FOV, sway * and inertia from look speed, bob from the movement probe, and a recoil kick, all driven by the same * handling frame third-person and over-the-shoulder rigs read. Deterministic and allocation-free per update. * @capability weapon-presentation per-weapon viewmodel offset, ADS pose, viewmodel FOV, sway, bob and recoil kick from a weapon handling frame */ export declare function createWeaponPresentation(initial?: WeaponPresentationTuning): WeaponPresentation; /** * Scale for a viewmodel drawn at `viewmodelFov` through a camera at `worldFov` (both degrees): multiply * the viewmodel's camera-space x and y by this and it projects as if rendered with its own FOV, without * a second camera or render pass. */ export declare function viewmodelFovScale(worldFov: number, viewmodelFov: number): number;