Skip to content

Commit 956703f

Browse files
committed
JsartoolkitNFT example
1 parent ae43c36 commit 956703f

7 files changed

+377
-0
lines changed

dist/ARToolkitNFT.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>ARToolkitNFT_ES6 example</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=0.5, maximum-scale=1">
7+
<link rel="stylesheet" href="css/nft-style.css">
8+
</head>
9+
<body>
10+
<div id="loading" >
11+
<img src="Data/JsartoolkitNFT-logo.gif"/>
12+
<span class="loading-text">Loading, please wait</span>
13+
</div>
14+
<!--
15+
==================
16+
STATS
17+
==================
18+
-->
19+
<div id="stats" class="ui stats">
20+
<div id="stats1" class="stats-item">
21+
<p class="stats-item-title">
22+
Main
23+
</p>
24+
</div>
25+
26+
<div id="stats2" class="stats-item">
27+
<p class="stats-item-title">
28+
Worker
29+
</p>
30+
</div>
31+
</div>
32+
33+
<div id="app">
34+
<video
35+
loop
36+
autoplay
37+
muted
38+
playsinline
39+
id="video">
40+
</video>
41+
<canvas id="canvas"></canvas>
42+
</div>
43+
<script src="../dist/ARToolkitNFT.js"></script>
44+
<script src="Data/js/third_party/three.js/stats.min.js"></script>
45+
<script src="Data/js/third_party/three.js/three.min.js"></script>
46+
<script src="index.js"></script>
47+
<script src="threejs_worker_ES6.js"></script>
48+
49+
<script>
50+
/**
51+
* STATS
52+
*/
53+
var statsMain = new Stats();
54+
statsMain.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom
55+
document.getElementById( 'stats1' ).appendChild( statsMain.dom );
56+
57+
var statsWorker = new Stats();
58+
statsWorker.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom
59+
document.getElementById( 'stats2' ).appendChild( statsWorker.dom );
60+
61+
window.addEventListener('load', () => {
62+
console.log('init ARToolkitNFT...');
63+
initCamera()
64+
.then(video => {
65+
66+
// start camera playback
67+
sourceVideo = video;
68+
sourceVideo.width = 640;
69+
sourceVideo.height = 480;
70+
sourceVideo.play();
71+
72+
// init target canvas
73+
initTargetCanvas();
74+
75+
return new Promise(resolve => {
76+
sourceVideo.addEventListener("loadeddata", event => {
77+
console.log("Camera is ready");
78+
resolve();
79+
});
80+
});
81+
})
82+
.then(_ => {
83+
84+
start('../examples/DataNFT/pinball', video, video.videoWidth, video.videoHeight, function() { statsMain.update() }, function() { statsWorker.update() })
85+
86+
});
87+
})
88+
</script>
89+
90+
</body>
91+
92+
</html>

examples/Data/JsartoolkitNFT-logo.gif

29.8 KB
Loading

examples/index.html

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
<a href="/examples/simple_2d_tracking.html"><h2>ArtoolkitX.js example with 2d tracking</h2></a>
1010
<p>A simple example that display a cube and a grid. You need the <a href="/examples/Data/Alterra_Postcard_2.jpg">Alterra image</a>
1111
</div>
12+
<div class='box'>
13+
<a href="/examples/ARToolkitNFT_ES6_example.html"><h2>JsartoolkitNFT example with NFT tracking</h2></a>
14+
<p>A simple example that display a simple sphere. You need the <a href="/examples/Data/pinball.jpg">Pinball image</a>
15+
</div>
1216
<div class='box'>
1317
<a href="/examples/arNFT_example.html"><h2>ARnft example with NFT tracking</h2></a>
1418
<p>A simple example that display a red cube. You need the <a href="/examples/Data/pinball.jpg">Pinball image</a>

