From 3e602fd6a28eb612900b241be6d866bc655fa6fc Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Wed, 25 Oct 2023 12:47:23 +0200 Subject: [PATCH] cleanup --- doc/RFC_XR_Fragments.md | 11 +- src/3rd/js/three/xrf/dynamic/XRWG-lines.js | 69 +++++++++++++ src/3rd/js/three/xrf/predefinedView.js | 113 +++------------------ src/3rd/js/three/{xrf => xrmacro}/clip.js | 0 src/3rd/js/three/{xrf => xrmacro}/fov.js | 0 5 files changed, 89 insertions(+), 104 deletions(-) create mode 100644 src/3rd/js/three/xrf/dynamic/XRWG-lines.js rename src/3rd/js/three/{xrf => xrmacro}/clip.js (100%) rename src/3rd/js/three/{xrf => xrmacro}/fov.js (100%) diff --git a/doc/RFC_XR_Fragments.md b/doc/RFC_XR_Fragments.md index 2a46c57..c88fe04 100644 --- a/doc/RFC_XR_Fragments.md +++ b/doc/RFC_XR_Fragments.md @@ -193,11 +193,12 @@ sub-delims = "," / "=" # List of URI Fragments -| fragment | type | example | info | -|-------------------|----------|-------------------|----------------------------------------------------------------------| -| `#pos` | vector3 | `#pos=0.5,0,0` | positions camera (or XR floor) to xyz-coord 0.5,0,0, | -| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 | -| `#t` | vector3 | `#t=1,500,1000` | play animation-loop range between frame 500 and 1000, at normal speed| +| fragment | type | example | info | +|-------------------|----------|--------------------|----------------------------------------------------------------------| +| `#pos` | vector3 | `#pos=0.5,0,0` | positions camera (or XR floor) to xyz-coord 0.5,0,0, | +| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 | +| `#t` | vector3 | `#t=1,500,1000` | play animation-loop range between frame 500 and 1000, at normal speed| +| `#q` | vector3 | `#q=-sky -tag:hide`| queries scene-graph (and removes object with name `cube` or `tag: hide`) | ## List of metadata for 3D nodes diff --git a/src/3rd/js/three/xrf/dynamic/XRWG-lines.js b/src/3rd/js/three/xrf/dynamic/XRWG-lines.js new file mode 100644 index 0000000..93b0295 --- /dev/null +++ b/src/3rd/js/three/xrf/dynamic/XRWG-lines.js @@ -0,0 +1,69 @@ + +const drawLineToMesh = (frag,scene,mesh) => { + let id = frag.string + let oldSelection + if(!id) return id // important: ignore empty strings + // Selection of Interest if predefined_view matches object name + if( mesh.visible && mesh.material){ + xrf.emit('focus',{...opts,frag}) + .then( () => { + const color = new THREE.Color(); + const colors = [] + let from = new THREE.Vector3() + + let getCenterPoint = (mesh) => { + var geometry = mesh.geometry; + geometry.computeBoundingBox(); + var center = new THREE.Vector3(); + geometry.boundingBox.getCenter( center ); + mesh.localToWorld( center ); + return center; + } + + xrf.camera.updateMatrixWorld(true); // always keeps me diving into the docs :] + xrf.camera.getWorldPosition(from) + from.y -= 0.5 // originate from the heart chakra! :p + const points = [from, getCenterPoint(mesh) ] + const geometry = new THREE.BufferGeometry().setFromPoints( points ); + let line = new THREE.Line( geometry, xrf.focusLine.material ); + line.isXRF = true + line.computeLineDistances(); + xrf.focusLine.lines.push(line) + xrf.focusLine.points.push(from) + xrf.focusLine.opacity = 1 + scene.add(line) + }) + } +} + +xrf.addEventListener('dynamicKey', (opts) => { + console.dir(opts) + let {scene,id,match,v} = opts + if( !scene ) return + let remove = [] + // erase previous lines + xrf.focusLine.lines.map( (line) => scene.remove(line) ) + xrf.focusLine.points = [] + xrf.focusLine.lines = [] + + scene.traverse( (n) => n.selection ? remove.push(n) : false ) + remove.map( (n) => scene.remove(n.selection) ) + // drawlines + match.map( (w) => { + w.nodes.map( (mesh) => drawLineToMesh( v, scene, mesh ) ) + }) +}) + +xrf.addEventListener('render', (opts) => { + let model = xrf.model + if( !model || !model.clock ) return + // update focusline + let {time} = opts + 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.opacity; + if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.2 + if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0 +}) + diff --git a/src/3rd/js/three/xrf/predefinedView.js b/src/3rd/js/three/xrf/predefinedView.js index e428e44..0d07bb5 100644 --- a/src/3rd/js/three/xrf/predefinedView.js +++ b/src/3rd/js/three/xrf/predefinedView.js @@ -8,98 +8,27 @@ xrf.frag.defaultPredefinedView = (opts) => { xrf.frag.updatePredefinedView = (opts) => { let {frag,scene,model,renderer} = opts - // spec: https://xrfragment.org/#Selection%20of%20interest - const selectionOfInterest = (frag,scene,mesh) => { - let id = frag.string - let oldSelection - if(!id) return id // important: ignore empty strings - // Selection of Interest if predefined_view matches object name - if( mesh.visible && mesh.material){ - xrf.emit('focus',{...opts,frag}) - .then( () => { - const color = new THREE.Color(); - const colors = [] - let from = new THREE.Vector3() - - let getCenterPoint = (mesh) => { - var geometry = mesh.geometry; - geometry.computeBoundingBox(); - var center = new THREE.Vector3(); - geometry.boundingBox.getCenter( center ); - mesh.localToWorld( center ); - return center; - } - - xrf.camera.updateMatrixWorld(true); // always keeps me diving into the docs :] - xrf.camera.getWorldPosition(from) - from.y -= 0.5 // originate from the heart chakra! :p - const points = [from, getCenterPoint(mesh) ] - const geometry = new THREE.BufferGeometry().setFromPoints( points ); - let line = new THREE.Line( geometry, xrf.focusLine.material ); - line.isXRF = true - line.computeLineDistances(); - xrf.focusLine.lines.push(line) - xrf.focusLine.points.push(from) - xrf.focusLine.opacity = 1 - scene.add(line) - }) - } - } - - //// spec: https://xrfragment.org/#predefined_view - //const predefinedView = (frag,scene,mesh) => { - // let id = frag.string || frag.fragment - // id = `#${id}` - // if( id == '##' ) id = '#'; // default predefined view - // if( !id ) return // prevent empty matches - // if( mesh.userData[id] ){ // get alias - // frag = xrf.URI.parse( mesh.userData[id], xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA ) - // xrf.emit('predefinedView',{...opts,frag}) - // .then( () => { - // for ( let k in frag ){ - // let opts = {frag, model, camera: xrf.camera, scene: xrf.scene, renderer: xrf.renderer, THREE: xrf.THREE } - // if( frag[k].is( xrf.XRF.PV_EXECUTE ) && scene.XRF_PV_ORIGIN != k ){ // cyclic detection - // highlightInScene(frag[k],scene) // recurse predefined views - // } - // } - // }) - // } - //} - - const highlightInScene = (v,scene) => { - if( !scene ) return - let remove = [] - let id = v.string || v.fragment - if( id == '#' ) return - let match = xrf.XRWG.match(id) - // erase previous lines - xrf.focusLine.lines.map( (line) => scene.remove(line) ) - xrf.focusLine.points = [] - xrf.focusLine.lines = [] - - scene.traverse( (n) => n.selection ? remove.push(n) : false ) - remove.map( (n) => scene.remove(n.selection) ) - // create new selections - match.map( (w) => { - if( w.key == `#${id}` ){ - if( 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) => selectionOfInterest( v, scene, mesh ) ) - }) - } - // if this query was triggered by an src-value, lets filter it const isSRC = opts.embedded && opts.embedded.fragment == 'src' if( !isSRC ){ // spec : https://xrfragment.org/#src for ( let i in frag ) { let v = frag[i] + let id = v.string || v.fragment + if( id == '#' ) return + let match = xrf.XRWG.match(id) + if( v.is( xrf.XRF.PV_EXECUTE ) ){ scene.XRF_PV_ORIGIN = v.string - // wait for nested instances to arrive at the scene ? - highlightInScene(v,scene) + // evaluate aliases + match.map( (w) => { + if( w.key == `#${id}` ){ + if( 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 ) + } + } + }) + xrf.emit('dynamicKey',{ ...opts,v,frag,id,match,scene }) } } } @@ -117,17 +46,3 @@ xrf.addEventListener('href', (opts) => { let frag = xrf.URI.parse( opts.xrf.string, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA ) xrf.frag.updatePredefinedView({frag,scene:xrf.scene,href:opts.xrf}) }) - -xrf.addEventListener('render', (opts) => { - let model = xrf.model - if( !model || !model.clock ) return - // update focusline - let {time} = opts - 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.opacity; - if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.2 - if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0 -}) - diff --git a/src/3rd/js/three/xrf/clip.js b/src/3rd/js/three/xrmacro/clip.js similarity index 100% rename from src/3rd/js/three/xrf/clip.js rename to src/3rd/js/three/xrmacro/clip.js diff --git a/src/3rd/js/three/xrf/fov.js b/src/3rd/js/three/xrmacro/fov.js similarity index 100% rename from src/3rd/js/three/xrf/fov.js rename to src/3rd/js/three/xrmacro/fov.js