@srsergio/taptapp-ar 1.0.101 → 1.1.2

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 (63) hide show
  1. package/dist/compiler/node-worker.js +1 -197
  2. package/dist/compiler/offline-compiler.js +1 -207
  3. package/dist/core/constants.js +1 -38
  4. package/dist/core/detector/crop-detector.js +1 -88
  5. package/dist/core/detector/detector-lite.js +1 -455
  6. package/dist/core/detector/freak.js +1 -89
  7. package/dist/core/estimation/estimate.js +1 -16
  8. package/dist/core/estimation/estimator.js +1 -30
  9. package/dist/core/estimation/morph-refinement.js +1 -116
  10. package/dist/core/estimation/non-rigid-refine.js +1 -70
  11. package/dist/core/estimation/pnp-solver.js +1 -109
  12. package/dist/core/estimation/refine-estimate.js +1 -311
  13. package/dist/core/estimation/utils.js +1 -67
  14. package/dist/core/features/auto-rotation-feature.js +1 -30
  15. package/dist/core/features/crop-detection-feature.js +1 -26
  16. package/dist/core/features/feature-base.js +1 -1
  17. package/dist/core/features/feature-manager.js +1 -55
  18. package/dist/core/features/one-euro-filter-feature.js +1 -44
  19. package/dist/core/features/temporal-filter-feature.js +1 -57
  20. package/dist/core/image-list.js +1 -54
  21. package/dist/core/input-loader.js +1 -87
  22. package/dist/core/matching/hamming-distance.js +1 -66
  23. package/dist/core/matching/hdc.js +1 -102
  24. package/dist/core/matching/hierarchical-clustering.js +1 -130
  25. package/dist/core/matching/hough.js +1 -170
  26. package/dist/core/matching/matcher.js +1 -66
  27. package/dist/core/matching/matching.js +1 -401
  28. package/dist/core/matching/ransacHomography.js +1 -132
  29. package/dist/core/perception/bio-inspired-engine.js +1 -232
  30. package/dist/core/perception/foveal-attention.js +1 -280
  31. package/dist/core/perception/index.js +1 -17
  32. package/dist/core/perception/predictive-coding.js +1 -278
  33. package/dist/core/perception/saccadic-controller.js +1 -269
  34. package/dist/core/perception/saliency-map.js +1 -254
  35. package/dist/core/perception/scale-orchestrator.js +1 -68
  36. package/dist/core/protocol.js +1 -254
  37. package/dist/core/tracker/extract-utils.js +1 -29
  38. package/dist/core/tracker/extract.js +1 -306
  39. package/dist/core/tracker/tracker.js +1 -352
  40. package/dist/core/utils/cumsum.js +1 -37
  41. package/dist/core/utils/delaunay.js +1 -125
  42. package/dist/core/utils/geometry.js +1 -101
  43. package/dist/core/utils/gpu-compute.js +1 -231
  44. package/dist/core/utils/homography.js +1 -138
  45. package/dist/core/utils/images.js +1 -108
  46. package/dist/core/utils/lsh-binarizer.js +1 -37
  47. package/dist/core/utils/lsh-direct.js +1 -76
  48. package/dist/core/utils/projection.js +1 -51
  49. package/dist/core/utils/randomizer.js +1 -25
  50. package/dist/core/utils/worker-pool.js +1 -89
  51. package/dist/index.js +1 -7
  52. package/dist/libs/one-euro-filter.js +1 -70
  53. package/dist/react/TaptappAR.js +1 -151
  54. package/dist/react/types.js +1 -16
  55. package/dist/react/use-ar.js +1 -118
  56. package/dist/runtime/aframe.js +1 -272
  57. package/dist/runtime/bio-inspired-controller.js +1 -358
  58. package/dist/runtime/controller.js +1 -592
  59. package/dist/runtime/controller.worker.js +1 -93
  60. package/dist/runtime/index.js +1 -5
  61. package/dist/runtime/three.js +1 -304
  62. package/dist/runtime/track.js +1 -381
  63. package/package.json +9 -3
