@srsergio/taptapp-ar 1.0.19 → 1.0.21
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.js +3 -3
- package/dist/compiler/detector/detector-lite.js +1 -1
- package/dist/compiler/simple-ar.d.ts +3 -1
- package/dist/compiler/simple-ar.js +22 -16
- package/package.json +1 -1
- package/src/compiler/controller.js +4 -3
- package/src/compiler/detector/detector-lite.js +2 -1
- package/src/compiler/simple-ar.js +22 -15
|
@@ -13,9 +13,9 @@ catch (e) {
|
|
|
13
13
|
// Fallback for tests or other environments
|
|
14
14
|
ControllerWorker = null;
|
|
15
15
|
}
|
|
16
|
-
const DEFAULT_FILTER_CUTOFF = 0.
|
|
17
|
-
const DEFAULT_FILTER_BETA = 0.01; //
|
|
18
|
-
const DEFAULT_WARMUP_TOLERANCE =
|
|
16
|
+
const DEFAULT_FILTER_CUTOFF = 0.1; // Menor cutoff para filtrar más ruidos cuando está quieto
|
|
17
|
+
const DEFAULT_FILTER_BETA = 0.01; // Beta bajo para suavizar movimientos rápidos
|
|
18
|
+
const DEFAULT_WARMUP_TOLERANCE = 8; // Más frames de calentamiento para asegurar estabilidad inicial
|
|
19
19
|
const DEFAULT_MISS_TOLERANCE = 5;
|
|
20
20
|
class Controller {
|
|
21
21
|
constructor({ inputWidth, inputHeight, onUpdate = null, debugMode = false, maxTrack = 1, warmupTolerance = null, missTolerance = null, filterMinCF = null, filterBeta = null, worker = null, // Allow custom worker injection
|
|
@@ -14,7 +14,7 @@ import { gpuCompute } from "../utils/gpu-compute.js";
|
|
|
14
14
|
const PYRAMID_MIN_SIZE = 4; // Reducido de 8 a 4 para exprimir al máximo la resolución
|
|
15
15
|
// PYRAMID_MAX_OCTAVE ya no es necesario, el límite lo da PYRAMID_MIN_SIZE
|
|
16
16
|
const NUM_BUCKETS_PER_DIMENSION = 8;
|
|
17
|
-
const MAX_FEATURES_PER_BUCKET =
|
|
17
|
+
const MAX_FEATURES_PER_BUCKET = 12; // Ajustado para un equilibrio óptimo entre densidad y estabilidad
|
|
18
18
|
const ORIENTATION_NUM_BINS = 36;
|
|
19
19
|
const FREAK_EXPANSION_FACTOR = 7.0;
|
|
20
20
|
// Global GPU mode flag
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
* await ar.start();
|
|
16
16
|
*/
|
|
17
17
|
export class SimpleAR {
|
|
18
|
-
constructor({ container, targetSrc, overlay, onFound, onLost, onUpdate, cameraConfig, }: {
|
|
18
|
+
constructor({ container, targetSrc, overlay, scale, onFound, onLost, onUpdate, cameraConfig, }: {
|
|
19
19
|
container: any;
|
|
20
20
|
targetSrc: any;
|
|
21
21
|
overlay: any;
|
|
22
|
+
scale?: number | undefined;
|
|
22
23
|
onFound?: null | undefined;
|
|
23
24
|
onLost?: null | undefined;
|
|
24
25
|
onUpdate?: null | undefined;
|
|
@@ -31,6 +32,7 @@ export class SimpleAR {
|
|
|
31
32
|
container: any;
|
|
32
33
|
targetSrc: any;
|
|
33
34
|
overlay: any;
|
|
35
|
+
scaleMultiplier: number;
|
|
34
36
|
onFound: any;
|
|
35
37
|
onLost: any;
|
|
36
38
|
onUpdateCallback: any;
|
|
@@ -16,10 +16,12 @@ import { Controller } from "./controller.js";
|
|
|
16
16
|
* await ar.start();
|
|
17
17
|
*/
|
|
18
18
|
class SimpleAR {
|
|
19
|
-
constructor({ container, targetSrc, overlay,
|
|
19
|
+
constructor({ container, targetSrc, overlay, scale = 1.0, // Multiplicador de escala personalizado
|
|
20
|
+
onFound = null, onLost = null, onUpdate = null, cameraConfig = { facingMode: 'environment', width: 1280, height: 720 }, }) {
|
|
20
21
|
this.container = container;
|
|
21
22
|
this.targetSrc = targetSrc;
|
|
22
23
|
this.overlay = overlay;
|
|
24
|
+
this.scaleMultiplier = scale;
|
|
23
25
|
this.onFound = onFound;
|
|
24
26
|
this.onLost = onLost;
|
|
25
27
|
this.onUpdateCallback = onUpdate;
|
|
@@ -150,28 +152,32 @@ class SimpleAR {
|
|
|
150
152
|
const scaleX = displayW / videoW;
|
|
151
153
|
const scaleY = displayH / videoH;
|
|
152
154
|
// Project the center of the marker (markerW/2, markerH/2, 0) into camera space
|
|
153
|
-
// Marker coordinates are pixels from top-left.
|
|
154
155
|
const tx = mVT[0][0] * (markerW / 2) + mVT[0][1] * (markerH / 2) + mVT[0][3];
|
|
155
156
|
const ty = mVT[1][0] * (markerW / 2) + mVT[1][1] * (markerH / 2) + mVT[1][3];
|
|
156
157
|
const tz = mVT[2][0] * (markerW / 2) + mVT[2][1] * (markerH / 2) + mVT[2][3];
|
|
157
158
|
// focal length (roughly 45 degrees FOV match Controller.js)
|
|
158
159
|
const f = videoH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
|
|
159
160
|
// Perspective projection to screen space
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
//
|
|
161
|
+
// Using + for both since t is relative to principal point and Y is down in screen coords.
|
|
162
|
+
const screenX = offsetX + (videoW / 2 + (tx * f / tz)) * scaleX;
|
|
163
|
+
const screenY = offsetY + (videoH / 2 + (ty * f / tz)) * scaleY;
|
|
164
|
+
// Rotation calculation: atan2(y, x) of world X-axis in camera space
|
|
164
165
|
const rotation = Math.atan2(mVT[1][0], mVT[0][0]);
|
|
165
166
|
const matrixScale = Math.sqrt(mVT[0][0] ** 2 + mVT[1][0] ** 2);
|
|
166
|
-
// Perspective scale:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
//
|
|
173
|
-
const
|
|
174
|
-
|
|
167
|
+
// Perspective scale: 1 world pixel = (f/tz) screen pixels
|
|
168
|
+
const perspectiveScale = (f / tz) * scaleX;
|
|
169
|
+
// Detect overlay intrinsic size
|
|
170
|
+
const intrinsicWidth = (this.overlay instanceof HTMLVideoElement)
|
|
171
|
+
? this.overlay.videoWidth
|
|
172
|
+
: (this.overlay instanceof HTMLImageElement ? this.overlay.naturalWidth : 0);
|
|
173
|
+
// Final scale = (Target Width in Pixels on screen) / (Overlay Intrinsic Width) * scaleMultiplier
|
|
174
|
+
const baseScale = intrinsicWidth > 0
|
|
175
|
+
? (matrixScale * markerW * perspectiveScale) / intrinsicWidth
|
|
176
|
+
: 1.0;
|
|
177
|
+
const finalScale = baseScale * this.scaleMultiplier;
|
|
178
|
+
// Ensure element doesn't have CSS width that interferes with scaling
|
|
179
|
+
this.overlay.style.width = 'auto';
|
|
180
|
+
this.overlay.style.height = 'auto';
|
|
175
181
|
this.overlay.style.position = 'absolute';
|
|
176
182
|
this.overlay.style.transformOrigin = 'center center';
|
|
177
183
|
this.overlay.style.left = '0';
|
|
@@ -180,7 +186,7 @@ class SimpleAR {
|
|
|
180
186
|
translate(${screenX}px, ${screenY}px)
|
|
181
187
|
translate(-50%, -50%)
|
|
182
188
|
scale(${finalScale})
|
|
183
|
-
rotate(${
|
|
189
|
+
rotate(${rotation}rad)
|
|
184
190
|
`;
|
|
185
191
|
}
|
|
186
192
|
}
|
package/package.json
CHANGED
|
@@ -15,10 +15,11 @@ try {
|
|
|
15
15
|
ControllerWorker = null;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const DEFAULT_FILTER_CUTOFF = 0.
|
|
19
|
-
const DEFAULT_FILTER_BETA = 0.01; //
|
|
18
|
+
const DEFAULT_FILTER_CUTOFF = 0.1; // Menor cutoff para filtrar más ruidos cuando está quieto
|
|
19
|
+
const DEFAULT_FILTER_BETA = 0.01; // Beta bajo para suavizar movimientos rápidos
|
|
20
|
+
|
|
21
|
+
const DEFAULT_WARMUP_TOLERANCE = 8; // Más frames de calentamiento para asegurar estabilidad inicial
|
|
20
22
|
|
|
21
|
-
const DEFAULT_WARMUP_TOLERANCE = 5;
|
|
22
23
|
const DEFAULT_MISS_TOLERANCE = 5;
|
|
23
24
|
|
|
24
25
|
class Controller {
|
|
@@ -18,7 +18,8 @@ const PYRAMID_MIN_SIZE = 4; // Reducido de 8 a 4 para exprimir al máximo la res
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
const NUM_BUCKETS_PER_DIMENSION = 8;
|
|
21
|
-
const MAX_FEATURES_PER_BUCKET =
|
|
21
|
+
const MAX_FEATURES_PER_BUCKET = 12; // Ajustado para un equilibrio óptimo entre densidad y estabilidad
|
|
22
|
+
|
|
22
23
|
|
|
23
24
|
const ORIENTATION_NUM_BINS = 36;
|
|
24
25
|
const FREAK_EXPANSION_FACTOR = 7.0;
|
|
@@ -21,6 +21,7 @@ class SimpleAR {
|
|
|
21
21
|
container,
|
|
22
22
|
targetSrc,
|
|
23
23
|
overlay,
|
|
24
|
+
scale = 1.0, // Multiplicador de escala personalizado
|
|
24
25
|
onFound = null,
|
|
25
26
|
onLost = null,
|
|
26
27
|
onUpdate = null,
|
|
@@ -29,6 +30,7 @@ class SimpleAR {
|
|
|
29
30
|
this.container = container;
|
|
30
31
|
this.targetSrc = targetSrc;
|
|
31
32
|
this.overlay = overlay;
|
|
33
|
+
this.scaleMultiplier = scale;
|
|
32
34
|
this.onFound = onFound;
|
|
33
35
|
this.onLost = onLost;
|
|
34
36
|
this.onUpdateCallback = onUpdate;
|
|
@@ -178,7 +180,6 @@ class SimpleAR {
|
|
|
178
180
|
const scaleY = displayH / videoH;
|
|
179
181
|
|
|
180
182
|
// Project the center of the marker (markerW/2, markerH/2, 0) into camera space
|
|
181
|
-
// Marker coordinates are pixels from top-left.
|
|
182
183
|
const tx = mVT[0][0] * (markerW / 2) + mVT[0][1] * (markerH / 2) + mVT[0][3];
|
|
183
184
|
const ty = mVT[1][0] * (markerW / 2) + mVT[1][1] * (markerH / 2) + mVT[1][3];
|
|
184
185
|
const tz = mVT[2][0] * (markerW / 2) + mVT[2][1] * (markerH / 2) + mVT[2][3];
|
|
@@ -187,26 +188,32 @@ class SimpleAR {
|
|
|
187
188
|
const f = videoH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
|
|
188
189
|
|
|
189
190
|
// Perspective projection to screen space
|
|
190
|
-
|
|
191
|
-
const
|
|
191
|
+
// Using + for both since t is relative to principal point and Y is down in screen coords.
|
|
192
|
+
const screenX = offsetX + (videoW / 2 + (tx * f / tz)) * scaleX;
|
|
193
|
+
const screenY = offsetY + (videoH / 2 + (ty * f / tz)) * scaleY;
|
|
192
194
|
|
|
193
|
-
//
|
|
194
|
-
// Since marker coordinates are in pixels, mVT[0][0] and mVT[0][1] are unitless scale factors
|
|
195
|
+
// Rotation calculation: atan2(y, x) of world X-axis in camera space
|
|
195
196
|
const rotation = Math.atan2(mVT[1][0], mVT[0][0]);
|
|
196
197
|
const matrixScale = Math.sqrt(mVT[0][0] ** 2 + mVT[1][0] ** 2);
|
|
197
198
|
|
|
198
|
-
// Perspective scale:
|
|
199
|
-
|
|
200
|
-
const perspectiveScale = (f / -tz) * scaleX;
|
|
199
|
+
// Perspective scale: 1 world pixel = (f/tz) screen pixels
|
|
200
|
+
const perspectiveScale = (f / tz) * scaleX;
|
|
201
201
|
|
|
202
|
-
//
|
|
203
|
-
const
|
|
202
|
+
// Detect overlay intrinsic size
|
|
203
|
+
const intrinsicWidth = (this.overlay instanceof HTMLVideoElement)
|
|
204
|
+
? this.overlay.videoWidth
|
|
205
|
+
: (this.overlay instanceof HTMLImageElement ? this.overlay.naturalWidth : 0);
|
|
204
206
|
|
|
205
|
-
// Final scale = (Target Width in Pixels on screen) / (Overlay
|
|
206
|
-
|
|
207
|
-
|
|
207
|
+
// Final scale = (Target Width in Pixels on screen) / (Overlay Intrinsic Width) * scaleMultiplier
|
|
208
|
+
const baseScale = intrinsicWidth > 0
|
|
209
|
+
? (matrixScale * markerW * perspectiveScale) / intrinsicWidth
|
|
210
|
+
: 1.0;
|
|
208
211
|
|
|
209
|
-
|
|
212
|
+
const finalScale = baseScale * this.scaleMultiplier;
|
|
213
|
+
|
|
214
|
+
// Ensure element doesn't have CSS width that interferes with scaling
|
|
215
|
+
this.overlay.style.width = 'auto';
|
|
216
|
+
this.overlay.style.height = 'auto';
|
|
210
217
|
this.overlay.style.position = 'absolute';
|
|
211
218
|
this.overlay.style.transformOrigin = 'center center';
|
|
212
219
|
this.overlay.style.left = '0';
|
|
@@ -215,7 +222,7 @@ class SimpleAR {
|
|
|
215
222
|
translate(${screenX}px, ${screenY}px)
|
|
216
223
|
translate(-50%, -50%)
|
|
217
224
|
scale(${finalScale})
|
|
218
|
-
rotate(${
|
|
225
|
+
rotate(${rotation}rad)
|
|
219
226
|
`;
|
|
220
227
|
}
|
|
221
228
|
}
|