@srsergio/taptapp-ar 1.0.73 → 1.0.74

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.
@@ -22,6 +22,19 @@ export class CropDetector {
22
22
  projectedImage?: undefined;
23
23
  };
24
24
  };
25
+ /**
26
+ * Scans the ENTIRE frame by downsampling it to cropSize
27
+ */
28
+ _detectGlobal(imageData: any): {
29
+ featurePoints: any[];
30
+ debugExtra: {
31
+ projectedImage: number[];
32
+ isGlobal: boolean;
33
+ } | {
34
+ projectedImage?: undefined;
35
+ isGlobal?: undefined;
36
+ };
37
+ };
25
38
  _detect(imageData: any, startX: any, startY: any): {
26
39
  featurePoints: any[];
27
40
  debugExtra: {
@@ -24,27 +24,51 @@ class CropDetector {
24
24
  }
25
25
  detectMoving(input) {
26
26
  const imageData = input;
27
- // Expanded to 5x5 grid (25 positions) for better coverage
27
+ // 🚀 MOONSHOT: Alternate between local crops and GLOBAL scan
28
+ // This solves the "not reading the whole screen" issue.
29
+ // Every 3 frames, we do a full screen downsampled scan.
30
+ if (this.lastRandomIndex % 3 === 0) {
31
+ this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
32
+ return this._detectGlobal(imageData);
33
+ }
34
+ // Original moving crop logic for high-detail local detection
28
35
  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
36
+ const idx = (this.lastRandomIndex - 1) % (gridSize * gridSize);
37
+ const dx = idx % gridSize;
38
+ const dy = Math.floor(idx / gridSize);
32
39
  const stepX = this.cropSize / 3;
33
40
  const stepY = this.cropSize / 3;
34
41
  let startY = Math.floor(this.height / 2 - this.cropSize / 2 + (dy - 2) * stepY);
35
42
  let startX = Math.floor(this.width / 2 - this.cropSize / 2 + (dx - 2) * stepX);
36
- // Clamp to valid bounds
37
- if (startX < 0)
38
- startX = 0;
39
- if (startY < 0)
40
- startY = 0;
41
- if (startX >= this.width - this.cropSize)
42
- startX = this.width - this.cropSize - 1;
43
- if (startY >= this.height - this.cropSize)
44
- startY = this.height - this.cropSize - 1;
45
- this.lastRandomIndex = (this.lastRandomIndex + 1) % (gridSize * gridSize);
46
- const result = this._detect(imageData, startX, startY);
47
- return result;
43
+ startX = Math.max(0, Math.min(this.width - this.cropSize - 1, startX));
44
+ startY = Math.max(0, Math.min(this.height - this.cropSize - 1, startY));
45
+ this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
46
+ return this._detect(imageData, startX, startY);
47
+ }
48
+ /**
49
+ * Scans the ENTIRE frame by downsampling it to cropSize
50
+ */
51
+ _detectGlobal(imageData) {
52
+ const croppedData = new Float32Array(this.cropSize * this.cropSize);
53
+ const scaleX = this.width / this.cropSize;
54
+ const scaleY = this.height / this.cropSize;
55
+ // Fast downsample (nearest neighbor is enough for initial feature detection)
56
+ for (let y = 0; y < this.cropSize; y++) {
57
+ const srcY = Math.floor(y * scaleY) * this.width;
58
+ const dstY = y * this.cropSize;
59
+ for (let x = 0; x < this.cropSize; x++) {
60
+ croppedData[dstY + x] = imageData[srcY + Math.floor(x * scaleX)];
61
+ }
62
+ }
63
+ const { featurePoints } = this.detector.detect(croppedData);
64
+ featurePoints.forEach((p) => {
65
+ p.x *= scaleX;
66
+ p.y *= scaleY;
67
+ });
68
+ return {
69
+ featurePoints,
70
+ debugExtra: this.debugMode ? { projectedImage: Array.from(croppedData), isGlobal: true } : {}
71
+ };
48
72
  }
49
73
  _detect(imageData, startX, startY) {
50
74
  // Crop manually since imageData is now a flat array (width * height)
@@ -1,7 +1,7 @@
1
1
  import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../estimation/utils.js";
2
2
  const AR2_DEFAULT_TS = 6;
3
3
  const AR2_DEFAULT_TS_GAP = 1;
4
- const AR2_SEARCH_SIZE = 18;
4
+ const AR2_SEARCH_SIZE = 34; // Increased from 18 to 34 for much better fast-motion tracking
5
5
  const AR2_SEARCH_GAP = 1;
6
6
  const AR2_SIM_THRESH = 0.6;
7
7
  const TRACKING_KEYFRAME = 0; // 0: 128px (optimized)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srsergio/taptapp-ar",
3
- "version": "1.0.73",
3
+ "version": "1.0.74",
4
4
  "description": "AR Compiler for Node.js and Browser",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,28 +33,62 @@ class CropDetector {
33
33
  detectMoving(input) {
34
34
  const imageData = input;
35
35
 
36
- // Expanded to 5x5 grid (25 positions) for better coverage
36
+ // 🚀 MOONSHOT: Alternate between local crops and GLOBAL scan
37
+ // This solves the "not reading the whole screen" issue.
38
+ // Every 3 frames, we do a full screen downsampled scan.
39
+ if (this.lastRandomIndex % 3 === 0) {
40
+ this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
41
+ return this._detectGlobal(imageData);
42
+ }
43
+
44
+ // Original moving crop logic for high-detail local detection
37
45
  const gridSize = 5;
38
- const dx = this.lastRandomIndex % gridSize;
39
- const dy = Math.floor(this.lastRandomIndex / gridSize);
46
+ const idx = (this.lastRandomIndex - 1) % (gridSize * gridSize);
47
+ const dx = idx % gridSize;
48
+ const dy = Math.floor(idx / gridSize);
40
49
 
41
- // Calculate offset from center, with overlap for better detection
42
50
  const stepX = this.cropSize / 3;
43
51
  const stepY = this.cropSize / 3;
44
52
 
45
53
  let startY = Math.floor(this.height / 2 - this.cropSize / 2 + (dy - 2) * stepY);
46
54
  let startX = Math.floor(this.width / 2 - this.cropSize / 2 + (dx - 2) * stepX);
47
55
 
48
- // Clamp to valid bounds
49
- if (startX < 0) startX = 0;
50
- if (startY < 0) startY = 0;
51
- if (startX >= this.width - this.cropSize) startX = this.width - this.cropSize - 1;
52
- if (startY >= this.height - this.cropSize) startY = this.height - this.cropSize - 1;
56
+ startX = Math.max(0, Math.min(this.width - this.cropSize - 1, startX));
57
+ startY = Math.max(0, Math.min(this.height - this.cropSize - 1, startY));
53
58
 
54
- this.lastRandomIndex = (this.lastRandomIndex + 1) % (gridSize * gridSize);
59
+ this.lastRandomIndex = (this.lastRandomIndex + 1) % 25;
55
60
 
56
- const result = this._detect(imageData, startX, startY);
57
- return result;
61
+ return this._detect(imageData, startX, startY);
62
+ }
63
+
64
+ /**
65
+ * Scans the ENTIRE frame by downsampling it to cropSize
66
+ */
67
+ _detectGlobal(imageData) {
68
+ const croppedData = new Float32Array(this.cropSize * this.cropSize);
69
+ const scaleX = this.width / this.cropSize;
70
+ const scaleY = this.height / this.cropSize;
71
+
72
+ // Fast downsample (nearest neighbor is enough for initial feature detection)
73
+ for (let y = 0; y < this.cropSize; y++) {
74
+ const srcY = Math.floor(y * scaleY) * this.width;
75
+ const dstY = y * this.cropSize;
76
+ for (let x = 0; x < this.cropSize; x++) {
77
+ croppedData[dstY + x] = imageData[srcY + Math.floor(x * scaleX)];
78
+ }
79
+ }
80
+
81
+ const { featurePoints } = this.detector.detect(croppedData);
82
+
83
+ featurePoints.forEach((p) => {
84
+ p.x *= scaleX;
85
+ p.y *= scaleY;
86
+ });
87
+
88
+ return {
89
+ featurePoints,
90
+ debugExtra: this.debugMode ? { projectedImage: Array.from(croppedData), isGlobal: true } : {}
91
+ };
58
92
  }
59
93
 
60
94
  _detect(imageData, startX, startY) {
@@ -2,7 +2,7 @@ import { buildModelViewProjectionTransform, computeScreenCoordiate } from "../es
2
2
 
3
3
  const AR2_DEFAULT_TS = 6;
4
4
  const AR2_DEFAULT_TS_GAP = 1;
5
- const AR2_SEARCH_SIZE = 18;
5
+ const AR2_SEARCH_SIZE = 34; // Increased from 18 to 34 for much better fast-motion tracking
6
6
  const AR2_SEARCH_GAP = 1;
7
7
  const AR2_SIM_THRESH = 0.6;
8
8