uvscroll works OK now

This commit is contained in:
Leon van Kammen 2023-10-27 16:55:48 +02:00
parent 5fa3e62627
commit 488e9050e9
10 changed files with 2706 additions and 2444 deletions

BIN
example/assets/index.glb Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -8,7 +8,7 @@ let pub = function( url, model, flags ){ // evaluate fragments in url
if( !url.match(/#/) ) url = `#${url}`
model = model || xrf.model
let { THREE, camera } = xrf
let frag = xrf.URI.parse( url, flags != undefined ? flags : xrf.XRF.NAVIGATOR )
let frag = xrf.URI.parse( url, flags )
let opts = {frag, mesh:xrf.camera, model, camera: xrf.camera, scene: xrf.scene, renderer: xrf.renderer, THREE: xrf.THREE, hashbus: xrf.hashbus }
xrf.emit('hashbus',opts)
.then( () => {
@ -44,4 +44,38 @@ pub.fragment = (k, opts ) => { // evaluate one fragment
})
}
pub.XRWG = (opts) => {
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
for ( let i in frag ) {
let v = frag[i]
let id = v.string || v.fragment
if( id == '#' || !id ) return
let match = xrf.XRWG.match(id)
if( v.is( xrf.XRF.PV_EXECUTE ) ){
console.log("pv_execute")
scene.XRF_PV_ORIGIN = v.string
// 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 })
}else{
console.log("non pv_execute")
xrf.emit('dynamicKeyValue',{ ...opts,v,frag,id,match,scene })
}
}
}
}
xrf.hashbus = { pub }

View file

@ -50,10 +50,6 @@ xrf.parseModel = function(model,url){
// eval embedded XR fragments
model.scene.traverse( (mesh) => {
xrf.hashbus.pub.mesh(mesh,model)
let obj = [ `'${mesh.name}'` ]
if( mesh.material ) obj.push([`material:'${mesh.material.name}'`])
if( mesh.material && mesh.material.map ) obj.push([`texture: '${mesh.material.map.name}'`])
console.log("obj "+obj.join(" ") )
})
model.animations.map( (a) => console.log("anim: "+a.name) )
xrf.emit('parseModel',{model,url,file})

View file

@ -33,12 +33,13 @@ xrf.navigator.to = (url,flags,loader,data) => {
// spec: 1. generate the XRWG
xrf.XRWG.generate({model,scene:model.scene})
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
xrf.frag.defaultPredefinedView({model,scene:model.scene})
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
// spec: 2. init metadata
let frag = hashbus.pub( url, model ) // and eval URI XR fragments
// spec: predefined view(s) from URL (https://xrfragment.org/#predefined_view)
setTimeout( () => { // give external objects some slack
xrf.frag.updatePredefinedView({model,scene:model.scene,frag})
let frag = hashbus.pub( url, model) // and eval URI XR fragments
hashbus.pub.XRWG({model,scene:model.scene,frag})
console.dir(frag)
},2000)
xrf.add( model.scene )
xrf.navigator.updateHash(hash)

View file

@ -1,52 +1,22 @@
xrf.frag.defaultPredefinedView = (opts) => {
xrf.frag.defaultPredefinedViews = (opts) => {
let {scene,model} = opts;
let frag = {}
xrf.Parser.parse("#","",frag)
xrf.frag.updatePredefinedView({frag,model,scene})
}
xrf.frag.updatePredefinedView = (opts) => {
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
for ( let i in frag ) {
let v = frag[i]
let id = v.string || v.fragment
if( id == '#' || !id ) return
let match = xrf.XRWG.match(id)
if( v.is( xrf.XRF.PV_EXECUTE ) ){
console.log("pv_execute")
scene.XRF_PV_ORIGIN = v.string
// 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 })
}else{
console.log("non pv_execute")
xrf.emit('dynamicKeyValue',{ ...opts,v,frag,id,match,scene })
}
scene.traverse( (n) => {
if( n.userData && n.userData['#'] ){
let frag = xrf.URI.parse( n.userData['#'] )
xrf.hashbus.pub.XRWG({frag,model,scene})
}
}
})
}
// react to enduser typing url
xrf.addEventListener('hash', (opts) => {
let frag = xrf.URI.parse( opts.hash )
xrf.frag.updatePredefinedView({frag,scene:xrf.scene})
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene})
})
// clicking href url with predefined view
xrf.addEventListener('href', (opts) => {
if( !opts.click || opts.xrf.string[0] != '#' ) return
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.hashbus.pub.XRWG({frag,scene:xrf.scene,href:opts.xrf})
})

View file

@ -1,24 +0,0 @@
xrf.addEventListener('dynamicKeyValue', (opts) => {
let {scene,match,v} = opts
let light = v.fragment
scene.traverse( (o) => {
if( o.isLight && o.name == light ){
if( v.x != undefined ){
o.color.r = v.x
o.color.g = v.y
o.color.b = v.z
console.dir(o)
}else{
let driver = xrf.scene.getObjectByName(v.string)
if( !driver ) return
o.onAfterRender = () => {
let model = xrf.model
if( !model || !model.clock ) return
o.color.r = v.x
o.color.g = v.y
o.color.b = v.z
}
}
}
})
})

View file

@ -1,15 +1,29 @@
xrf.addEventListener('dynamicKeyValue', (opts) => {
let {scene,match,v} = opts
let objname = v.fragment
let autoscroll = v.z > 0 || v.w > 0
scene.traverse( (mesh) => {
if( mesh.name == objname ){
if( !mesh.geometry ) return console.warn(`mesh '${objname}' has no uvcoordinates to offset`)
let uv = mesh.geometry.getAttribute("uv")
if( !uv.old ) uv.old = uv.clone()
for( let i = 0; i < uv.count; i++ ){
uv.setXY(i, uv.old.getX(i) + v.x, uv.old.getY(i) + v.y )
}
if( autoscroll ){
if( mesh.removeUVListener ) mesh.removeUVListener()
mesh.removeUVListener = xrf.addEventListener('render', (opts) => {
let {time} = opts
for( let i = 0; i < uv.count; i++ ){
uv.setXY(i, uv.getX(i) + v.z * time, uv.getY(i) + v.w * time)
}
uv.needsUpdate = true
})
}
uv.needsUpdate = true
}
})

View file

@ -105,7 +105,6 @@ xrf.frag.src.scale = function(scene, opts, url){
}else{
// spec 4 of https://xrfragment.org/#src
// spec 2 of https://xrfragment.org/#scaling%20of%20instanced%20objects
console.log("normal scale: "+url)
scene.scale.multiply( mesh.scale )
}
scene.isXRF = model.scene.isSRC = true
@ -132,7 +131,6 @@ xrf.frag.src.filterScene = (scene,opts) => {
if( frag.q ){
src = scene.clone(true);
xrf.frag.q.filter(src,frag)
console.dir(src)
}
src.traverse( (m) => {
if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion

View file

@ -66,11 +66,6 @@ xrf.frag.src.type['image/png'] = function(url,opts){
if( mesh.geometry ){
if( mesh.geometry.attributes.uv ){ // buffergeometries
let uv = mesh.geometry.attributes.uv;
// i u v
uv.setXY(0, 0, 0 )
uv.setXY(1, 1, 0 )
uv.setXY(2, 0, 1 )
uv.setXY(3, 1, 1 )
}else {
console.warn("xrfragment: uv's of ${url} might be off for non-buffer-geometries *TODO*")
//if( geometry.faceVertexUvs ){