examples/index.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
let sourceVideo;
2+
let targetCanvas;
3+
4+
async function initCamera() {
5+
6+
const constraints = {
7+
audio: false,
8+
video: {
9+
// using the "environment" rear camera
10+
facingMode: "environment",
11+
// using the "user" front camera
12+
// facingMode: "user",
13+
width: 640,
14+
height: 480
15+
}
16+
};
17+
18+
// initialize video source
19+
const video = document.querySelector("#video");
20+
const stream = await navigator.mediaDevices.getUserMedia(constraints);
21+
video.srcObject = stream;
22+
23+
return new Promise(resolve => {
24+
video.onloadedmetadata = () => {
25+
resolve(video);
26+
};
27+
});
28+
};
29+
30+
function initTargetCanvas() {
31+
// target canvas should overlap source video
32+
targetCanvas = document.querySelector("#canvas");
33+
targetCanvas.width = sourceVideo.width;
34+
targetCanvas.height = sourceVideo.height;
35+
}

examples/threejs_worker_ES6.js

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
function isMobile () {
2+
return /Android|mobile|iPad|iPhone/i.test(navigator.userAgent);
3+
}
4+
5+
var setMatrix = function (matrix, value) {
6+
var array = [];
7+
for (var key in value) {
8+
array[key] = value[key];
9+
}
10+
if (typeof matrix.elements.set === "function") {
11+
matrix.elements.set(array);
12+
} else {
13+
matrix.elements = [].slice.call(array);
14+
}
15+
};
16+
17+
function start(markerUrl, video, input_width, input_height, render_update, track_update) {
18+
var vw, vh;
19+
var sw, sh;
20+
var pscale, sscale;
21+
var w, h;
22+
var pw, ph;
23+
var ox, oy;
24+
var worker;
25+
var camera_para = './../examples/Data/camera_para.dat'
26+
27+
var canvas_process = document.createElement('canvas');
28+
var context_process = canvas_process.getContext('2d');
29+
var targetCanvas = document.querySelector("#canvas");
30+
31+
var renderer = new THREE.WebGLRenderer({ canvas: targetCanvas, alpha: true, antialias: true });
32+
renderer.setPixelRatio(window.devicePixelRatio);
33+
34+
var scene = new THREE.Scene();
35+
36+
var camera = new THREE.Camera();
37+
camera.matrixAutoUpdate = false;
38+
39+
scene.add(camera);
40+
41+
var sphere = new THREE.Mesh(
42+
new THREE.SphereGeometry(0.5, 8, 8),
43+
new THREE.MeshNormalMaterial()
44+
);
45+
46+
var root = new THREE.Object3D();
47+
scene.add(root);
48+
49+
sphere.material.flatShading;
50+
sphere.position.z = 0;
51+
sphere.position.x = 100;
52+
sphere.position.y = 100;
53+
sphere.scale.set(200, 200, 200);
54+
55+
root.matrixAutoUpdate = false;
56+
root.add(sphere);
57+
58+
var load = function () {
59+
vw = input_width;
60+
vh = input_height;
61+
62+
pscale = 320 / Math.max(vw, vh / 3 * 4);
63+
sscale = isMobile() ? window.outerWidth / input_width : 1;
64+
65+
sw = vw * sscale;
66+
sh = vh * sscale;
67+
68+
w = vw * pscale;
69+
h = vh * pscale;
70+
pw = Math.max(w, h / 3 * 4);
71+
ph = Math.max(h, w / 4 * 3);
72+
ox = (pw - w) / 2;
73+
oy = (ph - h) / 2;
74+
canvas_process.style.clientWidth = pw + "px";
75+
canvas_process.style.clientHeight = ph + "px";
76+
canvas_process.width = pw;
77+
canvas_process.height = ph;
78+
79+
renderer.setSize(sw, sh);
80+
81+
worker = new Worker('../js/artoolkitNFT_ES6.worker.js')
82+
83+
worker.postMessage({ type: "load", pw: pw, ph: ph, camera_para: camera_para, marker: markerUrl });
84+
85+
worker.onmessage = function (ev) {
86+
var msg = ev.data;
87+
switch (msg.type) {
88+
case "loaded": {
89+
var proj = JSON.parse(msg.proj);
90+
var ratioW = pw / w;
91+
var ratioH = ph / h;
92+
proj[0] *= ratioW;
93+
proj[4] *= ratioW;
94+
proj[8] *= ratioW;
95+
proj[12] *= ratioW;
96+
proj[1] *= ratioH;
97+
proj[5] *= ratioH;
98+
proj[9] *= ratioH;
99+
proj[13] *= ratioH;
100+
setMatrix(camera.projectionMatrix, proj);
101+
break;
102+
}
103+
case "endLoading": {
104+
if (msg.end == true) {
105+
// removing loader page if present
106+
var loader = document.getElementById('loading');
107+
if (loader) {
108+
loader.querySelector('.loading-text').innerText = 'Start the tracking!';
109+
setTimeout(function(){
110+
loader.parentElement.removeChild(loader);
111+
}, 2000);
112+
}
113+
}
114+
break;
115+
}
116+
case 'found': {
117+
found(msg);
118+
break;
119+
}
120+
case 'not found': {
121+
found(null);
122+
break;
123+
}
124+
}
125+
track_update();
126+
process();
127+
};
128+
};
129+
130+
var world;
131+
132+
var found = function (msg) {
133+
if (!msg) {
134+
world = null;
135+
} else {
136+
world = JSON.parse(msg.matrixGL_RH);
137+
}
138+
};
139+
140+
var lasttime = Date.now();
141+
var time = 0;
142+
143+
var draw = function () {
144+
render_update();
145+
var now = Date.now();
146+
var dt = now - lasttime;
147+
time += dt;
148+
lasttime = now;
149+
150+
if (!world) {
151+
sphere.visible = false;
152+
} else {
153+
sphere.visible = true;
154+
// set matrix of 'root' by detected 'world' matrix
155+
setMatrix(root.matrix, world);
156+
}
157+
renderer.render(scene, camera);
158+
};
159+
160+
var process = function () {
161+
context_process.fillStyle = 'black';
162+
context_process.fillRect(0, 0, pw, ph);
163+
context_process.drawImage(video, 0, 0, vw, vh, ox, oy, w, h);
164+
165+
var imageData = context_process.getImageData(0, 0, pw, ph);
166+
worker.postMessage({ type: 'process', imagedata: imageData }, [imageData.data.buffer]);
167+
}
168+
var tick = function () {
169+
draw();
170+
requestAnimationFrame(tick);
171+
};
172+
173+
load();
174+
tick();
175+
process();
176+
}

