Newer
Older
AegisforEcosystem / next / AR.js-3.4.0 / three.js / examples / profile.html
@KAOKA Daisuke KAOKA Daisuke on 31 May 2022 7 KB into AR.js
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<!-- three.js library -->
<script src='vendor/three.js/build/three.js'></script>
<script src="vendor/three.js/examples/js/libs/stats.min.js"></script>
<!-- include threex.artoolkit -->
<script src="../build/ar-threex.js"></script>
<script>THREEx.ArToolkitContext.baseURL = '../'</script>

<body style='margin : 0px; overflow: hidden; font-family: Monospace;'>
	<div style='position: absolute; top: 10px; width:100%; text-align: center;z-index:1' ;>
		<a href="https://github.com/AR-js-org/AR.js/" target="_blank">AR.js</a> - developement playground
		<br />
		Contact me any time at <a href='https://twitter.com/nicolocarp' target='_blank'>@nicolocarp</a>
	</div>
	<div
		style='position: absolute;bottom: 0;right: 0;background-color: rgba(255,255,255,0.4); padding: 1em; z-index: 1;'>
		<label title='Select the profile you like'>Profile :
			<select id='artoolkitProfile'>
				<option value="desktop-fast">desktop-fast</option>
				<option value="desktop-normal">desktop-normal</option>
				<option value="phone-normal">phone-normal</option>
				<option value="phone-slow">phone-slow</option>
				<option value="dynamic" selected>dynamic</option>
			</select>
		</label>
	</div>
	<script>
		//////////////////////////////////////////////////////////////////////////////////
		//		Init
		//////////////////////////////////////////////////////////////////////////////////

		// init renderer
		var renderer = new THREE.WebGLRenderer({
			// antialias	: true,
			alpha: true
		});
		renderer.setClearColor(new THREE.Color('lightgrey'), 0)
		// renderer.setPixelRatio( 2 );
		renderer.setSize(window.innerWidth, window.innerHeight);
		renderer.domElement.style.position = 'absolute'
		renderer.domElement.style.top = '0px'
		renderer.domElement.style.left = '0px'
		document.body.appendChild(renderer.domElement);

		// array of functions for the rendering loop
		var onRenderFcts = [];

		var arToolkitContext, artoolkitMarker;

		// init scene and camera
		var scene = new THREE.Scene();

		var ambient = new THREE.AmbientLight(0x666666);
		scene.add(ambient);

		var directionalLight = new THREE.DirectionalLight(0x887766);
		directionalLight.position.set(-1, 1, 1).normalize();
		scene.add(directionalLight);

		//////////////////////////////////////////////////////////////////////////////////
		//		Initialize a basic camera
		//////////////////////////////////////////////////////////////////////////////////

		// Create a camera
		var camera = new THREE.Camera();
		scene.add(camera);
		var markerRoot = new THREE.Group
		scene.add(markerRoot)

		//////////////////////////////////////////////////////////////////////////////
		//		handle profile ui
		//////////////////////////////////////////////////////////////////////////////

		if (localStorage.getItem('artoolkitPerformanceProfile') !== null) {
			var domElement = document.querySelector('#artoolkitProfile')
			domElement.value = localStorage.getItem('artoolkitPerformanceProfile')
		}

		document.querySelector('#artoolkitProfile').addEventListener('change', function () {
			var domElement = document.querySelector('#artoolkitProfile')
			localStorage.setItem('artoolkitPerformanceProfile', domElement.value);
			location.reload();
		})

		////////////////////////////////////////////////////////////////////////////////
		//          handle ArToolkitProfile
		////////////////////////////////////////////////////////////////////////////////


		var artoolkitProfile = new THREEx.ArToolkitProfile()
		artoolkitProfile.sourceWebcam()
		// artoolkitProfile.sourceVideo(THREEx.ArToolkitContext.baseURL + '../data/videos/headtracking.mp4').kanjiMarker();
		// artoolkitProfile.sourceImage(THREEx.ArToolkitContext.baseURL + '../data/images/img.jpg').hiroMarker()
		// artoolkitProfile.performance('desktop-fast')

		if (localStorage.getItem('artoolkitPerformanceProfile') !== null) {
			var label = localStorage.getItem('artoolkitPerformanceProfile')
			console.log('Using stored profile', label)
			artoolkitProfile.performance(label)
		}


		//////////////////////////////////////////////////////////////////////////////
		//		handle arToolkitSource
		//////////////////////////////////////////////////////////////////////////////

		var arToolkitSource = new THREEx.ArToolkitSource(artoolkitProfile.sourceParameters)

		arToolkitSource.init(function onReady() {
			initARContext()
			onResize()
		})

		// handle resize
		window.addEventListener('resize', function () {
			onResize()
		})
		function onResize() {
			arToolkitSource.onResizeElement()
			arToolkitSource.copyElementSizeTo(renderer.domElement)
			if (window.arToolkitContext.arController !== null) {
				arToolkitSource.copyElementSizeTo(window.arToolkitContext.arController.canvas)
			}
		}
		////////////////////////////////////////////////////////////////////////////////
		//          initialize arToolkitContext
		////////////////////////////////////////////////////////////////////////////////

		function initARContext() {
			console.log('initARContext()');
			// create atToolkitContext
			arToolkitContext = new THREEx.ArToolkitContext(artoolkitProfile.contextParameters)
			// initialize it
			arToolkitContext.init(function onCompleted() {
				// copy projection matrix to camera
				camera.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
				arToolkitContext.arController.orientation = getSourceOrientation();
				arToolkitContext.arController.options.orientation = getSourceOrientation();

				console.log('arToolkitContext', arToolkitContext);
				window.arToolkitContext = arToolkitContext;
			})
			artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot, artoolkitProfile.defaultMarkerParameters)
		}

		function getSourceOrientation() {
			if (!arToolkitSource) {
				return null;
			}

			console.log(
				'actual source dimensions',
				arToolkitSource.domElement.videoWidth,
				arToolkitSource.domElement.videoHeight
			);

			if (arToolkitSource.domElement.videoWidth > arToolkitSource.domElement.videoHeight) {
				console.log('source orientation', 'landscape');
				return 'landscape';
			} else {
				console.log('source orientation', 'portrait');
				return 'portrait';
			}
		}

		// update artoolkit on every frame
		onRenderFcts.push(function () {
			if (!arToolkitContext || !arToolkitSource || !arToolkitSource.ready) {
				return;
			}

			arToolkitContext.update(arToolkitSource.domElement)
		})


		//////////////////////////////////////////////////////////////////////////////////
		//		add an object in the scene
		//////////////////////////////////////////////////////////////////////////////////

		// add a torus knot
		var geometry = new THREE.BoxGeometry(1, 1, 1);
		var material = new THREE.MeshNormalMaterial({
			transparent: true,
			opacity: 0.5,
			side: THREE.DoubleSide
		});
		var mesh = new THREE.Mesh(geometry, material);
		mesh.position.y = geometry.parameters.height / 2
		markerRoot.add(mesh);

		var geometry = new THREE.TorusKnotGeometry(0.3, 0.1, 64, 16);
		var material = new THREE.MeshNormalMaterial();
		var mesh = new THREE.Mesh(geometry, material);
		mesh.position.y = 0.5
		markerRoot.add(mesh);

		onRenderFcts.push(function () {
			mesh.rotation.x += 0.1
		})

		//////////////////////////////////////////////////////////////////////////////////
		//		render the whole thing on the page
		//////////////////////////////////////////////////////////////////////////////////
		var stats = new Stats();
		document.body.appendChild(stats.dom);
		// render the scene
		onRenderFcts.push(function () {
			renderer.render(scene, camera);
			stats.update();
		})

		// run the rendering loop
		var lastTimeMsec = null
		requestAnimationFrame(function animate(nowMsec) {
			// keep looping
			requestAnimationFrame(animate);
			// measure time
			lastTimeMsec = lastTimeMsec || nowMsec - 1000 / 60
			var deltaMsec = Math.min(200, nowMsec - lastTimeMsec)
			lastTimeMsec = nowMsec
			// call each update function
			onRenderFcts.forEach(function (onRenderFct) {
				onRenderFct(deltaMsec / 1000, nowMsec / 1000)
			})
		})
	</script>
</body>