Skip to content

Commit

Permalink
gltf example with brave_robot model
Browse files Browse the repository at this point in the history
- see issue #393
  • Loading branch information
kalwalt committed Oct 24, 2024
1 parent 1ebbac6 commit bb6eb43
Show file tree
Hide file tree
Showing 2 changed files with 290 additions and 0 deletions.
100 changes: 100 additions & 0 deletions examples/ARToolkitNFT_ES6_gltf_example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ARToolkitNFT_ES6 example</title>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=0.5, maximum-scale=1">
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
}
}
</script>
<link rel="stylesheet" href="css/nft-style.css">
</head>
<body>
<div id="loading" >
<img alt="JsartoolkitNFT logo" src="Data/JsartoolkitNFT-logo.gif"/>
<span class="loading-text">Loading, please wait</span>
</div>
<!--
==================
STATS
==================
-->
<div id="stats" class="ui stats">
<div id="stats1" class="stats-item">
<p class="stats-item-title">
Main
</p>
</div>

<div id="stats2" class="stats-item">
<p class="stats-item-title">
Worker
</p>
</div>
</div>

<div id="app">
<video
loop
autoplay
muted
playsinline
id="video">
</video>
<canvas id="canvas"></canvas>
</div>
<script src="js/third_party/three.js/stats.min.js"></script>
<script src="index.js"></script>

<script type="module">
import start from './threejs_worker_brave_robot_gltf_ES6.js'
/**
* STATS
*/
const statsMain = new Stats();
statsMain.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom
document.getElementById( 'stats1' ).appendChild( statsMain.dom );

const statsWorker = new Stats();
statsWorker.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom
document.getElementById( 'stats2' ).appendChild( statsWorker.dom );

window.addEventListener('load', () => {
console.log('init ARToolkitNFT...');
initCamera()
.then(video => {

// start camera playback
sourceVideo = video;
sourceVideo.width = 640;
sourceVideo.height = 480;
sourceVideo.play();

// init target canvas
initTargetCanvas();

return new Promise(resolve => {
sourceVideo.addEventListener("loadeddata", event => {
const target = event.target;
console.log("Camera is ready");
console.log("Video stream with width, height: ", target.width, target.height)
resolve();
});
});
})
.then(_ => {

start('../examples/DataNFT/pinball', video, video.videoWidth, video.videoHeight, function() { statsMain.update() }, function() { statsWorker.update() })

});
})
</script>

</body>

</html>
190 changes: 190 additions & 0 deletions examples/threejs_worker_brave_robot_gltf_ES6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

function isMobile () {
return /Android|mobile|iPad|iPhone/i.test(navigator.userAgent);
}

const setMatrix = function (matrix, value) {
const array = [];
for (const key in value) {
array[key] = value[key];
}
if (typeof matrix.elements.set === "function") {
matrix.elements.set(array);
} else {
matrix.elements = [].slice.call(array);
}
};

export default function start(markerUrl, video, input_width, input_height, render_update, track_update) {
let vw, vh;
let sw, sh;
let pscale, sscale;
let w, h;
let pw, ph;
let ox, oy;
let worker;
const camera_para = './../examples/Data/camera_para.dat';

const modelURL = './../examples/Data/models/brave_robot/brave_robot.glb';
let model, marker;

const canvas_process = document.createElement('canvas');
const context_process = canvas_process.getContext('2d', {willReadFrequently: true});
const targetCanvas = document.querySelector("#canvas");

const renderer = new THREE.WebGLRenderer({canvas: targetCanvas, alpha: true, antialias: true, logarithmicDepthBuffer: true});
renderer.setPixelRatio(window.devicePixelRatio);

const threeGLTFLoader = new GLTFLoader();

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false;

scene.add(camera);

const light = new THREE.AmbientLight(0xffffff);
scene.add(light);

threeGLTFLoader.load(modelURL, (gltf) => {
model = gltf.scene;
let scale = 180;
model.scale.set(scale, scale, scale);
model.rotation.x = Math.PI / 2;
root.add(model);
});

const root = new THREE.Object3D();
scene.add(root);

root.matrixAutoUpdate = false;

const load = function () {
vw = input_width;
vh = input_height;

pscale = 320 / Math.max(vw, vh / 3 * 4);
sscale = isMobile() ? window.outerWidth / input_width : 1;

sw = vw * sscale;
sh = vh * sscale;

w = vw * pscale;
h = vh * pscale;
pw = Math.max(w, h / 3 * 4);
ph = Math.max(h, w / 4 * 3);
ox = (pw - w) / 2;
oy = (ph - h) / 2;
canvas_process.style.clientWidth = pw + "px";
canvas_process.style.clientHeight = ph + "px";
canvas_process.width = pw;
canvas_process.height = ph;

renderer.setSize(sw, sh);

worker = new Worker('../js/artoolkitNFT_ES6.worker.js')

worker.postMessage({type: "load", pw: pw, ph: ph, camera_para: camera_para, marker: markerUrl});

worker.onmessage = function (ev) {
const msg = ev.data;
switch (msg.type) {
case "loaded": {
const proj = JSON.parse(msg.proj);
const ratioW = pw / w;
const ratioH = ph / h;
proj[0] *= ratioW;
proj[4] *= ratioW;
proj[8] *= ratioW;
proj[12] *= ratioW;
proj[1] *= ratioH;
proj[5] *= ratioH;
proj[9] *= ratioH;
proj[13] *= ratioH;
setMatrix(camera.projectionMatrix, proj);
break;
}
case "endLoading": {
if (msg.end === true) {
// removing loader page if present
const loader = document.getElementById('loading');
if (loader) {
loader.querySelector('.loading-text').innerText = 'Start the tracking!';
setTimeout(function () {
loader.parentElement.removeChild(loader);
}, 2000);
}
}
break;
}
case 'found': {
found(msg);
model.visible = true;
break;
}
case 'not found': {
found(null);
model.visible = false;
break;
}
case 'markerInfos': {
marker = msg.marker;
model.position.y = ((marker.height / marker.dpi) * 2.54 * 10) / 2.0;
model.position.x = ((marker.width / marker.dpi) * 2.54 * 10) / 2.0;
}
}
track_update();
process();
};
};

let world;

const found = function (msg) {
if (!msg) {
world = null;
} else {
world = JSON.parse(msg.matrixGL_RH);
}
};

let lasttime = Date.now();
let time = 0;

const draw = function () {
render_update();
const now = Date.now();
const dt = now - lasttime;
time += dt;
lasttime = now;

if (!world) {
root.matrix = null;
} else {
// set matrix of 'root' by detected 'world' matrix
setMatrix(root.matrix, world);
}
renderer.render(scene, camera);
};

const process = function () {
context_process.fillStyle = 'black';
context_process.fillRect(0, 0, pw, ph);
context_process.drawImage(video, 0, 0, vw, vh, ox, oy, w, h);

const imageData = context_process.getImageData(0, 0, pw, ph);
worker.postMessage({ type: 'process', imagedata: imageData }, [imageData.data.buffer]);
}

const tick = function () {
draw();
requestAnimationFrame(tick);
};

load();
tick();
process();
}

0 comments on commit bb6eb43

Please sign in to comment.