js/artoolkitNFT_ES6.worker.js

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
importScripts('../dist/ARToolkitNFT.js')
2+
3+
self.onmessage = function (e) {
4+
var msg = e.data
5+
switch (msg.type) {
6+
case 'load': {
7+
load(msg)
8+
return
9+
}
10+
case 'process': {
11+
next = msg.imagedata
12+
process()
13+
}
14+
}
15+
}
16+
17+
var next = null
18+
var ar = null
19+
var markerResult = null
20+
21+
function load (msg) {
22+
console.debug('Loading marker at: ', msg.marker)
23+
24+
var onLoad = function (arController) {
25+
ar = arController
26+
var cameraMatrix = ar.getCameraMatrix()
27+
28+
ar.addEventListener('getNFTMarker', function (ev) {
29+
markerResult = { type: 'found', matrixGL_RH: JSON.stringify(ev.data.matrixGL_RH)}
30+
})
31+
32+
ar.loadNFTMarker(msg.marker).then(function (nft) {
33+
ar.trackNFTMarkerId(nft.id)
34+
console.log('loadNFTMarker -> ', nft.id)
35+
console.log('nftMarker struct: ', nft)
36+
postMessage({ type: 'endLoading', end: true })
37+
}).catch(function (err) {
38+
console.log('Error in loading marker on Worker', err)
39+
})
40+
41+
postMessage({ type: 'loaded', proj: JSON.stringify(cameraMatrix) })
42+
}
43+
44+
var onError = function (error) {
45+
console.error(error)
46+
}
47+
48+
console.debug('Loading camera at:', msg.camera_para)
49+
50+
// we cannot pass the entire ARControllerNFT, so we re-create one inside the Worker, starting from camera_param
51+
ARToolkitNFT.ARControllerNFT.initWithDimensions(msg.pw, msg.ph, msg.camera_para).then(onLoad).catch(onError)
52+
}
53+
54+
function process () {
55+
markerResult = null
56+
57+
if (ar && ar.process) {
58+
ar.process(next)
59+
}
60+
61+
if (markerResult) {
62+
postMessage(markerResult)
63+
} else {
64+
postMessage({ type: 'not found' })
65+
}
66+
67+
next = null
68+
}

0 commit comments

Comments
 (0)