WebAR FácilAbrir ejemploEnglish

API pública generada

Generada desde los exports fuente y las declaraciones TypeScript del build. No editar a mano.

Los imports relativos se muestran en su contexto original. Estos bloques describen contratos, no son implementaciones para pegar en una app. Las interfaces auxiliares describen parámetros y resultados; solo los nombres de la tabla son exports del entrypoint público.

Export Clase de export Entrypoints
ARAnimationOptions Tipo webar-facil
ARComponentsOptions Tipo webar-facil
ARDiagnostics Valor y/o tipo webar-facil/core, webar-facil
AREventMap Tipo webar-facil/core, webar-facil
ARModelElement Tipo webar-facil
ARModelLoadOptions Tipo webar-facil
ARModelOptions Tipo webar-facil
ARPose Tipo webar-facil/core, webar-facil
ARSceneElement Tipo webar-facil
ARSceneOptions Tipo webar-facil
ARVideoElement Tipo webar-facil
ARVideoOptions Tipo webar-facil
CalibrationReport Tipo webar-facil/core, webar-facil
CalibrationSession Valor y/o tipo webar-facil/core, webar-facil
CameraFrame Tipo webar-facil/core, webar-facil
CameraIntrinsics Tipo webar-facil/core, webar-facil
CameraManager Valor y/o tipo webar-facil/core, webar-facil
CameraManagerOptions Tipo webar-facil/core, webar-facil
CameraMetrics Tipo webar-facil/core, webar-facil
ChromaKeyOptions Tipo webar-facil
CompilerOptions Tipo webar-facil/core, webar-facil
DEVICE_TEST_PROTOCOL Valor y/o tipo webar-facil/core, webar-facil
DeviceTestCase Tipo webar-facil/core, webar-facil
DeviceTestResult Tipo webar-facil/core, webar-facil
DiagnosticConfiguration Tipo webar-facil/core, webar-facil
DiagnosticContext Tipo webar-facil/core, webar-facil
DiagnosticOptions Tipo webar-facil/core, webar-facil
DiagnosticRendererMetrics Tipo webar-facil/core, webar-facil
DiagnosticReport Tipo webar-facil/core, webar-facil
DiagnosticStats Tipo webar-facil/core, webar-facil
EngineOptions Tipo webar-facil/core, webar-facil
EngineState Valor y/o tipo webar-facil/core, webar-facil
ExperimentalMetricScale Valor y/o tipo webar-facil/core, webar-facil
FrameQuality Tipo webar-facil/core, webar-facil
ImageCompiler Valor y/o tipo webar-facil/core, webar-facil
ImageObservation Tipo webar-facil/core, webar-facil
ImageTargetMetadata Tipo webar-facil/core, webar-facil
ImageTargetOptions Tipo webar-facil/core, webar-facil
ImageTargetResult Tipo webar-facil/core, webar-facil
ImageTrackingProfile Tipo webar-facil/core, webar-facil
LIBRARY_BUILD Valor y/o tipo webar-facil/core, webar-facil
LIBRARY_VERSION Valor y/o tipo webar-facil/core, webar-facil
MarkerCompiler Valor y/o tipo webar-facil/core, webar-facil
MarkerFeatures Tipo webar-facil/core, webar-facil
MarkerQuality Tipo webar-facil/core, webar-facil
MetricScaleDiagnostics Tipo webar-facil/core, webar-facil
OdometryBackend Tipo webar-facil/core, webar-facil
OdometryConfig Tipo webar-facil/core, webar-facil
OdometryEstimate Tipo webar-facil/core, webar-facil
OdometryMapSnapshot Tipo webar-facil/core, webar-facil
OdometryModule Tipo webar-facil/core, webar-facil
OdometryScanHint Tipo webar-facil/core, webar-facil
OpticalFlowOptions Tipo webar-facil/core, webar-facil
OpticalFlowSLAM Valor y/o tipo webar-facil/core, webar-facil
PlacementState Tipo webar-facil
projectionFromIntrinsics Valor y/o tipo webar-facil/core, webar-facil
registerAFrameComponent Valor y/o tipo webar-facil
registerAFrameModelComponent Valor y/o tipo webar-facil
registerAFrameVideoComponent Valor y/o tipo webar-facil
registerARComponents Valor y/o tipo webar-facil
rotateIntrinsics Valor y/o tipo webar-facil/core, webar-facil
scaleIntrinsics Valor y/o tipo webar-facil/core, webar-facil
SLAMManager Valor y/o tipo webar-facil/core, webar-facil
SLAMMapSnapshot Tipo webar-facil/core, webar-facil
SLAMOptions Tipo webar-facil/core, webar-facil
SurfaceTransitionOptions Tipo webar-facil/core, webar-facil
SurfaceTransitionResult Tipo webar-facil/core, webar-facil
TargetFoundEvent Tipo webar-facil/core, webar-facil
TargetLostEvent Tipo webar-facil/core, webar-facil
TargetVisibilityEvent Tipo webar-facil/core, webar-facil
ThreeARGroup Valor y/o tipo webar-facil
ThreeARModel Valor y/o tipo webar-facil
ThreeARScene Valor y/o tipo webar-facil
ThreeARVideo Valor y/o tipo webar-facil
ThreeCameraBackground Valor y/o tipo webar-facil
Tracker Valor y/o tipo webar-facil/core, webar-facil
TrackerOptions Tipo webar-facil/core, webar-facil
TrackingIssue Tipo webar-facil/core, webar-facil
TrackingQualityEvent Tipo webar-facil/core, webar-facil
TrackingResult Tipo webar-facil/core, webar-facil
validateIntrinsics Valor y/o tipo webar-facil/core, webar-facil
VisualReferenceResult Tipo webar-facil/core, webar-facil
WebAREngine Valor y/o tipo webar-facil/core, webar-facil

El bundle standalone añade el namespace THREE. Consulta API del motor, Three.js y API avanzada para ejemplos y valores iniciales.

Pose.d.ts

/** Todos los backends entregan el mismo contrato, sin tipos del renderer. */
export interface ARPose {
    targetId?: string;
    backend: 'image' | 'webxr' | 'optical-flow';
    timestampMs: number;
    scale: 'metric' | 'relative';
    /** Session-only metric estimate from the experimental optical/inertial mode. */
    scaleSource?: 'experimental-inertial';
    /** T_camera_object: column-major WebGL. */
    matrix: Float32Array;
    /** T_world_object. En imagen, el mundo de render es el espacio de cámara. */
    worldMatrix: Float32Array;
    /** T_camera_world. */
    viewMatrix: Float32Array;
    /** null si el backend no dispone de calibración; el renderer decide su FOV. */
    projectionMatrix: Float32Array | null;
    projectionSource?: 'calibrated' | 'estimated' | 'webxr';
    /** El ancla óptica coincide con el plano verificado por el estimador. */
    surfaceDetected?: boolean;
    diagnostics?: {
        processingMs: number;
        inliers: number;
        reprojectionErrorPx: number;
        relocalized?: boolean;
        keyframeCorrected?: boolean;
    };
}
export interface CameraIntrinsics {
    width: number;
    height: number;
    fx: number;
    fy: number;
    cx: number;
    cy: number;
    distortion?: readonly number[];
}

