@srsergio/taptapp-ar 1.0.2 → 1.0.4
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 +47 -45
- package/dist/compiler/aframe.js +0 -3
- package/dist/compiler/compiler-base.d.ts +3 -7
- package/dist/compiler/compiler-base.js +28 -14
- package/dist/compiler/compiler.js +1 -1
- package/dist/compiler/compiler.worker.js +1 -1
- package/dist/compiler/controller.d.ts +4 -4
- package/dist/compiler/controller.js +4 -5
- package/dist/compiler/controller.worker.js +0 -2
- package/dist/compiler/detector/crop-detector.d.ts +12 -12
- package/dist/compiler/detector/crop-detector.js +0 -2
- package/dist/compiler/detector/detector-lite.d.ts +73 -0
- package/dist/compiler/detector/detector-lite.js +430 -0
- package/dist/compiler/detector/detector.d.ts +20 -21
- package/dist/compiler/detector/detector.js +236 -243
- package/dist/compiler/detector/kernels/cpu/binomialFilter.js +0 -1
- package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.d.ts +1 -1
- package/dist/compiler/detector/kernels/cpu/computeLocalization.js +0 -4
- package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -18
- package/dist/compiler/detector/kernels/cpu/fakeShader.js +1 -1
- package/dist/compiler/detector/kernels/cpu/prune.d.ts +7 -1
- package/dist/compiler/detector/kernels/cpu/prune.js +1 -42
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.d.ts +1 -1
- package/dist/compiler/detector/kernels/webgl/upsampleBilinear.js +2 -2
- package/dist/compiler/estimation/refine-estimate.js +0 -1
- package/dist/compiler/estimation/utils.d.ts +1 -1
- package/dist/compiler/estimation/utils.js +1 -14
- package/dist/compiler/image-list.js +4 -4
- package/dist/compiler/input-loader.d.ts +4 -5
- package/dist/compiler/input-loader.js +2 -2
- package/dist/compiler/matching/hamming-distance.js +13 -13
- package/dist/compiler/matching/hierarchical-clustering.js +1 -1
- package/dist/compiler/matching/matching.d.ts +20 -4
- package/dist/compiler/matching/matching.js +67 -41
- package/dist/compiler/matching/ransacHomography.js +1 -2
- package/dist/compiler/node-worker.d.ts +1 -0
- package/dist/compiler/node-worker.js +84 -0
- package/dist/compiler/offline-compiler.d.ts +171 -6
- package/dist/compiler/offline-compiler.js +303 -421
- package/dist/compiler/tensorflow-setup.d.ts +0 -1
- package/dist/compiler/tensorflow-setup.js +27 -1
- package/dist/compiler/three.d.ts +7 -12
- package/dist/compiler/three.js +3 -5
- package/dist/compiler/tracker/extract.d.ts +1 -0
- package/dist/compiler/tracker/extract.js +200 -244
- package/dist/compiler/tracker/tracker.d.ts +9 -17
- package/dist/compiler/tracker/tracker.js +13 -18
- package/dist/compiler/utils/cumsum.d.ts +4 -2
- package/dist/compiler/utils/cumsum.js +17 -19
- package/dist/compiler/utils/gpu-compute.d.ts +57 -0
- package/dist/compiler/utils/gpu-compute.js +262 -0
- package/dist/compiler/utils/images.d.ts +4 -4
- package/dist/compiler/utils/images.js +67 -53
- package/dist/compiler/utils/worker-pool.d.ts +13 -0
- package/dist/compiler/utils/worker-pool.js +84 -0
- package/package.json +12 -14
- package/src/compiler/aframe.js +2 -4
- package/src/compiler/compiler-base.js +29 -14
- package/src/compiler/compiler.js +1 -1
- package/src/compiler/compiler.worker.js +1 -1
- package/src/compiler/controller.js +4 -5
- package/src/compiler/controller.worker.js +0 -2
- package/src/compiler/detector/crop-detector.js +0 -2
- package/src/compiler/detector/detector-lite.js +494 -0
- package/src/compiler/detector/detector.js +1052 -1063
- package/src/compiler/detector/kernels/cpu/binomialFilter.js +0 -1
- package/src/compiler/detector/kernels/cpu/computeLocalization.js +0 -4
- package/src/compiler/detector/kernels/cpu/computeOrientationHistograms.js +0 -17
- package/src/compiler/detector/kernels/cpu/fakeShader.js +1 -1
- package/src/compiler/detector/kernels/cpu/prune.js +1 -37
- package/src/compiler/detector/kernels/webgl/upsampleBilinear.js +2 -2
- package/src/compiler/estimation/refine-estimate.js +0 -1
- package/src/compiler/estimation/utils.js +9 -24
- package/src/compiler/image-list.js +4 -4
- package/src/compiler/input-loader.js +2 -2
- package/src/compiler/matching/hamming-distance.js +11 -15
- package/src/compiler/matching/hierarchical-clustering.js +1 -1
- package/src/compiler/matching/matching.js +72 -42
- package/src/compiler/matching/ransacHomography.js +0 -2
- package/src/compiler/node-worker.js +93 -0
- package/src/compiler/offline-compiler.js +339 -504
- package/src/compiler/tensorflow-setup.js +29 -1
- package/src/compiler/three.js +3 -5
- package/src/compiler/tracker/extract.js +211 -267
- package/src/compiler/tracker/tracker.js +13 -22
- package/src/compiler/utils/cumsum.js +17 -19
- package/src/compiler/utils/gpu-compute.js +303 -0
- package/src/compiler/utils/images.js +84 -53
- package/src/compiler/utils/worker-pool.js +89 -0
- package/dist/compiler/estimation/esimate-experiment.d.ts +0 -5
- package/dist/compiler/estimation/esimate-experiment.js +0 -267
- package/dist/compiler/estimation/refine-estimate-experiment.d.ts +0 -6
- package/dist/compiler/estimation/refine-estimate-experiment.js +0 -429
- package/dist/react/AREditor.d.ts +0 -5
- package/dist/react/AREditor.js +0 -159
- package/dist/react/ProgressDialog.d.ts +0 -13
- package/dist/react/ProgressDialog.js +0 -57
- package/src/compiler/estimation/esimate-experiment.js +0 -316
- package/src/compiler/estimation/refine-estimate-experiment.js +0 -512
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Worker } from 'node:worker_threads';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
export class WorkerPool {
|
|
4
|
+
constructor(workerPath, poolSize = os.cpus().length) {
|
|
5
|
+
this.workerPath = workerPath;
|
|
6
|
+
this.poolSize = poolSize;
|
|
7
|
+
this.workers = [];
|
|
8
|
+
this.queue = [];
|
|
9
|
+
this.activeWorkers = 0;
|
|
10
|
+
}
|
|
11
|
+
runTask(taskData) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const task = { taskData, resolve, reject };
|
|
14
|
+
if (this.workers.length > 0) {
|
|
15
|
+
this._executeTask(this.workers.pop(), task);
|
|
16
|
+
}
|
|
17
|
+
else if (this.activeWorkers < this.poolSize) {
|
|
18
|
+
this._executeTask(this._createWorker(), task);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
this.queue.push(task);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
_createWorker() {
|
|
26
|
+
this.activeWorkers++;
|
|
27
|
+
const worker = new Worker(this.workerPath);
|
|
28
|
+
return worker;
|
|
29
|
+
}
|
|
30
|
+
_executeTask(worker, task) {
|
|
31
|
+
const onMessage = (msg) => {
|
|
32
|
+
if (msg.type === 'progress' && task.taskData.onProgress) {
|
|
33
|
+
task.taskData.onProgress(msg.percent);
|
|
34
|
+
}
|
|
35
|
+
else if (msg.type === 'compileDone') {
|
|
36
|
+
cleanup();
|
|
37
|
+
this._finishTask(worker, task.resolve, msg.trackingData);
|
|
38
|
+
}
|
|
39
|
+
else if (msg.type === 'matchDone') {
|
|
40
|
+
cleanup();
|
|
41
|
+
this._finishTask(worker, task.resolve, msg.matchingData);
|
|
42
|
+
}
|
|
43
|
+
else if (msg.type === 'error') {
|
|
44
|
+
cleanup();
|
|
45
|
+
this._finishTask(worker, task.reject, new Error(msg.error));
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const onError = (err) => {
|
|
49
|
+
cleanup();
|
|
50
|
+
this._finishTask(worker, task.reject, err);
|
|
51
|
+
};
|
|
52
|
+
const cleanup = () => {
|
|
53
|
+
worker.removeListener('message', onMessage);
|
|
54
|
+
worker.removeListener('error', onError);
|
|
55
|
+
};
|
|
56
|
+
worker.on('message', onMessage);
|
|
57
|
+
worker.on('error', onError);
|
|
58
|
+
// Create a copy of taskData without functions for the worker
|
|
59
|
+
const serializableData = {};
|
|
60
|
+
for (const [key, value] of Object.entries(task.taskData)) {
|
|
61
|
+
if (typeof value !== 'function') {
|
|
62
|
+
serializableData[key] = value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
worker.postMessage({
|
|
66
|
+
type: 'compile',
|
|
67
|
+
...serializableData
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
_finishTask(worker, callback, result) {
|
|
71
|
+
if (this.queue.length > 0) {
|
|
72
|
+
this._executeTask(worker, this.queue.shift());
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.workers.push(worker);
|
|
76
|
+
}
|
|
77
|
+
callback(result);
|
|
78
|
+
}
|
|
79
|
+
async destroy() {
|
|
80
|
+
await Promise.all(this.workers.map(w => w.terminate()));
|
|
81
|
+
this.workers = [];
|
|
82
|
+
this.activeWorkers = 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@srsergio/taptapp-ar",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "AR Visualizer and Compiler for Astro and React",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,33 +29,31 @@
|
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "tsc",
|
|
32
|
-
"prepublishOnly": "npm run build"
|
|
32
|
+
"prepublishOnly": "npm run build",
|
|
33
|
+
"test": "vitest"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
36
|
+
"aframe": ">=1.5.0",
|
|
35
37
|
"astro": ">=4.0.0",
|
|
36
38
|
"react": ">=18.0.0",
|
|
37
39
|
"react-dom": ">=18.0.0",
|
|
38
|
-
"three": ">=0.160.0"
|
|
39
|
-
"aframe": ">=1.5.0"
|
|
40
|
+
"three": ">=0.160.0"
|
|
40
41
|
},
|
|
41
42
|
"dependencies": {
|
|
42
|
-
"
|
|
43
|
-
"@tensorflow/tfjs-backend-cpu": "^4.22.0",
|
|
44
|
-
"@tensorflow/tfjs-backend-webgl": "^4.22.0",
|
|
43
|
+
"gpu.js": "^2.16.0",
|
|
45
44
|
"ml-matrix": "^6.10.4",
|
|
46
|
-
"
|
|
47
|
-
"tinyqueue": "^2.0.3",
|
|
48
|
-
"lucide-react": "^0.477.0",
|
|
49
|
-
"nanoid": "^5.0.7"
|
|
45
|
+
"tinyqueue": "^2.0.3"
|
|
50
46
|
},
|
|
51
47
|
"devDependencies": {
|
|
52
|
-
"typescript": "^5.4.5",
|
|
53
48
|
"@types/react": "^18.3.3",
|
|
54
49
|
"@types/react-dom": "^18.3.0",
|
|
55
50
|
"@types/three": "^0.170.0",
|
|
56
|
-
"astro": "5.16.4"
|
|
51
|
+
"astro": "5.16.4",
|
|
52
|
+
"jimp": "^1.6.0",
|
|
53
|
+
"typescript": "^5.4.5",
|
|
54
|
+
"vitest": "^4.0.16"
|
|
57
55
|
},
|
|
58
56
|
"publishConfig": {
|
|
59
57
|
"access": "public"
|
|
60
58
|
}
|
|
61
|
-
}
|
|
59
|
+
}
|
package/src/compiler/aframe.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Controller, UI } from "./index.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
AFRAME.registerSystem("mindar-image-system", {
|
|
5
5
|
container: null,
|
|
6
6
|
video: null,
|
|
@@ -10,7 +10,7 @@ AFRAME.registerSystem("mindar-image-system", {
|
|
|
10
10
|
this.anchorEntities = [];
|
|
11
11
|
},
|
|
12
12
|
|
|
13
|
-
tick: function () {},
|
|
13
|
+
tick: function () { },
|
|
14
14
|
|
|
15
15
|
setup: function ({
|
|
16
16
|
imageTargetSrc,
|
|
@@ -121,7 +121,6 @@ AFRAME.registerSystem("mindar-image-system", {
|
|
|
121
121
|
|
|
122
122
|
_startAR: async function () {
|
|
123
123
|
const video = this.video;
|
|
124
|
-
const container = this.container;
|
|
125
124
|
|
|
126
125
|
this.controller = new Controller({
|
|
127
126
|
inputWidth: video.videoWidth,
|
|
@@ -196,7 +195,6 @@ AFRAME.registerSystem("mindar-image-system", {
|
|
|
196
195
|
const fov = (2 * Math.atan((1 / proj[5] / vh) * container.clientHeight) * 180) / Math.PI; // vertical fov
|
|
197
196
|
const near = proj[14] / (proj[10] - 1.0);
|
|
198
197
|
const far = proj[14] / (proj[10] + 1.0);
|
|
199
|
-
const ratio = proj[5] / proj[0]; // (r-l) / (t-b)
|
|
200
198
|
//console.log("loaded proj: ", proj, ". fov: ", fov, ". near: ", near, ". far: ", far, ". ratio: ", ratio);
|
|
201
199
|
const newAspect = container.clientWidth / container.clientHeight;
|
|
202
200
|
const cameraEle = container.getElementsByTagName("a-camera")[0];
|
|
@@ -65,21 +65,35 @@ class CompilerBase {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
// compute matching data: 50% progress
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
let matchingDataList;
|
|
69
|
+
if (this.compileMatch) {
|
|
70
|
+
matchingDataList = await this.compileMatch({
|
|
71
|
+
progressCallback,
|
|
72
|
+
targetImages,
|
|
73
|
+
basePercent: 0,
|
|
74
|
+
});
|
|
75
|
+
} else {
|
|
76
|
+
const percentPerImage = 50.0 / targetImages.length;
|
|
77
|
+
let percent = 0.0;
|
|
78
|
+
const matchingPromises = targetImages.map(async (targetImage, i) => {
|
|
79
|
+
const imageList = buildImageList(targetImage);
|
|
80
|
+
const percentPerAction = percentPerImage / imageList.length;
|
|
81
|
+
|
|
82
|
+
const matchingData = await _extractMatchingFeatures(imageList, () => {
|
|
83
|
+
percent += percentPerAction;
|
|
84
|
+
progressCallback(percent);
|
|
85
|
+
});
|
|
86
|
+
return matchingData;
|
|
87
|
+
});
|
|
88
|
+
matchingDataList = await Promise.all(matchingPromises);
|
|
89
|
+
}
|
|
90
|
+
|
|
70
91
|
this.data = [];
|
|
71
92
|
for (let i = 0; i < targetImages.length; i++) {
|
|
72
|
-
const targetImage = targetImages[i];
|
|
73
|
-
const imageList = buildImageList(targetImage);
|
|
74
|
-
const percentPerAction = percentPerImage / imageList.length;
|
|
75
|
-
const matchingData = await _extractMatchingFeatures(imageList, () => {
|
|
76
|
-
percent += percentPerAction;
|
|
77
|
-
progressCallback(percent);
|
|
78
|
-
});
|
|
79
93
|
this.data.push({
|
|
80
|
-
targetImage:
|
|
81
|
-
imageList:
|
|
82
|
-
matchingData:
|
|
94
|
+
targetImage: targetImages[i],
|
|
95
|
+
imageList: buildImageList(targetImages[i]),
|
|
96
|
+
matchingData: matchingDataList[i],
|
|
83
97
|
});
|
|
84
98
|
}
|
|
85
99
|
|
|
@@ -145,14 +159,15 @@ class CompilerBase {
|
|
|
145
159
|
return this.data;
|
|
146
160
|
}
|
|
147
161
|
|
|
148
|
-
createProcessCanvas(
|
|
162
|
+
createProcessCanvas() {
|
|
149
163
|
// sub-class implements
|
|
150
164
|
console.warn("missing createProcessCanvas implementation");
|
|
151
165
|
}
|
|
152
166
|
|
|
153
|
-
compileTrack(
|
|
167
|
+
compileTrack() {
|
|
154
168
|
// sub-class implements
|
|
155
169
|
console.warn("missing compileTrack implementation");
|
|
170
|
+
return Promise.resolve([]);
|
|
156
171
|
}
|
|
157
172
|
}
|
|
158
173
|
|
package/src/compiler/compiler.js
CHANGED
|
@@ -10,7 +10,7 @@ export class Compiler extends CompilerBase {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
compileTrack({ progressCallback, targetImages, basePercent }) {
|
|
13
|
-
return new Promise((resolve
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
14
|
const worker = new CompilerWorker();
|
|
15
15
|
worker.onmessage = (e) => {
|
|
16
16
|
if (e.data.type === "progress") {
|
|
@@ -15,7 +15,7 @@ onmessage = (msg) => {
|
|
|
15
15
|
const percentPerAction = percentPerImage / imageList.length;
|
|
16
16
|
|
|
17
17
|
//console.log("compiling tracking...", i);
|
|
18
|
-
const trackingData = extractTrackingFeatures(imageList, (
|
|
18
|
+
const trackingData = extractTrackingFeatures(imageList, () => {
|
|
19
19
|
//console.log("done tracking", i, index);
|
|
20
20
|
percent += percentPerAction;
|
|
21
21
|
postMessage({ type: "progress", percent });
|
|
@@ -81,7 +81,7 @@ class Controller {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
addImageTargets(fileURL) {
|
|
84
|
-
return new Promise(async (resolve
|
|
84
|
+
return new Promise(async (resolve) => {
|
|
85
85
|
const content = await fetch(fileURL);
|
|
86
86
|
const buffer = await content.arrayBuffer();
|
|
87
87
|
const result = this.addImageTargetsFromBuffer(buffer);
|
|
@@ -95,7 +95,6 @@ class Controller {
|
|
|
95
95
|
|
|
96
96
|
const trackingDataList = [];
|
|
97
97
|
const matchingDataList = [];
|
|
98
|
-
const imageListList = [];
|
|
99
98
|
const dimensions = [];
|
|
100
99
|
for (let i = 0; i < dataList.length; i++) {
|
|
101
100
|
matchingDataList.push(dataList[i].matchingData);
|
|
@@ -329,7 +328,7 @@ class Controller {
|
|
|
329
328
|
|
|
330
329
|
async detect(input) {
|
|
331
330
|
const inputT = this.inputLoader.loadInput(input);
|
|
332
|
-
const { featurePoints, debugExtra } =
|
|
331
|
+
const { featurePoints, debugExtra } = this.cropDetector.detect(inputT);
|
|
333
332
|
inputT.dispose();
|
|
334
333
|
return { featurePoints, debugExtra };
|
|
335
334
|
}
|
|
@@ -355,7 +354,7 @@ class Controller {
|
|
|
355
354
|
}
|
|
356
355
|
|
|
357
356
|
_workerMatch(featurePoints, targetIndexes) {
|
|
358
|
-
return new Promise(
|
|
357
|
+
return new Promise((resolve) => {
|
|
359
358
|
this.workerMatchDone = (data) => {
|
|
360
359
|
resolve({
|
|
361
360
|
targetIndex: data.targetIndex,
|
|
@@ -368,7 +367,7 @@ class Controller {
|
|
|
368
367
|
}
|
|
369
368
|
|
|
370
369
|
_workerTrackUpdate(modelViewTransform, trackingFeatures) {
|
|
371
|
-
return new Promise(
|
|
370
|
+
return new Promise((resolve) => {
|
|
372
371
|
this.workerTrackDone = (data) => {
|
|
373
372
|
resolve(data.modelViewTransform);
|
|
374
373
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Matcher } from "./matching/matcher.js";
|
|
2
2
|
import { Estimator } from "./estimation/estimator.js";
|
|
3
3
|
|
|
4
|
-
let projectionTransform = null;
|
|
5
4
|
let matchingDataList = null;
|
|
6
5
|
let debugMode = false;
|
|
7
6
|
let matcher = null;
|
|
@@ -12,7 +11,6 @@ onmessage = (msg) => {
|
|
|
12
11
|
|
|
13
12
|
switch (data.type) {
|
|
14
13
|
case "setup":
|
|
15
|
-
projectionTransform = data.projectionTransform;
|
|
16
14
|
matchingDataList = data.matchingDataList;
|
|
17
15
|
debugMode = data.debugMode;
|
|
18
16
|
matcher = new Matcher(data.inputWidth, data.inputHeight, debugMode);
|