@srsergio/taptapp-ar 1.0.43 → 1.0.50

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.
Files changed (47) hide show
  1. package/README.md +42 -45
  2. package/dist/compiler/aframe.js +8 -8
  3. package/dist/compiler/controller.d.ts +50 -76
  4. package/dist/compiler/controller.js +72 -116
  5. package/dist/compiler/detector/detector-lite.js +82 -99
  6. package/dist/compiler/index.js +3 -3
  7. package/dist/compiler/matching/hamming-distance.d.ts +8 -0
  8. package/dist/compiler/matching/hamming-distance.js +35 -16
  9. package/dist/compiler/matching/hierarchical-clustering.d.ts +9 -0
  10. package/dist/compiler/matching/hierarchical-clustering.js +76 -56
  11. package/dist/compiler/matching/matching.js +3 -3
  12. package/dist/compiler/node-worker.js +144 -18
  13. package/dist/compiler/offline-compiler.d.ts +34 -83
  14. package/dist/compiler/offline-compiler.js +92 -96
  15. package/dist/compiler/simple-ar.d.ts +31 -57
  16. package/dist/compiler/simple-ar.js +32 -73
  17. package/dist/compiler/three.d.ts +13 -8
  18. package/dist/compiler/three.js +6 -6
  19. package/dist/compiler/tracker/extract.js +17 -14
  20. package/dist/compiler/utils/images.js +11 -16
  21. package/dist/compiler/utils/lsh-direct.d.ts +12 -0
  22. package/dist/compiler/utils/lsh-direct.js +76 -0
  23. package/dist/compiler/utils/worker-pool.js +10 -1
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +2 -2
  26. package/dist/react/types.d.ts +1 -1
  27. package/dist/react/types.js +1 -1
  28. package/package.json +2 -1
  29. package/src/compiler/aframe.js +8 -8
  30. package/src/compiler/controller.ts +512 -0
  31. package/src/compiler/detector/detector-lite.js +87 -107
  32. package/src/compiler/index.js +3 -3
  33. package/src/compiler/matching/hamming-distance.js +39 -16
  34. package/src/compiler/matching/hierarchical-clustering.js +85 -57
  35. package/src/compiler/matching/matching.js +3 -3
  36. package/src/compiler/node-worker.js +163 -18
  37. package/src/compiler/offline-compiler.ts +513 -0
  38. package/src/compiler/{simple-ar.js → simple-ar.ts} +64 -91
  39. package/src/compiler/three.js +6 -6
  40. package/src/compiler/tracker/extract.js +18 -15
  41. package/src/compiler/utils/images.js +11 -21
  42. package/src/compiler/utils/lsh-direct.js +86 -0
  43. package/src/compiler/utils/worker-pool.js +9 -1
  44. package/src/index.ts +2 -2
  45. package/src/react/types.ts +2 -2
  46. package/src/compiler/controller.js +0 -554
  47. package/src/compiler/offline-compiler.js +0 -515
@@ -1,4 +1,4 @@
1
- export class MindARThree {
1
+ export class TaarThree {
2
2
  constructor({ container, imageTargetSrc, maxTrack, uiLoading, uiScanning, uiError, filterMinCF, filterBeta, warmupTolerance, missTolerance, userDeviceId, environmentDeviceId, }: {
3
3
  container: any;
4
4
  imageTargetSrc: any;
@@ -24,17 +24,17 @@ export class MindARThree {
24
24
  userDeviceId: any;
25
25
  environmentDeviceId: any;
26
26
  shouldFaceUser: boolean;
27
- scene: any;
28
- cssScene: any;
29
- renderer: any;
30
- cssRenderer: any;
31
- camera: any;
27
+ scene: Scene;
28
+ cssScene: Scene;
29
+ renderer: WebGLRenderer;
30
+ cssRenderer: CSS3DRenderer;
31
+ camera: PerspectiveCamera;
32
32
  anchors: any[];
33
33
  start(): Promise<void>;
34
34
  stop(): void;
35
35
  switchCamera(): void;
36
36
  addAnchor(targetIndex: any): {
37
- group: any;
37
+ group: Group<import("three").Object3DEventMap>;
38
38
  targetIndex: any;
39
39
  onTargetFound: null;
40
40
  onTargetLost: null;
@@ -43,7 +43,7 @@ export class MindARThree {
43
43
  visible: boolean;
44
44
  };
45
45
  addCSSAnchor(targetIndex: any): {
46
- group: any;
46
+ group: Group<import("three").Object3DEventMap>;
47
47
  targetIndex: any;
48
48
  onTargetFound: null;
49
49
  onTargetLost: null;
@@ -58,4 +58,9 @@ export class MindARThree {
58
58
  postMatrixs: any[] | undefined;
59
59
  resize(): void;
60
60
  }
61
+ import { Scene } from "three";
62
+ import { WebGLRenderer } from "three";
63
+ import { CSS3DRenderer } from "three/addons/renderers/CSS3DRenderer.js";
64
+ import { PerspectiveCamera } from "three";
65
+ import { Group } from "three";
61
66
  import { Controller } from "./controller.js";
@@ -5,7 +5,7 @@ import { UI } from "../ui/ui.js";
5
5
  const cssScaleDownMatrix = new Matrix4();
6
6
  cssScaleDownMatrix.compose(new Vector3(), new Quaternion(), new Vector3(0.001, 0.001, 0.001));
7
7
  const invisibleMatrix = new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
8
- export class MindARThree {
8
+ export class TaarThree {
9
9
  constructor({ container, imageTargetSrc, maxTrack, uiLoading = "yes", uiScanning = "yes", uiError = "yes", filterMinCF = null, filterBeta = null, warmupTolerance = null, missTolerance = null, userDeviceId = null, environmentDeviceId = null, }) {
10
10
  this.container = container;
11
11
  this.imageTargetSrc = imageTargetSrc;
@@ -295,10 +295,10 @@ export class MindARThree {
295
295
  cssRenderer.setSize(container.clientWidth, container.clientHeight);
296
296
  }
297
297
  }
298
- if (!window.MINDAR) {
299
- window.MINDAR = {};
298
+ if (!window.TAAR) {
299
+ window.TAAR = {};
300
300
  }
301
- if (!window.MINDAR.IMAGE) {
302
- window.MINDAR.IMAGE = {};
301
+ if (!window.TAAR.IMAGE) {
302
+ window.TAAR.IMAGE = {};
303
303
  }
304
- window.MINDAR.IMAGE.MindARThree = MindARThree;
304
+ window.TAAR.IMAGE.TaarThree = TaarThree;
@@ -281,25 +281,28 @@ const _getSimilarityOptimized = (options) => {
281
281
  const nP = templateWidth * templateWidth;
282
282
  const sx = imageDataCumsum.query(cx - templateSize, cy - templateSize, cx + templateSize, cy + templateSize);
283
283
  const sxx = imageDataSqrCumsum.query(cx - templateSize, cy - templateSize, cx + templateSize, cy + templateSize);
284
- // Full calculation
284
+ // 🚀 MOONSHOT Early Exit: Check variance (vlen2) before expensive sxy loop
285
+ let vlen2 = sxx - (sx * sx) / nP;
286
+ if (vlen2 <= 0)
287
+ return null;
288
+ vlen2 = Math.sqrt(vlen2);
289
+ // Full calculation - Optimized with 2x2 sub-sampling for SPEED
285
290
  let sxy = 0;
286
- let p1 = (cy - templateSize) * width + (cx - templateSize);
287
- let p2 = 0;
288
- const nextRowOffset = width - templateWidth;
289
- for (let j = 0; j < templateWidth; j++) {
290
- for (let i = 0; i < templateWidth; i++) {
291
- sxy += imageData[p1++] * templateData[p2++];
291
+ const p1_start = (cy - templateSize) * width + (cx - templateSize);
292
+ for (let j = 0; j < templateWidth; j += 2) {
293
+ const rowOffset1 = p1_start + j * width;
294
+ const rowOffset2 = j * templateWidth;
295
+ for (let i = 0; i < templateWidth; i += 2) {
296
+ sxy += imageData[rowOffset1 + i] * templateData[rowOffset2 + i];
292
297
  }
293
- p1 += nextRowOffset;
294
298
  }
299
+ // Factor to normalize sxy back to full template area
300
+ // templateWidth is 13, steps of 2 hit 7 points per dim = 49 total points (vs 169)
301
+ const sampledCount = Math.ceil(templateWidth / 2) ** 2;
302
+ const totalCount = templateWidth * templateWidth;
303
+ sxy *= (totalCount / sampledCount);
295
304
  // Covariance check
296
- // E[(X-EX)(Y-EY)] = E[XY] - EX*EY
297
- // sum((Xi - avgX)(Yi - avgY)) = sum(XiYi) - avgY * sum(Xi)
298
305
  const sxy_final = sxy - templateAvg * sx;
299
- let vlen2 = sxx - (sx * sx) / (nP);
300
- if (vlen2 <= 0)
301
- return null;
302
- vlen2 = Math.sqrt(vlen2);
303
306
  return (1.0 * sxy_final) / (vlen * vlen2);
304
307
  };
305
308
  export { extract };
@@ -31,27 +31,22 @@ const upsampleBilinear = ({ image, padOneWidth, padOneHeight }) => {
31
31
  };
32
32
  const downsampleBilinear = ({ image }) => {
33
33
  const { data, width, height } = image;
34
- const dstWidth = width >>> 1; // Floor division by 2
34
+ const dstWidth = width >>> 1;
35
35
  const dstHeight = height >>> 1;
36
36
  const temp = new Uint8Array(dstWidth * dstHeight);
37
- // Cache width for fast indexing
38
- const srcWidth = width | 0;
39
- const srcRowStep = (srcWidth * 2) | 0;
40
- let srcRowOffset = 0;
41
- let dstIndex = 0;
37
+ // Speed optimization: using Int32 views and manual indexing
38
+ // Also using bitwise operations for color averaging
42
39
  for (let j = 0; j < dstHeight; j++) {
43
- let srcPos = srcRowOffset;
40
+ const row0 = (j * 2) * width;
41
+ const row1 = row0 + width;
42
+ const dstRow = j * dstWidth;
44
43
  for (let i = 0; i < dstWidth; i++) {
45
- // Unrolled loop for performance
46
- // (0,0), (1,0), (0,1), (1,1)
47
- const value = (data[srcPos] +
48
- data[srcPos + 1] +
49
- data[srcPos + srcWidth] +
50
- data[srcPos + srcWidth + 1]) * 0.25;
51
- temp[dstIndex++] = value | 0; // Fast floor
52
- srcPos += 2;
44
+ const i2 = i * 2;
45
+ // Efficient Int32 math for blurring
46
+ const val = (data[row0 + i2] + data[row0 + i2 + 1] +
47
+ data[row1 + i2] + data[row1 + i2 + 1]) >> 2;
48
+ temp[dstRow + i] = val & 0xFF;
53
49
  }
54
- srcRowOffset += srcRowStep;
55
50
  }
56
51
  return { data: temp, width: dstWidth, height: dstHeight };
57
52
  };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Directly compute 64-bit LSH from FREAK samples
3
+ * @param {Float32Array} samples - Pre-sampled intensities at FREAK positions
4
+ * @returns {Uint32Array} 2-element array (64 bits)
5
+ */
6
+ export function computeLSH64(samples: Float32Array): Uint32Array;
7
+ export function computeFullFREAK(samples: any): Uint8Array<ArrayBuffer>;
8
+ /**
9
+ * Super-fast 8-byte (64-bit) dummy descriptor for Protocol V6 compatibility
10
+ * when full descriptors are not required but an object is expected.
11
+ */
12
+ export function packLSHIntoDescriptor(lsh: any): Uint8Array<ArrayBuffer>;
@@ -0,0 +1,76 @@
1
+ import { FREAKPOINTS } from "../detector/freak.js";
2
+ /**
3
+ * 🚀 Moonshot: LSH-Direct Descriptor
4
+ *
5
+ * Instead of computing 672 bits of FREAK and then sampling 64 bits for LSH,
6
+ * we directly compute only the 64 bits we need.
7
+ *
8
+ * Speedup: >10x in descriptor generation.
9
+ */
10
+ // 1. Pre-calculate the 64 pairs of indices (i, j) that correspond to our LSH sampling
11
+ const LSH_PAIRS = new Int32Array(64 * 2);
12
+ const SAMPLING_INDICES = new Int32Array(64);
13
+ for (let i = 0; i < 64; i++) {
14
+ SAMPLING_INDICES[i] = Math.floor(i * (672 / 64));
15
+ }
16
+ // Map bit indices to FREAK point pairs
17
+ let currentBit = 0;
18
+ let samplingIdx = 0;
19
+ for (let i = 0; i < FREAKPOINTS.length; i++) {
20
+ for (let j = i + 1; j < FREAKPOINTS.length; j++) {
21
+ if (samplingIdx < 64 && currentBit === SAMPLING_INDICES[samplingIdx]) {
22
+ LSH_PAIRS[samplingIdx * 2] = i;
23
+ LSH_PAIRS[samplingIdx * 2 + 1] = j;
24
+ samplingIdx++;
25
+ }
26
+ currentBit++;
27
+ }
28
+ }
29
+ /**
30
+ * Directly compute 64-bit LSH from FREAK samples
31
+ * @param {Float32Array} samples - Pre-sampled intensities at FREAK positions
32
+ * @returns {Uint32Array} 2-element array (64 bits)
33
+ */
34
+ export function computeLSH64(samples) {
35
+ const result = new Uint32Array(2);
36
+ for (let i = 0; i < 64; i++) {
37
+ const p1 = LSH_PAIRS[i * 2];
38
+ const p2 = LSH_PAIRS[i * 2 + 1];
39
+ if (samples[p1] < samples[p2]) {
40
+ const uintIdx = i >> 5; // i / 32
41
+ const uintBitIdx = i & 31; // i % 32
42
+ result[uintIdx] |= (1 << uintBitIdx);
43
+ }
44
+ }
45
+ return result;
46
+ }
47
+ // For backward compatibility if any 84-byte descriptor is still needed
48
+ export function computeFullFREAK(samples) {
49
+ const descriptor = new Uint8Array(84);
50
+ let bitCount = 0;
51
+ let byteIdx = 0;
52
+ for (let i = 0; i < FREAKPOINTS.length; i++) {
53
+ for (let j = i + 1; j < FREAKPOINTS.length; j++) {
54
+ if (samples[i] < samples[j]) {
55
+ descriptor[byteIdx] |= (1 << (7 - bitCount));
56
+ }
57
+ bitCount++;
58
+ if (bitCount === 8) {
59
+ byteIdx++;
60
+ bitCount = 0;
61
+ }
62
+ }
63
+ }
64
+ return descriptor;
65
+ }
66
+ /**
67
+ * Super-fast 8-byte (64-bit) dummy descriptor for Protocol V6 compatibility
68
+ * when full descriptors are not required but an object is expected.
69
+ */
70
+ export function packLSHIntoDescriptor(lsh) {
71
+ const desc = new Uint8Array(8);
72
+ const view = new DataView(desc.buffer);
73
+ view.setUint32(0, lsh[0], true);
74
+ view.setUint32(4, lsh[1], true);
75
+ return desc;
76
+ }
@@ -33,7 +33,16 @@ export class WorkerPool {
33
33
  }
34
34
  else if (msg.type === 'compileDone') {
35
35
  cleanup();
36
- this._finishTask(worker, task.resolve, msg.trackingData);
36
+ // If it's the new unified result, return both.
37
+ if (msg.matchingData && msg.trackingData) {
38
+ this._finishTask(worker, task.resolve, {
39
+ matchingData: msg.matchingData,
40
+ trackingData: msg.trackingData
41
+ });
42
+ }
43
+ else {
44
+ this._finishTask(worker, task.resolve, msg.trackingData);
45
+ }
37
46
  }
38
47
  else if (msg.type === 'matchDone') {
39
48
  cleanup();
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from "./react/types";
2
- export * from "./compiler/offline-compiler";
1
+ export * from "./react/types.js";
2
+ export * from "./compiler/offline-compiler.js";
3
3
  export { Controller } from "./compiler/controller.js";
4
4
  export { SimpleAR } from "./compiler/simple-ar.js";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export * from "./react/types";
2
- export * from "./compiler/offline-compiler";
1
+ export * from "./react/types.js";
2
+ export * from "./compiler/offline-compiler.js";
3
3
  export { Controller } from "./compiler/controller.js";
4
4
  export { SimpleAR } from "./compiler/simple-ar.js";
@@ -1,7 +1,7 @@
1
1
  export interface PropsConfig {
2
2
  cardId: string;
3
3
  targetImageSrc: string;
4
- targetMindSrc: string;
4
+ targetTaarSrc: string;
5
5
  videoSrc: string;
6
6
  videoWidth: number;
7
7
  videoHeight: number;
@@ -5,7 +5,7 @@ export function mapDataToPropsConfig(data) {
5
5
  return {
6
6
  cardId: photos?.id || "",
7
7
  targetImageSrc: photos?.images?.[0]?.image || "",
8
- targetMindSrc: ar?.url || "",
8
+ targetTaarSrc: ar?.url || "",
9
9
  videoSrc: video?.url || "",
10
10
  videoWidth: video?.width || 0,
11
11
  videoHeight: video?.height || 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srsergio/taptapp-ar",
3
- "version": "1.0.43",
3
+ "version": "1.0.50",
4
4
  "description": "AR Compiler for Node.js and Browser",
5
5
  "repository": {
6
6
  "type": "git",
@@ -57,6 +57,7 @@
57
57
  "tinyqueue": "^2.0.3"
58
58
  },
59
59
  "devDependencies": {
60
+ "@types/node": "^25.0.3",
60
61
  "@types/react": "^18.3.3",
61
62
  "@types/react-dom": "^18.3.0",
62
63
  "@types/three": "^0.170.0",
@@ -1,7 +1,7 @@
1
1
  import { Controller, UI } from "./index.js";
2
2
 
3
3
 
4
- AFRAME.registerSystem("mindar-image-system", {
4
+ AFRAME.registerSystem("taar-image-system", {
5
5
  container: null,
6
6
  video: null,
7
7
  processingImage: false,
@@ -214,8 +214,8 @@ AFRAME.registerSystem("mindar-image-system", {
214
214
  },
215
215
  });
216
216
 
217
- AFRAME.registerComponent("mindar-image", {
218
- dependencies: ["mindar-image-system"],
217
+ AFRAME.registerComponent("taar-image", {
218
+ dependencies: ["taar-image-system"],
219
219
 
220
220
  schema: {
221
221
  imageTargetSrc: { type: "string" },
@@ -232,7 +232,7 @@ AFRAME.registerComponent("mindar-image", {
232
232
  },
233
233
 
234
234
  init: function () {
235
- const arSystem = this.el.sceneEl.systems["mindar-image-system"];
235
+ const arSystem = this.el.sceneEl.systems["taar-image-system"];
236
236
 
237
237
  arSystem.setup({
238
238
  imageTargetSrc: this.data.imageTargetSrc,
@@ -258,8 +258,8 @@ AFRAME.registerComponent("mindar-image", {
258
258
  },
259
259
  });
260
260
 
261
- AFRAME.registerComponent("mindar-image-target", {
262
- dependencies: ["mindar-image-system"],
261
+ AFRAME.registerComponent("taar-image-target", {
262
+ dependencies: ["taar-image-system"],
263
263
 
264
264
  schema: {
265
265
  targetIndex: { type: "number" },
@@ -268,7 +268,7 @@ AFRAME.registerComponent("mindar-image-target", {
268
268
  postMatrix: null, // rescale the anchor to make width of 1 unit = physical width of card
269
269
 
270
270
  init: function () {
271
- const arSystem = this.el.sceneEl.systems["mindar-image-system"];
271
+ const arSystem = this.el.sceneEl.systems["taar-image-system"];
272
272
  arSystem.registerAnchor(this, this.data.targetIndex);
273
273
 
274
274
  this.invisibleMatrix = new AFRAME.THREE.Matrix4().set(
@@ -336,6 +336,6 @@ then A-Frame will process the webpage *before* the system and components get reg
336
336
  Resulting in a blank page. This happens because module loading is deferred.
337
337
  */
338
338
  /* if(needsDOMRefresh){
339
- console.log("mindar-face-aframe::Refreshing DOM...")
339
+ console.log("taar-face-aframe::Refreshing DOM...")
340
340
  document.body.innerHTML=document.body.innerHTML;
341
341
  } */