import type { BufferAttribute, BufferGeometry, DataTexture, Node, NodeMaterial, UniformNode } from 'three/webgpu'; import type { GUIController } from '../Utils/guiUtils.js'; /** Sampling layout used by a baked animation texture. */ export type AnimationBakeMode = 'vertex' | 'object'; /** Playback interpolation behavior applied while the mixer is paused or seeking. */ export type AnimationBakeInterpolationOverride = 'auto' | 'force0' | 'force1'; /** Metadata emitted by the VAT/OAT baking pipeline. Unknown extension fields are preserved. */ export interface AnimationBakeMetadata { [key: string]: unknown; mode?: AnimationBakeMode; framesOut?: number; idCount?: number; vertexCount?: number; width?: number; height?: number; originalFrames?: number; sampleStep?: number; duration?: number; clipDuration?: number; textureOffset?: number; textureFile?: string; texture?: string; textureUrl?: string; bindMatrices?: readonly number[] | Float32Array; bindMatricesInverse?: readonly number[] | Float32Array; timelineStart?: number; timelineEnd?: number; timelineDuration?: number; relativeDuration?: number; relativeClipDuration?: number; instances?: readonly unknown[]; } /** Mutable playback settings accepted by {@link AnimationBakeMixer.setConfig}. */ export interface AnimationBakeConfig { fps?: number; playbackSpeed?: number; loop?: boolean; play?: boolean; } /** Construction settings for an animation-bake mixer. */ export interface AnimationBakeMixerOptions extends AnimationBakeConfig { mode?: AnimationBakeMode; framesCount?: number; } /** Options accepted when seeking the mixer timeline. */ export interface AnimationBakeSetTimeOptions { wrap?: boolean; } /** Normalized timeline mapping derived from packed animation metadata. */ export interface AnimationBakeTimeline { start: number; end: number; duration: number; relativeDuration: number; } /** NodeMaterial shape supported by baked animation bindings. */ export type AnimationBakeMaterial = NodeMaterial & { wireframe?: boolean; }; /** Per-material overrides for baked animation sampling. */ export interface AnimationBakeMaterialOptions { mode?: AnimationBakeMode; geometry?: BufferGeometry; positionAttribute?: BufferAttribute; normalAttribute?: BufferAttribute; vertexCount?: number; instanceCount?: number; frameIndexNode?: Node<'int'> | Node<'uint'> | number; framesCountNode?: Node<'int'> | Node<'uint'> | number; textureOffsetNode?: Node<'int'> | Node<'uint'> | number; idNode?: Node<'int'> | Node<'uint'> | number; positionInputNode?: Node<'vec3'>; normalInputNode?: Node<'vec3'>; } /** Hints used to infer a frame count from matrix texels. */ export interface AnimationBakeInferFramesOptions { vertexCount?: number; objectCount?: number; mode?: AnimationBakeMode; } /** Additional configuration for the optional playback GUI. */ export interface AnimationBakeGUIOptions { folderName?: string; } /** Structural controller shared by lil-gui, dat.gui, and Three.js Inspector. */ export interface AnimationBakeGUIController extends GUIController { name(label: string): this; max?(value: number): this; } /** Structural folder shared by the supported GUI implementations. */ export interface AnimationBakeGUIFolder { add(target: TTarget, property: TKey, ...options: unknown[]): AnimationBakeGUIController; } /** Structural root accepted by {@link AnimationBakeMixer.attachGUI}. */ export interface AnimationBakeGUI { addFolder(name: string): AnimationBakeGUIFolder; } /** Live state object bound to playback GUI controllers. */ export interface AnimationBakeGUIState { play: boolean; fps: number; playbackSpeed: number; framesCount: number; frame: number; time: number; duration: number; interpolation: number; interpolationOverride: AnimationBakeInterpolationOverride; wireframe: boolean; } /** Controller collection created by {@link AnimationBakeMixer.attachGUI}. */ export interface AnimationBakeGUIControllers { play?: AnimationBakeGUIController; fps?: AnimationBakeGUIController; speed?: AnimationBakeGUIController; time?: AnimationBakeGUIController; frame?: AnimationBakeGUIController; frames?: AnimationBakeGUIController; interp?: AnimationBakeGUIController; mode?: AnimationBakeGUIController; } /** Runtime GUI binding retained by a mixer after attachment. */ export interface AnimationBakeGUIBinding { gui: AnimationBakeGUI; folder: AnimationBakeGUIFolder; params: AnimationBakeGUIState; controllers: AnimationBakeGUIControllers; } /** * @typedef {Object} AnimationBakeMetadata * @memberof AnimationBakeMixer * @property {'vertex'|'object'} [mode] Source mode of the baked texture. * @property {number} [framesOut] Number of frames baked out. * @property {number} [idCount] Object count for OAT data. * @property {number} [vertexCount] Vertex count for VAT data. * @property {number} [width] Texture width in pixels. * @property {number} [height] Texture height in pixels. * @property {number} [originalFrames] Input frame count prior to baking. * @property {number} [sampleStep] Sampling step used during baking. * @property {number} [duration] Duration of the baked animation in seconds. * @property {number} [clipDuration] Duration of the baked clip in seconds. */ /** * @typedef {Object} AnimationBakeConfig * @memberof AnimationBakeMixer * @property {number} [fps] Frames per second override. * @property {number} [playbackSpeed] Playback speed multiplier override. * @property {boolean} [loop] Whether playback should loop. * @property {boolean} [play] Toggle the playing state. */ /** * Playback controller for baked animation textures (VAT/OAT). * - Manages frame uniforms: `frameIndexUniform`, `framesCountUniform`, `frameTimeUniform` * - Supports modes: 'vertex' (VAT) and 'object' (OAT) * - Provides playback controls and frame interpolation * * This implementation-level API is intentionally internal and has no public package import. * * @class AnimationBakeMixer * @short Playback controller for VAT/OAT textures that manages frame uniforms, interpolation, and material binding. * @category Animation * @tags WebGPU, WebGL * @see AnimationBakeLoader */ export declare class AnimationBakeMixer { texture: DataTexture; mode: AnimationBakeMode; frameIndexUniform: UniformNode<'int', number>; framesCountUniform: UniformNode<'int', number>; frameTimeUniform: UniformNode<'float', number>; textureOffsetUniform: UniformNode<'int', number>; detectedFrames: number; materials: Set; playing: boolean; fps: number; playbackSpeed: number; loop: boolean; duration: number; time: number; metadata: AnimationBakeMetadata | null; _playbackSeconds: number; _interpolationOverride: AnimationBakeInterpolationOverride; _gui: AnimationBakeGUIBinding | null; timeline: AnimationBakeTimeline | null; localDuration: number; /** * @param {THREE.DataTexture} texture - Baked EXR texture that contains vertex or object animation frames. * @param {Object} [options] - Configuration object for playback behaviour. * @param {'vertex'|'object'} [options.mode='vertex'] Selects how the baked animation should be sampled. * @param {number} [options.framesCount] Optional frame count override; inferred from metadata or texture otherwise. * @param {boolean} [options.play=true] Start in a playing state when `true`. * @param {number} [options.fps=60] Target frames per second for playback. * @param {number} [options.playbackSpeed=1] Playback speed multiplier where `1` equals real time. * @param {boolean} [options.loop=true] Loop animation when `true`, clamp to last frame otherwise. */ constructor(texture: DataTexture, options?: AnimationBakeMixerOptions); /** * Initialize from metadata JSON (single entry point for configuration). * Expected VAT metadata keys: `mode='vertex'`, `framesOut`, `vertexCount`, `width`, `height`, etc. * Expected OAT metadata keys: `mode='object'`, `framesOut`, `idCount`, `width`, `height`, etc. * * @param {AnimationBakeMetadata} [meta] Metadata exported by the baking pipeline. * @returns {this} */ init(meta?: AnimationBakeMetadata): this; /** * Update runtime playback configuration values. * * @param {AnimationBakeConfig} [config] Partial configuration overrides. */ setConfig({ fps, playbackSpeed, loop, play }?: AnimationBakeConfig): void; /** * Returns the effective duration of the baked animation in seconds. * Falls back to frames / fps when metadata does not provide a duration. * * @returns {number} */ getDuration(): number; /** * Returns the current playback time in seconds. * * @returns {number} */ getTime(): number; /** * Set playback time in seconds. When `wrap` is true and looping is enabled the * provided value wraps into the current loop duration, otherwise it is clamped. * * @param {number} seconds Target playback time. * @param {Object} [options] * @param {boolean} [options.wrap=true] * @returns {this} */ setTime(seconds: number, { wrap }?: AnimationBakeSetTimeOptions): this; /** * Set interpolation override. * @param {'auto'|'force0'|'force1'} mode */ setInterpolationOverride(mode: AnimationBakeInterpolationOverride): void; /** * Register a NodeMaterial to use the baked animation. * Pass `opts.mode` to override the mixer's mode per-material. * * Note: You can also wire manually using * ```js * animationTexturePosition( this.texture, mixer.frameIndexUniform, mixer.framesCountUniform, mixer.frameTimeUniform, mixer.textureOffsetUniform ) * animationTextureNormal( this.texture, mixer.frameIndexUniform, mixer.framesCountUniform, mixer.frameTimeUniform, mixer.textureOffsetUniform ) * ``` * * @param {THREE.NodeMaterial} material NodeMaterial instance to bind uniforms to. * @param {'vertex'|'object'|Object} [mode] Force a specific sampling mode for this material. When an object is passed, it can contain `{ mode, geometry, positionAttribute, normalAttribute, vertexCount, instanceCount, frameIndexNode, framesCountNode, textureOffsetNode, idNode, positionInputNode, normalInputNode }` * @returns {THREE.NodeMaterial} */ registerMaterial(material: TMaterial, mode?: AnimationBakeMode | AnimationBakeMaterialOptions): TMaterial; /** * Begin playback of the baked animation using the current configuration. */ play(): void; /** * Pause playback while preserving the current frame and interpolation value. */ pause(): void; /** * Stop playback and seek back to the first frame. */ stop(): void; /** * Jump to a specific baked frame index. * @param {number} frameIndex Zero-based frame index to seek to. */ seekFrame(frameIndex: number): void; /** * Seek to a specific playback time in seconds. * @param {number} seconds Target playback time in seconds. */ seekSeconds(seconds: number): void; /** * Advance playback by the provided delta time. * @param {number} deltaSeconds Elapsed time in seconds since the previous update. */ update(deltaSeconds: number): void; /** * Attach a standard playback GUI to this mixer. * Compatible with lil-gui, dat.gui, and Three.js Inspector. * @param {object} gui A lil-gui instance or folder. * @param {Object} [opts] Additional GUI options. * @param {string} [opts.folderName] Custom name for the created folder. * @returns {this} */ attachGUI(gui: AnimationBakeGUI, opts?: AnimationBakeGUIOptions): this; /** @private */ _resolveDuration(meta: AnimationBakeMetadata | null | undefined): number; /** @private */ _getFrameCount(): number; /** @private */ _getLoopDuration(): number; /** @private */ _setPlaybackSeconds(seconds: number, { wrap }?: AnimationBakeSetTimeOptions): void; /** @private */ _updateFrameFromTime(): void; /** @private */ _refreshGuiTime(): void; /** @private */ _getForcedInterpolation(): 0 | 1 | null; /** @private */ _applyForcedInterpolationWhenPaused(): void; /** @private */ _setInterpolation(value: number): void; /** @private */ _mapTimelineToLocalTime(seconds: number): number; /** @private */ _applyTimelineMetadata(meta: AnimationBakeMetadata | null | undefined): void; /** * Infer frame count from a baked animation texture. * @param {THREE.DataTexture} texture EXR texture to inspect. * @param {Object} [options] Additional hints for the inference. * @param {number} [options.vertexCount] Vertex count for VAT data. * @param {number} [options.objectCount] Instance/object count for OAT data. * @param {'vertex'|'object'} [options.mode='vertex'] Specifies how to interpret the texture layout. * @returns {number} Inferred number of frames. */ static inferFrames(texture: DataTexture, { vertexCount, objectCount, mode }?: AnimationBakeInferFramesOptions): number; }