Newer
Older
AegisforEcosystem / next / AR.js-3.4.0 / three.js / examples / multi-markers / examples / threex-screenasportal / examples / screenAsPortal-original.html
@KAOKA Daisuke KAOKA Daisuke on 31 May 2022 9 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>
<!-- jsartookit -->
<script src='../../vendor/jsartoolkit5/build/artoolkit.min.js'></script>
<script src='../../vendor/jsartoolkit5/js/artoolkit.api.js'></script>
<!-- include threex.artoolkit -->
<script src='../../src/threex/threex-artoolkitsource.js'></script>
<script src='../../src/threex/threex-artoolkitcontext.js'></script>
<script src='../../src/threex/threex-artoolkitprofile.js'></script>
<script src='../../src/threex/threex-arbasecontrols.js'></script>
<script src='../../src/threex/threex-armarkercontrols.js'></script>
<script src='../../src/threex/threex-armarkerhelper.js'></script>
<script src='../../src/threex/threex-arsmoothedcontrols.js'></script>
<script>THREEx.ArToolkitContext.baseURL = '../../'</script>

<script src='../multi-markers/threex-armultimarkerutils.js'></script>
<script src='../multi-markers/threex-armultimarkercontrols.js'></script>
<script src='../multi-markers/threex-armultimarkerlearning.js'></script>

<script src='js/threex-screenasportal.js'></script>

<style>
	#recordButton:hover {
		cursor: pointer;
	}
</style>


<body style='margin : 0px; overflow: hidden; font-family: Monospace;'><div style='position: absolute; top: 10px; width:100%; text-align: center;z-index:1; color: grey;';>
	Screen as a gate to another world - by <a href='https://twitter.com/jerome_etienne' target='_blank'>@jerome_etienne</a>
	with <a href='https://github.com/jeromeetienne/AR.js/' target='_blank'>AR.js</a>
	<br>
	Directly inspired of the <a href='https://www.youtube.com/watch?v=Jd3-eiid-Uw'>cult demo</a> by <a href='https://www.youtube.com/user/jcl5m/videos'>johnny lee</a>
</div>
<div style='position: fixed; bottom: 10px; width:100%; text-align: center;z-index:1; color: grey;';>
	<a href='javascript:void(0)' onclick='toggleMarkerHelper()'>marker helper : <span id='markerHelpersStatus'></span></a>
</div>
<div style='position: fixed; bottom: 16px; right: 16px; z-index:1';>
	<img id='recordButton' src="../multi-markers/examples/images/record-start.png" width='64px'  height='64px'>
</div>

