2023-09-15 19:42:37 +02:00
|
|
|
// the hashbus (QueryString eventBus) is mentioned in the spec
|
|
|
|
|
//
|
|
|
|
|
// it allows metadata-keys ('foo' e.g.) of 3D scene-nodes (.userData.foo e.g.) to
|
|
|
|
|
// react by executing code
|
|
|
|
|
|
2024-02-08 19:40:43 +01:00
|
|
|
let pub = function( url, node_or_model, flags ){ // evaluate fragments in url
|
2023-09-15 19:42:37 +02:00
|
|
|
if( !url ) return
|
|
|
|
|
if( !url.match(/#/) ) url = `#${url}`
|
|
|
|
|
let { THREE, camera } = xrf
|
2024-02-08 19:40:43 +01:00
|
|
|
let frag = xrf.URI.parse( url, flags )
|
|
|
|
|
let fromNode = node_or_model != xrf.model
|
|
|
|
|
|
|
|
|
|
let opts = {
|
|
|
|
|
frag,
|
|
|
|
|
mesh: fromNode ? node_or_model : xrf.camera,
|
|
|
|
|
model: xrf.model,
|
|
|
|
|
camera: xrf.camera,
|
|
|
|
|
scene: xrf.scene,
|
|
|
|
|
renderer: xrf.renderer,
|
|
|
|
|
THREE: xrf.THREE,
|
|
|
|
|
hashbus: xrf.hashbus
|
|
|
|
|
}
|
2023-09-15 19:42:37 +02:00
|
|
|
xrf.emit('hashbus',opts)
|
|
|
|
|
.then( () => {
|
|
|
|
|
for ( let k in frag ){
|
2024-02-08 19:40:43 +01:00
|
|
|
let nodeAlias = fromNode && opts.mesh && opts.mesh.userData && opts.mesh.userData[k] && opts.mesh.userData[k][0] == '#'
|
|
|
|
|
if( nodeAlias ) pub(opts.mesh.userData[k], opts.mesh) // evaluate node alias
|
|
|
|
|
else pub.fragment(k,opts)
|
2023-09-15 19:42:37 +02:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return frag
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-08 13:35:19 +01:00
|
|
|
// deprecated: (XR Macros) evaluate embedded fragments (metadata) inside mesh of model *REMOVEME*
|
|
|
|
|
pub.mesh = (mesh,model) => {
|
2023-09-15 19:42:37 +02:00
|
|
|
if( mesh.userData ){
|
|
|
|
|
let frag = {}
|
|
|
|
|
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
|
|
|
|
for( let k in frag ){
|
|
|
|
|
let opts = {frag, mesh, model, camera: xrf.camera, scene: model.scene, renderer: xrf.renderer, THREE: xrf.THREE, hashbus: xrf.hashbus }
|
|
|
|
|
mesh.userData.XRF = frag // allow fragment impl to access XRF obj already
|
2023-11-08 18:28:18 +01:00
|
|
|
xrf.emit('frag2mesh',opts)
|
2023-12-08 13:35:19 +01:00
|
|
|
.then( () => pub.fragment(k, {...opts, skipXRWG:true}) )
|
2023-09-15 19:42:37 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub.fragment = (k, opts ) => { // evaluate one fragment
|
|
|
|
|
let frag = opts.frag[k];
|
2023-10-12 17:04:46 +02:00
|
|
|
|
2024-02-01 19:10:41 +00:00
|
|
|
let isPVorMediaFrag = frag.is( xrf.XRF.PV_EXECUTE ) || frag.is( xrf.XRF.T_MEDIAFRAG)
|
2024-02-08 19:40:43 +01:00
|
|
|
if( !opts.skipXRWG && isPVorMediaFrag ) pub.XRWG(k,opts)
|
2023-11-23 12:30:18 +01:00
|
|
|
|
2023-09-15 19:42:37 +02:00
|
|
|
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
|
|
|
|
xrf.emit(k,opts)
|
|
|
|
|
.then( () => {
|
|
|
|
|
let func = xrf.frag[k] || function(){}
|
2023-11-08 18:28:18 +01:00
|
|
|
if( typeof xrf[k] == 'function' ) xrf[k]( func, frag, opts)
|
|
|
|
|
else func( frag, opts)
|
2023-09-15 19:42:37 +02:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 19:40:43 +01:00
|
|
|
pub.XRWG = (word,opts) => {
|
2023-10-27 16:55:48 +02:00
|
|
|
let {frag,scene,model,renderer} = opts
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
2024-02-08 19:40:43 +01:00
|
|
|
let triggeredByMesh = opts.model != opts.mesh
|
|
|
|
|
|
|
|
|
|
let v = frag[word]
|
|
|
|
|
let id = v.is( xrf.XRF.T_DYNAMICKEY ) ? word : v.string || word
|
|
|
|
|
|
|
|
|
|
if( id == '#' || !id ) return
|
|
|
|
|
let match = xrf.XRWG.match(id)
|
|
|
|
|
|
|
|
|
|
if( !triggeredByMesh && (v.is( xrf.XRF.PV_EXECUTE ) || v.is( xrf.XRF.T_DYNAMIC)) && !v.is( xrf.XRF.T_DYNAMICKEYVALUE ) ){
|
|
|
|
|
// evaluate global aliases or tag/objectnames
|
|
|
|
|
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 )
|
2023-10-27 16:55:48 +02:00
|
|
|
}
|
2024-02-08 19:40:43 +01:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
xrf.emit('dynamicKey',{ ...opts,v,frag,id,match,scene })
|
|
|
|
|
}else if( v.string ){
|
|
|
|
|
// evaluate global aliases
|
|
|
|
|
xrf.emit('dynamicKeyValue',{ ...opts,v,frag,id,match,scene })
|
|
|
|
|
}else{
|
|
|
|
|
xrf.emit('dynamicKey',{ ...opts,v,frag,id,match,scene })
|
2023-10-27 16:55:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-09-15 19:42:37 +02:00
|
|
|
xrf.hashbus = { pub }
|