WebAREngine.d.ts

import { type CameraManagerOptions, type CameraMetrics } from './camera/CameraManager.js';
import { type TrackerOptions } from './tracking/Tracker.js';
import { type MarkerQuality } from './tracking/ImageCompiler.js';
import { type OpticalFlowOptions } from './slam/OpticalFlowSLAM.js';
import type { ExperimentalMetricScale } from './slam/ExperimentalMetricScale.js';
import type { ARPose, CameraIntrinsics } from './Pose.js';
import type { OdometryMapSnapshot, VisualReferenceResult } from './slam/OdometryBackend.js';
import type { AREventMap } from './tracking/events.js';
export declare enum EngineState {
    Idle = "Idle",
    Camera = "Camera",
    TrackingImage = "TrackingImage",
    TrackingSurface = "TrackingSurface",
    Disposed = "Disposed"
}
export interface EngineOptions {
    /** Optional session-only conversion of relative optical poses into estimated meters. */
    experimentalMetricScale?: ExperimentalMetricScale;
    /** Corrección local experimental; desactivada por defecto. No es cierre de bucle global. */
    keyframeCorrection?: boolean;
    /** Ocultar tras una pérdida sostenida; sin publicar poses durante la incertidumbre. 0 desactiva la tolerancia. */
    imageLossGraceMs?: number;
    keepContentOnLost?: boolean;
    imageSmoothingMs?: number;
    camera?: Omit<CameraManagerOptions, 'onFrame' | 'onError'>;
    tracker?: TrackerOptions;
    opencvURL?: string | URL;
    calibration?: CameraIntrinsics;
    /** false deshabilita el fallback. Por defecto se usa el backend local integrado. */
    fallback?: OpticalFlowOptions | false;
    attachXRSession?: (session: XRSession) => Promise<void>;
    getXRContext?: () => WebGL2RenderingContext;
    overlayRoot?: HTMLElement;
}
export interface ImageTargetOptions {
    /** Opcional: escala de referencia de 0.2 m por defecto; no requiere medir el marcador. */
    physicalWidthMeters?: number;
    maxDimension?: number;
}
export interface ImageTargetMetadata {
    format: 'WART';
    version: 2;
    width: number;
    height: number;
    physicalWidthMeters: number;
    extractorId: number;
    quality: MarkerQuality;
}
export interface ImageTargetResult {
    /** Copia independiente: puede guardarse como .dat sin afectar al motor. */
    buffer: ArrayBuffer;
    /** Datos listos para JSON.stringify; no se necesita cargar ningún JSON. */
    metadata: ImageTargetMetadata;
}
export interface SurfaceTransitionOptions {
    targetId?: string;
    backend?: 'auto' | 'webxr' | 'optical-flow';
    placement?: 'auto' | 'preserve' | 'hit-test';
    initializationTimeoutMs?: number;
}
export interface SurfaceTransitionResult {
    backend: 'webxr' | 'optical-flow';
    placement: 'preserved' | 'scan-marker' | 'select-surface' | 'scan-floor';
}
export interface SLAMMapSnapshot {
    version: 1;
    map: OdometryMapSnapshot;
    anchor: Float32Array | null;
    targetId: string;
}
/** Fachada: cámara, tracking de imagen y espacios nativos/locales comparten ARPose. */
export declare class WebAREngine {
    constructor(options?: EngineOptions);
    get state(): EngineState;
    get videoElement(): HTMLVideoElement;
    get cameraSettings(): MediaTrackSettings | null;
    get calibration(): CameraIntrinsics | undefined;
    setFocus(mode: 'continuous' | 'manual', distance?: number): Promise<boolean>;
    onPose(fn: (matrix: Float32Array, pose: ARPose) => void): () => void;
    onStatus(fn: (message: string) => void): () => void;
    onError(fn: (error: Error) => void): () => void;
    onSurface(fn: (matrix: Float32Array) => void): () => void;
    onMetrics(fn: (metrics: CameraMetrics) => void): () => void;
    get targetIds(): readonly string[];
    on<K extends keyof AREventMap>(name: K, listener: (event: AREventMap[K]) => void): () => void;
    onTargetFound(listener: (event: AREventMap['targetFound']) => void): () => void;
    onTargetLost(listener: (event: AREventMap['targetLost']) => void): () => void;
    onTrackingQuality(listener: (event: AREventMap['trackingQuality']) => void): () => void;
    onTargetVisibility(listener: (event: AREventMap['targetVisibility']) => void): () => void;
    /** Retener es congelar la ultima transformacion, no crear un anclaje SLAM. */
    setKeepContentOnLost(value: boolean, targetId?: string): void;
    /** Compare a fresh optical frame against the pinned reference without correcting the live pose. */
    checkSLAMVisualReference(action: 'capture' | 'verify', id: string): Promise<VisualReferenceResult>;
    exportSLAMMap({ includeCurrentView }?: {
        includeCurrentView?: boolean;
    }): Promise<SLAMMapSnapshot>;
    importSLAMMap(snapshot: SLAMMapSnapshot): Promise<void>;
    startCamera(): Promise<void>;
    loadTarget(url: string | URL): Promise<void>;
    addTarget(id: string, url: string | URL): Promise<void>;
    /** Compila JPG/PNG en Worker y activa el marcador sin archivos intermedios. */
    loadImageTarget(source: Blob | string | URL, options?: ImageTargetOptions): Promise<ImageTargetResult>;
    addImageTarget(id: string, source: Blob | string | URL, options?: ImageTargetOptions): Promise<ImageTargetResult>;
    removeTarget(id: string): Promise<void>;
    /** Llamar desde un clic. preserve exige una observación reciente y una alineación verificable. */
    enableSLAM(options?: SurfaceTransitionOptions): Promise<SurfaceTransitionResult>;
    stop(): Promise<void>;
    dispose(): void;
}

build-info.d.ts

export declare const LIBRARY_VERSION: string;
export declare const LIBRARY_BUILD = "1c906eb944d9f8f4";

calibration/CalibrationSession.d.ts

import type { CalibrationCapture, CalibrationReport } from './types.js';
/** API de calibración sin cómputo WASM en el hilo de UI. */
export declare class CalibrationSession {
    constructor(options?: {
        workerFactory?: () => Worker;
    });
    initialize(opencvURL: string, signal?: AbortSignal): Promise<void>;
    addFrame(frame: ImageData, signal?: AbortSignal): Promise<CalibrationCapture>;
    board(): Promise<{
        data: Uint8ClampedArray;
        width: number;
        height: number;
    }>;
    solve(): Promise<CalibrationReport>;
    reset(): Promise<void>;
    dispose(): void;
}

calibration/types.d.ts

import type { CameraIntrinsics } from '../Pose.js';
export interface CalibrationObservation {
    width: number;
    height: number;
    objectPoints: Float32Array;
    imagePoints: Float32Array;
}
export interface CalibrationReport {
    calibration: CameraIntrinsics;
    rmsPx: number;
    perViewErrorsPx: number[];
    views: number;
    coverage: number;
    warnings: string[];
}
export interface CalibrationCapture {
    accepted: boolean;
    corners: Float32Array;
    views: number;
    reason: string;
}