<script>
;(function(){

	////////////////////////////////////////////////////////////////////////////////
	//          handle urlOptions
	////////////////////////////////////////////////////////////////////////////////

	// parse urlOptions from location.search
	if( location.search.substring(1) ){
		var urlOptions = JSON.parse(decodeURIComponent(location.search.substring(1)))
	}else{
		var urlOptions = {}
	}
	if( urlOptions.trackingBackend === undefined ) urlOptions.trackingBackend = 'artoolkit'

	//////////////////////////////////////////////////////////////////////////////////
	//		Init
	//////////////////////////////////////////////////////////////////////////////////

	// init renderer
	var renderer	= new THREE.WebGLRenderer({
		alpha: true
	});
	renderer.setClearColor(new THREE.Color('lightgrey'), 0)
	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= [];

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

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

	// Create a camera
	if( urlOptions.trackingBackend === 'artoolkit' ){
		var camera = new THREE.Camera();
	}else console.assert(false)
	scene.add(camera);

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

	var artoolkitProfile = new THREEx.ArToolkitProfile()
	artoolkitProfile.sourceWebcam()

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

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

	// handle resize
	window.addEventListener('resize', function(){
		onResize()
	})
	function onResize(){
		arToolkitSource.onResize()
		arToolkitSource.copySizeTo(renderer.domElement)
		if( urlOptions.trackingBackend === 'artoolkit' ){
			if( arToolkitContext.arController !== null ){
				arToolkitSource.copySizeTo(arToolkitContext.arController.canvas)
			}
		}else console.assert(false)
	}

	////////////////////////////////////////////////////////////////////////////////
	//          initialize arToolkitContext
	////////////////////////////////////////////////////////////////////////////////

	// honor urlOptions.trackingBackend
	artoolkitProfile.contextParameters.trackingBackend = urlOptions.trackingBackend

	// create atToolkitContext
	var arToolkitContext = new THREEx.ArToolkitContext(artoolkitProfile.contextParameters)
	// initialize it
	arToolkitContext.init(function onCompleted(){
		// if artoolkit, copy projection matrix to camera
		if( arToolkitContext.parameters.trackingBackend === 'artoolkit' ){
			camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );
		}
	})

	// update artoolkit on every frame
	onRenderFcts.push(function(){
		if( arToolkitSource.ready === false )	return

		arToolkitContext.update( arToolkitSource.domElement )
	})
	//////////////////////////////////////////////////////////////////////////////
	//		init learnerParameters and markersControlsParameters
	//////////////////////////////////////////////////////////////////////////////

	// build a multiMarkerControls
	var multiMarkerControls = THREEx.ArMultiMarkerControls.fromJSON(arToolkitContext, scene, markerRoot, multiMarkerFile)

	//////////////////////////////////////////////////////////////////////////////
	//		get multiMarkerFile
	//////////////////////////////////////////////////////////////////////////////

	// if no localStorage.ARjsMultiMarkerFile, then write one with default marker
	if( localStorage.getItem('ARjsMultiMarkerFile') === null ){
		THREEx.ArMultiMarkerControls.storeDefaultMultiMarkerFile(urlOptions.trackingBackend)
	}

	// get multiMarkerFile from localStorage
	console.assert( localStorage.getItem('ARjsMultiMarkerFile') !== null )
	var multiMarkerFile = localStorage.getItem('ARjsMultiMarkerFile')

	//////////////////////////////////////////////////////////////////////////////
	//		Create ArMultiMarkerControls
	//////////////////////////////////////////////////////////////////////////////
	// build a markerRoot
	var markerRoot = new THREE.Group()
	scene.add(markerRoot)

	// build a multiMarkerControls
	var multiMarkerControls = THREEx.ArMultiMarkerControls.fromJSON(arToolkitContext, scene, markerRoot, multiMarkerFile)

	// add an THREEx.ArMarkerHelper to visuable each sub-marker
	var markerHelpers = []
	multiMarkerControls.subMarkersControls.forEach(function(subMarkerControls){
		var markerHelper = new THREEx.ArMarkerHelper(subMarkerControls)
		subMarkerControls.object3d.add( markerHelper.object3d )
		markerHelpers.push(markerHelper)
	})


	// build a smoothedControls
	var smoothedRoot = new THREE.Group()
	scene.add(smoothedRoot)
	var smoothedControls = new THREEx.ArSmoothedControls(smoothedRoot)
	onRenderFcts.push(function(delta){
		// parameters for updateSmoothedControls
		var lerpsValues = [
			[0.1, 0.1, 0.5],
			[0.2, 0.1, 0.5],
			[0.2, 0.2, 0.5],
			[0.3, 0.2, 0.5],
			[0.3, 0.2, 0.5],
		]
		// update smoothedControls parameters depending on how many markers are visible in multiMarkerControls
		multiMarkerControls.updateSmoothedControls(smoothedControls, lerpsValues)
		// update multiMarkerRoot position
		smoothedControls.update(markerRoot)
	})

	var arWorldRoot = new THREE.Group()
	var averageMatrix = THREEx.ArMultiMarkerControls.computeCenter(multiMarkerFile)
	averageMatrix.decompose(arWorldRoot.position, arWorldRoot.quaternion, arWorldRoot.scale)
	smoothedRoot.add(arWorldRoot)

	//////////////////////////////////////////////////////////////////////////////
	//		toggle marker UI
	//////////////////////////////////////////////////////////////////////////////

	document.querySelector('#recordButton').addEventListener('click', function(){
		var learnerURL = THREEx.ArToolkitContext.baseURL + 'examples/multi-markers/examples/learner.html'
		THREEx.ArMultiMarkerUtils.navigateToLearnerPage(learnerURL, urlOptions.trackingBackend)
	})


	window.toggleMarkerHelper = toggleMarkerHelper
	function toggleMarkerHelper(){
		var wasVisible = markerHelpers[0].object3d.visible;

		document.querySelector('#markerHelpersStatus').innerHTML = wasVisible === false ? 'visible' : 'hidden'

		markerHelpers.forEach(function(markerHelper){
			markerHelper.object3d.visible = wasVisible ? false : true
		})
	}
	toggleMarkerHelper()



	//////////////////////////////////////////////////////////////////////////////////
	//		Add simple object on smoothedRoot
	//////////////////////////////////////////////////////////////////////////////////

	;(function(){
		var screenAsPortal = new THREEx.ScreenAsPortal(multiMarkerFile)
		arWorldRoot.add(screenAsPortal.object3d)
	})()

	//////////////////////////////////////////////////////////////////////////////////
	//		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>