@@ -1,16 +1 @@
1
- export function mapDataToPropsConfig(data) {
2
- const photos = data.find((item) => item.type === "photos");
3
- const video = data.find((item) => item.type === "videoNative");
4
- const imageOverlay = data.find((item) => item.type === "imageOverlay");
5
- const ar = data.find((item) => item.type === "ar");
6
- const overlay = video || imageOverlay;
7
- return {
8
- cardId: photos?.id || "",
9
- targetImageSrc: photos?.images?.[0]?.image || "",
10
- targetTaarSrc: ar?.url || "",
11
- videoSrc: overlay?.url || "",
12
- videoWidth: overlay?.width || 0,
13
- videoHeight: overlay?.height || 0,
14
- scale: overlay?.scale || 1,
15
- };
16
- }
1
+ export function mapDataToPropsConfig(e){const i=e.find(e=>"photos"===e.type),t=e.find(e=>"videoNative"===e.type),a=e.find(e=>"imageOverlay"===e.type),r=e.find(e=>"ar"===e.type),d=t||a;return{cardId:i?.id||"",targetImageSrc:i?.images?.[0]?.image||"",targetTaarSrc:r?.url||"",videoSrc:d?.url||"",videoWidth:d?.width||0,videoHeight:d?.height||0,scale:d?.scale||1}}
@@ -1,118 +1 @@
1
- import { useEffect, useRef, useState, useCallback } from "react";
2
- export const useAR = (config) => {
3
- const containerRef = useRef(null);
4
- const overlayRef = useRef(null);
5
- const [status, setStatus] = useState("scanning");
6
- const [isPlaying, setIsPlaying] = useState(false);
7
- const [trackedPoints, setTrackedPoints] = useState([]);
8
- const [error, setError] = useState(null);
9
- const arInstanceRef = useRef(null);
10
- const toggleVideo = useCallback(async () => {
11
- const overlay = overlayRef.current;
12
- if (!(overlay instanceof HTMLVideoElement))
13
- return;
14
- try {
15
- if (overlay.paused) {
16
- await overlay.play();
17
- setIsPlaying(true);
18
- }
19
- else {
20
- overlay.pause();
21
- setIsPlaying(false);
22
- }
23
- }
24
- catch (err) {
25
- console.error("Error toggling video:", err);
26
- }
27
- }, []);
28
- useEffect(() => {
29
- if (typeof window === "undefined" || !containerRef.current || !overlayRef.current)
30
- return;
31
- let isMounted = true;
32
- const initAR = async () => {
33
- try {
34
- // Safe hybrid import for SSR + Speed
35
- const { createTracker } = await import("../runtime/track.js");
36
- if (!isMounted)
37
- return;
38
- setStatus("compiling");
39
- const instance = await createTracker({
40
- container: containerRef.current,
41
- targetSrc: config.targetTaarSrc || config.targetImageSrc,
42
- overlay: overlayRef.current,
43
- scale: config.scale,
44
- cameraConfig: config.cameraConfig,
45
- debugMode: false,
46
- callbacks: {
47
- onUpdate: (data) => {
48
- const { screenCoords, reliabilities, stabilities } = data;
49
- if (screenCoords && reliabilities && stabilities) {
50
- const points = screenCoords.map((p, i) => ({
51
- x: p.x,
52
- y: p.y,
53
- reliability: reliabilities[i],
54
- stability: stabilities[i]
55
- }));
56
- setTrackedPoints(points);
57
- }
58
- },
59
- onFound: async ({ targetIndex }) => {
60
- console.log(`🎯 Target ${targetIndex} detected!`);
61
- if (!isMounted)
62
- return;
63
- setStatus("tracking");
64
- const overlay = overlayRef.current;
65
- if (overlay instanceof HTMLVideoElement) {
66
- try {
67
- await overlay.play();
68
- setIsPlaying(true);
69
- }
70
- catch (err) {
71
- console.warn("Auto-play blocked:", err);
72
- }
73
- }
74
- },
75
- onLost: ({ targetIndex }) => {
76
- console.log(`👋 Target ${targetIndex} lost`);
77
- if (!isMounted)
78
- return;
79
- setStatus("scanning");
80
- setTrackedPoints([]);
81
- const overlay = overlayRef.current;
82
- if (overlay instanceof HTMLVideoElement) {
83
- overlay.pause();
84
- setIsPlaying(false);
85
- }
86
- }
87
- }
88
- });
89
- arInstanceRef.current = instance;
90
- await instance.startCamera();
91
- if (isMounted)
92
- setStatus("scanning");
93
- }
94
- catch (err) {
95
- console.error("❌ [TapTapp AR] Error durante la inicialización:", err);
96
- if (isMounted) {
97
- setError(err.message || String(err));
98
- setStatus("error");
99
- }
100
- }
101
- };
102
- initAR();
103
- return () => {
104
- isMounted = false;
105
- arInstanceRef.current?.stop();
106
- arInstanceRef.current = null;
107
- };
108
- }, [config.targetTaarSrc, config.targetImageSrc, config.scale, config.cameraConfig]);
109
- return {
110
- containerRef,
111
- overlayRef,
112
- status,
113
- isPlaying,
114
- toggleVideo,
115
- trackedPoints,
116
- error
117
- };
118
- };
1
+ import{useEffect as e,useRef as r,useState as t,useCallback as n}from"react";export const useAR=a=>{const c=r(null),o=r(null),[i,s]=t("scanning"),[l,u]=t(!1),[g,d]=t([]),[f,p]=t(null),y=r(null),m=n(async()=>{const e=o.current;if(e instanceof HTMLVideoElement)try{e.paused?(await e.play(),u(!0)):(e.pause(),u(!1))}catch(e){console.error("Error toggling video:",e)}},[]);return e(()=>{if("undefined"==typeof window||!c.current||!o.current)return;let e=!0;return(async()=>{try{const{createTracker:r}=await import("../runtime/track.js");if(!e)return;s("compiling");const t=await r({container:c.current,targetSrc:a.targetTaarSrc||a.targetImageSrc,overlay:o.current,scale:a.scale,cameraConfig:a.cameraConfig,debugMode:!1,callbacks:{onUpdate:e=>{const{screenCoords:r,reliabilities:t,stabilities:n}=e;if(r&&t&&n){const e=r.map((e,r)=>({x:e.x,y:e.y,reliability:t[r],stability:n[r]}));d(e)}},onFound:async({targetIndex:r})=>{if(console.log(`🎯 Target ${r} detected!`),!e)return;s("tracking");const t=o.current;if(t instanceof HTMLVideoElement)try{await t.play(),u(!0)}catch(e){console.warn("Auto-play blocked:",e)}},onLost:({targetIndex:r})=>{if(console.log(`👋 Target ${r} lost`),!e)return;s("scanning"),d([]);const t=o.current;t instanceof HTMLVideoElement&&(t.pause(),u(!1))}}});y.current=t,await t.startCamera(),e&&s("scanning")}catch(r){console.error("❌ [TapTapp AR] Error durante la inicialización:",r),e&&(p(r.message||String(r)),s("error"))}})(),()=>{e=!1,y.current?.stop(),y.current=null}},[a.targetTaarSrc,a.targetImageSrc,a.scale,a.cameraConfig]),{containerRef:c,overlayRef:o,status:i,isPlaying:l,toggleVideo:m,trackedPoints:g,error:f}};
@@ -1,272 +1 @@
1
- import { Controller, UI } from "./index.js";
2
- AFRAME.registerSystem("taar-image-system", {
3
- container: null,
4
- video: null,
5
- processingImage: false,
6
- init: function () {
7
- this.anchorEntities = [];
8
- },
9
- tick: function () { },
10
- setup: function ({ imageTargetSrc, maxTrack, showStats, uiLoading, uiScanning, uiError, missTolerance, warmupTolerance, filterMinCF, filterBeta, }) {
11
- this.imageTargetSrc = imageTargetSrc;
12
- this.maxTrack = maxTrack;
13
- this.filterMinCF = filterMinCF;
14
- this.filterBeta = filterBeta;
15
- this.missTolerance = missTolerance;
16
- this.warmupTolerance = warmupTolerance;
17
- this.showStats = showStats;
18
- this.ui = new UI({ uiLoading, uiScanning, uiError });
19
- },
20
- registerAnchor: function (el, targetIndex) {
21
- this.anchorEntities.push({ el: el, targetIndex: targetIndex });
22
- },
23
- start: function () {
24
- this.container = this.el.sceneEl.parentNode;
25
- if (this.showStats) {
26
- this.mainStats = new Stats();
27
- this.mainStats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
28
- this.mainStats.domElement.style.cssText = "position:absolute;top:0px;left:0px;z-index:999";
29
- this.container.appendChild(this.mainStats.domElement);
30
- }
31
- this.ui.showLoading();
32
- this._startVideo();
33
- },
34
- switchTarget: function (targetIndex) {
35
- this.controller.interestedTargetIndex = targetIndex;
36
- },
37
- stop: function () {
38
- this.pause();
39
- const tracks = this.video.srcObject.getTracks();
40
- tracks.forEach(function (track) {
41
- track.stop();
42
- });
43
- this.video.remove();
44
- this.controller.dispose();
45
- },
46
- pause: function (keepVideo = false) {
47
- if (!keepVideo) {
48
- this.video.pause();
49
- }
50
- this.controller.stopProcessVideo();
51
- },
52
- unpause: function () {
53
- this.video.play();
54
- this.controller.processVideo(this.video);
55
- },
56
- _startVideo: function () {
57
- this.video = document.createElement("video");
58
- this.video.setAttribute("autoplay", "");
59
- this.video.setAttribute("muted", "");
60
- this.video.setAttribute("playsinline", "");
61
- this.video.style.position = "absolute";
62
- this.video.style.top = "0px";
63
- this.video.style.left = "0px";
64
- this.video.style.zIndex = "-2";
65
- this.container.appendChild(this.video);
66
- if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
67
- // TODO: show unsupported error
68
- this.el.emit("arError", { error: "VIDEO_FAIL" });
69
- this.ui.showCompatibility();
70
- return;
71
- }
72
- navigator.mediaDevices
73
- .getUserMedia({
74
- audio: false,
75
- video: {
76
- facingMode: "environment",
77
- },
78
- })
79
- .then((stream) => {
80
- this.video.addEventListener("loadedmetadata", () => {
81
- //console.log("video ready...", this.video);
82
- this.video.setAttribute("width", this.video.videoWidth);
83
- this.video.setAttribute("height", this.video.videoHeight);
84
- this._startAR();
85
- });
86
- this.video.srcObject = stream;
87
- })
88
- .catch((err) => {
89
- console.log("getUserMedia error", err);
90
- this.el.emit("arError", { error: "VIDEO_FAIL" });
91
- });
92
- },
93
- _startAR: async function () {
94
- const video = this.video;
95
- this.controller = new Controller({
96
- inputWidth: video.videoWidth,
97
- inputHeight: video.videoHeight,
98
- maxTrack: this.maxTrack,
99
- filterMinCF: this.filterMinCF,
100
- filterBeta: this.filterBeta,
101
- missTolerance: this.missTolerance,
102
- warmupTolerance: this.warmupTolerance,
103
- onUpdate: (data) => {
104
- if (data.type === "processDone") {
105
- if (this.mainStats)
106
- this.mainStats.update();
107
- }
108
- else if (data.type === "updateMatrix") {
109
- const { targetIndex, worldMatrix } = data;
110
- for (let i = 0; i < this.anchorEntities.length; i++) {
111
- if (this.anchorEntities[i].targetIndex === targetIndex) {
112
- this.anchorEntities[i].el.updateWorldMatrix(worldMatrix);
113
- }
114
- }
115
- let isAnyVisible = this.anchorEntities.reduce((acc, entity) => {
116
- return acc || entity.el.el.object3D.visible;
117
- }, false);
118
- if (isAnyVisible) {
119
- this.ui.hideScanning();
120
- }
121
- else {
122
- this.ui.showScanning();
123
- }
124
- }
125
- },
126
- });
127
- this._resize();
128
- window.addEventListener("resize", this._resize.bind(this));
129
- const { dimensions: imageTargetDimensions } = await this.controller.addImageTargets(this.imageTargetSrc);
130
- for (let i = 0; i < this.anchorEntities.length; i++) {
131
- const { el, targetIndex } = this.anchorEntities[i];
132
- if (targetIndex < imageTargetDimensions.length) {
133
- el.setupMarker(imageTargetDimensions[targetIndex]);
134
- }
135
- }
136
- await this.controller.dummyRun(this.video);
137
- this.el.emit("arReady");
138
- this.ui.hideLoading();
139
- this.ui.showScanning();
140
- this.controller.processVideo(this.video);
141
- },
142
- _resize: function () {
143
- const video = this.video;
144
- const container = this.container;
145
- let vw, vh; // display css width, height
146
- const videoRatio = video.videoWidth / video.videoHeight;
147
- const containerRatio = container.clientWidth / container.clientHeight;
148
- if (videoRatio > containerRatio) {
149
- vh = container.clientHeight;
150
- vw = vh * videoRatio;
151
- }
152
- else {
153
- vw = container.clientWidth;
154
- vh = vw / videoRatio;
155
- }
156
- const proj = this.controller.getProjectionMatrix();
157
- const fov = (2 * Math.atan((1 / proj[5] / vh) * container.clientHeight) * 180) / Math.PI; // vertical fov
158
- const near = proj[14] / (proj[10] - 1.0);
159
- const far = proj[14] / (proj[10] + 1.0);
160
- //console.log("loaded proj: ", proj, ". fov: ", fov, ". near: ", near, ". far: ", far, ". ratio: ", ratio);
161
- const newAspect = container.clientWidth / container.clientHeight;
162
- const cameraEle = container.getElementsByTagName("a-camera")[0];
163
- const camera = cameraEle.getObject3D("camera");
164
- camera.fov = fov;
165
- camera.aspect = newAspect;
166
- camera.near = near;
167
- camera.far = far;
168
- camera.updateProjectionMatrix();
169
- //const newCam = new AFRAME.THREE.PerspectiveCamera(fov, newRatio, near, far);
170
- //camera.getObject3D('camera').projectionMatrix = newCam.projectionMatrix;
171
- this.video.style.top = -(vh - container.clientHeight) / 2 + "px";
172
- this.video.style.left = -(vw - container.clientWidth) / 2 + "px";
173
- this.video.style.width = vw + "px";
174
- this.video.style.height = vh + "px";
175
- },
176
- });
177
- AFRAME.registerComponent("taar-image", {
178
- dependencies: ["taar-image-system"],
179
- schema: {
180
- imageTargetSrc: { type: "string" },
181
- maxTrack: { type: "int", default: 1 },
182
- filterMinCF: { type: "number", default: -1 },
183
- filterBeta: { type: "number", default: -1 },
184
- missTolerance: { type: "int", default: -1 },
185
- warmupTolerance: { type: "int", default: -1 },
186
- showStats: { type: "boolean", default: false },
187
- autoStart: { type: "boolean", default: true },
188
- uiLoading: { type: "string", default: "yes" },
189
- uiScanning: { type: "string", default: "yes" },
190
- uiError: { type: "string", default: "yes" },
191
- },
192
- init: function () {
193
- const arSystem = this.el.sceneEl.systems["taar-image-system"];
194
- arSystem.setup({
195
- imageTargetSrc: this.data.imageTargetSrc,
196
- maxTrack: this.data.maxTrack,
197
- filterMinCF: this.data.filterMinCF === -1 ? null : this.data.filterMinCF,
198
- filterBeta: this.data.filterBeta === -1 ? null : this.data.filterBeta,
199
- missTolerance: this.data.missTolerance === -1 ? null : this.data.missTolerance,
200
- warmupTolerance: this.data.warmupTolerance === -1 ? null : this.data.warmupTolerance,
201
- showStats: this.data.showStats,
202
- uiLoading: this.data.uiLoading,
203
- uiScanning: this.data.uiScanning,
204
- uiError: this.data.uiError,
205
- });
206
- if (this.data.autoStart) {
207
- this.el.sceneEl.addEventListener("renderstart", () => {
208
- arSystem.start();
209
- });
210
- }
211
- },
212
- remove: function () {
213
- const arSystem = this.el.sceneEl.systems["mindar-image-system"];
214
- arSystem.stop();
215
- },
216
- });
217
- AFRAME.registerComponent("taar-image-target", {
218
- dependencies: ["taar-image-system"],
219
- schema: {
220
- targetIndex: { type: "number" },
221
- },
222
- postMatrix: null, // rescale the anchor to make width of 1 unit = physical width of card
223
- init: function () {
224
- const arSystem = this.el.sceneEl.systems["taar-image-system"];
225
- arSystem.registerAnchor(this, this.data.targetIndex);
226
- this.invisibleMatrix = new AFRAME.THREE.Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
227
- const root = this.el.object3D;
228
- root.visible = false;
229
- root.matrixAutoUpdate = false;
230
- root.matrix = this.invisibleMatrix;
231
- },
232
- setupMarker([markerWidth, markerHeight]) {
233
- const position = new AFRAME.THREE.Vector3();
234
- const quaternion = new AFRAME.THREE.Quaternion();
235
- const scale = new AFRAME.THREE.Vector3();
236
- position.x = markerWidth / 2;
237
- position.y = markerWidth / 2 + (markerHeight - markerWidth) / 2;
238
- scale.x = markerWidth;
239
- scale.y = markerWidth;
240
- scale.z = markerWidth;
241
- this.postMatrix = new AFRAME.THREE.Matrix4();
242
- this.postMatrix.compose(position, quaternion, scale);
243
- },
244
- updateWorldMatrix(worldMatrix) {
245
- this.el.emit("targetUpdate");
246
- if (!this.el.object3D.visible && worldMatrix !== null) {
247
- this.el.emit("targetFound");
248
- }
249
- else if (this.el.object3D.visible && worldMatrix === null) {
250
- this.el.emit("targetLost");
251
- }
252
- this.el.object3D.visible = worldMatrix !== null;
253
- if (worldMatrix === null) {
254
- this.el.object3D.matrix = this.invisibleMatrix;
255
- return;
256
- }
257
- var m = new AFRAME.THREE.Matrix4();
258
- m.elements = worldMatrix;
259
- m.multiply(this.postMatrix);
260
- this.el.object3D.matrix = m;
261
- },
262
- });
263
- /*
264
- This is a hack.
265
- If the user's browser has cached A-Frame,
266
- then A-Frame will process the webpage *before* the system and components get registered.
267
- Resulting in a blank page. This happens because module loading is deferred.
268
- */
269
- /* if(needsDOMRefresh){
270
- console.log("taar-face-aframe::Refreshing DOM...")
271
- document.body.innerHTML=document.body.innerHTML;
272
- } */
1
+ import{Controller as t,UI as e}from"./index.js";AFRAME.registerSystem("taar-image-system",{container:null,video:null,processingImage:!1,init:function(){this.anchorEntities=[]},tick:function(){},setup:function({imageTargetSrc:t,maxTrack:i,showStats:s,uiLoading:a,uiScanning:n,uiError:r,missTolerance:o,warmupTolerance:h,filterMinCF:l,filterBeta:d}){this.imageTargetSrc=t,this.maxTrack=i,this.filterMinCF=l,this.filterBeta=d,this.missTolerance=o,this.warmupTolerance=h,this.showStats=s,this.ui=new e({uiLoading:a,uiScanning:n,uiError:r})},registerAnchor:function(t,e){this.anchorEntities.push({el:t,targetIndex:e})},start:function(){this.container=this.el.sceneEl.parentNode,this.showStats&&(this.mainStats=new Stats,this.mainStats.showPanel(0),this.mainStats.domElement.style.cssText="position:absolute;top:0px;left:0px;z-index:999",this.container.appendChild(this.mainStats.domElement)),this.ui.showLoading(),this._startVideo()},switchTarget:function(t){this.controller.interestedTargetIndex=t},stop:function(){this.pause(),this.video.srcObject.getTracks().forEach(function(t){t.stop()}),this.video.remove(),this.controller.dispose()},pause:function(t=!1){t||this.video.pause(),this.controller.stopProcessVideo()},unpause:function(){this.video.play(),this.controller.processVideo(this.video)},_startVideo:function(){if(this.video=document.createElement("video"),this.video.setAttribute("autoplay",""),this.video.setAttribute("muted",""),this.video.setAttribute("playsinline",""),this.video.style.position="absolute",this.video.style.top="0px",this.video.style.left="0px",this.video.style.zIndex="-2",this.container.appendChild(this.video),!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)return this.el.emit("arError",{error:"VIDEO_FAIL"}),void this.ui.showCompatibility();navigator.mediaDevices.getUserMedia({audio:!1,video:{facingMode:"environment"}}).then(t=>{this.video.addEventListener("loadedmetadata",()=>{this.video.setAttribute("width",this.video.videoWidth),this.video.setAttribute("height",this.video.videoHeight),this._startAR()}),this.video.srcObject=t}).catch(t=>{console.log("getUserMedia error",t),this.el.emit("arError",{error:"VIDEO_FAIL"})})},_startAR:async function(){const e=this.video;this.controller=new t({inputWidth:e.videoWidth,inputHeight:e.videoHeight,maxTrack:this.maxTrack,filterMinCF:this.filterMinCF,filterBeta:this.filterBeta,missTolerance:this.missTolerance,warmupTolerance:this.warmupTolerance,onUpdate:t=>{if("processDone"===t.type)this.mainStats&&this.mainStats.update();else if("updateMatrix"===t.type){const{targetIndex:e,worldMatrix:i}=t;for(let t=0;t<this.anchorEntities.length;t++)this.anchorEntities[t].targetIndex===e&&this.anchorEntities[t].el.updateWorldMatrix(i);this.anchorEntities.reduce((t,e)=>t||e.el.el.object3D.visible,!1)?this.ui.hideScanning():this.ui.showScanning()}}}),this._resize(),window.addEventListener("resize",this._resize.bind(this));const{dimensions:i}=await this.controller.addImageTargets(this.imageTargetSrc);for(let t=0;t<this.anchorEntities.length;t++){const{el:e,targetIndex:s}=this.anchorEntities[t];s<i.length&&e.setupMarker(i[s])}await this.controller.dummyRun(this.video),this.el.emit("arReady"),this.ui.hideLoading(),this.ui.showScanning(),this.controller.processVideo(this.video)},_resize:function(){const t=this.video,e=this.container;let i,s;const a=t.videoWidth/t.videoHeight;a>e.clientWidth/e.clientHeight?(s=e.clientHeight,i=s*a):(i=e.clientWidth,s=i/a);const n=this.controller.getProjectionMatrix(),r=2*Math.atan(1/n[5]/s*e.clientHeight)*180/Math.PI,o=n[14]/(n[10]-1),h=n[14]/(n[10]+1),l=e.clientWidth/e.clientHeight,d=e.getElementsByTagName("a-camera")[0].getObject3D("camera");d.fov=r,d.aspect=l,d.near=o,d.far=h,d.updateProjectionMatrix(),this.video.style.top=-(s-e.clientHeight)/2+"px",this.video.style.left=-(i-e.clientWidth)/2+"px",this.video.style.width=i+"px",this.video.style.height=s+"px"}}),AFRAME.registerComponent("taar-image",{dependencies:["taar-image-system"],schema:{imageTargetSrc:{type:"string"},maxTrack:{type:"int",default:1},filterMinCF:{type:"number",default:-1},filterBeta:{type:"number",default:-1},missTolerance:{type:"int",default:-1},warmupTolerance:{type:"int",default:-1},showStats:{type:"boolean",default:!1},autoStart:{type:"boolean",default:!0},uiLoading:{type:"string",default:"yes"},uiScanning:{type:"string",default:"yes"},uiError:{type:"string",default:"yes"}},init:function(){const t=this.el.sceneEl.systems["taar-image-system"];t.setup({imageTargetSrc:this.data.imageTargetSrc,maxTrack:this.data.maxTrack,filterMinCF:-1===this.data.filterMinCF?null:this.data.filterMinCF,filterBeta:-1===this.data.filterBeta?null:this.data.filterBeta,missTolerance:-1===this.data.missTolerance?null:this.data.missTolerance,warmupTolerance:-1===this.data.warmupTolerance?null:this.data.warmupTolerance,showStats:this.data.showStats,uiLoading:this.data.uiLoading,uiScanning:this.data.uiScanning,uiError:this.data.uiError}),this.data.autoStart&&this.el.sceneEl.addEventListener("renderstart",()=>{t.start()})},remove:function(){this.el.sceneEl.systems["mindar-image-system"].stop()}}),AFRAME.registerComponent("taar-image-target",{dependencies:["taar-image-system"],schema:{targetIndex:{type:"number"}},postMatrix:null,init:function(){this.el.sceneEl.systems["taar-image-system"].registerAnchor(this,this.data.targetIndex),this.invisibleMatrix=(new AFRAME.THREE.Matrix4).set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const t=this.el.object3D;t.visible=!1,t.matrixAutoUpdate=!1,t.matrix=this.invisibleMatrix},setupMarker([t,e]){const i=new AFRAME.THREE.Vector3,s=new AFRAME.THREE.Quaternion,a=new AFRAME.THREE.Vector3;i.x=t/2,i.y=t/2+(e-t)/2,a.x=t,a.y=t,a.z=t,this.postMatrix=new AFRAME.THREE.Matrix4,this.postMatrix.compose(i,s,a)},updateWorldMatrix(t){if(this.el.emit("targetUpdate"),this.el.object3D.visible||null===t?this.el.object3D.visible&&null===t&&this.el.emit("targetLost"):this.el.emit("targetFound"),this.el.object3D.visible=null!==t,null!==t){var e=new AFRAME.THREE.Matrix4;e.elements=t,e.multiply(this.postMatrix),this.el.object3D.matrix=e}else this.el.object3D.matrix=this.invisibleMatrix}});