camera/CameraManager.d.ts

import type { ImageTrackingProfile } from '../tracking/profile.js';
import type { TrackingQualityEvent } from '../tracking/events.js';
export interface CameraFrame {
    /** RGBA; el consumidor puede transferir imageData.data.buffer al Worker. */
    imageData: ImageData;
    /** Tiempo de extracción, en el reloj performance.now(); no es tiempo del sensor. */
    timestampMs: number;
    mediaTimeSeconds: number;
    sessionId: number;
    sourceWidth: number;
    sourceHeight: number;
}
export interface CameraManagerOptions {
    /** Resolver al terminar de procesar el frame, no solamente al enviarlo. */
    onFrame: (frame: CameraFrame, signal: AbortSignal) => void | Promise<void>;
    onError?: (error: Error) => void;
    /** Etapas reales de apertura; no confundir permiso concedido con vídeo reproduciéndose. */
    onStatus?: (status: 'camera-requesting' | 'camera-granted' | 'camera-playing') => void;
    /** Visor opcional para montar el vídeo debajo del renderer durante la captura. */
    playbackContainer?: HTMLElement;
    /** Presupuesto inicial; las opciones explícitas tienen prioridad. */
    performance?: 'auto' | 'balanced' | 'battery' | 'quality';
    width?: number;
    height?: number;
    /** Preferencia, no requisito: permite webcams sin cámara trasera. */
    facingMode?: 'environment' | 'user';
    /** Selección explícita; tiene prioridad sobre facingMode. */
    deviceId?: string;
    /** Objetivo de captura, hasta 60; limitado por cámara, pantalla y CPU. */
    fps?: number;
    /** Limita el coste de lectura RGBA conservando la relación de aspecto. */
    maxFrameWidth?: number;
    /** Límite de píxeles analizados en cualquier orientación; no recorta la imagen. */
    maxFramePixels?: number;
    focusMode?: 'continuous' | 'manual' | 'none';
    focusDistance?: number;
    adaptive?: boolean;
    minFrameWidth?: number;
    onMetrics?: (metrics: CameraMetrics) => void;
    onSuspend?: () => void;
    onResume?: () => void;
}
export interface CameraMetrics {
    tracking?: ImageTrackingProfile;
    odometry?: import('../slam/OdometryBackend.js').OdometryTimings;
    consumerMs?: number;
    processedFrames: number;
    skippedFrames: number;
    readbackMs: number;
    processingMs: number;
    averageProcessingMs: number;
    analysisWidth: number;
    targetAnalysisFPS: number;
    analysisHeight?: number;
    performance?: CameraManagerOptions['performance'];
}
/** Webcam o cámara móvil. Usar con HTTPS o localhost. */
export declare class CameraManager {
    constructor(options: CameraManagerOptions);
    get state(): 'idle' | 'starting' | 'running' | 'paused' | 'disposed';
    /** Vista previa del stream; la propiedad srcObject pertenece al gestor. */
    get videoElement(): HTMLVideoElement;
    get settings(): MediaTrackSettings | null;
    /** Fijar resolución durante VO: cambiarla invalidaría el mapa. La frecuencia sí se adapta. */
    setAdaptiveResolution(enabled: boolean): void;
    /** Priorizar detalle si bajar resolución puede hacer perder el marcador. */
    setTrackingFeedback(qualities: readonly TrackingQualityEvent[], frameWidth?: number): void;
    /** Ancho explícito para semillas/mapas: prima sobre el presupuesto de píxeles. */
    setAnalysisWidth(width: number): void;
    setFocus(mode: 'continuous' | 'manual', distance?: number): Promise<boolean>;
    /** Idempotente durante una sesión. Los errores de arranque rechazan la promesa. */
    start(): Promise<void>;
    /** Cancela y libera la captura. retainDevice conserva la entrada para una transición interna. */
    stop({ retainDevice }?: {
        retainDevice?: boolean;
    }): void;
    dispose(): void;
}

diagnostics/ARDiagnostics.d.ts

import { TRACKING_STAGES, TRACKING_COUNTS } from '../tracking/profile.js';
import type { WebAREngine } from '../WebAREngine.js';
import type { CameraMetrics } from '../camera/CameraManager.js';
import { ODOMETRY_STAGES } from '../slam/OdometryBackend.js';
export type DeviceTestResult = 'pending' | 'pass' | 'fail' | 'not-supported';
export interface DiagnosticContext {
    platform?: 'ios' | 'android' | 'desktop' | 'other';
    execution?: 'unspecified' | 'automated' | 'physical-user-reported';
    deviceModel?: string;
    osVersion?: string;
    browserVersion?: string;
    scenario?: string;
}
export interface DiagnosticConfiguration {
    mode?: string;
    backend?: string;
    performance?: string;
    maxFramePixels?: number;
    analysisWidth?: number;
    requestedFPS?: number;
    lossGraceMs?: number;
    keepContentOnLost?: boolean;
    manualPlacement?: boolean;
    keyframeCorrection?: boolean;
    renderPixelRatio?: number;
    antialias?: boolean;
}
export interface DiagnosticOptions {
    context?: DiagnosticContext;
    configuration?: DiagnosticConfiguration;
    sampleLimit?: number;
    now?: () => number;
}
export interface DiagnosticStats {
    count: number;
    mean: number | null;
    min: number | null;
    max: number | null;
    p50: number | null;
    p95: number | null;
    quantileSamples: number;
}
/** Contadores del renderer, no tiempo GPU ni bytes de VRAM. */
export interface DiagnosticRendererMetrics {
    drawCalls: number;
    triangles: number;
    geometries: number;
    textures: number;
    drawingBufferWidth: number;
    drawingBufferHeight: number;
    pixelRatio: number;
}
export interface DiagnosticReport {
    schemaVersion: 1;
    kind: 'webar-diagnostics';
    sdk: {
        version: string;
        build: string;
    };
    createdAt: string;
    durationMs: number;
    recording: boolean;
    context: Required<DiagnosticContext>;
    configuration: DiagnosticConfiguration;
    environment: {
        userAgent: string;
        secureContext: boolean;
        cameraAPI: boolean;
        webgl2API: boolean;
        xrAPI: boolean;
        immersiveAR: boolean | null;
    };
    camera: Record<string, string | number | boolean>;
    state: string;
    targets: Record<string, {
        found: number;
        lost: number;
        ended: number;
        firstFoundMs: number | null;
        recoveriesMs: number[];
    }>;
    poses: {
        count: number;
        backends: Record<string, number>;
        scales: Record<string, number>;
        projectionSources: Record<string, number>;
        relocalized: number;
        keyframeCorrected: number;
        firstPoseMs: number | null;
    };
    quality: {
        samples: Record<string, number>;
        issues: Record<string, number>;
        diagnosis: 'heuristic';
    };
    metrics: {
        processingMs: DiagnosticStats;
        readbackMs: DiagnosticStats;
        consumerMs: DiagnosticStats;
        renderLoopMs: DiagnosticStats;
        poseStepTranslation: DiagnosticStats;
        poseStepRotationDegrees: DiagnosticStats;
        reprojectionErrorPx: DiagnosticStats;
        latestCamera: CameraMetrics | null;
    };
    odometry: {
        frames: number;
        stages: Record<typeof ODOMETRY_STAGES[number], DiagnosticStats>;
    };
    tracking: {
        frames: number;
        stages: Record<typeof TRACKING_STAGES[number], DiagnosticStats>;
        paths: Record<typeof TRACKING_COUNTS[number], number>;
    };
    renderer: {
        latest: DiagnosticRendererMetrics | null;
        peakDrawCalls: number;
        peakTriangles: number;
    };
    timeline: {
        atMs: number;
        event: string;
        detail: string;
    }[];
    observations: {
        atMs: number;
        testId: string;
        result: DeviceTestResult;
        notes: string;
    }[];
    limits: {
        sampleLimit: number;
        timelineLimit: number;
        observationLimit: number;
        quantiles: 'latest bounded samples';
        poseSteps: 'not physical jitter or drift';
        renderLoop: 'callback interval, not completed GPU frames';
        physicalValidation: 'operator-declared, not independently certified';
    };
}
type Source = Pick<WebAREngine, 'state' | 'cameraSettings' | 'targetIds' | 'onPose' | 'onStatus' | 'onError' | 'onMetrics' | 'onTargetFound' | 'onTargetLost' | 'onTrackingQuality'>;
/** Telemetría local opt-in y acotada. No persiste frames/mapas ni exporta matrices/URLs de contenido. */
export declare class ARDiagnostics {
    constructor(source: Source, options?: DiagnosticOptions);
    setContext(context: DiagnosticContext): void;
    mark(event: string, detail?: string): void;
    observe(testId: string, result: DeviceTestResult, notes?: string): void;
    recordError(error: Error): void;
    recordRenderer(input: DiagnosticRendererMetrics): void;
    recordRenderFrame(): void;
    probeCapabilities(): Promise<void>;
    stop(): void;
    snapshot(): DiagnosticReport;
    download(filename?: string): void;
}
export {};

