import type { AnimGraph, AnimLayer } from "./animGraph.js"; /** A masked, optionally additive overlay layer: a resting clip plus one one-shot state per action. */ export interface ActionLayerInput { /** Layer id; also the prefix of its action state ids (`id:action`). */ id: string; /** * Bone name prefixes this layer drives (`["spine", "chest", "upperarm"]`). Required and nonempty: * an overlay that names no bones would silently drive the whole rig. `UPPER_BODY_MASK` and * `LOWER_BODY_MASK` (`@jgengine/core/anim/skeletonStandard`) cover a standard rig. */ mask: readonly string[]; /** * Clip held while no action plays. On an additive layer this state is held at its first frame, * which `makeClipAdditive` makes the zero reference, so rest contributes nothing to the pose. */ rest: string; /** Trigger name → clip, or clips for a random variant, played once over the rest state. */ actions: Readonly>; /** Add the actions to the base pose instead of replacing the masked bones. Default false. */ additive?: boolean; /** Layer influence `0..1`. Default 1. */ weight?: number; /** Crossfade seconds into and out of an action. Default 0.1. */ fadeSec?: number; /** Normalized time an action must reach before it returns to rest. Default 1. */ exitTime?: number; } /** State id of an action layer's resting state. */ export declare const ACTION_REST_STATE = "rest"; /** * One overlay layer from plain data: a resting state plus a one-shot state per action, each joined * to the rest by a consumed-trigger transition and returning on `exitTime`. Aim, reload, wave and * hit reactions are the same shape, so they are one builder instead of a hand-written state machine * per game. The layer is masked by bone prefix, and `additive: true` makes it a recoil/breathing * overlay on top of the base pose rather than a replacement. * * @capability animation build a masked one-shot overlay layer for upper-body actions and hit reactions */ export declare function actionLayer(input: ActionLayerInput): AnimLayer; /** * A graph plus overlay layers: the base layers keep their ids and order, and each overlay is * appended. Duplicate layer ids are rejected rather than silently shadowing, because the shell keys * its mixer actions by layer id. * * @capability animation attach masked action layers to a locomotion graph */ export declare function withActionLayers(graph: AnimGraph, layers: readonly ActionLayerInput[]): AnimGraph;