@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.
- package/dist/compiler/node-worker.js +1 -197
- package/dist/compiler/offline-compiler.js +1 -207
- package/dist/core/constants.js +1 -38
- package/dist/core/detector/crop-detector.js +1 -88
- package/dist/core/detector/detector-lite.js +1 -455
- package/dist/core/detector/freak.js +1 -89
- package/dist/core/estimation/estimate.js +1 -16
- package/dist/core/estimation/estimator.js +1 -30
- package/dist/core/estimation/morph-refinement.js +1 -116
- package/dist/core/estimation/non-rigid-refine.js +1 -70
- package/dist/core/estimation/pnp-solver.js +1 -109
- package/dist/core/estimation/refine-estimate.js +1 -311
- package/dist/core/estimation/utils.js +1 -67
- package/dist/core/features/auto-rotation-feature.js +1 -30
- package/dist/core/features/crop-detection-feature.js +1 -26
- package/dist/core/features/feature-base.js +1 -1
- package/dist/core/features/feature-manager.js +1 -55
- package/dist/core/features/one-euro-filter-feature.js +1 -44
- package/dist/core/features/temporal-filter-feature.js +1 -57
- package/dist/core/image-list.js +1 -54
- package/dist/core/input-loader.js +1 -87
- package/dist/core/matching/hamming-distance.js +1 -66
- package/dist/core/matching/hdc.js +1 -102
- package/dist/core/matching/hierarchical-clustering.js +1 -130
- package/dist/core/matching/hough.js +1 -170
- package/dist/core/matching/matcher.js +1 -66
- package/dist/core/matching/matching.js +1 -401
- package/dist/core/matching/ransacHomography.js +1 -132
- package/dist/core/perception/bio-inspired-engine.js +1 -232
- package/dist/core/perception/foveal-attention.js +1 -280
- package/dist/core/perception/index.js +1 -17
- package/dist/core/perception/predictive-coding.js +1 -278
- package/dist/core/perception/saccadic-controller.js +1 -269
- package/dist/core/perception/saliency-map.js +1 -254
- package/dist/core/perception/scale-orchestrator.js +1 -68
- package/dist/core/protocol.js +1 -254
- package/dist/core/tracker/extract-utils.js +1 -29
- package/dist/core/tracker/extract.js +1 -306
- package/dist/core/tracker/tracker.js +1 -352
- package/dist/core/utils/cumsum.js +1 -37
- package/dist/core/utils/delaunay.js +1 -125
- package/dist/core/utils/geometry.js +1 -101
- package/dist/core/utils/gpu-compute.js +1 -231
- package/dist/core/utils/homography.js +1 -138
- package/dist/core/utils/images.js +1 -108
- package/dist/core/utils/lsh-binarizer.js +1 -37
- package/dist/core/utils/lsh-direct.js +1 -76
- package/dist/core/utils/projection.js +1 -51
- package/dist/core/utils/randomizer.js +1 -25
- package/dist/core/utils/worker-pool.js +1 -89
- package/dist/index.js +1 -7
- package/dist/libs/one-euro-filter.js +1 -70
- package/dist/react/TaptappAR.js +1 -151
- package/dist/react/types.js +1 -16
- package/dist/react/use-ar.js +1 -118
- package/dist/runtime/aframe.js +1 -272
- package/dist/runtime/bio-inspired-controller.js +1 -358
- package/dist/runtime/controller.js +1 -592
- package/dist/runtime/controller.worker.js +1 -93
- package/dist/runtime/index.js +1 -5
- package/dist/runtime/three.js +1 -304
- package/dist/runtime/track.js +1 -381
- package/package.json +9 -3
package/dist/react/types.js
CHANGED
|
@@ -1,16 +1 @@
|
|
|
1
|
-
export function mapDataToPropsConfig(
|
|
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}}
|
package/dist/react/use-ar.js
CHANGED
|
@@ -1,118 +1 @@
|
|
|
1
|
-
import {
|
|
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}};
|
package/dist/runtime/aframe.js
CHANGED
|
@@ -1,272 +1 @@
|
|
|
1
|
-
import
|
|
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}});
|