@srsergio/taptapp-ar 1.0.0

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 (207) hide show
  1. package/README.md +62 -0
  2. package/dist/compiler/aframe.d.ts +1 -0
  3. package/dist/compiler/aframe.js +275 -0
  4. package/dist/compiler/compiler-base.d.ts +12 -0
  5. package/dist/compiler/compiler-base.js +165 -0
  6. package/dist/compiler/compiler.d.ts +9 -0
  7. package/dist/compiler/compiler.js +24 -0
  8. package/dist/compiler/compiler.worker.d.ts +1 -0
  9. package/dist/compiler/compiler.worker.js +28 -0
  10. package/dist/compiler/controller.d.ts +101 -0
  11. package/dist/compiler/controller.js +400 -0
  12. package/dist/compiler/controller.worker.d.ts +1 -0
  13. package/dist/compiler/controller.worker.js +61 -0
  14. package/dist/compiler/detector/crop-detector.d.ts +65 -0
  15. package/dist/compiler/detector/crop-detector.js +59 -0
  16. package/dist/compiler/detector/detector.d.ts +98 -0
  17. package/dist/compiler/detector/detector.js +1049 -0
  18. package/dist/compiler/detector/freak.d.ts +1 -0
  19. package/dist/compiler/detector/freak.js +89 -0
  20. package/dist/compiler/detector/kernels/cpu/binomialFilter.d.ts +6 -0
  21. package/dist/compiler/detector/kernels/cpu/binomialFilter.js +51 -0
  22. package/dist/compiler/detector/kernels/cpu/buildExtremas.d.ts +6 -0
  23. package/dist/compiler/detector/kernels/cpu/buildExtremas.js +89 -0
  24. package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.d.ts +7 -0
  25. package/dist/compiler/detector/kernels/cpu/computeExtremaAngles.js +79 -0
  26. package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.d.ts +6 -0
  27. package/dist/compiler/detector/kernels/cpu/computeExtremaFreak.js +68 -0
  28. package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.d.ts +6 -0
  29. package/dist/compiler/detector/kernels/cpu/computeFreakDescriptors.js +57 -0
  30. package/dist/compiler/detector/kernels/cpu/computeLocalization.d.ts +6 -0
  31. package/dist/compiler/detector/kernels/cpu/computeLocalization.js +54 -0
  32. package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.d.ts +6 -0
  33. package/dist/compiler/detector/kernels/cpu/computeOrientationHistograms.js +118 -0
  34. package/dist/compiler/detector/kernels/cpu/downsampleBilinear.d.ts +6 -0
  35. package/dist/compiler/detector/kernels/cpu/downsampleBilinear.js +29 -0
  36. package/dist/compiler/detector/kernels/cpu/extremaReduction.d.ts +6 -0
  37. package/dist/compiler/detector/kernels/cpu/extremaReduction.js +50 -0
  38. package/dist/compiler/detector/kernels/cpu/fakeShader.d.ts +20 -0
  39. package/dist/compiler/detector/kernels/cpu/fakeShader.js +80 -0
  40. package/dist/compiler/detector/kernels/cpu/index.d.ts +1 -0
  41. package/dist/compiler/detector/kernels/cpu/index.js +25 -0
  42. package/dist/compiler/detector/kernels/cpu/prune.d.ts +1 -0
  43. package/dist/compiler/detector/kernels/cpu/prune.js +103 -0
  44. package/dist/compiler/detector/kernels/cpu/smoothHistograms.d.ts +6 -0
  45. package/dist/compiler/detector/kernels/cpu/smoothHistograms.js +47 -0
  46. package/dist/compiler/detector/kernels/cpu/upsampleBilinear.d.ts +6 -0
  47. package/dist/compiler/detector/kernels/cpu/upsampleBilinear.js +43 -0
  48. package/dist/compiler/detector/kernels/index.d.ts +1 -0
  49. package/dist/compiler/detector/kernels/index.js +2 -0
  50. package/dist/compiler/detector/kernels/webgl/binomialFilter.d.ts +6 -0
  51. package/dist/compiler/detector/kernels/webgl/binomialFilter.js +67 -0
  52. package/dist/compiler/detector/kernels/webgl/buildExtremas.d.ts +6 -0
  53. package/dist/compiler/detector/kernels/webgl/buildExtremas.js +101 -0
  54. package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.d.ts +6 -0
  55. package/dist/compiler/detector/kernels/webgl/computeExtremaAngles.js +78 -0
  56. package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.d.ts +6 -0
  57. package/dist/compiler/detector/kernels/webgl/computeExtremaFreak.js +86 -0
  58. package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.d.ts +6 -0
  59. package/dist/compiler/detector/kernels/webgl/computeFreakDescriptors.js +52 -0
  60. package/dist/compiler/detector/kernels/webgl/computeLocalization.d.ts +6 -0
  61. package/dist/compiler/detector/kernels/webgl/computeLocalization.js +58 -0
  62. package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.d.ts +6 -0
  63. package/dist/compiler/detector/kernels/webgl/computeOrientationHistograms.js +116 -0
  64. package/dist/compiler/detector/kernels/webgl/downsampleBilinear.d.ts +6 -0
  65. package/dist/compiler/detector/kernels/webgl/downsampleBilinear.js +46 -0
  66. package/dist/compiler/detector/kernels/webgl/extremaReduction.d.ts +6 -0
  67. package/dist/compiler/detector/kernels/webgl/extremaReduction.js +48 -0
  68. package/dist/compiler/detector/kernels/webgl/index.d.ts +1 -0
  69. package/dist/compiler/detector/kernels/webgl/index.js +25 -0
  70. package/dist/compiler/detector/kernels/webgl/smoothHistograms.d.ts +6 -0
  71. package/dist/compiler/detector/kernels/webgl/smoothHistograms.js +49 -0
  72. package/dist/compiler/detector/kernels/webgl/upsampleBilinear.d.ts +6 -0
  73. package/dist/compiler/detector/kernels/webgl/upsampleBilinear.js +56 -0
  74. package/dist/compiler/estimation/esimate-experiment.d.ts +5 -0
  75. package/dist/compiler/estimation/esimate-experiment.js +267 -0
  76. package/dist/compiler/estimation/estimate.d.ts +5 -0
  77. package/dist/compiler/estimation/estimate.js +51 -0
  78. package/dist/compiler/estimation/estimator.d.ts +13 -0
  79. package/dist/compiler/estimation/estimator.js +30 -0
  80. package/dist/compiler/estimation/refine-estimate-experiment.d.ts +6 -0
  81. package/dist/compiler/estimation/refine-estimate-experiment.js +429 -0
  82. package/dist/compiler/estimation/refine-estimate.d.ts +6 -0
  83. package/dist/compiler/estimation/refine-estimate.js +299 -0
  84. package/dist/compiler/estimation/utils.d.ts +10 -0
  85. package/dist/compiler/estimation/utils.js +80 -0
  86. package/dist/compiler/image-list.d.ts +13 -0
  87. package/dist/compiler/image-list.js +52 -0
  88. package/dist/compiler/index.d.ts +3 -0
  89. package/dist/compiler/index.js +10 -0
  90. package/dist/compiler/input-loader.d.ts +23 -0
  91. package/dist/compiler/input-loader.js +88 -0
  92. package/dist/compiler/matching/hamming-distance.d.ts +1 -0
  93. package/dist/compiler/matching/hamming-distance.js +20 -0
  94. package/dist/compiler/matching/hierarchical-clustering.d.ts +7 -0
  95. package/dist/compiler/matching/hierarchical-clustering.js +109 -0
  96. package/dist/compiler/matching/hough.d.ts +1 -0
  97. package/dist/compiler/matching/hough.js +169 -0
  98. package/dist/compiler/matching/matcher.d.ts +28 -0
  99. package/dist/compiler/matching/matcher.js +48 -0
  100. package/dist/compiler/matching/matching.d.ts +41 -0
  101. package/dist/compiler/matching/matching.js +197 -0
  102. package/dist/compiler/matching/ransacHomography.d.ts +1 -0
  103. package/dist/compiler/matching/ransacHomography.js +136 -0
  104. package/dist/compiler/offline-compiler.d.ts +10 -0
  105. package/dist/compiler/offline-compiler.js +450 -0
  106. package/dist/compiler/tensorflow-setup.d.ts +7 -0
  107. package/dist/compiler/tensorflow-setup.js +73 -0
  108. package/dist/compiler/three.d.ts +66 -0
  109. package/dist/compiler/three.js +310 -0
  110. package/dist/compiler/tracker/extract-utils.d.ts +1 -0
  111. package/dist/compiler/tracker/extract-utils.js +29 -0
  112. package/dist/compiler/tracker/extract.d.ts +4 -0
  113. package/dist/compiler/tracker/extract.js +349 -0
  114. package/dist/compiler/tracker/tracker.d.ts +38 -0
  115. package/dist/compiler/tracker/tracker.js +327 -0
  116. package/dist/compiler/utils/cumsum.d.ts +5 -0
  117. package/dist/compiler/utils/cumsum.js +39 -0
  118. package/dist/compiler/utils/geometry.d.ts +8 -0
  119. package/dist/compiler/utils/geometry.js +101 -0
  120. package/dist/compiler/utils/homography.d.ts +1 -0
  121. package/dist/compiler/utils/homography.js +138 -0
  122. package/dist/compiler/utils/images.d.ts +24 -0
  123. package/dist/compiler/utils/images.js +99 -0
  124. package/dist/compiler/utils/randomizer.d.ts +5 -0
  125. package/dist/compiler/utils/randomizer.js +25 -0
  126. package/dist/index.d.ts +6 -0
  127. package/dist/index.js +7 -0
  128. package/dist/react/AREditor.d.ts +5 -0
  129. package/dist/react/AREditor.js +159 -0
  130. package/dist/react/ProgressDialog.d.ts +13 -0
  131. package/dist/react/ProgressDialog.js +57 -0
  132. package/dist/react/types.d.ts +22 -0
  133. package/dist/react/types.js +14 -0
  134. package/package.json +53 -0
  135. package/src/astro/ARScene.astro +59 -0
  136. package/src/astro/ARVideoTrigger.astro +73 -0
  137. package/src/astro/overlays/ErrorOverlay.astro +40 -0
  138. package/src/astro/overlays/LoadingOverlay.astro +28 -0
  139. package/src/astro/overlays/ScanningOverlay.astro +119 -0
  140. package/src/astro/scripts/ARScripts.astro +118 -0
  141. package/src/astro/styles/ARStyles.astro +147 -0
  142. package/src/compiler/aframe.js +343 -0
  143. package/src/compiler/compiler-base.js +195 -0
  144. package/src/compiler/compiler.js +25 -0
  145. package/src/compiler/compiler.worker.js +30 -0
  146. package/src/compiler/controller.js +473 -0
  147. package/src/compiler/controller.worker.js +77 -0
  148. package/src/compiler/detector/crop-detector.js +68 -0
  149. package/src/compiler/detector/detector.js +1130 -0
  150. package/src/compiler/detector/freak.js +91 -0
  151. package/src/compiler/detector/kernels/cpu/binomialFilter.js +59 -0
  152. package/src/compiler/detector/kernels/cpu/buildExtremas.js +108 -0
  153. package/src/compiler/detector/kernels/cpu/computeExtremaAngles.js +91 -0
  154. package/src/compiler/detector/kernels/cpu/computeExtremaFreak.js +92 -0
  155. package/src/compiler/detector/kernels/cpu/computeFreakDescriptors.js +68 -0
  156. package/src/compiler/detector/kernels/cpu/computeLocalization.js +71 -0
  157. package/src/compiler/detector/kernels/cpu/computeOrientationHistograms.js +141 -0
  158. package/src/compiler/detector/kernels/cpu/downsampleBilinear.js +33 -0
  159. package/src/compiler/detector/kernels/cpu/extremaReduction.js +53 -0
  160. package/src/compiler/detector/kernels/cpu/fakeShader.js +88 -0
  161. package/src/compiler/detector/kernels/cpu/index.js +26 -0
  162. package/src/compiler/detector/kernels/cpu/prune.js +114 -0
  163. package/src/compiler/detector/kernels/cpu/smoothHistograms.js +57 -0
  164. package/src/compiler/detector/kernels/cpu/upsampleBilinear.js +51 -0
  165. package/src/compiler/detector/kernels/index.js +2 -0
  166. package/src/compiler/detector/kernels/webgl/binomialFilter.js +72 -0
  167. package/src/compiler/detector/kernels/webgl/buildExtremas.js +109 -0
  168. package/src/compiler/detector/kernels/webgl/computeExtremaAngles.js +82 -0
  169. package/src/compiler/detector/kernels/webgl/computeExtremaFreak.js +105 -0
  170. package/src/compiler/detector/kernels/webgl/computeFreakDescriptors.js +56 -0
  171. package/src/compiler/detector/kernels/webgl/computeLocalization.js +70 -0
  172. package/src/compiler/detector/kernels/webgl/computeOrientationHistograms.js +129 -0
  173. package/src/compiler/detector/kernels/webgl/downsampleBilinear.js +50 -0
  174. package/src/compiler/detector/kernels/webgl/extremaReduction.js +50 -0
  175. package/src/compiler/detector/kernels/webgl/index.js +26 -0
  176. package/src/compiler/detector/kernels/webgl/smoothHistograms.js +53 -0
  177. package/src/compiler/detector/kernels/webgl/upsampleBilinear.js +62 -0
  178. package/src/compiler/estimation/esimate-experiment.js +316 -0
  179. package/src/compiler/estimation/estimate.js +67 -0
  180. package/src/compiler/estimation/estimator.js +34 -0
  181. package/src/compiler/estimation/refine-estimate-experiment.js +512 -0
  182. package/src/compiler/estimation/refine-estimate.js +365 -0
  183. package/src/compiler/estimation/utils.js +97 -0
  184. package/src/compiler/image-list.js +62 -0
  185. package/src/compiler/index.js +13 -0
  186. package/src/compiler/input-loader.js +107 -0
  187. package/src/compiler/matching/hamming-distance.js +23 -0
  188. package/src/compiler/matching/hierarchical-clustering.js +131 -0
  189. package/src/compiler/matching/hough.js +206 -0
  190. package/src/compiler/matching/matcher.js +59 -0
  191. package/src/compiler/matching/matching.js +237 -0
  192. package/src/compiler/matching/ransacHomography.js +192 -0
  193. package/src/compiler/offline-compiler.js +553 -0
  194. package/src/compiler/tensorflow-setup.js +88 -0
  195. package/src/compiler/three.js +368 -0
  196. package/src/compiler/tracker/extract-utils.js +34 -0
  197. package/src/compiler/tracker/extract.js +419 -0
  198. package/src/compiler/tracker/tracker.js +397 -0
  199. package/src/compiler/utils/cumsum.js +40 -0
  200. package/src/compiler/utils/geometry.js +114 -0
  201. package/src/compiler/utils/homography.js +150 -0
  202. package/src/compiler/utils/images.js +111 -0
  203. package/src/compiler/utils/randomizer.js +29 -0
  204. package/src/index.ts +8 -0
  205. package/src/react/AREditor.tsx +394 -0
  206. package/src/react/ProgressDialog.tsx +185 -0
  207. package/src/react/types.ts +35 -0
