import type { Object3D } from 'three'; export type Vec3 = [number, number, number]; export type MachineAnimationStatus = 'idle' | 'playing' | 'paused' | 'complete'; export type MachineAnimationDirection = 1 | -1; export type MachineAnimationTickSource = | 'initialize' | 'gsap' | 'manual' | 'restart' | 'seek' | 'step' | 'dispose'; export type ReducedMotionStrategy = 'pause' | 'slow' | 'static-snapshot' | 'continue'; export interface MachineCameraRequest { position: Vec3; target: Vec3; fov?: number; duration?: number; easing?: string; } export interface MachineAnimationEvent { type: | 'initialized' | 'updated' | 'played' | 'paused' | 'resumed' | 'restarted' | 'completed' | 'stepped' | 'disposed' | 'camera-request' | 'highlight-change' | 'phase-change'; machineId: string; moduleId: string; timestamp: number; partIds?: string[]; phaseLabel?: string; camera?: MachineCameraRequest; } export interface MachineAnimationSnapshot { moduleId: string | null; machineId: string | null; status: MachineAnimationStatus; elapsedSeconds: number; cycleElapsedSeconds: number; cycleDurationSeconds: number; cycleIndex: number; cycleProgress: number; rpm: number; minRpm: number; maxRpm: number; timeScale: number; loop: boolean; stepMode: boolean; stepIndex: number; stepCount: number; reducedMotion: boolean; direction: MachineAnimationDirection; revolutionsElapsed: number; shaftAngle: number; cycleAngle: number; highlightedPartIds: string[]; phaseLabel: string | null; } export interface MachinePartRef { id: string; object: Object3D; } export interface MachineAnimationContext extends MachineAnimationSnapshot { deltaSeconds: number; source: MachineAnimationTickSource; parts: ReadonlyMap; userData: Record; getPart: (partId: string) => Object3D | undefined; getPartsByPrefix: (prefix: string) => Object3D[]; setPartVisible: (partId: string, visible: boolean) => void; setPartOpacity: (partId: string, opacity: number) => void; setPartEmissive: (partId: string, color: string | number, intensity?: number) => void; clearPartEmissive: (partId: string) => void; highlightPart: (partId: string, intensity?: number) => void; highlightParts: (partIds: string[], intensity?: number) => void; clearHighlights: () => void; setPhaseLabel: (label: string | null) => void; requestCamera: (request: MachineCameraRequest) => void; emit: (event: Omit) => void; } export interface MachineAnimationModule { id: string; machineId: string; label: string; version: string; defaultRpm: number; minRpm: number; maxRpm: number; /** * Number of shaft revolutions represented by one logical animation cycle. * Four-stroke engines use two; most rotating mechanisms use one. */ cycleRevolutions?: number; cycleSteps?: number; loop?: boolean; supportsReverse?: boolean; reducedMotionStrategy?: ReducedMotionStrategy; initialize?: (context: MachineAnimationContext) => void; update: (context: MachineAnimationContext) => void; dispose?: (context: MachineAnimationContext) => void; onPlay?: (context: MachineAnimationContext) => void; onPause?: (context: MachineAnimationContext) => void; onResume?: (context: MachineAnimationContext) => void; onRestart?: (context: MachineAnimationContext) => void; onStep?: (context: MachineAnimationContext) => void; onBeforeTick?: (context: MachineAnimationContext) => void; onAfterTick?: (context: MachineAnimationContext) => void; } export interface MachineAnimationPlayerOptions { module?: MachineAnimationModule | null; rpm?: number; timeScale?: number; loop?: boolean; stepMode?: boolean; reducedMotion?: boolean; direction?: MachineAnimationDirection; autoPlay?: boolean; } export type MachineAnimationSubscriber = (snapshot: MachineAnimationSnapshot) => void; export type MachineAnimationEventSubscriber = (event: MachineAnimationEvent) => void; export interface MachineAnimationControls { play: () => void; pause: () => void; resume: () => void; restart: (autoPlay?: boolean) => void; stop: () => void; step: (steps?: number) => void; seekSeconds: (seconds: number) => void; seekCycleProgress: (progress: number) => void; setRpm: (rpm: number) => void; setTimeScale: (timeScale: number) => void; setLoop: (loop: boolean) => void; setStepMode: (enabled: boolean) => void; setReducedMotion: (enabled: boolean) => void; setDirection: (direction: MachineAnimationDirection) => void; } export interface MachineAnimationPlayerApi extends MachineAnimationControls { registerPart: (partId: string, object: Object3D | null) => void; getSnapshot: () => MachineAnimationSnapshot; subscribe: (subscriber: MachineAnimationSubscriber) => () => void; subscribeToEvents: (subscriber: MachineAnimationEventSubscriber) => () => void; }