From f08c0acfd403a06de332dfe02505e6945332647c Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Wed, 11 Oct 2023 20:12:48 +0200 Subject: [PATCH] various bugfixes --- dist/xrfragment.aframe.js | 32 +- dist/xrfragment.three.js | 30 +- dist/xrfragment.three.module.js | 30 +- example/aframe/sandbox/index.gltf | 1 + example/aframe/sandbox/index.html | 4 +- example/assets/example.gltf | 5111 +++++---------- example/assets/index.gltf | 8305 ++++++++++++++++++++++++ example/threejs/sandbox/index.gltf | 1 + example/threejs/sandbox/index.html | 4 +- src/3rd/js/XRWG.js | 2 +- src/3rd/js/aframe/xrf-button.js | 2 +- src/3rd/js/three/index.js | 7 +- src/3rd/js/three/xrf/href.js | 5 +- src/3rd/js/three/xrf/predefinedView.js | 5 + src/3rd/js/three/xrf/q.js | 2 + src/3rd/js/three/xrf/src.js | 6 +- src/3rd/js/three/xrf/t.js | 4 +- 17 files changed, 9972 insertions(+), 3579 deletions(-) create mode 120000 example/aframe/sandbox/index.gltf create mode 100644 example/assets/index.gltf create mode 120000 example/threejs/sandbox/index.gltf diff --git a/dist/xrfragment.aframe.js b/dist/xrfragment.aframe.js index a4f3495..2268e9d 100644 --- a/dist/xrfragment.aframe.js +++ b/dist/xrfragment.aframe.js @@ -725,7 +725,7 @@ XRWG.generate = (opts) => { if( node ){ node.nodes.push(spatialNode) }else{ - node = { word: XRWG.cleankey(key), key: key.toLowerCase(), nodes:[spatialNode] } + node = { word: XRWG.cleankey(key), key, nodes:[spatialNode] } if( spatialNode.userData[key] ) node.value = spatialNode.userData[key] node[type] = true xrf.emit('XRWG',node) @@ -857,13 +857,16 @@ xrf.parseModel = function(model,url){ let tmp = new xrf.THREE.Vector3() model.render = function(){ - model.mixer.update( model.clock.getDelta() ) + let time = model.clock.getDelta() + model.mixer.update( time ) // update focusline xrf.focusLine.material.color.r = (1.0 + Math.sin( model.clock.getElapsedTime()*10 ))/2 xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( model.clock.getElapsedTime() ) xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( model.clock.getElapsedTime() *3 ) - xrf.focusLine.material.opacity = 0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 ) + xrf.focusLine.material.opacity = (0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 )) * xrf.focusLine.opacity; + if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.3 + if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0 } } @@ -1407,6 +1410,7 @@ xrf.frag.href = function(v, opts){ let isLocal = v.string[0] == '#' let lastPos = `pos=${camera.position.x.toFixed(2)},${camera.position.y.toFixed(2)},${camera.position.z.toFixed(2)}` + console.dir(lastPos) xrf .emit('href',{click:true,mesh,xrf:v}) // let all listeners agree @@ -1414,8 +1418,7 @@ xrf.frag.href = function(v, opts){ const flags = v.string[0] == '#' ? xrf.XRF.PV_OVERRIDE : undefined let toFrag = xrf.URI.parse( v.string, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA ) // always keep a trail of last positions before we navigate - if( !v.string.match(/pos=/) ) v.string += `${v.string[0] == '#' ? '&' : '#'}${lastPos}` - if( !document.location.hash.match(/pos=/) ) xrf.navigator.to(`#${lastPos}`,flags) + if( !document.location.hash.match(lastPos) ) xrf.navigator.to(`#${lastPos}`) xrf.navigator.to(v.string) // let's surf to HREF! }) .catch( console.error ) @@ -1512,6 +1515,7 @@ xrf.frag.updatePredefinedView = (opts) => { line.computeLineDistances(); xrf.focusLine.lines.push(line) xrf.focusLine.points.push(from) + xrf.focusLine.opacity = 1 scene.add(line) }) } @@ -1553,6 +1557,10 @@ xrf.frag.updatePredefinedView = (opts) => { remove.map( (n) => scene.remove(n.selection) ) // create new selections match.map( (w) => { + if( w.key == `#${id}` && w.value && w.value[0] == '#' ){ + // if value is alias, execute fragment value + xrf.hashbus.pub( w.value, xrf.model, xrf.XRF.METADATA | xrf.XRF.PV_OVERRIDE | xrf.XRF.NAVIGATOR ) + } w.nodes.map( (mesh) => { if( mesh.material ) selectionOfInterest( v, scene, mesh ) @@ -1619,8 +1627,10 @@ xrf.frag.q = function(v, opts){ xrf.frag.q.filter = function(scene,frag){ // spec: https://xrfragment.org/#queries let q = frag.q.query + console.dir(q) scene.traverse( (mesh) => { for ( let i in q ) { + if( i == '' ) continue let isMeshId = q[i].id != undefined let isMeshProperty = q[i].rules != undefined && q[i].rules.length && !isMeshId if( q[i].root && mesh.isSRC ) continue; // ignore nested object for root-items (queryseletor '/foo' e.g.) @@ -1658,6 +1668,7 @@ xrf.frag.src = function(v, opts){ xrf.frag.src.scale( src, opts, url ) xrf.frag.src.eval( src, opts, url ) mesh.add(src) + mesh.traverse( (n) => n.isSRC = n.isXRF = true ) if( mesh.material ) mesh.material.visible = false } @@ -1687,7 +1698,6 @@ xrf.frag.src.eval = function(scene, opts, url){ let { mesh, model, camera, renderer, THREE, hashbus} = opts if( url ){ console.log(mesh.name+" url="+url) - console.dir(mesh) //let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url) //let frag = xrfragment.URI.parse(url) //// scale URI XR Fragments (queries) inside src-value @@ -1739,7 +1749,6 @@ xrf.frag.src.scale = function(scene, opts, url){ xrf.frag.src.filterScene = (scene,opts) => { let { mesh, model, camera, renderer, THREE, hashbus, frag} = opts let obj, src - console.dir(frag) // cherrypicking of object(s) if( !frag.q ){ src = new THREE.Group() @@ -1751,18 +1760,15 @@ xrf.frag.src.filterScene = (scene,opts) => { hashbus.pub.fragment(i, Object.assign(opts,{frag, model,scene})) } }else src = scene.clone(true) - console.dir({name: mesh.name, scene, frag}) if( src.children.length == 1 ) obj.position.set(0,0,0); } // filtering of objects using query if( frag.q ){ src = scene.clone(true); - src.isSRC = src.isXRF = true; xrf.frag.q.filter(src,frag) } src.traverse( (m) => { - src.isSRC = src.isXRF = true; if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion hashbus.pub.mesh(m,{scene,recursive:true}) // cool idea: recursion-depth based distance between face & src }) @@ -1881,9 +1887,7 @@ xrf.frag.t = function(v, opts){ if( v.y > 0 || v.z > 0 ) updateTime( mixer.loop.timeStart ) - console.dir(mixer) - - // update loop jump + // update loop when needed if( !mixer.update.patched ){ let update = mixer.update mixer.update = function(time){ @@ -2036,7 +2040,7 @@ window.AFRAME.registerComponent('xrf-button', { el.setAttribute('material', { color: this.color, transparent:true, - opacity:0.5 + opacity:0.7 }); el.setAttribute('pressable', ''); labelEl.setAttribute('position', '0 0 0.01'); diff --git a/dist/xrfragment.three.js b/dist/xrfragment.three.js index c46b1a6..94ef0cb 100644 --- a/dist/xrfragment.three.js +++ b/dist/xrfragment.three.js @@ -725,7 +725,7 @@ XRWG.generate = (opts) => { if( node ){ node.nodes.push(spatialNode) }else{ - node = { word: XRWG.cleankey(key), key: key.toLowerCase(), nodes:[spatialNode] } + node = { word: XRWG.cleankey(key), key, nodes:[spatialNode] } if( spatialNode.userData[key] ) node.value = spatialNode.userData[key] node[type] = true xrf.emit('XRWG',node) @@ -857,13 +857,16 @@ xrf.parseModel = function(model,url){ let tmp = new xrf.THREE.Vector3() model.render = function(){ - model.mixer.update( model.clock.getDelta() ) + let time = model.clock.getDelta() + model.mixer.update( time ) // update focusline xrf.focusLine.material.color.r = (1.0 + Math.sin( model.clock.getElapsedTime()*10 ))/2 xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( model.clock.getElapsedTime() ) xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( model.clock.getElapsedTime() *3 ) - xrf.focusLine.material.opacity = 0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 ) + xrf.focusLine.material.opacity = (0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 )) * xrf.focusLine.opacity; + if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.3 + if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0 } } @@ -1407,6 +1410,7 @@ xrf.frag.href = function(v, opts){ let isLocal = v.string[0] == '#' let lastPos = `pos=${camera.position.x.toFixed(2)},${camera.position.y.toFixed(2)},${camera.position.z.toFixed(2)}` + console.dir(lastPos) xrf .emit('href',{click:true,mesh,xrf:v}) // let all listeners agree @@ -1414,8 +1418,7 @@ xrf.frag.href = function(v, opts){ const flags = v.string[0] == '#' ? xrf.XRF.PV_OVERRIDE : undefined let toFrag = xrf.URI.parse( v.string, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA ) // always keep a trail of last positions before we navigate - if( !v.string.match(/pos=/) ) v.string += `${v.string[0] == '#' ? '&' : '#'}${lastPos}` - if( !document.location.hash.match(/pos=/) ) xrf.navigator.to(`#${lastPos}`,flags) + if( !document.location.hash.match(lastPos) ) xrf.navigator.to(`#${lastPos}`) xrf.navigator.to(v.string) // let's surf to HREF! }) .catch( console.error ) @@ -1512,6 +1515,7 @@ xrf.frag.updatePredefinedView = (opts) => { line.computeLineDistances(); xrf.focusLine.lines.push(line) xrf.focusLine.points.push(from) + xrf.focusLine.opacity = 1 scene.add(line) }) } @@ -1553,6 +1557,10 @@ xrf.frag.updatePredefinedView = (opts) => { remove.map( (n) => scene.remove(n.selection) ) // create new selections match.map( (w) => { + if( w.key == `#${id}` && w.value && w.value[0] == '#' ){ + // if value is alias, execute fragment value + xrf.hashbus.pub( w.value, xrf.model, xrf.XRF.METADATA | xrf.XRF.PV_OVERRIDE | xrf.XRF.NAVIGATOR ) + } w.nodes.map( (mesh) => { if( mesh.material ) selectionOfInterest( v, scene, mesh ) @@ -1619,8 +1627,10 @@ xrf.frag.q = function(v, opts){ xrf.frag.q.filter = function(scene,frag){ // spec: https://xrfragment.org/#queries let q = frag.q.query + console.dir(q) scene.traverse( (mesh) => { for ( let i in q ) { + if( i == '' ) continue let isMeshId = q[i].id != undefined let isMeshProperty = q[i].rules != undefined && q[i].rules.length && !isMeshId if( q[i].root && mesh.isSRC ) continue; // ignore nested object for root-items (queryseletor '/foo' e.g.) @@ -1658,6 +1668,7 @@ xrf.frag.src = function(v, opts){ xrf.frag.src.scale( src, opts, url ) xrf.frag.src.eval( src, opts, url ) mesh.add(src) + mesh.traverse( (n) => n.isSRC = n.isXRF = true ) if( mesh.material ) mesh.material.visible = false } @@ -1687,7 +1698,6 @@ xrf.frag.src.eval = function(scene, opts, url){ let { mesh, model, camera, renderer, THREE, hashbus} = opts if( url ){ console.log(mesh.name+" url="+url) - console.dir(mesh) //let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url) //let frag = xrfragment.URI.parse(url) //// scale URI XR Fragments (queries) inside src-value @@ -1739,7 +1749,6 @@ xrf.frag.src.scale = function(scene, opts, url){ xrf.frag.src.filterScene = (scene,opts) => { let { mesh, model, camera, renderer, THREE, hashbus, frag} = opts let obj, src - console.dir(frag) // cherrypicking of object(s) if( !frag.q ){ src = new THREE.Group() @@ -1751,18 +1760,15 @@ xrf.frag.src.filterScene = (scene,opts) => { hashbus.pub.fragment(i, Object.assign(opts,{frag, model,scene})) } }else src = scene.clone(true) - console.dir({name: mesh.name, scene, frag}) if( src.children.length == 1 ) obj.position.set(0,0,0); } // filtering of objects using query if( frag.q ){ src = scene.clone(true); - src.isSRC = src.isXRF = true; xrf.frag.q.filter(src,frag) } src.traverse( (m) => { - src.isSRC = src.isXRF = true; if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion hashbus.pub.mesh(m,{scene,recursive:true}) // cool idea: recursion-depth based distance between face & src }) @@ -1881,9 +1887,7 @@ xrf.frag.t = function(v, opts){ if( v.y > 0 || v.z > 0 ) updateTime( mixer.loop.timeStart ) - console.dir(mixer) - - // update loop jump + // update loop when needed if( !mixer.update.patched ){ let update = mixer.update mixer.update = function(time){ diff --git a/dist/xrfragment.three.module.js b/dist/xrfragment.three.module.js index 10e3771..0bd796f 100644 --- a/dist/xrfragment.three.module.js +++ b/dist/xrfragment.three.module.js @@ -725,7 +725,7 @@ XRWG.generate = (opts) => { if( node ){ node.nodes.push(spatialNode) }else{ - node = { word: XRWG.cleankey(key), key: key.toLowerCase(), nodes:[spatialNode] } + node = { word: XRWG.cleankey(key), key, nodes:[spatialNode] } if( spatialNode.userData[key] ) node.value = spatialNode.userData[key] node[type] = true xrf.emit('XRWG',node) @@ -857,13 +857,16 @@ xrf.parseModel = function(model,url){ let tmp = new xrf.THREE.Vector3() model.render = function(){ - model.mixer.update( model.clock.getDelta() ) + let time = model.clock.getDelta() + model.mixer.update( time ) // update focusline xrf.focusLine.material.color.r = (1.0 + Math.sin( model.clock.getElapsedTime()*10 ))/2 xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( model.clock.getElapsedTime() ) xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( model.clock.getElapsedTime() *3 ) - xrf.focusLine.material.opacity = 0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 ) + xrf.focusLine.material.opacity = (0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 )) * xrf.focusLine.opacity; + if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.3 + if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0 } } @@ -1407,6 +1410,7 @@ xrf.frag.href = function(v, opts){ let isLocal = v.string[0] == '#' let lastPos = `pos=${camera.position.x.toFixed(2)},${camera.position.y.toFixed(2)},${camera.position.z.toFixed(2)}` + console.dir(lastPos) xrf .emit('href',{click:true,mesh,xrf:v}) // let all listeners agree @@ -1414,8 +1418,7 @@ xrf.frag.href = function(v, opts){ const flags = v.string[0] == '#' ? xrf.XRF.PV_OVERRIDE : undefined let toFrag = xrf.URI.parse( v.string, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA ) // always keep a trail of last positions before we navigate - if( !v.string.match(/pos=/) ) v.string += `${v.string[0] == '#' ? '&' : '#'}${lastPos}` - if( !document.location.hash.match(/pos=/) ) xrf.navigator.to(`#${lastPos}`,flags) + if( !document.location.hash.match(lastPos) ) xrf.navigator.to(`#${lastPos}`) xrf.navigator.to(v.string) // let's surf to HREF! }) .catch( console.error ) @@ -1512,6 +1515,7 @@ xrf.frag.updatePredefinedView = (opts) => { line.computeLineDistances(); xrf.focusLine.lines.push(line) xrf.focusLine.points.push(from) + xrf.focusLine.opacity = 1 scene.add(line) }) } @@ -1553,6 +1557,10 @@ xrf.frag.updatePredefinedView = (opts) => { remove.map( (n) => scene.remove(n.selection) ) // create new selections match.map( (w) => { + if( w.key == `#${id}` && w.value && w.value[0] == '#' ){ + // if value is alias, execute fragment value + xrf.hashbus.pub( w.value, xrf.model, xrf.XRF.METADATA | xrf.XRF.PV_OVERRIDE | xrf.XRF.NAVIGATOR ) + } w.nodes.map( (mesh) => { if( mesh.material ) selectionOfInterest( v, scene, mesh ) @@ -1619,8 +1627,10 @@ xrf.frag.q = function(v, opts){ xrf.frag.q.filter = function(scene,frag){ // spec: https://xrfragment.org/#queries let q = frag.q.query + console.dir(q) scene.traverse( (mesh) => { for ( let i in q ) { + if( i == '' ) continue let isMeshId = q[i].id != undefined let isMeshProperty = q[i].rules != undefined && q[i].rules.length && !isMeshId if( q[i].root && mesh.isSRC ) continue; // ignore nested object for root-items (queryseletor '/foo' e.g.) @@ -1658,6 +1668,7 @@ xrf.frag.src = function(v, opts){ xrf.frag.src.scale( src, opts, url ) xrf.frag.src.eval( src, opts, url ) mesh.add(src) + mesh.traverse( (n) => n.isSRC = n.isXRF = true ) if( mesh.material ) mesh.material.visible = false } @@ -1687,7 +1698,6 @@ xrf.frag.src.eval = function(scene, opts, url){ let { mesh, model, camera, renderer, THREE, hashbus} = opts if( url ){ console.log(mesh.name+" url="+url) - console.dir(mesh) //let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url) //let frag = xrfragment.URI.parse(url) //// scale URI XR Fragments (queries) inside src-value @@ -1739,7 +1749,6 @@ xrf.frag.src.scale = function(scene, opts, url){ xrf.frag.src.filterScene = (scene,opts) => { let { mesh, model, camera, renderer, THREE, hashbus, frag} = opts let obj, src - console.dir(frag) // cherrypicking of object(s) if( !frag.q ){ src = new THREE.Group() @@ -1751,18 +1760,15 @@ xrf.frag.src.filterScene = (scene,opts) => { hashbus.pub.fragment(i, Object.assign(opts,{frag, model,scene})) } }else src = scene.clone(true) - console.dir({name: mesh.name, scene, frag}) if( src.children.length == 1 ) obj.position.set(0,0,0); } // filtering of objects using query if( frag.q ){ src = scene.clone(true); - src.isSRC = src.isXRF = true; xrf.frag.q.filter(src,frag) } src.traverse( (m) => { - src.isSRC = src.isXRF = true; if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion hashbus.pub.mesh(m,{scene,recursive:true}) // cool idea: recursion-depth based distance between face & src }) @@ -1881,9 +1887,7 @@ xrf.frag.t = function(v, opts){ if( v.y > 0 || v.z > 0 ) updateTime( mixer.loop.timeStart ) - console.dir(mixer) - - // update loop jump + // update loop when needed if( !mixer.update.patched ){ let update = mixer.update mixer.update = function(time){ diff --git a/example/aframe/sandbox/index.gltf b/example/aframe/sandbox/index.gltf new file mode 120000 index 0000000..7983488 --- /dev/null +++ b/example/aframe/sandbox/index.gltf @@ -0,0 +1 @@ +assets/index.gltf \ No newline at end of file diff --git a/example/aframe/sandbox/index.html b/example/aframe/sandbox/index.html index 06f475e..46dd19d 100644 --- a/example/aframe/sandbox/index.html +++ b/example/aframe/sandbox/index.html @@ -35,8 +35,8 @@ - - + + @@ -118,7 +118,7 @@ window.XRF = XRF // expose to form - let file = document.location.search.length > 2 ? document.location.search.substr(1) + document.location.hash : 'example.gltf#pos=0,1,20' + let file = document.location.search.length > 2 ? document.location.search.substr(1) + document.location.hash : 'index.gltf#pos=0,1,20' // optional decoration of href event XRF.addEventListener('href',(e) => { diff --git a/src/3rd/js/XRWG.js b/src/3rd/js/XRWG.js index d6b6eaf..c9c6251 100644 --- a/src/3rd/js/XRWG.js +++ b/src/3rd/js/XRWG.js @@ -39,7 +39,7 @@ XRWG.generate = (opts) => { if( node ){ node.nodes.push(spatialNode) }else{ - node = { word: XRWG.cleankey(key), key: key.toLowerCase(), nodes:[spatialNode] } + node = { word: XRWG.cleankey(key), key, nodes:[spatialNode] } if( spatialNode.userData[key] ) node.value = spatialNode.userData[key] node[type] = true xrf.emit('XRWG',node) diff --git a/src/3rd/js/aframe/xrf-button.js b/src/3rd/js/aframe/xrf-button.js index 14877e1..895a0fd 100644 --- a/src/3rd/js/aframe/xrf-button.js +++ b/src/3rd/js/aframe/xrf-button.js @@ -38,7 +38,7 @@ window.AFRAME.registerComponent('xrf-button', { el.setAttribute('material', { color: this.color, transparent:true, - opacity:0.5 + opacity:0.7 }); el.setAttribute('pressable', ''); labelEl.setAttribute('position', '0 0 0.01'); diff --git a/src/3rd/js/three/index.js b/src/3rd/js/three/index.js index 384eb72..0b6c584 100644 --- a/src/3rd/js/three/index.js +++ b/src/3rd/js/three/index.js @@ -57,13 +57,16 @@ xrf.parseModel = function(model,url){ let tmp = new xrf.THREE.Vector3() model.render = function(){ - model.mixer.update( model.clock.getDelta() ) + let time = model.clock.getDelta() + model.mixer.update( time ) // update focusline xrf.focusLine.material.color.r = (1.0 + Math.sin( model.clock.getElapsedTime()*10 ))/2 xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( model.clock.getElapsedTime() ) xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( model.clock.getElapsedTime() *3 ) - xrf.focusLine.material.opacity = 0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 ) + xrf.focusLine.material.opacity = (0.25 + 0.15*Math.sin( model.clock.getElapsedTime() * 3 )) * xrf.focusLine.opacity; + if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.3 + if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0 } } diff --git a/src/3rd/js/three/xrf/href.js b/src/3rd/js/three/xrf/href.js index 73d2dbb..8606f29 100644 --- a/src/3rd/js/three/xrf/href.js +++ b/src/3rd/js/three/xrf/href.js @@ -100,11 +100,8 @@ xrf.frag.href = function(v, opts){ .then( () => { const flags = v.string[0] == '#' ? xrf.XRF.PV_OVERRIDE : undefined let toFrag = xrf.URI.parse( v.string, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA ) - let url = v.string // always keep a trail of last positions before we navigate - if( v.string.match(/pos=/) == null ) { - url += `${v.string[0] == '#' ? '&' : '#'}${lastPos}` - } + if( !document.location.hash.match(lastPos) ) xrf.navigator.to(`#${lastPos}`) xrf.navigator.to(v.string) // let's surf to HREF! }) .catch( console.error ) diff --git a/src/3rd/js/three/xrf/predefinedView.js b/src/3rd/js/three/xrf/predefinedView.js index 2a28b42..4805852 100644 --- a/src/3rd/js/three/xrf/predefinedView.js +++ b/src/3rd/js/three/xrf/predefinedView.js @@ -40,6 +40,7 @@ xrf.frag.updatePredefinedView = (opts) => { line.computeLineDistances(); xrf.focusLine.lines.push(line) xrf.focusLine.points.push(from) + xrf.focusLine.opacity = 1 scene.add(line) }) } @@ -81,6 +82,10 @@ xrf.frag.updatePredefinedView = (opts) => { remove.map( (n) => scene.remove(n.selection) ) // create new selections match.map( (w) => { + if( w.key == `#${id}` && w.value && w.value[0] == '#' ){ + // if value is alias, execute fragment value + xrf.hashbus.pub( w.value, xrf.model, xrf.XRF.METADATA | xrf.XRF.PV_OVERRIDE | xrf.XRF.NAVIGATOR ) + } w.nodes.map( (mesh) => { if( mesh.material ) selectionOfInterest( v, scene, mesh ) diff --git a/src/3rd/js/three/xrf/q.js b/src/3rd/js/three/xrf/q.js index 279a4dd..c50e484 100644 --- a/src/3rd/js/three/xrf/q.js +++ b/src/3rd/js/three/xrf/q.js @@ -27,8 +27,10 @@ xrf.frag.q = function(v, opts){ xrf.frag.q.filter = function(scene,frag){ // spec: https://xrfragment.org/#queries let q = frag.q.query + console.dir(q) scene.traverse( (mesh) => { for ( let i in q ) { + if( i == '' ) continue let isMeshId = q[i].id != undefined let isMeshProperty = q[i].rules != undefined && q[i].rules.length && !isMeshId if( q[i].root && mesh.isSRC ) continue; // ignore nested object for root-items (queryseletor '/foo' e.g.) diff --git a/src/3rd/js/three/xrf/src.js b/src/3rd/js/three/xrf/src.js index bff3e39..c1113e9 100644 --- a/src/3rd/js/three/xrf/src.js +++ b/src/3rd/js/three/xrf/src.js @@ -16,6 +16,7 @@ xrf.frag.src = function(v, opts){ xrf.frag.src.scale( src, opts, url ) xrf.frag.src.eval( src, opts, url ) mesh.add(src) + mesh.traverse( (n) => n.isSRC = n.isXRF = true ) if( mesh.material ) mesh.material.visible = false } @@ -45,7 +46,6 @@ xrf.frag.src.eval = function(scene, opts, url){ let { mesh, model, camera, renderer, THREE, hashbus} = opts if( url ){ console.log(mesh.name+" url="+url) - console.dir(mesh) //let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url) //let frag = xrfragment.URI.parse(url) //// scale URI XR Fragments (queries) inside src-value @@ -97,7 +97,6 @@ xrf.frag.src.scale = function(scene, opts, url){ xrf.frag.src.filterScene = (scene,opts) => { let { mesh, model, camera, renderer, THREE, hashbus, frag} = opts let obj, src - console.dir(frag) // cherrypicking of object(s) if( !frag.q ){ src = new THREE.Group() @@ -109,18 +108,15 @@ xrf.frag.src.filterScene = (scene,opts) => { hashbus.pub.fragment(i, Object.assign(opts,{frag, model,scene})) } }else src = scene.clone(true) - console.dir({name: mesh.name, scene, frag}) if( src.children.length == 1 ) obj.position.set(0,0,0); } // filtering of objects using query if( frag.q ){ src = scene.clone(true); - src.isSRC = src.isXRF = true; xrf.frag.q.filter(src,frag) } src.traverse( (m) => { - src.isSRC = src.isXRF = true; if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion hashbus.pub.mesh(m,{scene,recursive:true}) // cool idea: recursion-depth based distance between face & src }) diff --git a/src/3rd/js/three/xrf/t.js b/src/3rd/js/three/xrf/t.js index a051426..a05f2ff 100644 --- a/src/3rd/js/three/xrf/t.js +++ b/src/3rd/js/three/xrf/t.js @@ -29,9 +29,7 @@ xrf.frag.t = function(v, opts){ if( v.y > 0 || v.z > 0 ) updateTime( mixer.loop.timeStart ) - console.dir(mixer) - - // update loop jump + // update loop when needed if( !mixer.update.patched ){ let update = mixer.update mixer.update = function(time){