@srsergio/taptapp-ar 1.0.38 → 1.0.41

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.
@@ -65,16 +65,12 @@ export class Controller {
65
65
  dummyRun(input: any): void;
66
66
  getProjectionMatrix(): number[];
67
67
  getRotatedZ90Matrix(m: any): any[];
68
- getWorldMatrix(modelViewTransform: any, targetIndex: any): any[] | null;
68
+ getWorldMatrix(modelViewTransform: any, targetIndex: any): any[];
69
69
  _detectAndMatch(inputData: any, targetIndexes: any): Promise<{
70
70
  targetIndex: any;
71
71
  modelViewTransform: any;
72
72
  }>;
73
- _trackAndUpdate(inputData: any, lastModelViewTransform: any, targetIndex: any): Promise<{
74
- modelViewTransform: any;
75
- inliers: number;
76
- octaveIndex: number;
77
- } | null>;
73
+ _trackAndUpdate(inputData: any, lastModelViewTransform: any, targetIndex: any): Promise<any>;
78
74
  processVideo(input: any): void;
79
75
  stopProcessVideo(): void;
80
76
  detect(input: any): Promise<{
@@ -102,7 +98,6 @@ export class Controller {
102
98
  x: number;
103
99
  y: number;
104
100
  }[];
105
- octaveIndex: number;
106
101
  debugExtra: {};
107
102
  }>;
108
103
  trackUpdate(modelViewTransform: any, trackFeatures: any): Promise<any>;
@@ -129,7 +124,7 @@ export class Controller {
129
124
  _workerTrackUpdate(modelViewTransform: any, trackingFeatures: any): Promise<any>;
130
125
  workerTrackDone: ((data: any) => void) | undefined;
131
126
  _trackUpdateOnMainThread(modelViewTransform: any, trackingFeatures: any): Promise<never[][] | null>;
132
- _glModelViewMatrix(modelViewTransform: any, targetIndex: any): any[] | null;
127
+ _glModelViewMatrix(modelViewTransform: any, targetIndex: any): any[];
133
128
  _glProjectionMatrix({ projectionTransform, width, height, near, far }: {
134
129
  projectionTransform: any;
135
130
  width: any;
@@ -181,18 +181,14 @@ class Controller {
181
181
  return { targetIndex: matchedTargetIndex, modelViewTransform };
182
182
  }
183
183
  async _trackAndUpdate(inputData, lastModelViewTransform, targetIndex) {
184
- const result = this.tracker.track(inputData, lastModelViewTransform, targetIndex);
185
- if (result.worldCoords.length < 6)
184
+ const { worldCoords, screenCoords } = this.tracker.track(inputData, lastModelViewTransform, targetIndex);
185
+ if (worldCoords.length < 6)
186
186
  return null; // Umbral de puntos mínimos para mantener el seguimiento
187
187
  const modelViewTransform = await this._workerTrackUpdate(lastModelViewTransform, {
188
- worldCoords: result.worldCoords,
189
- screenCoords: result.screenCoords,
188
+ worldCoords,
189
+ screenCoords,
190
190
  });
191
- return {
192
- modelViewTransform,
193
- inliers: result.worldCoords.length,
194
- octaveIndex: result.octaveIndex
195
- };
191
+ return modelViewTransform;
196
192
  }
197
193
  processVideo(input) {
198
194
  if (this.processingVideo)
@@ -206,7 +202,6 @@ class Controller {
206
202
  currentModelViewTransform: null,
207
203
  trackCount: 0,
208
204
  trackMiss: 0,
209
- stabilityCount: 0, // Nuevo: Contador para Live Adaptation
210
205
  filter: new OneEuroFilter({ minCutOff: this.filterMinCF, beta: this.filterBeta }),
211
206
  });
212
207
  }
@@ -219,22 +214,18 @@ class Controller {
219
214
  return acc + (!!s.isTracking ? 1 : 0);
220
215
  }, 0);
221
216
  // detect and match only if less then maxTrack
222
- // BUG FIX: Only match if we are NOT in a "ghosting" period for a target
223
- // to prevent the "found but immediately lost" loop that keeps opacity at 1.
224
217
  if (nTracking < this.maxTrack) {
225
218
  const matchingIndexes = [];
226
219
  for (let i = 0; i < this.trackingStates.length; i++) {
227
220
  const trackingState = this.trackingStates[i];
228
221
  if (trackingState.isTracking === true)
229
222
  continue;
230
- if (trackingState.showing === true)
231
- continue; // Don't try to re-detect if we are still buffers-showing the last position
232
223
  if (this.interestedTargetIndex !== -1 && this.interestedTargetIndex !== i)
233
224
  continue;
234
225
  matchingIndexes.push(i);
235
226
  }
236
227
  const { targetIndex: matchedTargetIndex, modelViewTransform } = await this._detectAndMatch(inputData, matchingIndexes);
237
- if (matchedTargetIndex !== -1 && modelViewTransform) {
228
+ if (matchedTargetIndex !== -1) {
238
229
  this.trackingStates[matchedTargetIndex].isTracking = true;
239
230
  this.trackingStates[matchedTargetIndex].currentModelViewTransform = modelViewTransform;
240
231
  }
@@ -243,29 +234,12 @@ class Controller {
243
234
  for (let i = 0; i < this.trackingStates.length; i++) {
244
235
  const trackingState = this.trackingStates[i];
245
236
  if (trackingState.isTracking) {
246
- let result = await this._trackAndUpdate(inputData, trackingState.currentModelViewTransform, i);
247
- if (result === null) {
237
+ let modelViewTransform = await this._trackAndUpdate(inputData, trackingState.currentModelViewTransform, i);
238
+ if (modelViewTransform === null) {
248
239
  trackingState.isTracking = false;
249
- trackingState.stabilityCount = 0;
250
240
  }
251
241
  else {
252
- trackingState.currentModelViewTransform = result.modelViewTransform;
253
- // --- LIVE MODEL ADAPTATION LOGIC ---
254
- // Si el tracking es muy sólido (muchos inliers) y estable, refinamos el modelo
255
- // Requisito: > 35 inliers (muy exigente) para evitar polución por ruido
256
- if (result.inliers > 35) {
257
- trackingState.stabilityCount++;
258
- if (trackingState.stabilityCount > 30) { // 30 frames (~1s) de estabilidad absoluta
259
- this.tracker.applyLiveFeedback(i, result.octaveIndex, 0.05); // Menor alpha (5%) para ser más conservador
260
- if (this.debugMode)
261
- console.log(`✨ Live Reification: Target ${i} (Octave ${result.octaveIndex}) updated.`);
262
- trackingState.stabilityCount = 0;
263
- }
264
- }
265
- else {
266
- trackingState.stabilityCount = Math.max(0, trackingState.stabilityCount - 1);
267
- }
268
- // -----------------------------------
242
+ trackingState.currentModelViewTransform = modelViewTransform;
269
243
  }
270
244
  }
271
245
  // if not showing, then show it once it reaches warmup number of frames
@@ -297,7 +271,7 @@ class Controller {
297
271
  }
298
272
  }
299
273
  // if showing, then call onUpdate, with world matrix
300
- if (trackingState.showing && trackingState.currentModelViewTransform) {
274
+ if (trackingState.showing) {
301
275
  const worldMatrix = this._glModelViewMatrix(trackingState.currentModelViewTransform, i);
302
276
  trackingState.trackingMatrix = trackingState.filter.filter(Date.now(), worldMatrix);
303
277
  let clone = [];
@@ -438,8 +412,6 @@ class Controller {
438
412
  return finalModelViewTransform;
439
413
  }
440
414
  _glModelViewMatrix(modelViewTransform, targetIndex) {
441
- if (!modelViewTransform)
442
- return null;
443
415
  const height = this.markerDimensions[targetIndex][1];
444
416
  const openGLWorldMatrix = [
445
417
  modelViewTransform[0][0],
@@ -20,7 +20,6 @@ export class Tracker {
20
20
  x: number;
21
21
  y: number;
22
22
  }[];
23
- octaveIndex: number;
24
23
  debugExtra: {};
25
24
  };
26
25
  /**
@@ -34,11 +33,4 @@ export class Tracker {
34
33
  * Pure JS implementation of Bilinear Warping
35
34
  */
36
35
  _computeProjection(M: any, inputData: any, prebuilt: any): void;
37
- /**
38
- * Refines the target data (Living Mind Map) using actual camera feedback
39
- * @param {number} targetIndex
40
- * @param {number} octaveIndex
41
- * @param {number} alpha - Blending factor (e.g. 0.1 for 10% new data)
42
- */
43
- applyLiveFeedback(targetIndex: number, octaveIndex: number, alpha: number): void;
44
36
  }
@@ -87,7 +87,16 @@ class Tracker {
87
87
  });
88
88
  }
89
89
  }
90
- return { worldCoords, screenCoords, octaveIndex, debugExtra };
90
+ if (this.debugMode) {
91
+ debugExtra = {
92
+ octaveIndex,
93
+ projectedImage: Array.from(projectedImage),
94
+ matchingPoints,
95
+ goodTrack,
96
+ trackedPoints: screenCoords,
97
+ };
98
+ }
99
+ return { worldCoords, screenCoords, debugExtra };
91
100
  }
92
101
  /**
93
102
  * Pure JS implementation of NCC matching
@@ -223,33 +232,5 @@ class Tracker {
223
232
  }
224
233
  }
225
234
  }
226
- /**
227
- * Refines the target data (Living Mind Map) using actual camera feedback
228
- * @param {number} targetIndex
229
- * @param {number} octaveIndex
230
- * @param {number} alpha - Blending factor (e.g. 0.1 for 10% new data)
231
- */
232
- applyLiveFeedback(targetIndex, octaveIndex, alpha) {
233
- if (targetIndex === undefined || octaveIndex === undefined)
234
- return;
235
- const targetPrebuilts = this.prebuiltData[targetIndex];
236
- if (!targetPrebuilts)
237
- return;
238
- const prebuilt = targetPrebuilts[octaveIndex];
239
- if (!prebuilt || !prebuilt.projectedImage || !prebuilt.data)
240
- return;
241
- const markerPixels = prebuilt.data;
242
- const projectedPixels = prebuilt.projectedImage;
243
- const count = markerPixels.length;
244
- // Blend the projected (camera-sourced) pixels into the marker reference data
245
- // This allows the NCC matching to adapt to real-world lighting and print quality
246
- for (let i = 0; i < count; i++) {
247
- const val = projectedPixels[i];
248
- if (isNaN(val))
249
- continue; // Don't pollute with NaN
250
- // Simple linear blend
251
- markerPixels[i] = (1 - alpha) * markerPixels[i] + alpha * val;
252
- }
253
- }
254
235
  }
255
236
  export { Tracker };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srsergio/taptapp-ar",
3
- "version": "1.0.38",
3
+ "version": "1.0.41",
4
4
  "description": "AR Compiler for Node.js and Browser",
5
5
  "repository": {
6
6
  "type": "git",
@@ -226,21 +226,17 @@ class Controller {
226
226
  return { targetIndex: matchedTargetIndex, modelViewTransform };
227
227
  }
228
228
  async _trackAndUpdate(inputData, lastModelViewTransform, targetIndex) {
229
- const result = this.tracker.track(
229
+ const { worldCoords, screenCoords } = this.tracker.track(
230
230
  inputData,
231
231
  lastModelViewTransform,
232
232
  targetIndex,
233
233
  );
234
- if (result.worldCoords.length < 6) return null; // Umbral de puntos mínimos para mantener el seguimiento
234
+ if (worldCoords.length < 6) return null; // Umbral de puntos mínimos para mantener el seguimiento
235
235
  const modelViewTransform = await this._workerTrackUpdate(lastModelViewTransform, {
236
- worldCoords: result.worldCoords,
237
- screenCoords: result.screenCoords,
236
+ worldCoords,
237
+ screenCoords,
238
238
  });
239
- return {
240
- modelViewTransform,
241
- inliers: result.worldCoords.length,
242
- octaveIndex: result.octaveIndex
243
- };
239
+ return modelViewTransform;
244
240
  }
245
241
 
246
242
  processVideo(input) {
@@ -256,7 +252,6 @@ class Controller {
256
252
  currentModelViewTransform: null,
257
253
  trackCount: 0,
258
254
  trackMiss: 0,
259
- stabilityCount: 0, // Nuevo: Contador para Live Adaptation
260
255
  filter: new OneEuroFilter({ minCutOff: this.filterMinCF, beta: this.filterBeta }),
261
256
  });
262
257
  }
@@ -272,14 +267,11 @@ class Controller {
272
267
  }, 0);
273
268
 
274
269
  // detect and match only if less then maxTrack
275
- // BUG FIX: Only match if we are NOT in a "ghosting" period for a target
276
- // to prevent the "found but immediately lost" loop that keeps opacity at 1.
277
270
  if (nTracking < this.maxTrack) {
278
271
  const matchingIndexes = [];
279
272
  for (let i = 0; i < this.trackingStates.length; i++) {
280
273
  const trackingState = this.trackingStates[i];
281
274
  if (trackingState.isTracking === true) continue;
282
- if (trackingState.showing === true) continue; // Don't try to re-detect if we are still buffers-showing the last position
283
275
  if (this.interestedTargetIndex !== -1 && this.interestedTargetIndex !== i) continue;
284
276
 
285
277
  matchingIndexes.push(i);
@@ -288,7 +280,7 @@ class Controller {
288
280
  const { targetIndex: matchedTargetIndex, modelViewTransform } =
289
281
  await this._detectAndMatch(inputData, matchingIndexes);
290
282
 
291
- if (matchedTargetIndex !== -1 && modelViewTransform) {
283
+ if (matchedTargetIndex !== -1) {
292
284
  this.trackingStates[matchedTargetIndex].isTracking = true;
293
285
  this.trackingStates[matchedTargetIndex].currentModelViewTransform = modelViewTransform;
294
286
  }
@@ -299,31 +291,15 @@ class Controller {
299
291
  const trackingState = this.trackingStates[i];
300
292
 
301
293
  if (trackingState.isTracking) {
302
- let result = await this._trackAndUpdate(
294
+ let modelViewTransform = await this._trackAndUpdate(
303
295
  inputData,
304
296
  trackingState.currentModelViewTransform,
305
297
  i,
306
298
  );
307
- if (result === null) {
299
+ if (modelViewTransform === null) {
308
300
  trackingState.isTracking = false;
309
- trackingState.stabilityCount = 0;
310
301
  } else {
311
- trackingState.currentModelViewTransform = result.modelViewTransform;
312
-
313
- // --- LIVE MODEL ADAPTATION LOGIC ---
314
- // Si el tracking es muy sólido (muchos inliers) y estable, refinamos el modelo
315
- // Requisito: > 35 inliers (muy exigente) para evitar polución por ruido
316
- if (result.inliers > 35) {
317
- trackingState.stabilityCount++;
318
- if (trackingState.stabilityCount > 30) { // 30 frames (~1s) de estabilidad absoluta
319
- this.tracker.applyLiveFeedback(i, result.octaveIndex, 0.05); // Menor alpha (5%) para ser más conservador
320
- if (this.debugMode) console.log(`✨ Live Reification: Target ${i} (Octave ${result.octaveIndex}) updated.`);
321
- trackingState.stabilityCount = 0;
322
- }
323
- } else {
324
- trackingState.stabilityCount = Math.max(0, trackingState.stabilityCount - 1);
325
- }
326
- // -----------------------------------
302
+ trackingState.currentModelViewTransform = modelViewTransform;
327
303
  }
328
304
  }
329
305
 
@@ -358,7 +334,7 @@ class Controller {
358
334
  }
359
335
 
360
336
  // if showing, then call onUpdate, with world matrix
361
- if (trackingState.showing && trackingState.currentModelViewTransform) {
337
+ if (trackingState.showing) {
362
338
  const worldMatrix = this._glModelViewMatrix(trackingState.currentModelViewTransform, i);
363
339
  trackingState.trackingMatrix = trackingState.filter.filter(Date.now(), worldMatrix);
364
340
 
@@ -525,7 +501,6 @@ class Controller {
525
501
  }
526
502
 
527
503
  _glModelViewMatrix(modelViewTransform, targetIndex) {
528
- if (!modelViewTransform) return null;
529
504
  const height = this.markerDimensions[targetIndex][1];
530
505
 
531
506
  const openGLWorldMatrix = [
@@ -127,7 +127,17 @@ class Tracker {
127
127
  }
128
128
  }
129
129
 
130
- return { worldCoords, screenCoords, octaveIndex, debugExtra };
130
+ if (this.debugMode) {
131
+ debugExtra = {
132
+ octaveIndex,
133
+ projectedImage: Array.from(projectedImage),
134
+ matchingPoints,
135
+ goodTrack,
136
+ trackedPoints: screenCoords,
137
+ };
138
+ }
139
+
140
+ return { worldCoords, screenCoords, debugExtra };
131
141
  }
132
142
 
133
143
  /**
@@ -290,34 +300,6 @@ class Tracker {
290
300
  }
291
301
  }
292
302
  }
293
-
294
- /**
295
- * Refines the target data (Living Mind Map) using actual camera feedback
296
- * @param {number} targetIndex
297
- * @param {number} octaveIndex
298
- * @param {number} alpha - Blending factor (e.g. 0.1 for 10% new data)
299
- */
300
- applyLiveFeedback(targetIndex, octaveIndex, alpha) {
301
- if (targetIndex === undefined || octaveIndex === undefined) return;
302
- const targetPrebuilts = this.prebuiltData[targetIndex];
303
- if (!targetPrebuilts) return;
304
-
305
- const prebuilt = targetPrebuilts[octaveIndex];
306
- if (!prebuilt || !prebuilt.projectedImage || !prebuilt.data) return;
307
-
308
- const markerPixels = prebuilt.data;
309
- const projectedPixels = prebuilt.projectedImage;
310
- const count = markerPixels.length;
311
-
312
- // Blend the projected (camera-sourced) pixels into the marker reference data
313
- // This allows the NCC matching to adapt to real-world lighting and print quality
314
- for (let i = 0; i < count; i++) {
315
- const val = projectedPixels[i];
316
- if (isNaN(val)) continue; // Don't pollute with NaN
317
- // Simple linear blend
318
- markerPixels[i] = (1 - alpha) * markerPixels[i] + alpha * val;
319
- }
320
- }
321
303
  }
322
304
 
323
305
  export { Tracker };