WebAR FácilOpen exampleEspañol

Generated public API

Generated from the public exports and TypeScript declarations. Relative imports retain their original context. The standalone script also exposes the THREE namespace.

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

See WebAREngine and the advanced API for integration guidance.

Pose.d.ts

export interface ARPose {
    targetId?: string;
    backend: 'image' | 'webxr' | 'optical-flow';
    timestampMs: number;
    scale: 'metric' | 'relative';
    scaleSource?: 'experimental-inertial';
    matrix: Float32Array;
    worldMatrix: Float32Array;
    viewMatrix: Float32Array;
    projectionMatrix: Float32Array | null;
    projectionSource?: 'calibrated' | 'estimated' | 'webxr';
    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 {
    experimentalMetricScale?: ExperimentalMetricScale;
    keyframeCorrection?: boolean;
    imageLossGraceMs?: number;
    keepContentOnLost?: boolean;
    imageSmoothingMs?: number;
    camera?: Omit<CameraManagerOptions, 'onFrame' | 'onError'>;
    tracker?: TrackerOptions;
    opencvURL?: string | URL;
    calibration?: CameraIntrinsics;
    fallback?: OpticalFlowOptions | false;
    attachXRSession?: (session: XRSession) => Promise<void>;
    getXRContext?: () => WebGL2RenderingContext;
    overlayRoot?: HTMLElement;
}
export interface ImageTargetOptions {
    physicalWidthMeters?: number;
    maxDimension?: number;
}
export interface ImageTargetMetadata {
    format: 'WART';
    version: 2;
    width: number;
    height: number;
    physicalWidthMeters: number;
    extractorId: number;
    quality: MarkerQuality;
}
export interface ImageTargetResult {
    buffer: ArrayBuffer;
    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;
}
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;
    setKeepContentOnLost(value: boolean, targetId?: string): void;
    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>;
    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>;
    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';
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 {
    imageData: ImageData;
    timestampMs: number;
    mediaTimeSeconds: number;
    sessionId: number;
    sourceWidth: number;
    sourceHeight: number;
}
export interface CameraManagerOptions {
    onFrame: (frame: CameraFrame, signal: AbortSignal) => void | Promise<void>;
    onError?: (error: Error) => void;
    onStatus?: (status: 'camera-requesting' | 'camera-granted' | 'camera-playing') => void;
    playbackContainer?: HTMLElement;
    performance?: 'auto' | 'balanced' | 'battery' | 'quality';
    width?: number;
    height?: number;
    facingMode?: 'environment' | 'user';
    deviceId?: string;
    fps?: number;
    maxFrameWidth?: number;
    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'];
}
export declare class CameraManager {
    constructor(options: CameraManagerOptions);
    get state(): 'idle' | 'starting' | 'running' | 'paused' | 'disposed';
    get videoElement(): HTMLVideoElement;
    get settings(): MediaTrackSettings | null;
    setAdaptiveResolution(enabled: boolean): void;
    setTrackingFeedback(qualities: readonly TrackingQualityEvent[], frameWidth?: number): void;
    setAnalysisWidth(width: number): void;
    setFocus(mode: 'continuous' | 'manual', distance?: number): Promise<boolean>;
    start(): Promise<void>;
    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;
}
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'>;
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')[];
}
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>;
}
export declare class ExperimentalMetricScale {
    start(): Promise<boolean>;
    stop(): void;
    setGuidedMotionCapture(active: boolean): void;
    hasStableVisualTracking(now?: number): boolean;
    pauseGuidedMotionPhase(): void;
    setGuidedMotionPhase(id: string): void;
    diagnostics(): MetricScaleDiagnostics;
    guidedReturnError(outboundId: string, inboundId: string): number | null;
    resetMap(): void;
    interrupt(reason?: Interruption): void;
    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;
    keyframeCorrection?: boolean;
    floorROI: {
        x: number;
        y: number;
        width: number;
        height: number;
    };
}
export interface OdometryMapSnapshot {
    version: 1;
    intrinsics: CameraIntrinsics;
    scale: 'relative' | 'metric';
    mapId: string;
    keyframes: {
        descriptors: Uint8Array;
        points: Float32Array;
        view: Float32Array;
    }[];
    groundPlane?: {
        worldFromPlane: Float32Array;
        inliers: number;
    };
    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"
];
export type OdometryScanHint = typeof ODOMETRY_SCAN_HINTS[number];
export type OdometryEstimate = ({
    status: 'initializing' | 'lost';
    mapId: string;
} | {
    status: 'tracked';
    mapId: string;
    worldFromCamera: Float32Array;
    projectionMatrix: Float32Array;
    scale: 'relative' | 'metric';
    trackedPoints: number;
    environmentReady?: boolean;
    processingMs?: number;
    reprojectionErrorPx?: number;
    relocalized?: boolean;
    keyframeCorrected?: boolean;
    stationary?: boolean;
    groundPlane?: {
        worldFromPlane: Float32Array;
        inliers: number;
    };
}) & {
    timings?: OdometryTimings;
    scanHint?: OdometryScanHint;
};
export interface OdometryBackend {
    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 {
    moduleURL?: URL;
    workerFactory?: () => Worker;
}
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 {
    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;
}
export declare class SLAMManager {
    get imageAlignmentAvailable(): boolean;
    get hasPlacement(): boolean;
    get referenceEpoch(): number;
    constructor(options: SLAMOptions);
    static isSupported(): Promise<boolean>;
    start(signal?: AbortSignal): Promise<void>;
    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;
    });
    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;
    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 {
    affineViews?: boolean;
    physicalWidthMeters: number;
    opencvURL?: string;
    extractorId?: number;
    maxDimension?: number;
    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[];
}
export declare function crc32(bytes: Uint8Array): number;
export declare function analyzeFeatures(features: MarkerFeatures): MarkerQuality;
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;
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>;
    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';
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

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;
export declare function scaleIntrinsics(k: CameraIntrinsics, width: number, height: number): CameraIntrinsics;
export declare function estimateIntrinsics(width: number, height: number, verticalFovDegrees?: number): CameraIntrinsics;
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';
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();
    bind(engine: WebAREngine, targetId?: string): this;
    unbind(): void;
    dispose(): void;
    update(matrix: Float32Array, pose?: ARPose): void;
}

wrappers/ThreeARModel.d.ts

import { Group } from 'three';
export interface ARModelOptions {
    dracoDecoderPath?: string | URL;
    maxBytes?: number;
}
export interface ARModelLoadOptions {
    fitSize?: number | false;
    autoplay?: boolean;
    signal?: AbortSignal;
}
export interface ARAnimationOptions {
    loop?: 'repeat' | 'once' | 'pingpong';
    repetitions?: number;
    speed?: number;
    crossFadeSeconds?: number;
    clampWhenFinished?: boolean;
}
export declare class ThreeARModel extends Group {
    constructor(options?: ARModelOptions);
    get model(): Group | null;
    load(source: Blob | string | URL, options?: ARModelLoadOptions): Promise<this>;
    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';
    antialias?: boolean;
}
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;
}
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;
    setSource(source: Blob | string | URL): Promise<void>;
    play(): Promise<void>;
    pause(): void;
    dispose(): void;
}

wrappers/ThreeCameraBackground.d.ts

import { Mesh } from 'three';
import type { CameraIntrinsics } from '../Pose.js';
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;
}
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;
}
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;
}
export declare function registerARComponents(options?: ARComponentsOptions): void;
Support WebAR Fácil