/** * The engine's one humanoid skeleton standard, and the path any other CC0 rig takes onto it. * * The standard is the **KayKit character rig**: one armature shared by every rigged character in * `kaykit-adventurers` (Barbarian, Knight, Mage, Rogue, Rogue_Hooded) and `kaykit-skeletons` * (Skeleton_Mage/Minion/Rogue/Warrior). Because they share it, all nine characters play the same * clip set and one authored graph, foot-IK rig, attachment slot or ragdoll layout serves all of * them. There is no second standard to keep in sync. * * A rig on a different scheme (Quaternius aliens, Mixamo exports) is not rewritten: its bones are * *mapped* slot by slot onto the standard's names, and what it does not have is reported rather * than guessed. A rig missing every leg slot can still be driven on its spine and head; a rig * missing a slot never silently borrows a neighbour's bone. */ /** * One canonical bone on the standard. Names are the authored names in the KayKit armature; the * loaded runtime name drops `.` (see {@link runtimeBoneName}), so `upperleg.l` is `upperlegl` in * the scene graph and both spellings resolve through `resolveRigNode`. */ export type SkeletonSlot = "root" | "hips" | "spine" | "chest" | "head" | "upperArm.l" | "upperArm.r" | "lowerArm.l" | "lowerArm.r" | "hand.l" | "hand.r" | "handSlot.l" | "handSlot.r" | "upperLeg.l" | "upperLeg.r" | "lowerLeg.l" | "lowerLeg.r" | "foot.l" | "foot.r" | "toes.l" | "toes.r"; /** Every standard slot, in parent-before-child order. */ export declare const SKELETON_SLOTS: readonly SkeletonSlot[]; /** The parent slot of each slot that has one; `root` has none. */ export declare const SKELETON_PARENT: Readonly>>; /** A named skeleton standard: its id and the authored bone name for each slot it defines. */ export interface SkeletonStandard { id: string; label: string; slots: Readonly>>; } /** * The one humanoid skeleton standard. Bone names are the authored KayKit names; the loaded * hierarchy spells them without `.` and `resolveRigNode` accepts either. * * @capability skeleton-standard the shared humanoid bone standard every rigged character maps onto */ export declare const SKELETON_STANDARD: SkeletonStandard; /** * A source naming scheme and the bone names on it that fill each standard slot. A slot lists every * accepted spelling; matching is case- and punctuation-insensitive, so `mixamorigLeftUpLeg` and * `LeftUpLeg` are the same candidate. */ export interface RigScheme { id: string; label: string; /** Where the scheme comes from, for credits and diagnostics. */ source: string; slots: Readonly>>; } /** * The standard itself, as a scheme: a KayKit rig already is the standard, so its own names are the * candidates. Both authored (`upperleg.l`) and runtime (`upperlegl`) spellings are accepted. * * @capability skeleton-standard map a rig on the standard scheme onto the standard's slots */ export declare const KAYKIT_SCHEME: RigScheme; /** * Mixamo exports (`mixamorig*` names, or the same names without the prefix). Mixamo has a neck and * a shoulder per side, which the standard folds into `chest` and `upperArm`; its toe is * `ToeBase`, which is the standard's `toes`. Mixamo's topmost bone is `Hips`, so `root` and `hips` * both resolve to it — a rig on this scheme has no bone above the pelvis. */ export declare const MIXAMO_SCHEME: RigScheme; /** * Quaternius sci-fi aliens: a `Root` plus a `Spine_1..Spine_6` chain, a `Neck` and a `Head`. The * pack ships no arms and no legs, so those slots stay empty and the alien can only be driven on * its spine and head. That is the honest mapping: the pack's own clip set is `Alien_Idle` alone. */ export declare const QUATERNIUS_ALIEN_SCHEME: RigScheme; /** Every scheme the engine ships a mapping for, keyed by {@link RigScheme.id}. */ export declare const RIG_SCHEMES: Readonly>; /** * The runtime name GLTFLoader gives an authored bone name: three's `PropertyBinding.sanitizeNodeName` * strips `[ ] . : /`, so the authored `upperleg.l` loads as `upperlegl`. * * @capability skeleton-standard convert an authored bone name to its loaded runtime name */ export declare function runtimeBoneName(authored: string): string; /** The result of mapping a rig's bones onto {@link SKELETON_STANDARD}. */ export interface SkeletonMap { /** Scheme the map was built from. */ scheme: string; /** Standard slot → the bone name on this rig that fills it. */ slots: Partial>; /** Slots the standard defines that this rig has no bone for. */ missing: SkeletonSlot[]; /** Bones on the rig that fill no standard slot (helpers, props, IK targets). */ unmapped: string[]; } /** * Maps a rig's bone names onto {@link SKELETON_STANDARD} through one {@link RigScheme}. Each slot * takes the first candidate that resolves; a candidate list is tried in order, so a scheme can name * a preferred bone and fall back. Bones that fill no slot come back in `unmapped`, and slots the rig * cannot fill in `missing` — the caller decides whether a partial map is usable. * * @capability skeleton-standard map any CC0 rig's bones onto the shared humanoid slots */ export declare function mapRigToStandard(bones: readonly string[], scheme?: RigScheme | string): SkeletonMap; /** A standard slot and the rest-pose length of the bone chain that reaches it. */ export interface SlotLength { slot: SkeletonSlot; /** Distance from the slot's bone to its parent bone, in the rig's own units. */ length: number; } /** * Per-slot length ratios that stretch a source rig's bone chain onto the standard's proportions, so * a retargeted clip moves both rigs the same distance rather than the same angle. Slots with no * counterpart on either side are omitted; a source length of zero is skipped instead of dividing. * * @capability skeleton-standard scale a retargeted clip to the target rig's bone proportions */ export declare function retargetBoneScales(source: readonly SlotLength[], target: readonly SlotLength[]): Partial>; /** * Bone-name prefixes for a set of standard slots, for an {@link AnimLayer.mask}. A slot on one side * contributes its side-less prefix (`upperLeg.l` → `upperleg`), which matches both sides' tracks; an * unsided slot contributes its own runtime name. Masking by slot means a rig mapped onto the * standard is masked without hand-typing its bone names. * * @capability skeleton-standard build a layer mask from the standard's own slots */ export declare function standardBoneMask(slots: readonly SkeletonSlot[]): string[]; /** Standard slots an upper-body action layer drives: spine, chest, head and both arms. */ export declare const UPPER_BODY_SLOTS: readonly SkeletonSlot[]; /** Standard slots a lower-body layer drives: hips, both legs and both feet. */ export declare const LOWER_BODY_SLOTS: readonly SkeletonSlot[]; /** Layer mask for an upper-body action layer (aim, reload, hit reaction) on a standard rig. */ export declare const UPPER_BODY_MASK: readonly string[]; /** Layer mask for a lower-body layer on a standard rig. */ export declare const LOWER_BODY_MASK: readonly string[]; /** * Renames a clip's tracks from a rig's own bone names onto the standard's, so one authored clip * plays on a mapped rig. The emitted node is the **runtime** bone name (see {@link runtimeBoneName}), * which is what both the loaded scene graph and the loaded clips spell. A track whose node fills no * slot is dropped (`null` in the result) rather than left pointing at a bone the rig does not have; * a track whose property is not one of the four three writes is dropped too, since renaming it * would not make it resolvable. * * @capability skeleton-standard rename an animation clip's tracks onto a mapped rig */ export declare function retargetTracks(tracks: readonly string[], map: SkeletonMap): (string | null)[];