huge refactor because of xrmacro vs xrfragment separation+2
This commit is contained in:
parent
ed5ecc5be6
commit
89e5af7d28
17 changed files with 85 additions and 203 deletions
|
|
@ -38,7 +38,7 @@ window.AFRAME.registerComponent('xrf-button', {
|
|||
el.setAttribute('material', {
|
||||
color: this.color,
|
||||
transparent:true,
|
||||
opacity:0.3
|
||||
opacity:0.5
|
||||
});
|
||||
el.setAttribute('pressable', '');
|
||||
labelEl.setAttribute('position', '0 0 0.01');
|
||||
|
|
|
|||
|
|
@ -57,9 +57,11 @@ xrf.parseModel = function(model,url){
|
|||
xrf.getLastModel = () => xrf.model.last
|
||||
|
||||
xrf.eval = function( url, model, flags ){ // evaluate fragments in url
|
||||
if( !url ) return
|
||||
if( !url.match(/#/) ) url = `#${url}`
|
||||
model = model || xrf.model
|
||||
let { THREE, camera } = xrf
|
||||
let frag = xrf.URI.parse( url, flags || xrf.XRF.NAVIGATOR )
|
||||
let frag = xrf.URI.parse( url, flags != undefined ? flags : xrf.XRF.NAVIGATOR )
|
||||
let opts = {frag, mesh:xrf.camera, model, camera: xrf.camera, scene: xrf.scene, renderer: xrf.renderer, THREE: xrf.THREE }
|
||||
xrf.emit('eval',opts)
|
||||
.then( () => {
|
||||
|
|
@ -67,6 +69,7 @@ xrf.eval = function( url, model, flags ){ // evaluate fragments in url
|
|||
xrf.eval.fragment(k,opts)
|
||||
}
|
||||
})
|
||||
return frag
|
||||
}
|
||||
|
||||
xrf.eval.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) inside mesh of model
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
|
||||
if( !file || xrf.model.file == file ){ // we're already loaded
|
||||
xrf.eval( url, xrf.model, flags ) // and eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash)
|
||||
return resolve(xrf.model)
|
||||
}
|
||||
|
||||
|
|
@ -33,8 +34,10 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
// spec: 2. execute predefined view(s) from URL (https://xrfragment.org/#predefined_view)
|
||||
xrf.eval( url, model ) // and eval URI XR fragments
|
||||
xrf.add( model.scene )
|
||||
if( !hash.match(/pos=/) )
|
||||
if( !hash.match(/pos=/) ){
|
||||
xrf.eval( '#pos=0,0,0' ) // set default position if not specified
|
||||
}
|
||||
xrf.navigator.updateHash(hash)
|
||||
resolve(model)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
xrf.frag.bg = function(v, opts){
|
||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
console.log("└ bg "+v.x+","+v.y+","+v.z);
|
||||
if( scene.background ) delete scene.background
|
||||
scene.background = new THREE.Color( v.x, v.y, v.z )
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
xrf.frag.env = function(v, opts){
|
||||
let { mesh, model, camera, scene, renderer, THREE} = opts
|
||||
let env = mesh.getObjectByName(v.string)
|
||||
if( !env ) return console.warn("xrf.env "+v.string+" not found")
|
||||
env.material.map.mapping = THREE.EquirectangularReflectionMapping;
|
||||
scene.environment = env.material.map
|
||||
//scene.texture = env.material.map
|
||||
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
||||
renderer.toneMappingExposure = 2;
|
||||
console.log(` └ applied image '${v.string}' as environment map`)
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
xrf.frag.fog = function(v, opts){
|
||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
console.log("└ fog "+v.x+","+v.y);
|
||||
if( v.x == 0 && v.y == 0 ){
|
||||
if( scene.fog ) delete scene.fog
|
||||
scene.fog = null;
|
||||
}else scene.fog = new THREE.Fog( scene.background, v.x, v.y );
|
||||
}
|
||||
|
|
@ -96,9 +96,10 @@ xrf.frag.href = function(v, opts){
|
|||
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
||||
.then( () => {
|
||||
const flags = v.string[0] == '#' ? xrf.XRF.PV_OVERRIDE : undefined
|
||||
//const flags = v.string[0] == '#' && v.string.match(/(\||#q)/) ? xrf.XRF.PV_OVERRIDE : undefined
|
||||
if( !v.string.match(/pos=/) ) v.string += `${v.string[0] == '#' ? '&' : '#'}${lastPos}` // always commit last position
|
||||
console.log(v.string)
|
||||
// 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)
|
||||
|
||||
xrf.navigator.to(v.string,flags) // let's surf to HREF!
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
xrf.frag.mov = function(v, opts){
|
||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
if( frag.q ){ // only operate on queried object(s)
|
||||
frag.q.getObjects().map( (o) => {
|
||||
o.position.add( new THREE.Vector3( v.x, v.y, v.z ) )
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,21 +1,6 @@
|
|||
xrf.frag.pos = function(v, opts){
|
||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
if( frag.q ){ // only operate on queried object(s)
|
||||
|
||||
// apply roundrobin (if any)
|
||||
if( v.args ) v = v.args[ xrf.roundrobin(v,model) ]
|
||||
|
||||
frag.q.getObjects().map( (o) => {
|
||||
// if object has no parent (name == 'Scene') use absolute positioning, otherwise relative to parent
|
||||
o.position.x = o.parent.name == 'Scene' ? v.x : o.positionOriginal.x + v.x
|
||||
o.position.y = o.parent.name == 'Scene' ? v.z : o.positionOriginal.y + v.z
|
||||
o.position.z = o.parent.name == 'Scene' ? v.y : o.positionOriginal.z + v.y
|
||||
})
|
||||
}else{
|
||||
camera.position.x = v.x
|
||||
camera.position.y = v.y
|
||||
camera.position.z = v.z
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ xrf.frag.updatePredefinedView = (opts) => {
|
|||
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
|
||||
traverseScene(frag[k],scene) // recurse predefined views
|
||||
}else xrf.eval.fragment(k,opts)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -63,27 +63,28 @@ xrf.frag.updatePredefinedView = (opts) => {
|
|||
})
|
||||
}
|
||||
|
||||
let pviews = []
|
||||
// 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
|
||||
console.log("filtering predefined view of src")
|
||||
console.dir(frag)
|
||||
}else{
|
||||
for ( let i in frag ) {
|
||||
let v = frag[i]
|
||||
if( v.is( xrf.XRF.PV_EXECUTE ) ){
|
||||
scene.XRF_PV_ORIGIN = v.string
|
||||
if( v.args ) v = v.args[ xrf.roundrobin(v,xrf.model) ]
|
||||
// wait for nested instances to arrive at the scene ?
|
||||
traverseScene(v,scene)
|
||||
if( v.string ) pviews.push(v.string)
|
||||
}else if( v.is( xrf.XRF.NAVIGATOR ) ) pviews.push(`${i}=${v.string}`)
|
||||
}
|
||||
if( pviews.length ) xrf.navigator.updateHash( pviews.join("&") )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// react to url changes
|
||||
//xrf.addEventListener('updateHash', (opts) => {
|
||||
// console.log("update hash");
|
||||
// console.dir(opts)
|
||||
// let frag = xrf.URI.parse( opts.hash, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA )
|
||||
// xrf.frag.updatePredefinedView({frag,scene:xrf.scene})
|
||||
//})
|
||||
xrf.addEventListener('updateHash', (opts) => {
|
||||
let frag = xrf.URI.parse( opts.hash, xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.METADATA )
|
||||
xrf.frag.updatePredefinedView({frag,scene:xrf.scene})
|
||||
})
|
||||
|
||||
// clicking href url with predefined view
|
||||
xrf.addEventListener('href', (opts) => {
|
||||
|
|
|
|||
|
|
@ -21,42 +21,11 @@ xrf.frag.q = function(v, opts){
|
|||
return o
|
||||
})
|
||||
}
|
||||
|
||||
// spec: https://xrfragment.org/#src
|
||||
const instanceScene = () => {
|
||||
v.scene = new THREE.Group()
|
||||
for ( let i in v.query ) {
|
||||
let target = v.query[i]
|
||||
if( !scene.getObjectByName(i) && i != '*' ) return console.log(` └ mesh not found: ${i}`)
|
||||
if( i == '*' ){
|
||||
let cloneScene = scene.clone()
|
||||
// add interactive elements (href's e.g.) *TODO* this is called by both internal/external src's
|
||||
v.scene.add( xrf.interactive.clone() )
|
||||
cloneScene.children.forEach( (child) => v.scene.getObjectByName(child.name) ? null : v.scene.add(child) )
|
||||
target.mesh = v.scene
|
||||
}else{
|
||||
if( !v.scene.getObjectByName(i) && target.id === true ){
|
||||
console.log(` └ query-ing mesh: ${i}`)
|
||||
v.scene.add( target.mesh = scene.getObjectByName(i).clone() )
|
||||
}
|
||||
}
|
||||
if( target.id != undefined && target.mesh ){
|
||||
target.mesh.position.set(0,0,0)
|
||||
target.mesh.rotation.set(0,0,0)
|
||||
}
|
||||
}
|
||||
// hide negative selectors
|
||||
let negative = []
|
||||
v.scene.traverse( (mesh) => {
|
||||
for ( let i in v.query ) {
|
||||
if( mesh.name == i && v.query[i].id === false ) negative.push(mesh)
|
||||
}
|
||||
})
|
||||
negative.map( (mesh) => mesh.visible = false )
|
||||
xrf.frag.q.filter(scene,frag) // spec : https://xrfragment.org/#queries
|
||||
}
|
||||
|
||||
xrf.frag.q.filter = function(scene,frag){
|
||||
// spec: https://xrfragment.org/#queries
|
||||
const showHide = () => {
|
||||
let q = frag.q.query
|
||||
scene.traverse( (mesh) => {
|
||||
for ( let i in q ) {
|
||||
|
|
@ -70,8 +39,3 @@ xrf.frag.q = function(v, opts){
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
const doLocalInstancing = opts.embedded && opts.embedded.fragment == 'src' && opts.embedded.string[0] == '#'
|
||||
if( doLocalInstancing ) instanceScene() // spec : https://xrfragment.org/#src
|
||||
else showHide() // spec : https://xrfragment.org/#queries
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,5 @@
|
|||
xrf.frag.rot = function(v, opts){
|
||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
// apply roundrobin (if any)
|
||||
if( v.args ) v = v.args[ xrf.roundrobin(v,model) ]
|
||||
|
||||
if( frag.q ){ // only operate on queried object(s)
|
||||
frag.q.getObjects().map( (o) => {
|
||||
o.rotation.set(
|
||||
v.x * Math.PI / 180,
|
||||
v.y * Math.PI / 180,
|
||||
v.z * Math.PI / 180
|
||||
)
|
||||
})
|
||||
}else{
|
||||
console.log(" └ setting camera rotation to "+v.string)
|
||||
camera.rotation.set(
|
||||
v.x * Math.PI / 180,
|
||||
|
|
@ -21,4 +8,3 @@ xrf.frag.rot = function(v, opts){
|
|||
)
|
||||
camera.updateMatrixWorld()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
xrf.frag.scale = function(v, opts){
|
||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
// apply roundrobin (if any)
|
||||
if( v.args ) v = v.args[ xrf.roundrobin(v,model) ]
|
||||
|
||||
if( frag.q ){ // only operate on queried object(s)
|
||||
frag.q.getObjects().map( (o) => {
|
||||
o.scale.x = v.x
|
||||
o.scale.y = v.y
|
||||
o.scale.z = v.z
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
xrf.frag.show = function(v, opts){
|
||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||
|
||||
// apply roundrobin (if any)
|
||||
if( v.args ) v = v.args[ xrf.roundrobin(v,model) ]
|
||||
|
||||
if( frag.q ){ // only operate on queried object(s)
|
||||
frag.q.getObjects().map( (o) => {
|
||||
o.visible = v.int == 1;
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,27 +10,29 @@ xrf.frag.src = function(v, opts){
|
|||
let frag = xrfragment.URI.parse(v.string)
|
||||
|
||||
const localSRC = () => {
|
||||
let obj
|
||||
|
||||
setTimeout( () => {
|
||||
// scale URI XR Fragments inside src-value
|
||||
// cherrypicking of object(s)
|
||||
if( !frag.q ){
|
||||
for( var i in frag ){
|
||||
if( scene.getObjectByName(i) ) src.add( obj = scene.getObjectByName(i).clone() )
|
||||
xrf.eval.fragment(i, Object.assign(opts,{frag, model,scene}))
|
||||
}
|
||||
if( frag.q.query ){
|
||||
let srcScene = frag.q.scene // three/xrf/q.js initializes .scene
|
||||
if( !srcScene || !srcScene.visible ) return
|
||||
console.log(" └ inserting "+i+" (srcScene)")
|
||||
srcScene.position.set(0,0,0)
|
||||
srcScene.rotation.set(0,0,0)
|
||||
srcScene.traverse( (m) => {
|
||||
m.isSRC = true
|
||||
if( m.userData && (m.userData.src || m.userData.href) ) return ;//delete m.userData.src // prevent infinite recursion
|
||||
xrf.eval.mesh(m,{scene,recursive:true})
|
||||
})
|
||||
if( srcScene.visible ) src.add( srcScene )
|
||||
if( src.children.length == 1 ) obj.position.set(0,0,0);
|
||||
}
|
||||
|
||||
// filtering of objects using query
|
||||
if( frag.q ){
|
||||
src = scene.clone();
|
||||
src.isSRC = true;
|
||||
xrf.frag.q.filter(src,frag)
|
||||
}
|
||||
src.traverse( (m) => {
|
||||
m.isSRC = true
|
||||
if( m.userData && (m.userData.src || m.userData.href) ) return ; // prevent infinite recursion
|
||||
xrf.eval.mesh(m,{scene,recursive:true}) // cool idea: recursion-depth based distance between face & src
|
||||
})
|
||||
xrf.frag.src.scale( src, opts )
|
||||
},10)
|
||||
}
|
||||
|
||||
const externalSRC = () => {
|
||||
|
|
@ -46,7 +48,7 @@ xrf.frag.src = function(v, opts){
|
|||
.catch( console.error )
|
||||
}
|
||||
|
||||
if( v.string[0] == "#" ) localSRC() // current file
|
||||
if( v.string[0] == "#" ) setTimeout( localSRC, 10 ) // current file
|
||||
else externalSRC() // external file
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,9 +85,10 @@ class Parser {
|
|||
}
|
||||
store.set(key, v ); // 1. if valid, add to store
|
||||
if( debug ) trace("✔ "+key+": "+v.string);
|
||||
}else{ // 1. prefix non-offical fragment key's with underscore (and add to store)
|
||||
}else{ // 1. expose (but mark) non-offical fragments too
|
||||
if( Std.isOfType(value, String) ) v.guessType(v,value);
|
||||
store.set("_"+key,v);
|
||||
v.noXRF = true;
|
||||
store.set(key,v);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class XRF {
|
|||
public var float:Float; // |float | | [-]x[.xxxx] (ieee)| #prio=-20 |
|
||||
public var args:Array<XRF>; // |array | mixed| \|-separated | #pos=0,0,0\|90,0,0 |
|
||||
public var query:Query;
|
||||
public var noXRF:Bool;
|
||||
//
|
||||
public function new(_fragment:String,_flags:Int){
|
||||
fragment = _fragment;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue