@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.
- package/README.md +42 -45
- package/dist/compiler/aframe.js +8 -8
- package/dist/compiler/controller.d.ts +50 -76
- package/dist/compiler/controller.js +72 -116
- package/dist/compiler/detector/detector-lite.js +82 -99
- package/dist/compiler/index.js +3 -3
- package/dist/compiler/matching/hamming-distance.d.ts +8 -0
- package/dist/compiler/matching/hamming-distance.js +35 -16
- package/dist/compiler/matching/hierarchical-clustering.d.ts +9 -0
- package/dist/compiler/matching/hierarchical-clustering.js +76 -56
- package/dist/compiler/matching/matching.js +3 -3
- package/dist/compiler/node-worker.js +144 -18
- package/dist/compiler/offline-compiler.d.ts +34 -83
- package/dist/compiler/offline-compiler.js +92 -96
- package/dist/compiler/simple-ar.d.ts +31 -57
- package/dist/compiler/simple-ar.js +32 -73
- package/dist/compiler/three.d.ts +13 -8
- package/dist/compiler/three.js +6 -6
- package/dist/compiler/tracker/extract.js +17 -14
- package/dist/compiler/utils/images.js +11 -16
- package/dist/compiler/utils/lsh-direct.d.ts +12 -0
- package/dist/compiler/utils/lsh-direct.js +76 -0
- package/dist/compiler/utils/worker-pool.js +10 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/react/types.d.ts +1 -1
- package/dist/react/types.js +1 -1
- package/package.json +2 -1
- package/src/compiler/aframe.js +8 -8
- package/src/compiler/controller.ts +512 -0
- package/src/compiler/detector/detector-lite.js +87 -107
- package/src/compiler/index.js +3 -3
- package/src/compiler/matching/hamming-distance.js +39 -16
- package/src/compiler/matching/hierarchical-clustering.js +85 -57
- package/src/compiler/matching/matching.js +3 -3
- package/src/compiler/node-worker.js +163 -18
- package/src/compiler/offline-compiler.ts +513 -0
- package/src/compiler/{simple-ar.js → simple-ar.ts} +64 -91
- package/src/compiler/three.js +6 -6
- package/src/compiler/tracker/extract.js +18 -15
- package/src/compiler/utils/images.js +11 -21
- package/src/compiler/utils/lsh-direct.js +86 -0
- package/src/compiler/utils/worker-pool.js +9 -1
- package/src/index.ts +2 -2
- package/src/react/types.ts +2 -2
- package/src/compiler/controller.js +0 -554
- package/src/compiler/offline-compiler.js +0 -515
package/dist/compiler/three.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export class
|
|
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:
|
|
28
|
-
cssScene:
|
|
29
|
-
renderer:
|
|
30
|
-
cssRenderer:
|
|
31
|
-
camera:
|
|
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:
|
|
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:
|
|
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";
|
package/dist/compiler/three.js
CHANGED
|
@@ -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
|
|
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.
|
|
299
|
-
window.
|
|
298
|
+
if (!window.TAAR) {
|
|
299
|
+
window.TAAR = {};
|
|
300
300
|
}
|
|
301
|
-
if (!window.
|
|
302
|
-
window.
|
|
301
|
+
if (!window.TAAR.IMAGE) {
|
|
302
|
+
window.TAAR.IMAGE = {};
|
|
303
303
|
}
|
|
304
|
-
window.
|
|
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
|
-
//
|
|
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
|
-
|
|
287
|
-
let
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
for (let i = 0; i < templateWidth; i
|
|
291
|
-
sxy += imageData[
|
|
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;
|
|
34
|
+
const dstWidth = width >>> 1;
|
|
35
35
|
const dstHeight = height >>> 1;
|
|
36
36
|
const temp = new Uint8Array(dstWidth * dstHeight);
|
|
37
|
-
//
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
46
|
-
//
|
|
47
|
-
const
|
|
48
|
-
data[
|
|
49
|
-
|
|
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
|
-
|
|
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";
|
package/dist/react/types.d.ts
CHANGED
package/dist/react/types.js
CHANGED
|
@@ -5,7 +5,7 @@ export function mapDataToPropsConfig(data) {
|
|
|
5
5
|
return {
|
|
6
6
|
cardId: photos?.id || "",
|
|
7
7
|
targetImageSrc: photos?.images?.[0]?.image || "",
|
|
8
|
-
|
|
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.
|
|
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",
|
package/src/compiler/aframe.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Controller, UI } from "./index.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
AFRAME.registerSystem("
|
|
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("
|
|
218
|
-
dependencies: ["
|
|
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["
|
|
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("
|
|
262
|
-
dependencies: ["
|
|
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["
|
|
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("
|
|
339
|
+
console.log("taar-face-aframe::Refreshing DOM...")
|
|
340
340
|
document.body.innerHTML=document.body.innerHTML;
|
|
341
341
|
} */
|