@@ -0,0 +1,343 @@
1
+ import { Controller, UI } from "./index.js";
2
+
3
+ const needsDOMRefresh = document.readyState === "complete" || document.readyState == "interactive";
4
+ AFRAME.registerSystem("mindar-image-system", {
5
+ container: null,
6
+ video: null,
7
+ processingImage: false,
8
+
9
+ init: function () {
10
+ this.anchorEntities = [];
11
+ },
12
+
13
+ tick: function () {},
14
+
15
+ setup: function ({
16
+ imageTargetSrc,
17
+ maxTrack,
18
+ showStats,
19
+ uiLoading,
20
+ uiScanning,
21
+ uiError,
22
+ missTolerance,
23
+ warmupTolerance,
24
+ filterMinCF,
25
+ filterBeta,
26
+ }) {
27
+ this.imageTargetSrc = imageTargetSrc;
28
+ this.maxTrack = maxTrack;
29
+ this.filterMinCF = filterMinCF;
30
+ this.filterBeta = filterBeta;
31
+ this.missTolerance = missTolerance;
32
+ this.warmupTolerance = warmupTolerance;
33
+ this.showStats = showStats;
34
+ this.ui = new UI({ uiLoading, uiScanning, uiError });
35
+ },
36
+
37
+ registerAnchor: function (el, targetIndex) {
38
+ this.anchorEntities.push({ el: el, targetIndex: targetIndex });
39
+ },
40
+
41
+ start: function () {
42
+ this.container = this.el.sceneEl.parentNode;
43
+
44
+ if (this.showStats) {
45
+ this.mainStats = new Stats();
46
+ this.mainStats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
47
+ this.mainStats.domElement.style.cssText = "position:absolute;top:0px;left:0px;z-index:999";
48
+ this.container.appendChild(this.mainStats.domElement);
49
+ }
50
+
51
+ this.ui.showLoading();
52
+ this._startVideo();
53
+ },
54
+
55
+ switchTarget: function (targetIndex) {
56
+ this.controller.interestedTargetIndex = targetIndex;
57
+ },
58
+
59
+ stop: function () {
60
+ this.pause();
61
+ const tracks = this.video.srcObject.getTracks();
62
+ tracks.forEach(function (track) {
63
+ track.stop();
64
+ });
65
+ this.video.remove();
66
+ this.controller.dispose();
67
+ },
68
+
69
+ pause: function (keepVideo = false) {
70
+ if (!keepVideo) {
71
+ this.video.pause();
72
+ }
73
+ this.controller.stopProcessVideo();
74
+ },
75
+
76
+ unpause: function () {
77
+ this.video.play();
78
+ this.controller.processVideo(this.video);
79
+ },
80
+
81
+ _startVideo: function () {
82
+ this.video = document.createElement("video");
83
+
84
+ this.video.setAttribute("autoplay", "");
85
+ this.video.setAttribute("muted", "");
86
+ this.video.setAttribute("playsinline", "");
87
+ this.video.style.position = "absolute";
88
+ this.video.style.top = "0px";
89
+ this.video.style.left = "0px";
90
+ this.video.style.zIndex = "-2";
91
+ this.container.appendChild(this.video);
92
+
93
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
94
+ // TODO: show unsupported error
95
+ this.el.emit("arError", { error: "VIDEO_FAIL" });
96
+ this.ui.showCompatibility();
97
+ return;
98
+ }
99
+
100
+ navigator.mediaDevices
101
+ .getUserMedia({
102
+ audio: false,
103
+ video: {
104
+ facingMode: "environment",
105
+ },
106
+ })
107
+ .then((stream) => {
108
+ this.video.addEventListener("loadedmetadata", () => {
109
+ //console.log("video ready...", this.video);
110
+ this.video.setAttribute("width", this.video.videoWidth);
111
+ this.video.setAttribute("height", this.video.videoHeight);
112
+ this._startAR();
113
+ });
114
+ this.video.srcObject = stream;
115
+ })
116
+ .catch((err) => {
117
+ console.log("getUserMedia error", err);
118
+ this.el.emit("arError", { error: "VIDEO_FAIL" });
119
+ });
120
+ },
121
+
122
+ _startAR: async function () {
123
+ const video = this.video;
124
+ const container = this.container;
125
+
126
+ this.controller = new Controller({
127
+ inputWidth: video.videoWidth,
128
+ inputHeight: video.videoHeight,
129
+ maxTrack: this.maxTrack,
130
+ filterMinCF: this.filterMinCF,
131
+ filterBeta: this.filterBeta,
132
+ missTolerance: this.missTolerance,
133
+ warmupTolerance: this.warmupTolerance,
134
+ onUpdate: (data) => {
135
+ if (data.type === "processDone") {
136
+ if (this.mainStats) this.mainStats.update();
137
+ } else if (data.type === "updateMatrix") {
138
+ const { targetIndex, worldMatrix } = data;
139
+
140
+ for (let i = 0; i < this.anchorEntities.length; i++) {
141
+ if (this.anchorEntities[i].targetIndex === targetIndex) {
142
+ this.anchorEntities[i].el.updateWorldMatrix(worldMatrix);
143
+ }
144
+ }
145
+
146
+ let isAnyVisible = this.anchorEntities.reduce((acc, entity) => {
147
+ return acc || entity.el.el.object3D.visible;
148
+ }, false);
149
+ if (isAnyVisible) {
150
+ this.ui.hideScanning();
151
+ } else {
152
+ this.ui.showScanning();
153
+ }
154
+ }
155
+ },
156
+ });
157
+
158
+ this._resize();
159
+ window.addEventListener("resize", this._resize.bind(this));
160
+
161
+ const { dimensions: imageTargetDimensions } = await this.controller.addImageTargets(
162
+ this.imageTargetSrc,
163
+ );
164
+
165
+ for (let i = 0; i < this.anchorEntities.length; i++) {
166
+ const { el, targetIndex } = this.anchorEntities[i];
167
+ if (targetIndex < imageTargetDimensions.length) {
168
+ el.setupMarker(imageTargetDimensions[targetIndex]);
169
+ }
170
+ }
171
+
172
+ await this.controller.dummyRun(this.video);
173
+ this.el.emit("arReady");
174
+ this.ui.hideLoading();
175
+ this.ui.showScanning();
176
+
177
+ this.controller.processVideo(this.video);
178
+ },
179
+
180
+ _resize: function () {
181
+ const video = this.video;
182
+ const container = this.container;
183
+
184
+ let vw, vh; // display css width, height
185
+ const videoRatio = video.videoWidth / video.videoHeight;
186
+ const containerRatio = container.clientWidth / container.clientHeight;
187
+ if (videoRatio > containerRatio) {
188
+ vh = container.clientHeight;
189
+ vw = vh * videoRatio;
190
+ } else {
191
+ vw = container.clientWidth;
192
+ vh = vw / videoRatio;
193
+ }
194
+
195
+ const proj = this.controller.getProjectionMatrix();
196
+ const fov = (2 * Math.atan((1 / proj[5] / vh) * container.clientHeight) * 180) / Math.PI; // vertical fov
197
+ const near = proj[14] / (proj[10] - 1.0);
198
+ const far = proj[14] / (proj[10] + 1.0);
199
+ const ratio = proj[5] / proj[0]; // (r-l) / (t-b)
200
+ //console.log("loaded proj: ", proj, ". fov: ", fov, ". near: ", near, ". far: ", far, ". ratio: ", ratio);
201
+ const newAspect = container.clientWidth / container.clientHeight;
202
+ const cameraEle = container.getElementsByTagName("a-camera")[0];
203
+ const camera = cameraEle.getObject3D("camera");
204
+ camera.fov = fov;
205
+ camera.aspect = newAspect;
206
+ camera.near = near;
207
+ camera.far = far;
208
+ camera.updateProjectionMatrix();
209
+ //const newCam = new AFRAME.THREE.PerspectiveCamera(fov, newRatio, near, far);
210
+ //camera.getObject3D('camera').projectionMatrix = newCam.projectionMatrix;
211
+
212
+ this.video.style.top = -(vh - container.clientHeight) / 2 + "px";
213
+ this.video.style.left = -(vw - container.clientWidth) / 2 + "px";
214
+ this.video.style.width = vw + "px";
215
+ this.video.style.height = vh + "px";
216
+ },
217
+ });
218
+
219
+ AFRAME.registerComponent("mindar-image", {
220
+ dependencies: ["mindar-image-system"],
221
+
222
+ schema: {
223
+ imageTargetSrc: { type: "string" },
224
+ maxTrack: { type: "int", default: 1 },
225
+ filterMinCF: { type: "number", default: -1 },
226
+ filterBeta: { type: "number", default: -1 },
227
+ missTolerance: { type: "int", default: -1 },
228
+ warmupTolerance: { type: "int", default: -1 },
229
+ showStats: { type: "boolean", default: false },
230
+ autoStart: { type: "boolean", default: true },
231
+ uiLoading: { type: "string", default: "yes" },
232
+ uiScanning: { type: "string", default: "yes" },
233
+ uiError: { type: "string", default: "yes" },
234
+ },
235
+
236
+ init: function () {
237
+ const arSystem = this.el.sceneEl.systems["mindar-image-system"];
238
+
239
+ arSystem.setup({
240
+ imageTargetSrc: this.data.imageTargetSrc,
241
+ maxTrack: this.data.maxTrack,
242
+ filterMinCF: this.data.filterMinCF === -1 ? null : this.data.filterMinCF,
243
+ filterBeta: this.data.filterBeta === -1 ? null : this.data.filterBeta,
244
+ missTolerance: this.data.missTolerance === -1 ? null : this.data.missTolerance,
245
+ warmupTolerance: this.data.warmupTolerance === -1 ? null : this.data.warmupTolerance,
246
+ showStats: this.data.showStats,
247
+ uiLoading: this.data.uiLoading,
248
+ uiScanning: this.data.uiScanning,
249
+ uiError: this.data.uiError,
250
+ });
251
+ if (this.data.autoStart) {
252
+ this.el.sceneEl.addEventListener("renderstart", () => {
253
+ arSystem.start();
254
+ });
255
+ }
256
+ },
257
+ remove: function () {
258
+ const arSystem = this.el.sceneEl.systems["mindar-image-system"];
259
+ arSystem.stop();
260
+ },
261
+ });
262
+
263
+ AFRAME.registerComponent("mindar-image-target", {
264
+ dependencies: ["mindar-image-system"],
265
+
266
+ schema: {
267
+ targetIndex: { type: "number" },
268
+ },
269
+
270
+ postMatrix: null, // rescale the anchor to make width of 1 unit = physical width of card
271
+
272
+ init: function () {
273
+ const arSystem = this.el.sceneEl.systems["mindar-image-system"];
274
+ arSystem.registerAnchor(this, this.data.targetIndex);
275
+
276
+ this.invisibleMatrix = new AFRAME.THREE.Matrix4().set(
277
+ 0,
278
+ 0,
279
+ 0,
280
+ 0,
281
+ 0,
282
+ 0,
283
+ 0,
284
+ 0,
285
+ 0,
286
+ 0,
287
+ 0,
288
+ 0,
289
+ 0,
290
+ 0,
291
+ 0,
292
+ 0,
293
+ );
294
+
295
+ const root = this.el.object3D;
296
+ root.visible = false;
297
+ root.matrixAutoUpdate = false;
298
+
299
+ root.matrix = this.invisibleMatrix;
300
+ },
301
+
302
+ setupMarker([markerWidth, markerHeight]) {
303
+ const position = new AFRAME.THREE.Vector3();
304
+ const quaternion = new AFRAME.THREE.Quaternion();
305
+ const scale = new AFRAME.THREE.Vector3();
306
+ position.x = markerWidth / 2;
307
+ position.y = markerWidth / 2 + (markerHeight - markerWidth) / 2;
308
+ scale.x = markerWidth;
309
+ scale.y = markerWidth;
310
+ scale.z = markerWidth;
311
+ this.postMatrix = new AFRAME.THREE.Matrix4();
312
+ this.postMatrix.compose(position, quaternion, scale);
313
+ },
314
+
315
+ updateWorldMatrix(worldMatrix) {
316
+ this.el.emit("targetUpdate");
317
+ if (!this.el.object3D.visible && worldMatrix !== null) {
318
+ this.el.emit("targetFound");
319
+ } else if (this.el.object3D.visible && worldMatrix === null) {
320
+ this.el.emit("targetLost");
321
+ }
322
+
323
+ this.el.object3D.visible = worldMatrix !== null;
324
+ if (worldMatrix === null) {
325
+ this.el.object3D.matrix = this.invisibleMatrix;
326
+ return;
327
+ }
328
+ var m = new AFRAME.THREE.Matrix4();
329
+ m.elements = worldMatrix;
330
+ m.multiply(this.postMatrix);
331
+ this.el.object3D.matrix = m;
332
+ },
333
+ });
334
+ /*
335
+ This is a hack.
336
+ If the user's browser has cached A-Frame,
337
+ then A-Frame will process the webpage *before* the system and components get registered.
338
+ Resulting in a blank page. This happens because module loading is deferred.
339
+ */
340
+ /* if(needsDOMRefresh){
341
+ console.log("mindar-face-aframe::Refreshing DOM...")
342
+ document.body.innerHTML=document.body.innerHTML;
343
+ } */
@@ -0,0 +1,195 @@
1
+ import { Detector } from "./detector/detector.js";
2
+ import { buildImageList, buildTrackingImageList } from "./image-list.js";
3
+ import { build as hierarchicalClusteringBuild } from "./matching/hierarchical-clustering.js";
4
+ import * as msgpack from "@msgpack/msgpack";
5
+ import { tf } from "./tensorflow-setup.js";
6
+
7
+ // TODO: better compression method. now grey image saved in pixels, which could be larger than original image
8
+
9
+ const CURRENT_VERSION = 2;
10
+
11
+ class CompilerBase {
12
+ constructor() {
13
+ this.data = null;
14
+ }
15
+
16
+ // input images con formato {width, height, data}
17
+ compileImageTargets(images, progressCallback) {
18
+ return new Promise(async (resolve, reject) => {
19
+ try {
20
+ const targetImages = [];
21
+ for (let i = 0; i < images.length; i++) {
22
+ const img = images[i];
23
+
24
+ if (!img || !img.width || !img.height || !img.data) {
25
+ reject(
26
+ new Error(
27
+ `Imagen inválida en posición ${i}. Debe tener propiedades width, height y data.`,
28
+ ),
29
+ );
30
+ return;
31
+ }
32
+
33
+ // Convertir a escala de grises si aún no lo está
34
+ // Buffer alineado para optimización SIMD
35
+ const greyImageData = new Uint8Array(
36
+ new SharedArrayBuffer(Math.ceil((img.width * img.height) / 16) * 16),
37
+ );
38
+
39
+ // Si los datos ya están en escala de grises (1 byte por píxel)
40
+ if (img.data.length === img.width * img.height) {
41
+ greyImageData.set(img.data);
42
+ }
43
+ // Si los datos están en formato RGBA (4 bytes por píxel)
44
+ else if (img.data.length === img.width * img.height * 4) {
45
+ for (let j = 0; j < greyImageData.length; j++) {
46
+ const offset = j * 4;
47
+ greyImageData[j] = Math.floor(
48
+ (img.data[offset] + img.data[offset + 1] + img.data[offset + 2]) / 3,
49
+ );
50
+ }
51
+ }
52
+ // Si los datos están en otro formato, rechazar
53
+ else {
54
+ reject(new Error(`Formato de datos de imagen no soportado en posición ${i}`));
55
+ return;
56
+ }
57
+
58
+ const targetImage = {
59
+ data: greyImageData,
60
+ height: img.height,
61
+ width: img.width,
62
+ };
63
+
64
+ targetImages.push(targetImage);
65
+ }
66
+
67
+ // compute matching data: 50% progress
68
+ const percentPerImage = 50.0 / targetImages.length;
69
+ let percent = 0.0;
70
+ this.data = [];
71
+ 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
+ this.data.push({
80
+ targetImage: targetImage,
81
+ imageList: imageList,
82
+ matchingData: matchingData,
83
+ });
84
+ }
85
+
86
+ for (let i = 0; i < targetImages.length; i++) {
87
+ const trackingImageList = buildTrackingImageList(targetImages[i]);
88
+ this.data[i].trackingImageList = trackingImageList;
89
+ }
90
+
91
+ const trackingDataList = await this.compileTrack({
92
+ progressCallback,
93
+ targetImages,
94
+ basePercent: 50,
95
+ });
96
+
97
+ for (let i = 0; i < targetImages.length; i++) {
98
+ this.data[i].trackingData = trackingDataList[i];
99
+ }
100
+ resolve(this.data);
101
+ } catch (error) {
102
+ reject(error);
103
+ }
104
+ });
105
+ }
106
+
107
+ // not exporting imageList because too large. rebuild this using targetImage
108
+ exportData() {
109
+ const dataList = [];
110
+ for (let i = 0; i < this.data.length; i++) {
111
+ dataList.push({
112
+ //targetImage: this.data[i].targetImage,
113
+ targetImage: {
114
+ width: this.data[i].targetImage.width,
115
+ height: this.data[i].targetImage.height,
116
+ },
117
+ trackingData: this.data[i].trackingData,
118
+ matchingData: this.data[i].matchingData,
119
+ });
120
+ }
121
+ const buffer = msgpack.encode({
122
+ v: CURRENT_VERSION,
123
+ dataList,
124
+ });
125
+ return buffer;
126
+ }
127
+
128
+ importData(buffer) {
129
+ const content = msgpack.decode(new Uint8Array(buffer));
130
+ //console.log("import", content);
131
+
132
+ if (!content.v || content.v !== CURRENT_VERSION) {
133
+ console.error("Your compiled .mind might be outdated. Please recompile");
134
+ return [];
135
+ }
136
+ const { dataList } = content;
137
+ this.data = [];
138
+ for (let i = 0; i < dataList.length; i++) {
139
+ this.data.push({
140
+ targetImage: dataList[i].targetImage,
141
+ trackingData: dataList[i].trackingData,
142
+ matchingData: dataList[i].matchingData,
143
+ });
144
+ }
145
+ return this.data;
146
+ }
147
+
148
+ createProcessCanvas(img) {
149
+ // sub-class implements
150
+ console.warn("missing createProcessCanvas implementation");
151
+ }
152
+
153
+ compileTrack({ progressCallback, targetImages, basePercent }) {
154
+ // sub-class implements
155
+ console.warn("missing compileTrack implementation");
156
+ }
157
+ }
158
+
159
+ const _extractMatchingFeatures = async (imageList, doneCallback) => {
160
+ const keyframes = [];
161
+ for (let i = 0; i < imageList.length; i++) {
162
+ const image = imageList[i];
163
+ // TODO: can improve performance greatly if reuse the same detector. just need to handle resizing the kernel outputs
164
+ const detector = new Detector(image.width, image.height);
165
+
166
+ await tf.nextFrame();
167
+ tf.tidy(() => {
168
+ //const inputT = tf.tensor(image.data, [image.data.length]).reshape([image.height, image.width]);
169
+ const inputT = tf
170
+ .tensor(image.data, [image.data.length], "float32")
171
+ .reshape([image.height, image.width]);
172
+ //const ps = detector.detectImageData(image.data);
173
+ const { featurePoints: ps } = detector.detect(inputT);
174
+
175
+ const maximaPoints = ps.filter((p) => p.maxima);
176
+ const minimaPoints = ps.filter((p) => !p.maxima);
177
+ const maximaPointsCluster = hierarchicalClusteringBuild({ points: maximaPoints });
178
+ const minimaPointsCluster = hierarchicalClusteringBuild({ points: minimaPoints });
179
+
180
+ keyframes.push({
181
+ maximaPoints,
182
+ minimaPoints,
183
+ maximaPointsCluster,
184
+ minimaPointsCluster,
185
+ width: image.width,
186
+ height: image.height,
187
+ scale: image.scale,
188
+ });
189
+ doneCallback(i);
190
+ });
191
+ }
192
+ return keyframes;
193
+ };
194
+
195
+ export { CompilerBase };
@@ -0,0 +1,25 @@
1
+ import { CompilerBase } from "./compiler-base.js";
2
+ import CompilerWorker from "./compiler.worker.js?worker&inline";
3
+
4
+ export class Compiler extends CompilerBase {
5
+ createProcessCanvas(img) {
6
+ const processCanvas = document.createElement("canvas");
7
+ processCanvas.width = img.width;
8
+ processCanvas.height = img.height;
9
+ return processCanvas;
10
+ }
11
+
12
+ compileTrack({ progressCallback, targetImages, basePercent }) {
13
+ return new Promise((resolve, reject) => {
14
+ const worker = new CompilerWorker();
15
+ worker.onmessage = (e) => {
16
+ if (e.data.type === "progress") {
17
+ progressCallback(basePercent + (e.data.percent * basePercent) / 100);
18
+ } else if (e.data.type === "compileDone") {
19
+ resolve(e.data.list);
20
+ }
21
+ };
22
+ worker.postMessage({ type: "compile", targetImages });
23
+ });
24
+ }
25
+ }
@@ -0,0 +1,30 @@
1
+ import { extractTrackingFeatures } from "./tracker/extract-utils.js";
2
+ import { buildTrackingImageList } from "./image-list.js";
3
+
4
+ onmessage = (msg) => {
5
+ const { data } = msg;
6
+ if (data.type === "compile") {
7
+ //console.log("worker compile...");
8
+ const { targetImages } = data;
9
+ const percentPerImage = 100.0 / targetImages.length;
10
+ let percent = 0.0;
11
+ const list = [];
12
+ for (let i = 0; i < targetImages.length; i++) {
13
+ const targetImage = targetImages[i];
14
+ const imageList = buildTrackingImageList(targetImage);
15
+ const percentPerAction = percentPerImage / imageList.length;
16
+
17
+ //console.log("compiling tracking...", i);
18
+ const trackingData = extractTrackingFeatures(imageList, (index) => {
19
+ //console.log("done tracking", i, index);
20
+ percent += percentPerAction;
21
+ postMessage({ type: "progress", percent });
22
+ });
23
+ list.push(trackingData);
24
+ }
25
+ postMessage({
26
+ type: "compileDone",
27
+ list,
28
+ });
29
+ }
30
+ };