@srsergio/taptapp-ar 1.0.95 → 1.0.96
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/react/TaptappAR.js +20 -6
- package/dist/react/types.d.ts +1 -1
- package/dist/react/use-ar.d.ts +2 -1
- package/dist/react/use-ar.js +52 -45
- package/dist/runtime/index.d.ts +2 -1
- package/dist/runtime/index.js +2 -1
- package/dist/runtime/track.d.ts +170 -0
- package/dist/runtime/track.js +381 -0
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/react/TaptappAR.tsx +31 -6
- package/src/react/types.ts +1 -1
- package/src/react/use-ar.ts +59 -49
- package/src/runtime/index.ts +2 -1
- package/src/runtime/track.ts +623 -0
- package/dist/runtime/simple-ar.d.ts +0 -86
- package/dist/runtime/simple-ar.js +0 -323
- package/src/runtime/simple-ar.ts +0 -399
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export * from "./react/TaptappAR.js";
|
|
|
3
3
|
export * from "./react/use-ar.js";
|
|
4
4
|
export * from "./compiler/offline-compiler.js";
|
|
5
5
|
export { Controller } from "./runtime/controller.js";
|
|
6
|
-
export {
|
|
6
|
+
export { createTracker, startTracking } from "./runtime/track.js";
|
|
7
7
|
export * as protocol from "./core/protocol.js";
|
package/dist/index.js
CHANGED
|
@@ -3,5 +3,5 @@ export * from "./react/TaptappAR.js";
|
|
|
3
3
|
export * from "./react/use-ar.js";
|
|
4
4
|
export * from "./compiler/offline-compiler.js";
|
|
5
5
|
export { Controller } from "./runtime/controller.js";
|
|
6
|
-
export {
|
|
6
|
+
export { createTracker, startTracking } from "./runtime/track.js";
|
|
7
7
|
export * as protocol from "./core/protocol.js";
|
package/dist/react/TaptappAR.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { useAR } from "./use-ar.js";
|
|
4
4
|
export const TaptappAR = ({ config, className = "", showScanningOverlay = true, showErrorOverlay = true }) => {
|
|
5
|
-
const { containerRef, overlayRef, status, toggleVideo, trackedPoints } = useAR(config);
|
|
5
|
+
const { containerRef, overlayRef, status, toggleVideo, trackedPoints, error } = useAR(config);
|
|
6
6
|
// Simple heuristic to determine if it's a video or image
|
|
7
7
|
// based on the presence of videoSrc and common extensions
|
|
8
8
|
const isVideo = useMemo(() => {
|
|
@@ -12,7 +12,7 @@ export const TaptappAR = ({ config, className = "", showScanningOverlay = true,
|
|
|
12
12
|
const url = config.videoSrc.toLowerCase().split('?')[0];
|
|
13
13
|
return videoExtensions.some(ext => url.endsWith(ext)) || config.videoSrc.includes('video');
|
|
14
14
|
}, [config.videoSrc]);
|
|
15
|
-
return (_jsxs("div", { className: `taptapp-ar-wrapper ${className} ${status}`, style: { position: 'relative', width: '100%', height: '100%', overflow: 'hidden' }, children: [showScanningOverlay && status === "scanning" && (_jsx("div", { className: "taptapp-ar-overlay taptapp-ar-scanning", children: _jsxs("div", { className: "scanning-content", children: [_jsxs("div", { className: "scanning-frame", children: [_jsx("img", { className: "target-preview", src: config.targetImageSrc, alt: "Target", crossOrigin: "anonymous" }), _jsx("div", { className: "scanning-line" })] }), _jsx("p", { className: "scanning-text", children: "Apunta a la imagen para comenzar" })] }) })), showErrorOverlay && status === "error" && (_jsx("div", { className: "taptapp-ar-overlay taptapp-ar-error", children: _jsxs("div", { className: "error-content", children: [_jsx("span", { className: "error-icon", children: "\u26A0\uFE0F" }), _jsx("p", { className: "error-title", children: "No se pudo iniciar AR" }), _jsx("p", { className: "error-text", children: "Verifica los permisos de
|
|
15
|
+
return (_jsxs("div", { className: `taptapp-ar-wrapper ${className} ${status}`, style: { position: 'relative', width: '100%', height: '100%', overflow: 'hidden' }, children: [showScanningOverlay && status === "scanning" && (_jsx("div", { className: "taptapp-ar-overlay taptapp-ar-scanning", children: _jsxs("div", { className: "scanning-content", children: [_jsxs("div", { className: "scanning-frame", children: [_jsx("img", { className: "target-preview", src: config.targetImageSrc, alt: "Target", crossOrigin: "anonymous" }), _jsx("div", { className: "scanning-line" })] }), _jsx("p", { className: "scanning-text", children: "Apunta a la imagen para comenzar" })] }) })), status === "compiling" && (_jsx("div", { className: "taptapp-ar-overlay taptapp-ar-compiling", style: { background: 'rgba(0,0,0,0.9)' }, children: _jsxs("div", { className: "scanning-content", children: [_jsx("div", { className: "loading-spinner" }), _jsx("p", { className: "scanning-text", style: { marginTop: '20px' }, children: "Preparando motor AR..." }), _jsx("p", { style: { fontSize: '0.8rem', opacity: 0.6 }, children: "Compilando imagen de referencia" })] }) })), showErrorOverlay && status === "error" && (_jsx("div", { className: "taptapp-ar-overlay taptapp-ar-error", children: _jsxs("div", { className: "error-content", children: [_jsx("span", { className: "error-icon", children: "\u26A0\uFE0F" }), _jsx("p", { className: "error-title", children: "No se pudo iniciar AR" }), _jsx("p", { className: "error-text", children: error || "Verifica los permisos de cámara" }), _jsx("button", { className: "retry-btn", onClick: () => window.location.reload(), children: "Reintentar" })] }) })), _jsx("div", { ref: containerRef, className: "taptapp-ar-container", onClick: toggleVideo, style: { width: '100%', height: '100%' }, children: isVideo ? (_jsx("video", { ref: overlayRef, className: "taptapp-ar-overlay-element", src: config.videoSrc, preload: "auto", loop: true, playsInline: true, muted: true, crossOrigin: "anonymous" })) : (_jsx("img", { ref: overlayRef, className: "taptapp-ar-overlay-element", src: config.videoSrc || config.targetImageSrc, crossOrigin: "anonymous", alt: "AR Overlay" })) }), trackedPoints.length > 0 && (_jsx("div", { className: "taptapp-ar-points-overlay", style: { opacity: status === "tracking" ? 1 : 0.6 }, children: trackedPoints
|
|
16
16
|
.map((point, i) => {
|
|
17
17
|
// 🚀 Reflex visualization of the engine's new sensitivity
|
|
18
18
|
const isStable = point.stability > 0.3 && point.reliability > 0.2;
|
|
@@ -89,6 +89,17 @@ export const TaptappAR = ({ config, className = "", showScanningOverlay = true,
|
|
|
89
89
|
font-weight: 500;
|
|
90
90
|
letter-spacing: 0.5px;
|
|
91
91
|
}
|
|
92
|
+
.loading-spinner {
|
|
93
|
+
width: 40px;
|
|
94
|
+
height: 40px;
|
|
95
|
+
border: 3px solid rgba(255,255,255,0.1);
|
|
96
|
+
border-radius: 50%;
|
|
97
|
+
border-top-color: #00e5ff;
|
|
98
|
+
animation: spin 1s ease-in-out infinite;
|
|
99
|
+
}
|
|
100
|
+
@keyframes spin {
|
|
101
|
+
to { transform: rotate(360deg); }
|
|
102
|
+
}
|
|
92
103
|
.error-icon { font-size: 3rem; margin-bottom: 10px; }
|
|
93
104
|
.error-title { font-size: 1.2rem; font-weight: bold; margin: 0; }
|
|
94
105
|
.error-text { opacity: 0.8; margin: 5px 0 20px; }
|
|
@@ -104,12 +115,15 @@ export const TaptappAR = ({ config, className = "", showScanningOverlay = true,
|
|
|
104
115
|
}
|
|
105
116
|
.retry-btn:active { transform: scale(0.95); }
|
|
106
117
|
.taptapp-ar-overlay-element {
|
|
107
|
-
display:
|
|
108
|
-
|
|
118
|
+
display: none; /* Controlled by tracker */
|
|
119
|
+
position: absolute;
|
|
120
|
+
top: 0;
|
|
121
|
+
left: 0;
|
|
122
|
+
width: auto;
|
|
109
123
|
height: auto;
|
|
110
|
-
opacity: 0;
|
|
111
124
|
pointer-events: none;
|
|
112
|
-
|
|
125
|
+
z-index: 10;
|
|
126
|
+
/* Will be positioned via matrix3d by track.ts */
|
|
113
127
|
}
|
|
114
128
|
.taptapp-ar-points-overlay {
|
|
115
129
|
position: absolute;
|
package/dist/react/types.d.ts
CHANGED
package/dist/react/use-ar.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ARConfig } from "./types.js";
|
|
2
|
-
export type ARStatus = "scanning" | "tracking" | "error";
|
|
2
|
+
export type ARStatus = "compiling" | "scanning" | "tracking" | "error";
|
|
3
3
|
export interface TrackedPoint {
|
|
4
4
|
x: number;
|
|
5
5
|
y: number;
|
|
@@ -13,5 +13,6 @@ export interface UseARReturn {
|
|
|
13
13
|
isPlaying: boolean;
|
|
14
14
|
toggleVideo: () => Promise<void>;
|
|
15
15
|
trackedPoints: TrackedPoint[];
|
|
16
|
+
error: string | null;
|
|
16
17
|
}
|
|
17
18
|
export declare const useAR: (config: ARConfig) => UseARReturn;
|
package/dist/react/use-ar.js
CHANGED
|
@@ -5,6 +5,7 @@ export const useAR = (config) => {
|
|
|
5
5
|
const [status, setStatus] = useState("scanning");
|
|
6
6
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
7
7
|
const [trackedPoints, setTrackedPoints] = useState([]);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
8
9
|
const arInstanceRef = useRef(null);
|
|
9
10
|
const toggleVideo = useCallback(async () => {
|
|
10
11
|
const overlay = overlayRef.current;
|
|
@@ -31,65 +32,70 @@ export const useAR = (config) => {
|
|
|
31
32
|
const initAR = async () => {
|
|
32
33
|
try {
|
|
33
34
|
// Safe hybrid import for SSR + Speed
|
|
34
|
-
const {
|
|
35
|
+
const { createTracker } = await import("../runtime/track.js");
|
|
35
36
|
if (!isMounted)
|
|
36
37
|
return;
|
|
37
|
-
|
|
38
|
+
setStatus("compiling");
|
|
39
|
+
const instance = await createTracker({
|
|
38
40
|
container: containerRef.current,
|
|
39
|
-
targetSrc: config.targetTaarSrc,
|
|
41
|
+
targetSrc: config.targetTaarSrc || config.targetImageSrc,
|
|
40
42
|
overlay: overlayRef.current,
|
|
41
43
|
scale: config.scale,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
},
|
|
55
|
-
onFound: async ({ targetIndex }) => {
|
|
56
|
-
console.log(`🎯 Target ${targetIndex} detected!`);
|
|
57
|
-
if (!isMounted)
|
|
58
|
-
return;
|
|
59
|
-
setStatus("tracking");
|
|
60
|
-
const overlay = overlayRef.current;
|
|
61
|
-
if (overlay instanceof HTMLVideoElement) {
|
|
62
|
-
try {
|
|
63
|
-
await overlay.play();
|
|
64
|
-
setIsPlaying(true);
|
|
44
|
+
debugMode: false,
|
|
45
|
+
callbacks: {
|
|
46
|
+
onUpdate: (data) => {
|
|
47
|
+
const { screenCoords, reliabilities, stabilities } = data;
|
|
48
|
+
if (screenCoords && reliabilities && stabilities) {
|
|
49
|
+
const points = screenCoords.map((p, i) => ({
|
|
50
|
+
x: p.x,
|
|
51
|
+
y: p.y,
|
|
52
|
+
reliability: reliabilities[i],
|
|
53
|
+
stability: stabilities[i]
|
|
54
|
+
}));
|
|
55
|
+
setTrackedPoints(points);
|
|
65
56
|
}
|
|
66
|
-
|
|
67
|
-
|
|
57
|
+
},
|
|
58
|
+
onFound: async ({ targetIndex }) => {
|
|
59
|
+
console.log(`🎯 Target ${targetIndex} detected!`);
|
|
60
|
+
if (!isMounted)
|
|
61
|
+
return;
|
|
62
|
+
setStatus("tracking");
|
|
63
|
+
const overlay = overlayRef.current;
|
|
64
|
+
if (overlay instanceof HTMLVideoElement) {
|
|
65
|
+
try {
|
|
66
|
+
await overlay.play();
|
|
67
|
+
setIsPlaying(true);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
console.warn("Auto-play blocked:", err);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
onLost: ({ targetIndex }) => {
|
|
75
|
+
console.log(`👋 Target ${targetIndex} lost`);
|
|
76
|
+
if (!isMounted)
|
|
77
|
+
return;
|
|
78
|
+
setStatus("scanning");
|
|
79
|
+
setTrackedPoints([]);
|
|
80
|
+
const overlay = overlayRef.current;
|
|
81
|
+
if (overlay instanceof HTMLVideoElement) {
|
|
82
|
+
overlay.pause();
|
|
83
|
+
setIsPlaying(false);
|
|
68
84
|
}
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
onLost: ({ targetIndex }) => {
|
|
72
|
-
console.log(`👋 Target ${targetIndex} lost`);
|
|
73
|
-
if (!isMounted)
|
|
74
|
-
return;
|
|
75
|
-
setStatus("scanning");
|
|
76
|
-
setTrackedPoints([]);
|
|
77
|
-
const overlay = overlayRef.current;
|
|
78
|
-
if (overlay instanceof HTMLVideoElement) {
|
|
79
|
-
overlay.pause();
|
|
80
|
-
setIsPlaying(false);
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
});
|
|
84
88
|
arInstanceRef.current = instance;
|
|
85
|
-
await instance.
|
|
89
|
+
await instance.startCamera();
|
|
86
90
|
if (isMounted)
|
|
87
91
|
setStatus("scanning");
|
|
88
92
|
}
|
|
89
93
|
catch (err) {
|
|
90
|
-
console.error("
|
|
91
|
-
if (isMounted)
|
|
94
|
+
console.error("❌ [TapTapp AR] Error durante la inicialización:", err);
|
|
95
|
+
if (isMounted) {
|
|
96
|
+
setError(err.message || String(err));
|
|
92
97
|
setStatus("error");
|
|
98
|
+
}
|
|
93
99
|
}
|
|
94
100
|
};
|
|
95
101
|
initAR();
|
|
@@ -98,13 +104,14 @@ export const useAR = (config) => {
|
|
|
98
104
|
arInstanceRef.current?.stop();
|
|
99
105
|
arInstanceRef.current = null;
|
|
100
106
|
};
|
|
101
|
-
}, [config.targetTaarSrc, config.scale]);
|
|
107
|
+
}, [config.targetTaarSrc, config.targetImageSrc, config.scale]);
|
|
102
108
|
return {
|
|
103
109
|
containerRef,
|
|
104
110
|
overlayRef,
|
|
105
111
|
status,
|
|
106
112
|
isPlaying,
|
|
107
113
|
toggleVideo,
|
|
108
|
-
trackedPoints
|
|
114
|
+
trackedPoints,
|
|
115
|
+
error
|
|
109
116
|
};
|
|
110
117
|
};
|
package/dist/runtime/index.d.ts
CHANGED
package/dist/runtime/index.js
CHANGED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TapTapp AR - Easy Tracking Configuration
|
|
3
|
+
*
|
|
4
|
+
* Simple API for configuring image target tracking with minimal setup.
|
|
5
|
+
* Based on the reliable configuration from reliability-test.html.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createTracker } from 'taptapp-ar';
|
|
10
|
+
*
|
|
11
|
+
* const tracker = await createTracker({
|
|
12
|
+
* targetSrc: './my-target.png',
|
|
13
|
+
* container: document.getElementById('ar-container')!,
|
|
14
|
+
* overlay: document.getElementById('overlay')!,
|
|
15
|
+
* callbacks: {
|
|
16
|
+
* onFound: () => console.log('Target found!'),
|
|
17
|
+
* onLost: () => console.log('Target lost'),
|
|
18
|
+
* onUpdate: (data) => console.log('Update:', data)
|
|
19
|
+
* }
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Start tracking from camera
|
|
23
|
+
* tracker.startCamera();
|
|
24
|
+
*
|
|
25
|
+
* // Or track from a video/canvas element
|
|
26
|
+
* tracker.startVideo(videoElement);
|
|
27
|
+
*
|
|
28
|
+
* // Stop tracking
|
|
29
|
+
* tracker.stop();
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import { BioInspiredController } from './bio-inspired-controller.js';
|
|
33
|
+
/**
|
|
34
|
+
* Tracking update data passed to onUpdate callback
|
|
35
|
+
*/
|
|
36
|
+
export interface TrackingUpdate {
|
|
37
|
+
/** Whether the target is currently being tracked */
|
|
38
|
+
isTracking: boolean;
|
|
39
|
+
/** 4x4 world transformation matrix (column-major, for WebGL/Three.js) */
|
|
40
|
+
worldMatrix: number[] | null;
|
|
41
|
+
/** 3x4 model-view transform matrix */
|
|
42
|
+
modelViewTransform: number[][] | null;
|
|
43
|
+
/** Screen coordinates of tracked feature points */
|
|
44
|
+
screenCoords: Array<{
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
id: number;
|
|
48
|
+
}>;
|
|
49
|
+
/** Reliability scores (0-1) for each tracked point */
|
|
50
|
+
reliabilities: number[];
|
|
51
|
+
/** Stability scores (0-1) for each tracked point */
|
|
52
|
+
stabilities: number[];
|
|
53
|
+
/** Average reliability across all points */
|
|
54
|
+
avgReliability: number;
|
|
55
|
+
/** Average stability across all points */
|
|
56
|
+
avgStability: number;
|
|
57
|
+
/** Reference to the controller for advanced usage */
|
|
58
|
+
controller: BioInspiredController;
|
|
59
|
+
/** Index of the tracked target (for multi-target tracking) */
|
|
60
|
+
targetIndex: number;
|
|
61
|
+
/** Target dimensions [width, height] */
|
|
62
|
+
targetDimensions: [number, number];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Tracking event callbacks
|
|
66
|
+
*/
|
|
67
|
+
export interface TrackingCallbacks {
|
|
68
|
+
/**
|
|
69
|
+
* Called when the target is first detected
|
|
70
|
+
* @param data Initial tracking data
|
|
71
|
+
*/
|
|
72
|
+
onFound?: (data: TrackingUpdate) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Called when tracking is lost
|
|
75
|
+
* @param data Last known tracking data
|
|
76
|
+
*/
|
|
77
|
+
onLost?: (data: TrackingUpdate) => void;
|
|
78
|
+
/**
|
|
79
|
+
* Called on every frame update while tracking
|
|
80
|
+
* @param data Current tracking data
|
|
81
|
+
*/
|
|
82
|
+
onUpdate?: (data: TrackingUpdate) => void;
|
|
83
|
+
/**
|
|
84
|
+
* Called during target compilation
|
|
85
|
+
* @param progress Progress percentage (0-100)
|
|
86
|
+
*/
|
|
87
|
+
onCompileProgress?: (progress: number) => void;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Configuration options for the tracker
|
|
91
|
+
*/
|
|
92
|
+
export interface TrackerConfig {
|
|
93
|
+
/**
|
|
94
|
+
* Source of the target image to track.
|
|
95
|
+
* Can be a URL string, HTMLImageElement, ImageData, or ArrayBuffer (pre-compiled .taar)
|
|
96
|
+
*/
|
|
97
|
+
targetSrc: string | HTMLImageElement | ImageData | ArrayBuffer;
|
|
98
|
+
/**
|
|
99
|
+
* Container element for the video/canvas display
|
|
100
|
+
*/
|
|
101
|
+
container: HTMLElement;
|
|
102
|
+
/**
|
|
103
|
+
* Optional overlay element to position over the tracked target
|
|
104
|
+
*/
|
|
105
|
+
overlay?: HTMLElement;
|
|
106
|
+
/**
|
|
107
|
+
* Tracking event callbacks
|
|
108
|
+
*/
|
|
109
|
+
callbacks?: TrackingCallbacks;
|
|
110
|
+
/**
|
|
111
|
+
* Camera configuration (MediaStreamConstraints['video'])
|
|
112
|
+
* @default { facingMode: 'environment', width: { ideal: 1280 }, height: { ideal: 960 } }
|
|
113
|
+
*/
|
|
114
|
+
cameraConfig?: MediaStreamConstraints['video'];
|
|
115
|
+
/**
|
|
116
|
+
* Viewport width for processing
|
|
117
|
+
* @default 1280
|
|
118
|
+
*/
|
|
119
|
+
viewportWidth?: number;
|
|
120
|
+
/**
|
|
121
|
+
* Viewport height for processing
|
|
122
|
+
* @default 960
|
|
123
|
+
*/
|
|
124
|
+
viewportHeight?: number;
|
|
125
|
+
/**
|
|
126
|
+
* Enable debug mode for additional logging
|
|
127
|
+
* @default false
|
|
128
|
+
*/
|
|
129
|
+
debugMode?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Enable bio-inspired perception optimizations
|
|
132
|
+
* @default true
|
|
133
|
+
*/
|
|
134
|
+
bioInspiredEnabled?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Scale multiplier for the overlay
|
|
137
|
+
* @default 1.0
|
|
138
|
+
*/
|
|
139
|
+
scale?: number;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Tracker instance returned by createTracker
|
|
143
|
+
*/
|
|
144
|
+
export interface Tracker {
|
|
145
|
+
/** Start tracking from device camera */
|
|
146
|
+
startCamera(): Promise<void>;
|
|
147
|
+
/** Start tracking from a video or canvas element */
|
|
148
|
+
startVideo(source: HTMLVideoElement | HTMLCanvasElement): void;
|
|
149
|
+
/** Stop tracking and release resources */
|
|
150
|
+
stop(): void;
|
|
151
|
+
/** Whether the tracker is currently active */
|
|
152
|
+
readonly isActive: boolean;
|
|
153
|
+
/** Whether a target is currently being tracked */
|
|
154
|
+
readonly isTracking: boolean;
|
|
155
|
+
/** The underlying BioInspiredController instance */
|
|
156
|
+
readonly controller: BioInspiredController;
|
|
157
|
+
/** Target dimensions [width, height] */
|
|
158
|
+
readonly targetDimensions: [number, number];
|
|
159
|
+
/** Get the projection matrix for 3D rendering */
|
|
160
|
+
getProjectionMatrix(): number[];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create and configure an AR tracker with minimal setup
|
|
164
|
+
*/
|
|
165
|
+
export declare function createTracker(config: TrackerConfig): Promise<Tracker>;
|
|
166
|
+
/**
|
|
167
|
+
* Convenience function to create a tracker with camera autostart
|
|
168
|
+
*/
|
|
169
|
+
export declare function startTracking(config: TrackerConfig): Promise<Tracker>;
|
|
170
|
+
export default createTracker;
|