提交 5a2d7671 编写于 作者: J Jerome Etienne

cleaning up multi-markers

上级 6d8d827e
......@@ -3,3 +3,18 @@
---
- make it easily usable on multiple marker configurations
# Demo.html
- write a basic.html when player is done
- fix the hiro case
- picking doesnt work on mobile
- or on horizontal aspect on desktop
- video refraction doesnt work on chromium
- DONE make delete button more obvious
- make it possible to save/load scene from localstorage
- remove the sceneName='' in the url
- put all that in chromium webar
- create repo with those demo in webar/ar.js webar/chromiumAR
- make your demo scene in there
<!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>
<script src='../../vendor/hammer.min.js'></script>
<script src='../../vendor/hammer-time.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='../../../threex-artoolkitsource.js'></script>
<script src='../../../threex-artoolkitcontext.js'></script>
<script src='../../../threex-artoolkitprofile.js'></script>
<script src='../../../threex-arbasecontrols.js'></script>
<script src='../../../threex-armarkercontrols.js'></script>
<script src='../../../threex-armarkerhelper.js'></script>
<script src='../../../threex-arsmoothedcontrols.js'></script>
<script>THREEx.ArToolkitContext.baseURL = '../../../'</script>
<script src='../../../../three.js/examples/multi-markers/threex-armultimarkercontrols.js'></script>
<!-- <script src='../../../../three.js/examples/multi-markers/threex-armultimarkerlearning.js'></script> -->
<!-- include demo scenes -->
<script src='../../../../three.js/examples/demo-scenes/threex-demoscenes.js'></script>
<script src='../../../../three.js/examples/refraction/threex.refractionmaterial.js'></script>
<script src='../../../../three.js/examples/hole-in-the-wall/threex.holeinthewall.js'></script>
<script src='../../../../three.js/examples/vendor/three.js/examples/js/loaders/GLTFLoader.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraft.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftcontrols.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.animation.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.animations.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftcharheadanim.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftcharbodyanim.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftnickname.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftbubble.js'></script>
<script>THREEx.ARjsDemoScenes.baseURL = '../../../../three.js/'</script>
<style>
#recordButton:hover {
cursor: pointer;
}
#objectList ul {
list-style: none;
font-size: 15px;
}
#objectList ul li {
cursor: pointer;
padding: 5px;
border-radius: 10px;
}
#objectList ul li.selected {
background: lightgray;
}
#objectList ul li:hover {
background: gray;
color: white;
}
</style>
<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/jeromeetienne/AR.js/' target='_blank'>AR.js</a> - Multi marker
by <a href='https://twitter.com/jerome_etienne' target='_blank'>@jerome_etienne</a>
<br>
<span style='font-weight: bold;'>Instruction:</span> position with tap - rotate with horizontal pan - scale with vertical pan
</div>
<div style='position: fixed; bottom: 10px; width:100%; text-align: center;z-index:1';>
Scenes:
<a href='javascript:void(0)' onclick='javascript: createDemoScene("torus")'>torus</a>
- <a href='javascript:void(0)' onclick='javascript: createDemoScene("glassTorus")'>glassTorus</a>
- <a href='javascript:void(0)' onclick='javascript: createDemoScene("holePortal")'>holePortal</a>
- <a href='javascript:void(0)' onclick='javascript: createDemoScene("holeTorus")'>holeTorus</a>
- <a href='javascript:void(0)' onclick='javascript: createDemoScene("holePool")'>holePool</a>
- <a href='javascript:void(0)' onclick='javascript: createDemoScene("minecraft")'>minecraft</a>
- <a href='javascript:void(0)' onclick='javascript: createDemoScene("shaddowTorusKnot")'>shaddowTorusKnot</a>
<br>
<br>
Area source:
<a href='javascript:void(0)' onclick='urlOptions.areaSource = "localStorage"; reload()'>localStorage</a>
/
<a href='javascript:void(0)' onclick='urlOptions.areaSource = "onlyHiro"; reload()'>onlyHiro</a>
<br>
Marker helpers:
<a href='javascript:void(0)' onclick='urlOptions.markerHelpers = true; reload()'>yes</a>
/
<a href='javascript:void(0)' onclick='urlOptions.markerHelpers = false; reload()'>no</a>
</div>
<div style='position: fixed; bottom: 16px; right: 16px; z-index:1';>
<img id='recordButton' src="images/record-start.png" width='64px' height='64px'>
</div>
<div style='position: fixed; bottom: 16px; left: 16px; z-index:1';>
<a href='javascript:void(0)' onclick='deleteSelectedScene()'>
<img src="images/delete-scene.png" width='64px' height='64px'>
</a>
</div>
<div id='objectList' style='position: fixed; top: 16px; right: 16px; z-index:1';>
<ul></ul>
</div>
<script>
// ;(function(){
//////////////////////////////////////////////////////////////////////////////////
// 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 );
// enable shadow in renderer
renderer.shadowMap.type = THREE.PCFSoftShadowMap
renderer.shadowMap.enabled = true;
// array of functions for the rendering loop
var onRenderFcts= [];
// 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);
////////////////////////////////////////////////////////////////////////////////
// handle arToolkitSource
////////////////////////////////////////////////////////////////////////////////
var artoolkitProfile = new THREEx.ArToolkitProfile()
artoolkitProfile.sourceWebcam()
// .performance('desktop-fast')
// artoolkitProfile.sourceVideo(THREEx.ArToolkitContext.baseURL + '../data/videos/headtracking.mp4').kanjiMarker();
// artoolkitProfile.sourceImage(THREEx.ArToolkitContext.baseURL + '../data/images/img.jpg').hiroMarker()
var arToolkitSource = new THREEx.ArToolkitSource(artoolkitProfile.sourceParameters)
arToolkitSource.init(function onReady(){
// handle resize of renderer
arToolkitSource.onResize([renderer.domElement, arToolkitContext.arController.canvas])
})
// handle resize
window.addEventListener('resize', function(){
// handle arToolkitSource resize
arToolkitSource.onResize([renderer.domElement, arToolkitContext.arController.canvas])
})
////////////////////////////////////////////////////////////////////////////////
// initialize arToolkitContext
////////////////////////////////////////////////////////////////////////////////
// create atToolkitContext
var arToolkitContext = new THREEx.ArToolkitContext(artoolkitProfile.contextParameters)
// initialize it
arToolkitContext.init(function onCompleted(){
// copy projection matrix to camera
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
//////////////////////////////////////////////////////////////////////////////
// pattern hiro/kanji/a/b/c/f
var markersControlsParameters = [
{
type : 'pattern',
patternUrl : THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro',
},
{
type : 'pattern',
patternUrl : THREEx.ArToolkitContext.baseURL + '../data/data/patt.kanji',
},
{
type : 'pattern',
patternUrl : THREEx.ArToolkitContext.baseURL + '../data/multimarkers/multi-abcdef/patt.a',
},
{
type : 'pattern',
patternUrl : THREEx.ArToolkitContext.baseURL + '../data/multimarkers/multi-abcdef/patt.b',
},
{
type : 'pattern',
patternUrl : THREEx.ArToolkitContext.baseURL + '../data/multimarkers/multi-abcdef/patt.c',
},
{
type : 'pattern',
patternUrl : THREEx.ArToolkitContext.baseURL + '../data/multimarkers/multi-abcdef/patt.f',
},
]
document.querySelector('#recordButton').addEventListener('click', function(){
urlOptions.areaSource = 'localStorage'
urlOptionsUpdate()
var learnerParameters = {
backURL : location.href,
markersControlsParameters: markersControlsParameters,
}
location.href = '../../../../three.js/examples/multi-markers/examples/learner.html#'+JSON.stringify(learnerParameters)
})
////////////////////////////////////////////////////////////////////////////////
// handle urlOptions
////////////////////////////////////////////////////////////////////////////////
var hasHash = location.hash.substring(1) !== '' ? true : false
if( hasHash === true ){
var urlOptions = JSON.parse(location.hash.substring(1))
}else{
var urlOptions = {
areaSource : 'localStorage',
markerHelpers: false,
sceneName: 'torus',
}
}
window.urlOptions = urlOptions
urlOptionsUpdate()
window.reload = function(){
urlOptionsUpdate()
location.reload()
}
function urlOptionsUpdate(){
location.hash = '#'+JSON.stringify(urlOptions)
}
if( urlOptions.areaSource === 'localStorage' && localStorage.getItem('ARjsMultiMarkerFile') === null ){
alert('No area has been learned on this device!\n Using only hiro.')
urlOptions.areaSource === 'onlyHiro'
urlOptionsUpdate()
}
//////////////////////////////////////////////////////////////////////////////
// get multiMarkerFile
//////////////////////////////////////////////////////////////////////////////
if( urlOptions.areaSource === 'localStorage' ){
console.assert( localStorage.getItem('ARjsMultiMarkerFile') !== null )
var multiMarkerFile = localStorage.getItem('ARjsMultiMarkerFile')
}else if( urlOptions.areaSource === 'onlyHiro' ){
var multiMarkerFile = JSON.stringify({
subMarkersControls : [
{
parameters: {
type : 'pattern',
patternUrl : THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro',
},
poseMatrix: new THREE.Matrix4().makeTranslation(0,0, 0).toArray()
},
]
})
}else{
console.assert('unknown areaSource', areaSource)
}
//////////////////////////////////////////////////////////////////////////////
// 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)
// display THREEx.ArMarkerHelper if needed - useful to debug
if( urlOptions.markerHelpers === true ){
multiMarkerControls.subMarkersControls.forEach(function(subMarkerControls){
// add an helper to visuable each sub-marker
var markerHelper = new THREEx.ArMarkerHelper(subMarkerControls)
subMarkerControls.object3d.add( markerHelper.object3d )
})
}
// build a smoothedControls
var smoothedRoot = new THREE.Group()
scene.add(smoothedRoot)
var smoothedControls = new THREEx.ArSmoothedControls(smoothedRoot, {
lerpPosition: 0.7,
lerpQuaternion: 0.7,
lerpScale: 0.7,
minVisibleDelay: 0.3,
minUnvisibleDelay: 0.2,
})
onRenderFcts.push(function(delta){
smoothedControls.update(markerRoot)
})
//////////////////////////////////////////////////////////////////////////////////
// create ARjs demo scenes
//////////////////////////////////////////////////////////////////////////////////
// create demo scenes
var demoScenes = new THREEx.ARjsDemoScenes()
onRenderFcts.push(function(delta){
demoScenes.update(delta)
})
// create the selectedMarkerScene based on sceneName
var markerScenes = []
var selectedMarkerScene = null
createDemoScene(urlOptions.sceneName)
// function to dynamically switch demoScenes
window.createDemoScene = createDemoScene
function createDemoScene(newSceneName){
var demoRoot = new THREE.Group
var averageMatrix = THREEx.ArMultiMarkerControls.computeCenter(multiMarkerFile)
averageMatrix.decompose(demoRoot.position, demoRoot.quaternion, demoRoot.scale)
smoothedRoot.add(demoRoot)
// create the new selectedMarkerScene
var markerScene = demoScenes.createMarkerScene(newSceneName)
demoRoot.add( markerScene )
markerScenes[markerScene.id] = markerScene
// update the UI
var domElement = document.createElement('li')
document.querySelector('#objectList ul').appendChild(domElement)
domElement.classList.add('selected')
domElement.innerHTML = newSceneName
domElement.dataset.markerSceneId = markerScene.id
domElement.addEventListener('click', function(){
var object3dId = domElement.dataset.markerSceneId
var markerScene = markerScenes[object3dId];
selectScene(markerScene)
})
// update urlOptions.sceneName
urlOptions.sceneName = newSceneName
urlOptionsUpdate()
// actually select this scene
selectScene(markerScene)
}
window.deleteSelectedScene = deleteSelectedScene
function deleteSelectedScene(){
if( Object.keys(markerScenes).length === 1 ){
alert('unable to delete when there is only one object')
return
}
var markerScene = selectedMarkerScene
markerScenes.splice(markerScene.id, 2)
var domElement = document.querySelector('#objectList ul li[data-marker-scene-id="'+markerScene.id+'"]')
domElement.parentNode.removeChild(domElement)
var markerRoot = markerScene.parent
markerRoot.parent.remove( markerRoot )
var lastDomElement = [].slice.call(document.querySelectorAll('#objectList ul li')).pop()
var markerScene = markerScenes[lastDomElement.dataset.markerSceneId]
selectScene(markerScene)
}
function selectScene(markerScene){
// set selectedMarkerScene
selectedMarkerScene = markerScene
// remove any domElement with selected class
;[].slice.call(document.querySelectorAll('#objectList ul li.selected')).forEach(function(domElement){
domElement.classList.remove('selected')
})
// add selected class tot the domElement
var domElement = document.querySelector('#objectList ul li[data-marker-scene-id="'+markerScene.id+'"]')
domElement.classList.add('selected')
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
var hammertime = new Hammer(renderer.domElement);
// var hammertime = new Hammer(document.body);
hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammertime.on('pan', function(event) {
if( event.additionalEvent !== 'panright' && event.additionalEvent !== 'panleft' ) return
var delta = event.velocityX / window.innerWidth * 60
var demoRoot = selectedMarkerScene.parent
demoRoot.rotation.y += delta
});
hammertime.on('pan', function(event) {
if( event.additionalEvent !== 'panup' && event.additionalEvent !== 'pandown' ) return
var delta = -event.velocityY/window.innerHeight * 60
delta = THREE.Math.clamp(delta, -0.2, 0.2)
var demoRoot = selectedMarkerScene.parent
var scale = demoRoot.scale.x * (1 + delta)
scale = THREE.Math.clamp(scale, 0.2, 10)
demoRoot.scale.set(scale, scale, scale)
});
//////////////////////////////////////////////////////////////////////////////
// Picking on ground
//////////////////////////////////////////////////////////////////////////////
var raycaster = new THREE.Raycaster();
var mouseCoordinate = new THREE.Vector2()
document.addEventListener( 'mousemove', function onDocumentMouseMove( event ) {
event.preventDefault();
mouseCoordinate.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouseCoordinate.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}, false );
// Create a three.js camera.
var cameraPicking = new THREE.PerspectiveCamera(42, window.innerWidth / window.innerHeight, 0.1, 100);
scene.add(cameraPicking);
// handle resize
window.addEventListener('resize', function(){
cameraPicking.aspect = window.innerWidth / window.innerHeight;
cameraPicking.updateProjectionMatrix();
})
var geometry = new THREE.PlaneGeometry(20,20).rotateX(-Math.PI/2)
var material = new THREE.MeshBasicMaterial({
// opacity: 0.5,
// transparent: true,
})
material.visible = false
var pickingPlane = new THREE.Mesh(geometry, material)
selectedMarkerScene.parent.add(pickingPlane)
// keep pickingPlane the same size even if parent is changing scale
onRenderFcts.push(function(delta){
pickingPlane.scale.set(1,1,1).multiplyScalar(1 / pickingPlane.parent.scale.x)
})
hammertime.on('tap', function(event) {
// compute intersections between mouseCoordinate and pickingPlane
raycaster.setFromCamera( mouseCoordinate, cameraPicking );
var intersects = raycaster.intersectObjects( [pickingPlane] )
// if no intersection occurs, return now
if( intersects.length === 0 ) return
// set new demoRoot position
var demoRoot = selectedMarkerScene.parent
var newPosition = demoRoot.parent.worldToLocal( intersects[0].point.clone() )
demoRoot.position.copy(newPosition)
})
//////////////////////////////////////////////////////////////////////////////////
// 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>
- every time you add a new object
- make a list of all the objects in the scene in a <li> element
- on top left
- easy element of this list an idea aka demoScene.id
- each created demoSCene is set in array demoScene.id
- click on <li> is about setting the demoScene variable - rename it selectedDemoScene
- each click on li change selectedDemoScene
- add a button to delete element
- write a basic.html
- fix the hiro case
---
- make a simple multi marker with a hardcoded cube
- make a player more useful
- pick to create object on the ground plane
- drag to rotate on y
- scale with pinch in/out
- demo.html
- put all that in chromium webar
- create repo with those demo in webar/ar.js webar/chromiumAR
- make your demo scene in there
- CLEAN UP STUFF
- NOGO in player, load the hardcoded from a file
- clean up the code and demo the case
- link the hardcoded one with the image of the multi marker
- in player, remove the function multiMarkerPlay() - serialise it
- either you take it from localstore or hardcoded
- in player, parameters this is a sceneName='' in the url
- maybe some placements depending multi placements
- all this code will be copyed directly in chromiumAR
- DONE appMode: areaUsing become areaSource: 'localStorage' or 'hardcodedABCF'
- DONE add link to the abcf images
- it is in https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Multi%20pattern%20(template%2C%20A4).pdf
- take a screenshots
- store it in data/images
- clean up data/images
- a lot of file from experiementation qr-code or multimarker
......
......@@ -19,6 +19,12 @@
<script src='../threex-armultimarkercontrols.js'></script>
<script src='../threex-armultimarkerlearning.js'></script>
<style>
#recordButton:hover, #recordStopButton: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';>
<a href='https://github.com/jeromeetienne/AR.js/' target='_blank'>AR.js</a> - Multi marker
by <a href='https://twitter.com/jerome_etienne' target='_blank'>@jerome_etienne</a>
......
......@@ -21,36 +21,18 @@
<script src='../threex-armultimarkercontrols.js'></script>
<script src='../threex-armultimarkerlearning.js'></script>
<!-- include demo scenes -->
<script src='../../../../three.js/examples/demo-scenes/threex-demoscenes.js'></script>
<script src='../../../../three.js/examples/refraction/threex.refractionmaterial.js'></script>
<script src='../../../../three.js/examples/hole-in-the-wall/threex.holeinthewall.js'></script>
<script src='../../../../three.js/examples/vendor/three.js/examples/js/loaders/GLTFLoader.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraft.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftcontrols.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.animation.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.animations.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftcharheadanim.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftcharbodyanim.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftnickname.js'></script>
<script src='../../../../aframe/examples/vendor/threex.minecraft/threex.minecraftbubble.js'></script>
<script>THREEx.ARjsDemoScenes.baseURL = '../../../../three.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';>
<a href='https://github.com/jeromeetienne/AR.js/' target='_blank'>AR.js</a> - Multi marker
by <a href='https://twitter.com/jerome_etienne' target='_blank'>@jerome_etienne</a>
</div>
<div style='position: fixed; bottom: 10px; width:100%; text-align: center;z-index:1';>
Scenes:
<a href='javascript:void(0)' onclick='javascript: switchDemoScene("torus")'>torus</a>
- <a href='javascript:void(0)' onclick='javascript: switchDemoScene("glassTorus")'>glassTorus</a>
- <a href='javascript:void(0)' onclick='javascript: switchDemoScene("holePortal")'>holePortal</a>
- <a href='javascript:void(0)' onclick='javascript: switchDemoScene("holeTorus")'>holeTorus</a>
- <a href='javascript:void(0)' onclick='javascript: switchDemoScene("holePool")'>holePool</a>
- <a href='javascript:void(0)' onclick='javascript: switchDemoScene("minecraft")'>minecraft</a>
- <a href='javascript:void(0)' onclick='javascript: switchDemoScene("shaddowTorusKnot")'>shaddowTorusKnot</a>
<br>
<br>
Area source:
<a href='javascript:void(0)' onclick='urlOptions.areaSource = "localStorage"; reload()'>localStorage</a>
/
......@@ -62,34 +44,10 @@
<a href='javascript:void(0)' onclick='urlOptions.markerHelpers = false; reload()'>no</a>
</div>
<div style='position: fixed; bottom: 16px; right: 16px; z-index:1';>
<a id='recordButton' href='learner.html?url=player.html'>
<img src="images/record-start.png" width='64px' height='64px'>
</a>
</div>
<div id='objectList' style='position: fixed; top: 16px; right: 16px; z-index:1';>
<ul>
</ul>
<style>
#objectList ul {
list-style: none;
font-size: 15px;
}
#objectList ul li {
cursor: pointer;
padding: 5px;
border-radius: 10px;
}
#objectList ul li.selected {
background: lightgray;
}
#objectList ul li:hover {
background: gray;
color: white;
}
</style>
<img id='recordButton' src="images/record-start.png" width='64px' height='64px'>
</div>
<script>
// ;(function(){
;(function(){
//////////////////////////////////////////////////////////////////////////////////
// Init
//////////////////////////////////////////////////////////////////////////////////
......@@ -135,9 +93,6 @@
var artoolkitProfile = new THREEx.ArToolkitProfile()
artoolkitProfile.sourceWebcam()
// .performance('desktop-fast')
// artoolkitProfile.sourceVideo(THREEx.ArToolkitContext.baseURL + '../data/videos/headtracking.mp4').kanjiMarker();
// artoolkitProfile.sourceImage(THREEx.ArToolkitContext.baseURL + '../data/images/img.jpg').hiroMarker()
var arToolkitSource = new THREEx.ArToolkitSource(artoolkitProfile.sourceParameters)
......@@ -204,10 +159,17 @@
},
]
var learnerParameters = {
backURL : 'player.html',
markersControlsParameters: markersControlsParameters,
}
document.querySelector('#recordButton').addEventListener('click', function(){
urlOptions.areaSource = 'localStorage'
urlOptionsUpdate()
var learnerParameters = {
backURL : location.href,
markersControlsParameters: markersControlsParameters,
}
location.href = 'learner.html#'+JSON.stringify(learnerParameters)
})
////////////////////////////////////////////////////////////////////////////////
// handle urlOptions
......@@ -220,7 +182,6 @@
var urlOptions = {
areaSource : 'localStorage',
markerHelpers: false,
sceneName: 'torus',
}
}
window.urlOptions = urlOptions
......@@ -231,8 +192,6 @@
}
function urlOptionsUpdate(){
location.hash = '#'+JSON.stringify(urlOptions)
learnerParameters.backURL= 'player.html'+location.hash
document.querySelector('#recordButton').href = 'learner.html#'+JSON.stringify(learnerParameters)
}
if( urlOptions.areaSource === 'localStorage' && localStorage.getItem('ARjsMultiMarkerFile') === null ){
......@@ -287,178 +246,59 @@
var smoothedRoot = new THREE.Group()
scene.add(smoothedRoot)
var smoothedControls = new THREEx.ArSmoothedControls(smoothedRoot, {
lerpPosition: 0.3,
lerpQuaternion: 0.5,
lerpScale: 0.5,
lerpPosition: 0.7,
lerpQuaternion: 0.7,
lerpScale: 0.7,
minVisibleDelay: 0.3,
minUnvisibleDelay: 0.2,
})
onRenderFcts.push(function(delta){
smoothedControls.update(markerRoot)
})
//////////////////////////////////////////////////////////////////////////////////
// create ARjs demo scenes
// Add simple object on smoothedRoot
//////////////////////////////////////////////////////////////////////////////////
// create demo scenes
var demoScenes = new THREEx.ARjsDemoScenes()
onRenderFcts.push(function(delta){
demoScenes.update(delta)
})
// create the selectedMarkerScene based on sceneName
var markerScenes = []
var selectedMarkerScene = null
switchDemoScene(urlOptions.sceneName)
// function to dynamically switch demoScenes
window.switchDemoScene = switchDemoScene
function switchDemoScene(newSceneName){
// remove previous selectedMarkerScene if suiltabled
if( selectedMarkerScene ){
// selectedMarkerScene.parent.remove( selectedMarkerScene )
// demoScenes.dispose()
// selectedMarkerScene = null
}
;(function(){
var demoRoot = new THREE.Group
var averageMatrix = THREEx.ArMultiMarkerControls.computeCenter(multiMarkerFile)
averageMatrix.decompose(demoRoot.position, demoRoot.quaternion, demoRoot.scale)
smoothedRoot.add(demoRoot)
// create the new selectedMarkerScene
var markerScene = demoScenes.createMarkerScene(newSceneName)
demoRoot.add( markerScene )
markerScenes[markerScene.id] = markerScene
// update the UI
var domElement = document.createElement('li')
document.querySelector('#objectList ul').appendChild(domElement)
domElement.classList.add('selected')
domElement.innerHTML = newSceneName
domElement.dataset.markerSceneId = markerScene.id
// update urlOptions.sceneName
urlOptions.sceneName = newSceneName
urlOptionsUpdate()
selectScene(markerScene)
domElement.addEventListener('click', function(){
var object3dId = domElement.dataset.markerSceneId
var markerScene = markerScenes[object3dId];
selectScene(markerScene)
})
return
function selectScene(markerScene){
// debugger
selectedMarkerScene = markerScene
;[].slice.call(document.querySelectorAll('#objectList ul li.selected')).forEach(function(domElement){
// debugger
domElement.classList.remove('selected')
})
domElement.classList.add('selected')
}
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
var hammertime = new Hammer(renderer.domElement);
// var hammertime = new Hammer(document.body);
hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammertime.on('pan', function(event) {
if( event.additionalEvent !== 'panright' && event.additionalEvent !== 'panleft' ) return
var mesh = new THREE.AxisHelper()
demoRoot.add(mesh)
var delta = event.velocityX / window.innerWidth * 60
var demoRoot = selectedMarkerScene.parent
demoRoot.rotation.y += delta
});
hammertime.on('pan', function(event) {
if( event.additionalEvent !== 'panup' && event.additionalEvent !== 'pandown' ) return
var delta = -event.velocityY/window.innerHeight * 60
delta = THREE.Math.clamp(delta, -0.2, 0.2)
// add a torus knot
var geometry = new THREE.CubeGeometry(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
demoRoot.add(mesh)
var demoRoot = selectedMarkerScene.parent
var scale = demoRoot.scale.x * (1 + delta)
scale = THREE.Math.clamp(scale, 0.2, 10)
demoRoot.scale.set(scale, scale, scale)
});
//////////////////////////////////////////////////////////////////////////////
// Picking on ground
//////////////////////////////////////////////////////////////////////////////
var raycaster = new THREE.Raycaster();
var mouseCoordinate = new THREE.Vector2()
document.addEventListener( 'mousemove', function onDocumentMouseMove( event ) {
event.preventDefault();
mouseCoordinate.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouseCoordinate.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}, false );
// Create a three.js camera.
var cameraPicking = new THREE.PerspectiveCamera(42, window.innerWidth / window.innerHeight, 0.1, 100);
scene.add(cameraPicking);
// handle resize
window.addEventListener('resize', function(){
cameraPicking.aspect = window.innerWidth / window.innerHeight;
cameraPicking.updateProjectionMatrix();
})
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
demoRoot.add( mesh );
var geometry = new THREE.PlaneGeometry(20,20).rotateX(-Math.PI/2)
var material = new THREE.MeshBasicMaterial({
// opacity: 0.5,
// transparent: true,
})
material.visible = false
var pickingPlane = new THREE.Mesh(geometry, material)
selectedMarkerScene.parent.add(pickingPlane)
// keep pickingPlane the same size even if parent is changing scale
onRenderFcts.push(function(delta){
pickingPlane.scale.set(1,1,1).multiplyScalar(1 / pickingPlane.parent.scale.x)
})
hammertime.on('tap', function(event) {
// compute intersections between mouseCoordinate and pickingPlane
raycaster.setFromCamera( mouseCoordinate, cameraPicking );
var intersects = raycaster.intersectObjects( [pickingPlane] )
// if no intersection occurs, return now
if( intersects.length === 0 ) return
// set new demoRoot position
var demoRoot = selectedMarkerScene.parent
var newPosition = demoRoot.parent.worldToLocal( intersects[0].point.clone() )
demoRoot.position.copy(newPosition)
})
onRenderFcts.push(function(delta){
mesh.rotation.x += delta * Math.PI
})
})()
//////////////////////////////////////////////////////////////////////////////////
// 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 );
// scene.updateMatrixWorld(true)
// renderer.render( scenePicking, cameraPicking );
stats.update();
})
......@@ -476,5 +316,5 @@
onRenderFct(deltaMsec/1000, nowMsec/1000)
})
})
// })()
})()
</script></body>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册