diagnostics/device-protocol.d.ts

export interface DeviceTestCase {
    id: string;
    title: string;
    instructions: string;
    seconds: number;
    modes: readonly ('image' | 'flow' | 'transition' | 'webxr')[];
}
/** Pasos manuales comunes a iOS y Android. Ninguno se aprueba automáticamente. */
export declare const DEVICE_TEST_PROTOCOL: readonly DeviceTestCase[];

slam/ExperimentalMetricScale.d.ts

type WindowRejection = 'visualCoverage' | 'sensorCoverage' | 'sensorGap' | 'weakVisualMotion' | 'weakInertialMotion';
type Interruption = 'poseGap' | 'trackingLost' | 'relocalized' | 'keyframeCorrection' | 'mapReset';
type AxisValues = {
    x: number;
    y: number;
    z: number;
};
interface MotionSignal {
    windows: number;
    deviceAccelerationRmsMps2: AxisValues;
    worldAccelerationRmsMps2: AxisValues;
    integratedRmsMeters: AxisValues;
    meanAbsoluteIntegralMeters: AxisValues;
}
interface GuidedPhaseDiagnostics {
    visualPoses: number;
    visualDisplacementUnits: number | null;
    visualDisplacementMeters: number | null;
    visualCoverageMs: number;
    stationaryPoses: number;
    maxExcursionUnits: number | null;
    durationMs: number;
    samples: number;
    usableSamples: number;
    accelerationPeakMps2: AxisValues | null;
    accelerationRmsMps2: AxisValues | null;
    accelerationStdDevMps2: AxisValues | null;
    integratedWindows: number;
    weakWindows: number;
}
export interface MetricScaleDiagnostics {
    permission: 'idle' | 'listening' | 'denied' | 'unavailable';
    motionEvents: number;
    samples: number;
    usableSamples: number;
    medianIntervalMs: number | null;
    largestGapMs: number;
    visualFrames: number;
    medianVisualIntervalMs: number | null;
    pairedWindows: number;
    relativeResidual: number | null;
    metersPerUnit: number | null;
    windowsEvaluated: number;
    windowsAccepted: number;
    rejectedWindows: Record<WindowRejection, number>;
    interruptions: Record<Interruption, number>;
    fitState: 'waiting' | 'inconsistent' | 'accepted';
    fitAttempts: number;
    timing: {
        comparableWindows: number;
        estimatedOffsetMs: number | null;
        zeroOffsetResidual: number | null;
        bestResidual: number | null;
    };
    lastTimingFit: MetricScaleDiagnostics['timing'] | null;
    motionSignal: {
        all: MotionSignal | null;
        weak: MotionSignal | null;
        guided: MotionSignal | null;
        guidedWeak: MotionSignal | null;
    };
    guidedPhases: Record<string, GuidedPhaseDiagnostics>;
}
/** Experimental alignment of metric inertial and relative visual displacements. */
export declare class ExperimentalMetricScale {
    /** Call directly from a user gesture, before awaiting camera startup. */
    start(): Promise<boolean>;
    /** Keep the last diagnostic available after stopping. */
    stop(): void;
    /** Aggregate the windows entirely contained in the current guided exercise. */
    setGuidedMotionCapture(active: boolean): void;
    /** True after a continuous interval of fresh optical poses, including poses before plane detection. */
    hasStableVisualTracking(now?: number): boolean;
    pauseGuidedMotionPhase(): void;
    /** Mark the start of a named exercise phase on the same clock as sensor delivery. */
    setGuidedMotionPhase(id: string): void;
    diagnostics(): MetricScaleDiagnostics;
    /** Compare the observed positions at the beginning and end of a completed round trip. */
    guidedReturnError(outboundId: string, inboundId: string): number | null;
    resetMap(): void;
    /** Exclude windows that cross a lost pose, correction, or relocalization. */
    interrupt(reason?: Interruption): void;
    /** Receives unfiltered T_world_camera and the frame read time on the same page clock. */
    observe(time: number, worldFromCamera: Float32Array, stationary?: boolean): number | null;
}
export {};

slam/OdometryBackend.d.ts

