/** * MotionMatching training/inference data schema. * * Defines the on-disk + in-memory shape for motion data consumed by the * future MotionMatchingEngine reimplementation (BUILD-1, per /founder * ruling 2026-04-26 — primary-literature reimplement: Holden 2017 * Phase-Functioned NN, Starke 2019 NSM, 2020 Local Motion Phases, * 2022 DeepPhase). * * Schema is versioned so future captures remain identifiable as the format * evolves. v1 covers the minimum needed for Phase-Functioned + NSM-style * inference: per-frame joint transforms, root velocity, contact features, * gait label, phase value. * * No backend dependency (pure types + validators). Backends — ONNX, pure-JS * forward pass, WebGPU compute — slot in via the MotionMatchingEngine * interface in motion-matching.ts. */ import type { Vec3, ContactFeatures, Gait, SkeletonPose } from './motion-matching'; export declare const MOTION_DATA_SCHEMA_VERSION: 1; /** * One frame of training data — paired (input, output) for supervised learning. * * Captured at FPS specified in the parent TrainingCorpus. Source can be: * - mocap (Vicon, Xsens, etc.) * - retargeted gameplay (Unity ML Agents reinforcement-learning rollouts) * - synthetic (procedural walk-cycle generator — see fixtures/) */ export interface TrainingFrame { /** Sequential frame index within the parent capture session. */ frameIndex: number; /** Wall-clock timestamp when the frame was captured (ms epoch). */ timestampMs: number; /** Skeletal pose at this frame. Keys are joint names (skeleton-specific). */ pose: SkeletonPose; /** Root-bone linear velocity in world-space (m/s). */ rootVelocity: Vec3; /** Root-bone angular velocity around vertical axis (rad/s). */ rootAngularVelocity: number; /** Phase value in [0, 1) — the Phase-Functioned cyclic position. */ phase: number; /** Terrain surface normal at the root position (optional — defaults to up). */ terrainNormal?: Vec3; /** Foot-contact bitmask — which feet are grounded at this frame. */ contactFeatures: ContactFeatures; /** Discrete gait label — for classifier head + ablation studies. */ gait: Gait; /** Energy-cost annotation for this frame (joules — optional, for energy-aware training). */ energyCost?: number; } /** * One frame of inference input — what the engine receives at runtime. * Strict subset of TrainingFrame — only the input fields, no labels. */ export interface InferenceFrame { pose: SkeletonPose; rootVelocity: Vec3; rootAngularVelocity: number; phase: number; terrainNormal?: Vec3; } /** * A captured motion sequence. Multiple frames sharing skeleton + sampling rate. */ export interface MotionCapture { /** Schema version — used to gate ingest compatibility. */ schemaVersion: typeof MOTION_DATA_SCHEMA_VERSION; /** Capture identifier — e.g. "mocap_walk_run_001" or "synth_walk_cycle_v1". */ captureId: string; /** Skeleton identifier — e.g. "biped_humanoid_v2". */ skeletonId: string; /** Source modality. */ source: 'mocap' | 'retargeted' | 'synthetic' | 'gameplay'; /** Capture frame rate in Hz (typically 30 or 60). */ fps: number; /** License + provenance — required for any capture used in training. */ license: { /** SPDX identifier or 'proprietary' — must be commercial-use-OK for HoloScript. */ spdx: string; /** Original creator / capture owner. */ attribution: string; /** URL or reference to the capture source. */ sourceUrl?: string; }; /** Sequential frames in temporal order. */ frames: TrainingFrame[]; } /** * A training corpus = many MotionCaptures grouped for one training run. */ export interface TrainingCorpus { schemaVersion: typeof MOTION_DATA_SCHEMA_VERSION; /** Corpus identifier — e.g. "biped_v1_train_2026-Q3". */ corpusId: string; /** Target skeleton — all captures must share this. */ skeletonId: string; /** Train/val/test split — frames assigned by captureId, not frame-by-frame. */ splits: { train: string[]; val: string[]; test: string[]; }; captures: MotionCapture[]; } export declare function validateTrainingFrame(frame: TrainingFrame): void; export declare function validateMotionCapture(capture: MotionCapture): void; export declare function validateTrainingCorpus(corpus: TrainingCorpus): void; /** * Convert an InferenceFrame into the flat tensor input shape that backends * (ONNX, WebGPU compute, pure-JS forward pass) all consume identically. * * Layout: [phase, rootVelX, rootVelY, rootVelZ, rootAngVel, * terrainNX, terrainNY, terrainNZ, * jointPos[0..N*3-1], jointRot[0..N*4-1]] * * Joint order is determined by the caller-provided sortedJointNames so the * tensor layout is deterministic across calls (matches training-time order). */ export declare function inferenceFrameToTensor(frame: InferenceFrame, sortedJointNames: string[]): Float32Array;