@srsergio/taptapp-ar 1.0.77 → 1.0.79
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/compiler/controller.d.ts +2 -6
- package/dist/compiler/controller.js +43 -44
- package/dist/compiler/features/auto-rotation-feature.d.ts +15 -0
- package/dist/compiler/features/auto-rotation-feature.js +30 -0
- package/dist/compiler/features/crop-detection-feature.d.ts +18 -0
- package/dist/compiler/features/crop-detection-feature.js +26 -0
- package/dist/compiler/features/feature-base.d.ts +46 -0
- package/dist/compiler/features/feature-base.js +1 -0
- package/dist/compiler/features/feature-manager.d.ts +12 -0
- package/dist/compiler/features/feature-manager.js +55 -0
- package/dist/compiler/features/one-euro-filter-feature.d.ts +15 -0
- package/dist/compiler/features/one-euro-filter-feature.js +37 -0
- package/dist/compiler/features/temporal-filter-feature.d.ts +19 -0
- package/dist/compiler/features/temporal-filter-feature.js +57 -0
- package/dist/compiler/offline-compiler.d.ts +92 -8
- package/dist/compiler/offline-compiler.js +3 -86
- package/dist/react/TaptappAR.js +3 -0
- package/dist/react/use-ar.js +1 -0
- package/package.json +1 -1
- package/src/compiler/FEATURES.md +40 -0
- package/src/compiler/controller.ts +54 -42
- package/src/compiler/features/auto-rotation-feature.ts +36 -0
- package/src/compiler/features/crop-detection-feature.ts +31 -0
- package/src/compiler/features/feature-base.ts +48 -0
- package/src/compiler/features/feature-manager.ts +65 -0
- package/src/compiler/features/one-euro-filter-feature.ts +44 -0
- package/src/compiler/features/temporal-filter-feature.ts +68 -0
- package/src/compiler/offline-compiler.ts +3 -94
- package/src/react/TaptappAR.tsx +3 -0
- package/src/react/use-ar.ts +1 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ControllerFeature } from "./feature-base.js";
|
|
2
|
+
|
|
3
|
+
export interface TemporalState {
|
|
4
|
+
showing: boolean;
|
|
5
|
+
trackCount: number;
|
|
6
|
+
trackMiss: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class TemporalFilterFeature implements ControllerFeature {
|
|
10
|
+
id = "temporal-filter";
|
|
11
|
+
name = "Temporal Filter";
|
|
12
|
+
description = "Provides warmup tolerance (to avoid false positives) and miss tolerance (to maintain tracking during brief occlusions).";
|
|
13
|
+
enabled = true;
|
|
14
|
+
|
|
15
|
+
private states: TemporalState[] = [];
|
|
16
|
+
private warmupTolerance: number;
|
|
17
|
+
private missTolerance: number;
|
|
18
|
+
private onToggleShowing?: (targetIndex: number, showing: boolean) => void;
|
|
19
|
+
|
|
20
|
+
constructor(warmup: number = 2, miss: number = 5, onToggleShowing?: (targetIndex: number, showing: boolean) => void) {
|
|
21
|
+
this.warmupTolerance = warmup;
|
|
22
|
+
this.missTolerance = miss;
|
|
23
|
+
this.onToggleShowing = onToggleShowing;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private getState(targetIndex: number): TemporalState {
|
|
27
|
+
if (!this.states[targetIndex]) {
|
|
28
|
+
this.states[targetIndex] = {
|
|
29
|
+
showing: false,
|
|
30
|
+
trackCount: 0,
|
|
31
|
+
trackMiss: 0,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return this.states[targetIndex];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
shouldShow(targetIndex: number, isTracking: boolean): boolean {
|
|
38
|
+
if (!this.enabled) return isTracking;
|
|
39
|
+
|
|
40
|
+
const state = this.getState(targetIndex);
|
|
41
|
+
|
|
42
|
+
if (!state.showing) {
|
|
43
|
+
if (isTracking) {
|
|
44
|
+
state.trackMiss = 0;
|
|
45
|
+
state.trackCount += 1;
|
|
46
|
+
if (state.trackCount > this.warmupTolerance) {
|
|
47
|
+
state.showing = true;
|
|
48
|
+
this.onToggleShowing?.(targetIndex, true);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
state.trackCount = 0;
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
if (!isTracking) {
|
|
55
|
+
state.trackCount = 0;
|
|
56
|
+
state.trackMiss += 1;
|
|
57
|
+
if (state.trackMiss > this.missTolerance) {
|
|
58
|
+
state.showing = false;
|
|
59
|
+
this.onToggleShowing?.(targetIndex, false);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
state.trackMiss = 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return state.showing;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -11,7 +11,6 @@ import { extractTrackingFeatures } from "./tracker/extract-utils.js";
|
|
|
11
11
|
import { DetectorLite } from "./detector/detector-lite.js";
|
|
12
12
|
import { build as hierarchicalClusteringBuild } from "./matching/hierarchical-clustering.js";
|
|
13
13
|
import * as msgpack from "@msgpack/msgpack";
|
|
14
|
-
import { WorkerPool } from "./utils/worker-pool.js";
|
|
15
14
|
|
|
16
15
|
// Detect environment
|
|
17
16
|
const isNode = typeof process !== "undefined" &&
|
|
@@ -22,40 +21,9 @@ const CURRENT_VERSION = 7; // Protocol v7: Moonshot - 4-bit Packed Tracking Data
|
|
|
22
21
|
|
|
23
22
|
export class OfflineCompiler {
|
|
24
23
|
data: any = null;
|
|
25
|
-
workerPool: WorkerPool | null = null;
|
|
26
24
|
|
|
27
25
|
constructor() {
|
|
28
|
-
|
|
29
|
-
if (!isNode) {
|
|
30
|
-
console.log("🌐 OfflineCompiler: Browser mode (no workers)");
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async _initNodeWorkers() {
|
|
35
|
-
try {
|
|
36
|
-
const pathModule = "path";
|
|
37
|
-
const urlModule = "url";
|
|
38
|
-
const osModule = "os";
|
|
39
|
-
const workerThreadsModule = "node:worker_threads";
|
|
40
|
-
|
|
41
|
-
const [path, url, os, { Worker }] = await Promise.all([
|
|
42
|
-
import(/* @vite-ignore */ pathModule),
|
|
43
|
-
import(/* @vite-ignore */ urlModule),
|
|
44
|
-
import(/* @vite-ignore */ osModule),
|
|
45
|
-
import(/* @vite-ignore */ workerThreadsModule)
|
|
46
|
-
]);
|
|
47
|
-
|
|
48
|
-
const __filename = url.fileURLToPath(import.meta.url);
|
|
49
|
-
const __dirname = path.dirname(__filename);
|
|
50
|
-
const workerPath = path.join(__dirname, "node-worker.js");
|
|
51
|
-
|
|
52
|
-
// Limit workers to avoid freezing system
|
|
53
|
-
const numWorkers = Math.min(os.cpus().length, 4);
|
|
54
|
-
|
|
55
|
-
this.workerPool = new WorkerPool(workerPath, numWorkers, Worker);
|
|
56
|
-
} catch (e) {
|
|
57
|
-
console.log("⚡ OfflineCompiler: Running without workers (initialization failed)", e);
|
|
58
|
-
}
|
|
26
|
+
console.log("⚡ OfflineCompiler: Main thread mode (no workers)");
|
|
59
27
|
}
|
|
60
28
|
|
|
61
29
|
async compileImageTargets(images: any[], progressCallback: (p: number) => void) {
|
|
@@ -108,25 +76,7 @@ export class OfflineCompiler {
|
|
|
108
76
|
}
|
|
109
77
|
|
|
110
78
|
async _compileTarget(targetImages: any[], progressCallback: (p: number) => void) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (this.workerPool) {
|
|
114
|
-
const progressMap = new Float32Array(targetImages.length);
|
|
115
|
-
const wrappedPromises = targetImages.map((targetImage: any, index: number) => {
|
|
116
|
-
return this.workerPool!.runTask({
|
|
117
|
-
type: 'compile-all', // 🚀 MOONSHOT: Combined task
|
|
118
|
-
targetImage,
|
|
119
|
-
onProgress: (p: number) => {
|
|
120
|
-
progressMap[index] = p;
|
|
121
|
-
const sum = progressMap.reduce((a, b) => a + b, 0);
|
|
122
|
-
progressCallback(sum / targetImages.length);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
return Promise.all(wrappedPromises);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Fallback or non-worker implementation: run match and track sequentially
|
|
79
|
+
// Run match and track sequentially to match browser behavior exactly
|
|
130
80
|
const matchingResults = await this._compileMatch(targetImages, (p) => progressCallback(p * 0.5));
|
|
131
81
|
const trackingResults = await this._compileTrack(targetImages, (p) => progressCallback(50 + p * 0.5));
|
|
132
82
|
|
|
@@ -140,27 +90,6 @@ export class OfflineCompiler {
|
|
|
140
90
|
const percentPerImage = 100 / targetImages.length;
|
|
141
91
|
let currentPercent = 0;
|
|
142
92
|
|
|
143
|
-
if (isNode) await this._initNodeWorkers();
|
|
144
|
-
if (this.workerPool) {
|
|
145
|
-
const progressMap = new Float32Array(targetImages.length);
|
|
146
|
-
|
|
147
|
-
const wrappedPromises = targetImages.map((targetImage: any, index: number) => {
|
|
148
|
-
return this.workerPool!.runTask({
|
|
149
|
-
type: 'match',
|
|
150
|
-
targetImage,
|
|
151
|
-
percentPerImage,
|
|
152
|
-
basePercent: 0,
|
|
153
|
-
onProgress: (p: number) => {
|
|
154
|
-
progressMap[index] = p;
|
|
155
|
-
const sum = progressMap.reduce((a, b) => a + b, 0);
|
|
156
|
-
progressCallback(sum);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
return Promise.all(wrappedPromises);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
93
|
const results = [];
|
|
165
94
|
for (let i = 0; i < targetImages.length; i++) {
|
|
166
95
|
const targetImage = targetImages[i];
|
|
@@ -201,24 +130,6 @@ export class OfflineCompiler {
|
|
|
201
130
|
const percentPerImage = 100 / targetImages.length;
|
|
202
131
|
let currentPercent = 0;
|
|
203
132
|
|
|
204
|
-
if (this.workerPool) {
|
|
205
|
-
const progressMap = new Float32Array(targetImages.length);
|
|
206
|
-
const wrappedPromises = targetImages.map((targetImage: any, index: number) => {
|
|
207
|
-
return this.workerPool!.runTask({
|
|
208
|
-
type: 'compile',
|
|
209
|
-
targetImage,
|
|
210
|
-
percentPerImage,
|
|
211
|
-
basePercent: 0,
|
|
212
|
-
onProgress: (p: number) => {
|
|
213
|
-
progressMap[index] = p;
|
|
214
|
-
const sum = progressMap.reduce((a, b) => a + b, 0);
|
|
215
|
-
progressCallback(sum);
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
return Promise.all(wrappedPromises);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
133
|
const results = [];
|
|
223
134
|
for (let i = 0; i < targetImages.length; i++) {
|
|
224
135
|
const targetImage = targetImages[i];
|
|
@@ -480,9 +391,7 @@ export class OfflineCompiler {
|
|
|
480
391
|
}
|
|
481
392
|
|
|
482
393
|
async destroy() {
|
|
483
|
-
|
|
484
|
-
await this.workerPool.destroy();
|
|
485
|
-
}
|
|
394
|
+
// No workers to destroy
|
|
486
395
|
}
|
|
487
396
|
|
|
488
397
|
|
package/src/react/TaptappAR.tsx
CHANGED
package/src/react/use-ar.ts
CHANGED
|
@@ -52,6 +52,7 @@ export const useAR = (config: ARConfig): UseARReturn => {
|
|
|
52
52
|
targetSrc: config.targetTaarSrc,
|
|
53
53
|
overlay: overlayRef.current!,
|
|
54
54
|
scale: config.scale,
|
|
55
|
+
debug: false,
|
|
55
56
|
onFound: async ({ targetIndex }) => {
|
|
56
57
|
console.log(`🎯 Target ${targetIndex} detected!`);
|
|
57
58
|
if (!isMounted) return;
|