import type { CameraIntrinsics } from '../Pose.js';
import type { ImageObservation } from '../tracking/types.js';
export interface OdometryConfig {
    intrinsics: CameraIntrinsics;
    opencvURL?: string;
    seed?: ImageObservation;
    /** Experimental, desactivada por defecto: reobservación de keyframes locales. */
    keyframeCorrection?: boolean;
    /** ROI normalizada para seleccionar esquinas candidatas del suelo. No prueba un plano. */
    floorROI: {
        x: number;
        y: number;
        width: number;
        height: number;
    };
}
/** Snapshot local: no imágenes de cámara; solo descriptores y geometría verificada. */
export interface OdometryMapSnapshot {
    version: 1;
    intrinsics: CameraIntrinsics;
    scale: 'relative' | 'metric';
    mapId: string;
    keyframes: {
        descriptors: Uint8Array;
        points: Float32Array;
        view: Float32Array;
    }[];
    groundPlane?: {
        worldFromPlane: Float32Array;
        inliers: number;
    };
    /** La exportación añadió un fotograma clave de la vista actual. */
    currentViewCaptured?: boolean;
}
export declare const ODOMETRY_STAGES: readonly [
    "grayMs",
    "cornersMs",
    "flowMs",
    "flowNormalMs",
    "flowWideMs",
    "flowRetryMs",
    "initializationMs",
    "poseMs",
    "mapUpdateMs",
    "keyframesMs",
    "planeMs",
    "planeFitMs",
    "planeConsensusMs",
    "relocalizationMs",
    "workerMs"
];
export type OdometryTimings = Partial<Record<typeof ODOMETRY_STAGES[number], number>>;
export declare const ODOMETRY_SCAN_HINTS: readonly [
    "low-texture",
    "move-sideways",
    "map-initializing",
    "plane-unverified",
    "return-to-map",
    "map-matches-insufficient",
    "map-pose-unverified",
    "map-pose-confirming",
    "surface-ready"
];
/** Indicio de escaneo derivado del estimador local. */
export type OdometryScanHint = typeof ODOMETRY_SCAN_HINTS[number];
export type OdometryEstimate = ({
    status: 'initializing' | 'lost';
    mapId: string;
} | {
    status: 'tracked';
    mapId: string;
    /** Pose acumulada T_world_camera, NO delta entre frames. Convención WebGL. */
    worldFromCamera: Float32Array;
    projectionMatrix: Float32Array;
    scale: 'relative' | 'metric';
    trackedPoints: number;
    environmentReady?: boolean;
    processingMs?: number;
    reprojectionErrorPx?: number;
    relocalized?: boolean;
    keyframeCorrected?: boolean;
    /** Pose held against distributed, near-static visual correspondences. */
    stationary?: boolean;
    /** Solo emitir tras triangulación y verificación geométrica de un plano. */
    groundPlane?: {
        worldFromPlane: Float32Array;
        inliers: number;
    };
}) & {
    timings?: OdometryTimings;
    scanHint?: OdometryScanHint;
};
/** ABI JavaScript del módulo local que encapsula el WASM del usuario. */
export interface OdometryBackend {
    /**
     * Pipeline esperado en WASM: gris -> Shi-Tomasi/FAST -> Lucas-Kanade piramidal
     * -> comprobación forward/backward -> geometría robusta -> keyframes/mapa -> pose.
     * Reponer puntos, detectar falta de paralaje y declarar lost ante degeneración.
     * Intrínsecos se escalan al tamaño RGBA recibido. No inferir traslación 3D
     * simplemente sumando desplazamientos de píxeles.
     */
    processFrame(frame: {
        rgba: Uint8ClampedArray;
        width: number;
        height: number;
        timestampMs: number;
    }): OdometryEstimate | Promise<OdometryEstimate>;
    reset(): void | Promise<void>;
    exportMap?(includeCurrentView?: boolean): OdometryMapSnapshot;
    importMap?(snapshot: OdometryMapSnapshot): void;
    checkVisualReference?(action: 'capture' | 'verify', id: string, timestampMs: number): VisualReferenceResult;
}
export type VisualReferenceResult = {
    status: 'captured';
    points: number;
} | {
    status: 'verified';
    inliers: number;
    reprojectionErrorPx: number;
    medianImageShiftPx: number;
    directReturnUnits: number;
    trajectoryDeltaUnits: number;
} | {
    status: 'unavailable' | 'insufficient-support' | 'missing-reference';
};
export interface OdometryModule {
    createOdometryBackend(config: OdometryConfig): Promise<OdometryBackend>;
}

slam/OpticalFlowSLAM.d.ts

import type { CameraFrame } from '../camera/CameraManager.js';
import type { OdometryConfig, OdometryEstimate, OdometryMapSnapshot, VisualReferenceResult } from './OdometryBackend.js';
export interface OpticalFlowOptions extends OdometryConfig {
    /** Módulo ESM local que exporta createOdometryBackend; carga su propio .wasm. */
    moduleURL?: URL;
    workerFactory?: () => Worker;
}
/** Cliente del backend WASM. No simula una pose si el backend no está disponible. */
export declare class OpticalFlowSLAM {
    constructor(options: OpticalFlowOptions);
    start(signal?: AbortSignal): Promise<void>;
    processFrame(frame: CameraFrame, signal?: AbortSignal): Promise<OdometryEstimate | null>;
    checkVisualReference(action: 'capture' | 'verify', referenceId: string, signal?: AbortSignal): Promise<VisualReferenceResult>;
    exportMap(signal?: AbortSignal, includeCurrentView?: boolean): Promise<OdometryMapSnapshot>;
    importMap(snapshot: OdometryMapSnapshot, signal?: AbortSignal): Promise<void>;
    stop(): void;
    dispose(): void;
}

slam/SLAMManager.d.ts

import type { ARPose } from '../Pose.js';
import type { CameraFrame } from '../camera/CameraManager.js';
import type { CameraIntrinsics } from '../Pose.js';
export interface SLAMOptions {
    /** El renderer configura XRWebGLLayer y su propio bucle de renderizado. */
    attachSession: (session: XRSession) => Promise<void>;
    overlayRoot?: HTMLElement;
    onPose: (pose: ARPose) => void;
    onSurface?: (matrix: Float32Array) => void;
    onLost?: () => void;
    onEnd?: () => void;
    onError?: (error: Error) => void;
    getGLContext?: () => WebGL2RenderingContext;
    requireCameraAccess?: boolean;
    onCameraFrame?: (frame: CameraFrame, worldFromCamera: Float32Array, intrinsics: CameraIntrinsics, referenceEpoch: number) => Promise<void>;
    onAlignmentUnavailable?: (error: Error) => void;
}
/** Tracking nativo; las poses de hit-test no se presentan como una malla completa. */
export declare class SLAMManager {
    get imageAlignmentAvailable(): boolean;
    get hasPlacement(): boolean;
    get referenceEpoch(): number;
    constructor(options: SLAMOptions);
    static isSupported(): Promise<boolean>;
    /** Llamar desde un gesto de usuario; requestSession se invoca antes del primer await. */
    start(signal?: AbortSignal): Promise<void>;
    /**
     * Solo preservar pose con T_world_camera alineada al MISMO frame del marcador.
     * Sin esa observación, habilitar hit-test y colocar mediante un gesto select.
     */
    switchToSLAM(currentMatrix: Float32Array, alignedWorldFromCamera?: Float32Array): void;
    stop(): Promise<void>;
}

tools/MarkerCompiler.d.ts

import type { MarkerQuality } from '../tracking/ImageCompiler.js';
export declare class MarkerCompiler {
    constructor(options?: {
        workerFactory?: () => Worker;
    });
    /** JPG/PNG original; decodificación EXIF, ORB y binario se calculan en Worker. */
    compile(file: Blob, options: {
        physicalWidthMeters: number;
        opencvURL: string;
        maxDimension?: number;
    }, signal?: AbortSignal): Promise<{
        buffer: ArrayBuffer;
        quality: MarkerQuality;
    }>;
    dispose(): void;
}

tracking/ImageCompiler.d.ts

