From c626f7c7625671e68509bb912fc7e496fd28b840 Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Fri, 12 May 2023 22:40:09 +0200 Subject: [PATCH] wip: solve AFRAME teleport issue --- dist/xrfragment.aframe.js | 28 ++++++++++++++++++++------- dist/xrfragment.three.js | 8 ++++---- example/threejs/sandbox/example3.gltf | 1 + example/threejs/sandbox/index.html | 2 +- src/3rd/aframe/index.js | 20 ++++++++++++++++--- src/3rd/three/index.js | 2 +- src/3rd/three/xrf/href.js | 6 +++--- 7 files changed, 48 insertions(+), 19 deletions(-) create mode 120000 example/threejs/sandbox/example3.gltf diff --git a/dist/xrfragment.aframe.js b/dist/xrfragment.aframe.js index d071b60..82d6634 100644 --- a/dist/xrfragment.aframe.js +++ b/dist/xrfragment.aframe.js @@ -816,7 +816,7 @@ xrf.reset = () => { if( !xrf.model.scene ) return xrf.scene.remove( xrf.model.scene ) xrf.model.scene.traverse( function(node){ - if( node instanceof THREE.Mesh ){ + if( node instanceof xrf.THREE.Mesh ){ node.geometry.dispose() node.material.dispose() } @@ -944,9 +944,9 @@ xrf.frag.href = function(v, opts){ }); mesh.material.needsUpdate = true - const handleTeleport = (e) => { + mesh.handleTeleport = (e) => { if( mesh.clicked ) return - this.clicked = true + mesh.clicked = true let portalArea = 1 // 1 meter const meshWorldPosition = new THREE.Vector3(); meshWorldPosition.setFromMatrixPosition(mesh.matrixWorld); @@ -980,7 +980,7 @@ xrf.frag.href = function(v, opts){ setTimeout( () => mesh.clicked = false, 200 ) // prevent double clicks } - if( !opts.frag.q ) mesh.addEventListener('click', handleTeleport ) + if( !opts.frag.q ) mesh.addEventListener('click', mesh.handleTeleport ) // lazy remove mesh (because we're inside a traverse) setTimeout( () => { @@ -1048,7 +1048,7 @@ window.AFRAME.registerComponent('xrf', { AFRAME.XRF.navigate.to(this.data) .then( (model) => { let gets = [ ...document.querySelectorAll('[xrf-get]') ] - gets.map( (g) => g.emit('update',model) ) + gets.map( (g) => g.emit('update') ) }) } }, @@ -1074,7 +1074,19 @@ window.AFRAME.registerComponent('xrf', { XRF.pos = camOverride XRF.rot = camOverride - XRF.href = camOverride + + XRF.href = (xrf,v,opts) => { // convert portal to a-entity so AFRAME + camOverride(xrf,v,opts) // raycaster can reach it + let {mesh,camera} = opts; + let el = document.createElement("a-entity") + el.setAttribute("xrf-get",mesh.name ) + el.setAttribute("class","collidable") + el.addEventListener("click", (e) => { + mesh.handleTeleport() // *TODO* rename to fragment-neutral mesh.xrf.exec() e.g. + $('#player').object3D.position.copy(camera.position) + }) + $('a-scene').appendChild(el) + } }, }) @@ -1092,7 +1104,7 @@ window.AFRAME.registerComponent('xrf-get', { this.el.addEventListener('update', (evt) => { - let scene = evt.detail.scene + let scene = AFRAME.XRF.scene let mesh = scene.getObjectByName(meshname); if (!mesh){ console.error("mesh with name '"+meshname+"' not found in model") @@ -1109,6 +1121,8 @@ window.AFRAME.registerComponent('xrf-get', { }) + if( this.el.className == "collidable" ) this.el.emit("update") + } }); diff --git a/dist/xrfragment.three.js b/dist/xrfragment.three.js index 4b5f013..69d2509 100644 --- a/dist/xrfragment.three.js +++ b/dist/xrfragment.three.js @@ -816,7 +816,7 @@ xrf.reset = () => { if( !xrf.model.scene ) return xrf.scene.remove( xrf.model.scene ) xrf.model.scene.traverse( function(node){ - if( node instanceof THREE.Mesh ){ + if( node instanceof xrf.THREE.Mesh ){ node.geometry.dispose() node.material.dispose() } @@ -944,9 +944,9 @@ xrf.frag.href = function(v, opts){ }); mesh.material.needsUpdate = true - const handleTeleport = (e) => { + mesh.handleTeleport = (e) => { if( mesh.clicked ) return - this.clicked = true + mesh.clicked = true let portalArea = 1 // 1 meter const meshWorldPosition = new THREE.Vector3(); meshWorldPosition.setFromMatrixPosition(mesh.matrixWorld); @@ -980,7 +980,7 @@ xrf.frag.href = function(v, opts){ setTimeout( () => mesh.clicked = false, 200 ) // prevent double clicks } - if( !opts.frag.q ) mesh.addEventListener('click', handleTeleport ) + if( !opts.frag.q ) mesh.addEventListener('click', mesh.handleTeleport ) // lazy remove mesh (because we're inside a traverse) setTimeout( () => { diff --git a/example/threejs/sandbox/example3.gltf b/example/threejs/sandbox/example3.gltf new file mode 120000 index 0000000..1f5ae60 --- /dev/null +++ b/example/threejs/sandbox/example3.gltf @@ -0,0 +1 @@ +../../assets/example3.gltf \ No newline at end of file diff --git a/example/threejs/sandbox/index.html b/example/threejs/sandbox/index.html index dbafc8c..d214de3 100644 --- a/example/threejs/sandbox/index.html +++ b/example/threejs/sandbox/index.html @@ -129,7 +129,7 @@ let file = document.location.search.length > 2 ? document.location.search.substr(1) : './../../assets/example3.gltf' $('#model').setAttribute("href","./../../asset/"+file) - XRF.navigate( file ) + XRF.navigate.to( file ) // setup mouse controls diff --git a/src/3rd/aframe/index.js b/src/3rd/aframe/index.js index 7985918..93690d8 100644 --- a/src/3rd/aframe/index.js +++ b/src/3rd/aframe/index.js @@ -8,7 +8,7 @@ window.AFRAME.registerComponent('xrf', { AFRAME.XRF.navigate.to(this.data) .then( (model) => { let gets = [ ...document.querySelectorAll('[xrf-get]') ] - gets.map( (g) => g.emit('update',model) ) + gets.map( (g) => g.emit('update') ) }) } }, @@ -34,7 +34,19 @@ window.AFRAME.registerComponent('xrf', { XRF.pos = camOverride XRF.rot = camOverride - XRF.href = camOverride + + XRF.href = (xrf,v,opts) => { // convert portal to a-entity so AFRAME + camOverride(xrf,v,opts) // raycaster can reach it + let {mesh,camera} = opts; + let el = document.createElement("a-entity") + el.setAttribute("xrf-get",mesh.name ) + el.setAttribute("class","collidable") + el.addEventListener("click", (e) => { + mesh.handleTeleport() // *TODO* rename to fragment-neutral mesh.xrf.exec() e.g. + //$('#player').object3D.position.copy(camera.position) + }) + $('a-scene').appendChild(el) + } }, }) @@ -52,7 +64,7 @@ window.AFRAME.registerComponent('xrf-get', { this.el.addEventListener('update', (evt) => { - let scene = evt.detail.scene + let scene = AFRAME.XRF.scene let mesh = scene.getObjectByName(meshname); if (!mesh){ console.error("mesh with name '"+meshname+"' not found in model") @@ -69,6 +81,8 @@ window.AFRAME.registerComponent('xrf-get', { }) + if( this.el.className == "collidable" ) this.el.emit("update") + } }); diff --git a/src/3rd/three/index.js b/src/3rd/three/index.js index d21ec35..f2c44b8 100644 --- a/src/3rd/three/index.js +++ b/src/3rd/three/index.js @@ -95,7 +95,7 @@ xrf.reset = () => { if( !xrf.model.scene ) return xrf.scene.remove( xrf.model.scene ) xrf.model.scene.traverse( function(node){ - if( node instanceof THREE.Mesh ){ + if( node instanceof xrf.THREE.Mesh ){ node.geometry.dispose() node.material.dispose() } diff --git a/src/3rd/three/xrf/href.js b/src/3rd/three/xrf/href.js index 433d814..f744d23 100644 --- a/src/3rd/three/xrf/href.js +++ b/src/3rd/three/xrf/href.js @@ -47,9 +47,9 @@ xrf.frag.href = function(v, opts){ }); mesh.material.needsUpdate = true - const handleTeleport = (e) => { + mesh.handleTeleport = (e) => { if( mesh.clicked ) return - this.clicked = true + mesh.clicked = true let portalArea = 1 // 1 meter const meshWorldPosition = new THREE.Vector3(); meshWorldPosition.setFromMatrixPosition(mesh.matrixWorld); @@ -83,7 +83,7 @@ xrf.frag.href = function(v, opts){ setTimeout( () => mesh.clicked = false, 200 ) // prevent double clicks } - if( !opts.frag.q ) mesh.addEventListener('click', handleTeleport ) + if( !opts.frag.q ) mesh.addEventListener('click', mesh.handleTeleport ) // lazy remove mesh (because we're inside a traverse) setTimeout( () => {