@srsergio/taptapp-ar 1.0.14 → 1.0.16

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.
@@ -24,11 +24,16 @@ class CropDetector {
24
24
  }
25
25
  detectMoving(input) {
26
26
  const imageData = input;
27
- // loop a few locations around center
28
- const dx = this.lastRandomIndex % 3;
29
- const dy = Math.floor(this.lastRandomIndex / 3);
30
- let startY = Math.floor(this.height / 2 - this.cropSize + (dy * this.cropSize) / 2);
31
- let startX = Math.floor(this.width / 2 - this.cropSize + (dx * this.cropSize) / 2);
27
+ // Expanded to 5x5 grid (25 positions) for better coverage
28
+ const gridSize = 5;
29
+ const dx = this.lastRandomIndex % gridSize;
30
+ const dy = Math.floor(this.lastRandomIndex / gridSize);
31
+ // Calculate offset from center, with overlap for better detection
32
+ const stepX = this.cropSize / 3;
33
+ const stepY = this.cropSize / 3;
34
+ let startY = Math.floor(this.height / 2 - this.cropSize / 2 + (dy - 2) * stepY);
35
+ let startX = Math.floor(this.width / 2 - this.cropSize / 2 + (dx - 2) * stepX);
36
+ // Clamp to valid bounds
32
37
  if (startX < 0)
33
38
  startX = 0;
34
39
  if (startY < 0)
@@ -37,7 +42,7 @@ class CropDetector {
37
42
  startX = this.width - this.cropSize - 1;
38
43
  if (startY >= this.height - this.cropSize)
39
44
  startY = this.height - this.cropSize - 1;
40
- this.lastRandomIndex = (this.lastRandomIndex + 1) % 9;
45
+ this.lastRandomIndex = (this.lastRandomIndex + 1) % (gridSize * gridSize);
41
46
  const result = this._detect(imageData, startX, startY);
42
47
  return result;
43
48
  }
@@ -14,7 +14,7 @@ import { gpuCompute } from "../utils/gpu-compute.js";
14
14
  const PYRAMID_MIN_SIZE = 8;
15
15
  const PYRAMID_MAX_OCTAVE = 5;
16
16
  const NUM_BUCKETS_PER_DIMENSION = 8;
17
- const MAX_FEATURES_PER_BUCKET = 3; // Optimizado: Reducido de 5 a 3 para menor peso
17
+ const MAX_FEATURES_PER_BUCKET = 10; // Aumentado de 3 a 10 para mayor densidad de puntos tracking
18
18
  const ORIENTATION_NUM_BINS = 36;
19
19
  const FREAK_EXPANSION_FACTOR = 7.0;
20
20
  // Global GPU mode flag
@@ -241,8 +241,8 @@ export class DetectorLite {
241
241
  for (let y = 1; y < height - 1; y++) {
242
242
  for (let x = 1; x < width - 1; x++) {
243
243
  const val = curr.data[y * width + x];
244
- if (Math.abs(val) < 0.015)
245
- continue; // Threshold
244
+ if (Math.abs(val) < 0.01)
245
+ continue; // Threshold reducido de 0.015 a 0.01 para mayor sensibilidad
246
246
  let isMaxima = true;
247
247
  let isMinima = true;
248
248
  // Check 3x3 neighborhood in current scale
@@ -152,11 +152,19 @@ class SimpleAR {
152
152
  // Matrix is column-major: [m0,m1,m2,m3, m4,m5,m6,m7, m8,m9,m10,m11, m12,m13,m14,m15]
153
153
  const tx = worldMatrix[12];
154
154
  const ty = worldMatrix[13];
155
- const scale = Math.sqrt(worldMatrix[0] ** 2 + worldMatrix[1] ** 2);
155
+ const tz = worldMatrix[14];
156
+ // focal length (roughly 45 degrees FOV)
157
+ const f = videoH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
158
+ // Standard perspective projection to screen space
159
+ // tx, ty, tz are in marker units relative to camera
160
+ const screenX = offsetX + (videoW / 2 + (tx * f / -tz)) * scaleX;
161
+ const screenY = offsetY + (videoH / 2 - (ty * f / -tz)) * scaleY;
162
+ // Calculate rotation and scale from the matrix
156
163
  const rotation = Math.atan2(worldMatrix[1], worldMatrix[0]);
157
- // Convert from normalized coords to screen coords
158
- const screenX = offsetX + (videoW / 2 + tx) * scaleX;
159
- const screenY = offsetY + (videoH / 2 - ty) * scaleY;
164
+ const matrixScale = Math.sqrt(worldMatrix[0] ** 2 + worldMatrix[1] ** 2);
165
+ // Perspective scale: how much larger/smaller the object is based on distance (tz)
166
+ const perspectiveScale = (f / -tz) * scaleX;
167
+ const finalScale = matrixScale * perspectiveScale;
160
168
  // Apply transform
161
169
  this.overlay.style.position = 'absolute';
162
170
  this.overlay.style.transformOrigin = 'center center';
@@ -165,7 +173,7 @@ class SimpleAR {
165
173
  this.overlay.style.transform = `
166
174
  translate(${screenX}px, ${screenY}px)
167
175
  translate(-50%, -50%)
168
- scale(${scale * scaleX * 0.01})
176
+ scale(${finalScale})
169
177
  rotate(${-rotation}rad)
170
178
  `;
171
179
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srsergio/taptapp-ar",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "AR Compiler for Node.js and Browser",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,19 +33,25 @@ class CropDetector {
33
33
  detectMoving(input) {
34
34
  const imageData = input;
35
35
 
36
- // loop a few locations around center
37
- const dx = this.lastRandomIndex % 3;
38
- const dy = Math.floor(this.lastRandomIndex / 3);
36
+ // Expanded to 5x5 grid (25 positions) for better coverage
37
+ const gridSize = 5;
38
+ const dx = this.lastRandomIndex % gridSize;
39
+ const dy = Math.floor(this.lastRandomIndex / gridSize);
39
40
 
40
- let startY = Math.floor(this.height / 2 - this.cropSize + (dy * this.cropSize) / 2);
41
- let startX = Math.floor(this.width / 2 - this.cropSize + (dx * this.cropSize) / 2);
41
+ // Calculate offset from center, with overlap for better detection
42
+ const stepX = this.cropSize / 3;
43
+ const stepY = this.cropSize / 3;
42
44
 
45
+ let startY = Math.floor(this.height / 2 - this.cropSize / 2 + (dy - 2) * stepY);
46
+ let startX = Math.floor(this.width / 2 - this.cropSize / 2 + (dx - 2) * stepX);
47
+
48
+ // Clamp to valid bounds
43
49
  if (startX < 0) startX = 0;
44
50
  if (startY < 0) startY = 0;
45
51
  if (startX >= this.width - this.cropSize) startX = this.width - this.cropSize - 1;
46
52
  if (startY >= this.height - this.cropSize) startY = this.height - this.cropSize - 1;
47
53
 
48
- this.lastRandomIndex = (this.lastRandomIndex + 1) % 9;
54
+ this.lastRandomIndex = (this.lastRandomIndex + 1) % (gridSize * gridSize);
49
55
 
50
56
  const result = this._detect(imageData, startX, startY);
51
57
  return result;
@@ -16,7 +16,7 @@ import { gpuCompute } from "../utils/gpu-compute.js";
16
16
  const PYRAMID_MIN_SIZE = 8;
17
17
  const PYRAMID_MAX_OCTAVE = 5;
18
18
  const NUM_BUCKETS_PER_DIMENSION = 8;
19
- const MAX_FEATURES_PER_BUCKET = 3; // Optimizado: Reducido de 5 a 3 para menor peso
19
+ const MAX_FEATURES_PER_BUCKET = 10; // Aumentado de 3 a 10 para mayor densidad de puntos tracking
20
20
  const ORIENTATION_NUM_BINS = 36;
21
21
  const FREAK_EXPANSION_FACTOR = 7.0;
22
22
 
@@ -282,7 +282,7 @@ export class DetectorLite {
282
282
  for (let x = 1; x < width - 1; x++) {
283
283
  const val = curr.data[y * width + x];
284
284
 
285
- if (Math.abs(val) < 0.015) continue; // Threshold
285
+ if (Math.abs(val) < 0.01) continue; // Threshold reducido de 0.015 a 0.01 para mayor sensibilidad
286
286
 
287
287
  let isMaxima = true;
288
288
  let isMinima = true;
@@ -179,12 +179,23 @@ class SimpleAR {
179
179
  // Matrix is column-major: [m0,m1,m2,m3, m4,m5,m6,m7, m8,m9,m10,m11, m12,m13,m14,m15]
180
180
  const tx = worldMatrix[12];
181
181
  const ty = worldMatrix[13];
182
- const scale = Math.sqrt(worldMatrix[0] ** 2 + worldMatrix[1] ** 2);
182
+ const tz = worldMatrix[14];
183
+
184
+ // focal length (roughly 45 degrees FOV)
185
+ const f = videoH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
186
+
187
+ // Standard perspective projection to screen space
188
+ // tx, ty, tz are in marker units relative to camera
189
+ const screenX = offsetX + (videoW / 2 + (tx * f / -tz)) * scaleX;
190
+ const screenY = offsetY + (videoH / 2 - (ty * f / -tz)) * scaleY;
191
+
192
+ // Calculate rotation and scale from the matrix
183
193
  const rotation = Math.atan2(worldMatrix[1], worldMatrix[0]);
194
+ const matrixScale = Math.sqrt(worldMatrix[0] ** 2 + worldMatrix[1] ** 2);
184
195
 
185
- // Convert from normalized coords to screen coords
186
- const screenX = offsetX + (videoW / 2 + tx) * scaleX;
187
- const screenY = offsetY + (videoH / 2 - ty) * scaleY;
196
+ // Perspective scale: how much larger/smaller the object is based on distance (tz)
197
+ const perspectiveScale = (f / -tz) * scaleX;
198
+ const finalScale = matrixScale * perspectiveScale;
188
199
 
189
200
  // Apply transform
190
201
  this.overlay.style.position = 'absolute';
@@ -194,7 +205,7 @@ class SimpleAR {
194
205
  this.overlay.style.transform = `
195
206
  translate(${screenX}px, ${screenY}px)
196
207
  translate(-50%, -50%)
197
- scale(${scale * scaleX * 0.01})
208
+ scale(${finalScale})
198
209
  rotate(${-rotation}rad)
199
210
  `;
200
211
  }