export declare const TARGET_HEADER_BYTES = 48;
export declare const TARGET_MAX_BYTES: number;
export declare const TARGET_MAX_FEATURES = 100000;
export declare const ORB_DESCRIPTOR_BYTES = 32;
export interface MarkerFeatures {
    width: number;
    height: number;
    /** x,y,ángulo en radianes,respuesta por punto; descriptores ORB de 32 bytes. */
    keypoints: Float32Array;
    descriptors: Uint8Array;
}
export interface CompiledMarker extends MarkerFeatures {
    simulated: boolean;
    physicalWidthMeters: number;
    extractorId: number;
}
export interface DecodedImage {
    data: Uint8ClampedArray;
    width: number;
    height: number;
}
export interface CompilerOptions {
    /** Precalcular vistas acortadas para inclinaciones fuertes. true por defecto. */
    affineViews?: boolean;
    physicalWidthMeters: number;
    opencvURL?: string;
    extractorId?: number;
    maxDimension?: number;
    /** Solo fixtures o compatibilidad: nunca se habilita implícitamente. */
    simulate?: boolean;
    extract?: (encoded: Uint8Array) => Promise<MarkerFeatures>;
    decode?: (encoded: Uint8Array) => Promise<DecodedImage>;
}
export interface MarkerQuality {
    featureCount: number;
    coverage: number;
    duplicateRatio: number;
    usable: boolean;
    warnings: string[];
}
/** CRC32 IEEE: corrupción de almacenamiento/transporte, no autenticación. */
export declare function crc32(bytes: Uint8Array): number;
export declare function analyzeFeatures(features: MarkerFeatures): MarkerQuality;
/** Compilador real; usar en un Worker de preprocesamiento o con el CLI de Node. */
export declare class ImageCompiler {
    compile(source: Uint8Array | Blob, options: CompilerOptions): Promise<ArrayBuffer>;
    compileRGBA(image: DecodedImage, options: CompilerOptions): Promise<ArrayBuffer>;
}
export declare function decodeImageBrowser(encoded: Uint8Array, max: number): Promise<DecodedImage>;
export declare function encodeMarker(features: MarkerFeatures, options: CompilerOptions, simulated?: boolean): ArrayBuffer;
/** Valida antes de reservar arrays. El llamador conserva el buffer de entrada. */
export declare function decodeMarker(buffer: ArrayBuffer): CompiledMarker;

tracking/Tracker.d.ts

import { type ImageTrackingProfile } from './profile.js';
import type { CameraFrame } from '../camera/CameraManager.js';
import type { CameraIntrinsics } from '../Pose.js';
import type { TrackingResult, TrackingBatchResult } from './types.js';
export type { TrackingResult, ImageObservation } from './types.js';
export interface TrackerOptions {
    opencvURL?: string | URL;
    calibration?: CameraIntrinsics;
    allowEstimatedCalibration?: boolean;
    timeoutMs?: number;
    workerFactory?: () => Worker;
}
export declare class Tracker {
    get latestProfile(): ImageTrackingProfile | null;
    constructor(options?: TrackerOptions);
    get state(): 'idle' | 'busy' | 'disposed';
    get hasTarget(): boolean;
    loadTarget(buffer: ArrayBuffer, signal?: AbortSignal, targetId?: string): Promise<void>;
    get targetIds(): readonly string[];
    loadTargets(targets: readonly {
        id: string;
        buffer: ArrayBuffer;
    }[], signal?: AbortSignal): Promise<void>;
    processFrame(frame: CameraFrame, signal?: AbortSignal, calibrationOverride?: CameraIntrinsics): Promise<TrackingResult | null>;
    /** Un RGBA y un Worker para todos los marcadores. No duplicar el frame por target. */
    processTargetsFrame(frame: CameraFrame, signal?: AbortSignal): Promise<TrackingBatchResult | null>;
    dispose(): void;
}

tracking/events.d.ts

import type { ARPose } from '../Pose.js';
import type { OdometryScanHint } from '../slam/OdometryBackend.js';
export type TrackingIssue = 'low-texture' | 'small-target' | 'blur' | 'high-motion' | 'insufficient-matches' | 'occlusion-or-out-of-view' | 'device-load';
/** Indicadores heurísticos: una imagen sin rasgos no permite distinguir siempre blur y poca textura. */
export interface FrameQuality {
    gradient: number;
    laplacianVariance: number;
    motionPixels: number;
    targetSizePx: number;
    featureCount: number;
    inliers: number;
    reprojectionErrorPx: number;
}
export interface TrackingQualityEvent extends FrameQuality {
    targetId: string;
    timestampMs: number;
    state: 'tracking' | 'recovering' | 'lost';
    score: number;
    processingMs: number;
    issues: TrackingIssue[];
    diagnosis: 'heuristic';
}
export interface TargetFoundEvent {
    targetId: string;
    timestampMs: number;
    pose: ARPose;
}
export interface TargetLostEvent {
    targetId: string;
    timestampMs: number;
    retained: boolean;
    reason: 'lost' | 'removed' | 'stopped';
}
export interface TargetVisibilityEvent {
    targetId: string;
    visible: boolean;
    reason: 'tracked' | 'recovering' | 'lost' | 'removed' | 'stopped' | 'policy';
}
export interface AREventMap {
    scanGuidance: {
        hint: OdometryScanHint;
        timestampMs: number;
    };
    targetFound: TargetFoundEvent;
    targetLost: TargetLostEvent;
    trackingQuality: TrackingQualityEvent;
    targetVisibility: TargetVisibilityEvent;
}

tracking/profile.d.ts

/** Tiempos monotónicos por frame; el total Worker incluye las etapas y su preparación. */
export declare const TRACKING_STAGES: readonly [
    "grayMs",
    "qualityMs",
    "supportMs",
    "opticalFlowMs",
    "flowValidationMs",
    "orbMs",
    "matchingMs",
    "homographyMs",
    "poseMs",
    "workerMs",
    "roundTripMs",
    "transportAndSchedulingMs"
];
export declare const TRACKING_COUNTS: readonly [
    "flowAttempts",
    "flowAccepted",
    "redetections",
    "orbExtractions",
    "flowInputPoints",
    "cachedAttempts",
    "fullDetections",
    "matchingQueryDescriptors",
    "flowReliable",
    "redetectMissing",
    "redetectWeakSupport",
    "redetectDeadline",
    "redetectVerification",
    "globalDeferred",
    "flowSparseReliable",
    "weakDistribution",
    "weakReprojection",
    "weakRetention",
    "cacheConflicts",
    "exactMatchingCalls",
    "opencvMatchingCalls",
    "emptyMatchingCalls"
];
export interface ImageTrackingProfile {
    timings: Record<typeof TRACKING_STAGES[number], number>;
    counts: Record<typeof TRACKING_COUNTS[number], number>;
}
export declare function createTrackingProfile(): ImageTrackingProfile;
export declare function copyTrackingProfile(value: unknown): ImageTrackingProfile | null;
export declare function measureTracking<T>(profile: ImageTrackingProfile, key: typeof TRACKING_STAGES[number], run: () => T): T;

tracking/types.d.ts

