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;