import type { CameraIntrinsics } from '../Pose.js';
import type { ImageTrackingProfile } from './profile.js';
import type { FrameQuality } from './events.js';
export interface ImageObservation {
    rgba: ArrayBuffer;
    width: number;
    height: number;
    timestampMs: number;
    sessionId: number;
    intrinsics: CameraIntrinsics;
    projectionSource?: 'calibrated' | 'estimated';
    cameraFromMarker: Float32Array;
    imagePoints: Float32Array;
    objectPoints: Float32Array;
    markerCorners: Float32Array;
}
export type TrackingResult = {
    sessionId: number;
    timestampMs: number;
    processingMs: number;
    quality?: FrameQuality;
    targetId?: string;
    profile?: ImageTrackingProfile;
} & ({
    status: 'not-found';
    matrix: null;
} | {
    status: 'tracked';
    matrix: Float32Array;
    projectionMatrix: Float32Array;
    projectionSource: 'calibrated' | 'estimated';
    inliers: number;
    reprojectionErrorPx: number;
    reference: ImageObservation;
});
export interface TrackingFrameRequest {
    type: 'FRAME' | 'FRAME_BATCH';
    id: number;
    buffer: ArrayBuffer;
    width: number;
    height: number;
    sessionId: number;
    timestampMs: number;
    intrinsics: CameraIntrinsics;
    projectionSource: 'calibrated' | 'estimated';
}
export interface TrackingBatchResult {
    results: TrackingResult[];
    processingMs: number;
    profile?: ImageTrackingProfile;
}

vision/calibration.d.ts

import type { CameraIntrinsics } from '../Pose.js';
export declare function validateIntrinsics(k: CameraIntrinsics): void;
/** No corregir silenciosamente un recorte o una rotación no observados. */
export declare function scaleIntrinsics(k: CameraIntrinsics, width: number, height: number): CameraIntrinsics;
export declare function estimateIntrinsics(width: number, height: number, verticalFovDegrees?: number): CameraIntrinsics;
/** Proyección OpenGL/WebGL, píxeles sin distorsión, origen superior izquierdo. */
export declare function projectionFromIntrinsics(k: CameraIntrinsics, near?: number, far?: number): Float32Array;
export declare function rotateIntrinsics(k: CameraIntrinsics, degrees: 0 | 90 | 180 | 270): CameraIntrinsics;
export declare function normalizedPixel(x: number, y: number, k: CameraIntrinsics): [
    number,
    number
];

wrappers/SurfacePlacement.d.ts

import { RingGeometry, MeshBasicMaterial, Mesh } from 'three';
import type { ARPose } from '../Pose.js';
export type PlacementState = 'idle' | 'scanning' | 'surface-found' | 'placed' | 'lost';
/** Guía de presentación; nunca genera una pose ni supone que un hit-test sea suelo semántico. */
export declare class SurfacePlacement {
    readonly reticle: Mesh<RingGeometry, MeshBasicMaterial, import("three").Object3DEventMap>;
    constructor(manual: boolean, changed: (state: PlacementState) => void, now?: () => number, onStale?: () => void, showGrid?: boolean);
    get state(): PlacementState;
    get canConfirm(): boolean;
    begin(): void;
    status(message: string): void;
    observeSurface(matrix: Float32Array): void;
    observePose(pose: ARPose): void;
    confirm(): void;
    tick(): void;
    dispose(): void;
}

wrappers/ThreeARGroup.d.ts

import { Group } from 'three';
import type { ARPose } from '../Pose.js';
import type { WebAREngine } from '../WebAREngine.js';
export declare class ThreeARGroup extends Group {
    constructor();
    /** Contenido independiente por marcador; no reinicia animaciones al perderlo. */
    bind(engine: WebAREngine, targetId?: string): this;
    unbind(): void;
    dispose(): void;
    /**
     * Con metadata, usar pose de mundo: sirve con cámara normal y cámara XR.
     * Sin metadata, matrix es modelView y requiere una cámara identidad.
     * El core ya normalizó OpenCV -> WebGL; no repetir la conversión aquí.
     */
    update(matrix: Float32Array, pose?: ARPose): void;
}

wrappers/ThreeARModel.d.ts

import { Group } from 'three';
export interface ARModelOptions {
    /** Carpeta local con draco_wasm_wrapper.js, draco_decoder.wasm y draco_decoder.js. */
    dracoDecoderPath?: string | URL;
    maxBytes?: number;
}
export interface ARModelLoadOptions {
    /** Ajustar dimensión máxima, centrar X/Z y apoyar base en Y=0. false conserva unidades originales. */
    fitSize?: number | false;
    autoplay?: boolean;
    signal?: AbortSignal;
}
export interface ARAnimationOptions {
    loop?: 'repeat' | 'once' | 'pingpong';
    repetitions?: number;
    speed?: number;
    crossFadeSeconds?: number;
    clampWhenFinished?: boolean;
}
/** GLB autocontenido, sin CDN. Añadirlo a ThreeARGroup o a una entidad A-Frame. */
export declare class ThreeARModel extends Group {
    constructor(options?: ARModelOptions);
    get model(): Group | null;
    /** Una carga nueva cancela la anterior. El modelo previo se mantiene si la nueva falla. */
    load(source: Blob | string | URL, options?: ARModelLoadOptions): Promise<this>;
    /** Llamar con delta en segundos desde el bucle del renderer. */
    update(deltaSeconds: number): void;
    setSize(size: number | false): void;
    playAnimation(nameOrIndex?: string | number, options?: ARAnimationOptions): void;
    configureAnimation(options: ARAnimationOptions): void;
    pauseAnimations(): void;
    resumeAnimations(): void;
    get animationState(): {
        name: string;
        time: number;
        paused: boolean;
        speed: number;
        running: boolean;
    } | null;
    onAnimationFinished(listener: (name: string) => void): () => void;
    stopAnimations(): void;
    unload(): void;
    dispose(): void;
}

wrappers/ThreeARScene.d.ts

import { Scene, PerspectiveCamera, WebGLRenderer, type Object3D } from 'three';
import { WebAREngine, type EngineOptions } from '../WebAREngine.js';
import { ThreeARGroup } from './ThreeARGroup.js';
export interface ARSceneOptions {
    container: HTMLElement;
    engineOptions?: EngineOptions;
    maxPixelRatio?: number;
    lighting?: boolean;
    fit?: 'contain' | 'cover';
    /** MSAA al crear el contexto; cambiar exige recrear la escena. */
    antialias?: boolean;
}
/** Wrapper opcional: script clásico + API propia, sin editor ni framework obligatorio. */
export declare class ThreeARScene {
    readonly engine: WebAREngine;
    readonly scene: Scene;
    readonly camera: PerspectiveCamera;
    readonly renderer: WebGLRenderer;
    constructor(options: ARSceneOptions);
    getAnchor(targetId?: string): ThreeARGroup;
    addContent(targetId: string, content: Object3D): void;
    removeContent(content: Object3D): void;
    onRender(callback: (deltaSeconds: number) => void): () => void;
    onAfterRender(callback: () => void): () => void;
    dispose(): Promise<void>;
}

wrappers/ThreeARVideo.d.ts

import { Group, Mesh, PlaneGeometry, ShaderMaterial, type ColorRepresentation } from 'three';
export interface ChromaKeyOptions {
    color?: ColorRepresentation;
    similarity?: number;
    smoothness?: number;
    spill?: number;
}
export interface ARVideoOptions {
    width?: number;
    orientation?: 'flat' | 'upright';
    muted?: boolean;
    loop?: boolean;
    chromaKey?: ChromaKeyOptions | false;
}
/** MP4 a través del decoder nativo. Reproducción independiente del estado del marcador. */
export declare class ThreeARVideo extends Group {
    readonly videoElement: HTMLVideoElement;
    readonly mesh: Mesh<PlaneGeometry, ShaderMaterial>;
    constructor(options?: ARVideoOptions);
    setChromaKey(options: ChromaKeyOptions | false): void;
    setWidth(width: number): void;
    setOrientation(orientation: 'flat' | 'upright'): void;
    /** No reproduce ni rebobina automáticamente al recuperar un marcador. */
    setSource(source: Blob | string | URL): Promise<void>;
    /** Invocar desde un gesto del usuario; propaga bloqueos de autoplay para mostrar un botón. */
    play(): Promise<void>;
    pause(): void;
    dispose(): void;
}

wrappers/ThreeCameraBackground.d.ts

import { Mesh } from 'three';
import type { CameraIntrinsics } from '../Pose.js';
/** Fondo de cámara rectificado en GPU: la proyección K debe coincidir con la escena 3D. */
export declare class ThreeCameraBackground {
    readonly object3D: Mesh;
    constructor(video: HTMLVideoElement, calibration?: CameraIntrinsics);
    setCalibration(calibration?: CameraIntrinsics): void;
    dispose(): void;
}

wrappers/aframe-component.d.ts

import type { Object3D, Camera } from 'three';
import type { WebAREngine } from '../WebAREngine.js';
import { ThreeCameraBackground } from './ThreeCameraBackground.js';
interface ComponentInstance {
    data: {
        target: string;
        physicalWidth: number;
        targetId: string;
    };
    el: HTMLElement & {
        object3D: Object3D;
        sceneEl?: {
            camera?: Camera;
            object3D?: Object3D;
        };
    };
    unsubscribe?: () => void;
    originalAutoUpdate?: boolean;
    originalVisible?: boolean;
    removed?: boolean;
    camera?: Camera;
    cameraAutoUpdate?: boolean;
    background?: ThreeCameraBackground;
    releaseBackground?: () => void;
    releaseCamera?: () => void;
}
interface AFrameRegistry {
    registerComponent(name: string, definition: {
        schema: {
            target: {
                type: 'string';
                default: string;
            };
            physicalWidth: {
                type: 'number';
                default: number;
            };
            targetId: {
                type: 'string';
                default: string;
            };
        };
        init(this: ComponentInstance): void;
        update(this: ComponentInstance, previous: {
            target?: string;
            physicalWidth?: number;
            targetId?: string;
        }): void;
        remove(this: ComponentInstance): void;
    }): unknown;
}
/** Una instancia de motor por escena; configurar su cámara/renderer al crearla. */
export declare function registerAFrameComponent(AFRAME: AFrameRegistry, engine: WebAREngine): void;
export {};

wrappers/aframe-model.d.ts

import type { Object3D } from 'three';
import { ThreeARModel, type ARModelOptions } from './ThreeARModel.js';
interface Instance {
    data: {
        src: string;
        fitSize: number;
        autoplay: boolean;
    };
    el: HTMLElement & {
        object3D: Object3D;
    };
    model?: ThreeARModel;
    generation?: number;
}
interface Registry {
    registerComponent(name: string, definition: {
        schema: {
            src: {
                type: 'string';
                default: string;
            };
            fitSize: {
                type: 'number';
                default: number;
            };
            autoplay: {
                type: 'boolean';
                default: boolean;
            };
        };
        init(this: Instance): void;
        update(this: Instance, previous: Partial<Instance['data']>): void;
        tick(this: Instance, time: number, delta: number): void;
        remove(this: Instance): void;
    }): unknown;
}
/** Usar en un hijo de la entidad my-ar-tracker; mantiene separada la pose del contenido. */
export declare function registerAFrameModelComponent(AFRAME: Registry, options?: ARModelOptions): void;
export {};

wrappers/aframe-video.d.ts

import type { Object3D } from 'three';
import { ThreeARVideo } from './ThreeARVideo.js';
interface Instance {
    data: {
        src: string;
        width: number;
        chromaKey: boolean;
        keyColor: string;
        similarity: number;
        smoothness: number;
        spill: number;
        muted: boolean;
        loop: boolean;
    };
    el: HTMLElement & {
        object3D: Object3D;
    };
    video?: ThreeARVideo;
    generation?: number;
}
interface Registry {
    registerComponent(name: string, definition: {
        schema: Record<string, {
            type: string;
            default: string | number | boolean;
        }>;
        init(this: Instance): void;
        update(this: Instance, previous: Partial<Instance['data']>): void;
        remove(this: Instance): void;
    }): unknown;
}
export declare function registerAFrameVideoComponent(AFRAME: Registry): void;
export {};

wrappers/web-components.d.ts

import { ThreeARScene } from './ThreeARScene.js';
import { ThreeARModel, type ARAnimationOptions } from './ThreeARModel.js';
import { ThreeARVideo } from './ThreeARVideo.js';
import { type PlacementState } from './SurfacePlacement.js';
import { ARDiagnostics, type DiagnosticReport } from '../diagnostics/ARDiagnostics.js';
import type { WebAREngine, SurfaceTransitionOptions, SurfaceTransitionResult } from '../WebAREngine.js';
export interface ARComponentsOptions {
    assetBase?: string | URL;
}
export interface ARSceneElement extends HTMLElement {
    readonly app: ThreeARScene | null;
    readonly engine: WebAREngine | null;
    readonly updateComplete: Promise<void>;
    readonly diagnostics: ARDiagnostics | null;
    readonly placementState: PlacementState;
    confirmPlacement(): void;
    getDiagnosticsReport(): DiagnosticReport | null;
    downloadDiagnostics(): void;
    start(): Promise<void>;
    stop(): Promise<void>;
    refresh(): Promise<void>;
    enableSLAM(options?: SurfaceTransitionOptions): Promise<SurfaceTransitionResult>;
}
export interface ARModelElement extends HTMLElement {
    readonly model: ThreeARModel | null;
    readonly updateComplete: Promise<void>;
    reload(): Promise<void>;
    playAnimation(nameOrIndex: string | number, options?: ARAnimationOptions): void;
    pauseAnimations(): void;
    resumeAnimations(): void;
    stopAnimations(): void;
}
export interface ARVideoElement extends HTMLElement {
    readonly video: ThreeARVideo | null;
    readonly updateComplete: Promise<void>;
    reload(): Promise<void>;
    play(): Promise<void>;
    pause(): void;
}
/** Opt-in en ESM; standalone registra automáticamente. No toca DOM al importar en Node. */
export declare function registerARComponents(options?: ARComponentsOptions): void;
Apoya WebAR Fácil