better AR support (auto-publishes #AR to the hashbus)
This commit is contained in:
parent
f18acea3ff
commit
77d820212e
13 changed files with 21680 additions and 77 deletions
2
.github/workflows/website.yml
vendored
2
.github/workflows/website.yml
vendored
|
|
@ -41,7 +41,7 @@ jobs:
|
||||||
- name: create index.gltf
|
- name: create index.gltf
|
||||||
run: cp example/assets/query.gltf index.gltf
|
run: cp example/assets/query.gltf index.gltf
|
||||||
- name: copy gltfs
|
- name: copy gltfs
|
||||||
run: cp example/assets/*.gltf .
|
run: cp example/assets/*.{gltf,glb} .
|
||||||
# working-directory: ./
|
# working-directory: ./
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v1
|
uses: actions/upload-pages-artifact@v1
|
||||||
|
|
|
||||||
31
dist/xrfragment.aframe.all.js
vendored
31
dist/xrfragment.aframe.all.js
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* v0.5.1 generated at Thu Dec 7 10:14:06 PM CET 2023
|
* v0.5.1 generated at Fri Dec 8 01:31:41 PM CET 2023
|
||||||
* https://xrfragment.org
|
* https://xrfragment.org
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|
@ -784,7 +784,8 @@ let pub = function( url, model, flags ){ // evaluate fragments in url
|
||||||
return frag
|
return frag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) inside mesh of model
|
// deprecated: (XR Macros) evaluate embedded fragments (metadata) inside mesh of model *REMOVEME*
|
||||||
|
pub.mesh = (mesh,model) => {
|
||||||
if( mesh.userData ){
|
if( mesh.userData ){
|
||||||
let frag = {}
|
let frag = {}
|
||||||
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
||||||
|
|
@ -792,7 +793,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
let opts = {frag, mesh, model, camera: xrf.camera, scene: model.scene, renderer: xrf.renderer, THREE: xrf.THREE, hashbus: xrf.hashbus }
|
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
|
mesh.userData.XRF = frag // allow fragment impl to access XRF obj already
|
||||||
xrf.emit('frag2mesh',opts)
|
xrf.emit('frag2mesh',opts)
|
||||||
.then( () => pub.fragment(k,opts) )
|
.then( () => pub.fragment(k, {...opts, skipXRWG:true}) )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -800,7 +801,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
pub.fragment = (k, opts ) => { // evaluate one fragment
|
pub.fragment = (k, opts ) => { // evaluate one fragment
|
||||||
let frag = opts.frag[k];
|
let frag = opts.frag[k];
|
||||||
|
|
||||||
if( frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG({...opts,frag})
|
if( !opts.skipXRWG && frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG(opts)
|
||||||
|
|
||||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||||
xrf.emit(k,opts)
|
xrf.emit(k,opts)
|
||||||
|
|
@ -992,9 +993,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: 2. init metadata
|
// spec: 2. init metadata
|
||||||
// spec: predefined view(s) from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
||||||
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
hashbus.pub.XRWG({model,scene:model.scene,frag})
|
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.navigator.updateHash(hash)
|
xrf.navigator.updateHash(hash)
|
||||||
|
|
@ -1789,22 +1789,17 @@ xrf.frag.defaultPredefinedViews = (opts) => {
|
||||||
if( n.userData && n.userData['#'] ){
|
if( n.userData && n.userData['#'] ){
|
||||||
let frag = xrf.URI.parse( n.userData['#'] )
|
let frag = xrf.URI.parse( n.userData['#'] )
|
||||||
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
||||||
xrf.hashbus.pub.XRWG({frag,model,scene}) // evaluate dynamic XR fragment using XRWG (see spec)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// react to enduser typing url
|
// react to enduser typing url
|
||||||
xrf.addEventListener('hash', (opts) => {
|
xrf.addEventListener('hash', (opts) => xrf.hashbus.pub( opts.hash ) )
|
||||||
let frag = xrf.URI.parse( opts.hash )
|
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene})
|
|
||||||
})
|
|
||||||
|
|
||||||
// clicking href url with predefined view
|
// clicking href url with predefined view
|
||||||
xrf.addEventListener('href', (opts) => {
|
xrf.addEventListener('href', (opts) => {
|
||||||
if( !opts.click || opts.xrf.string[0] != '#' ) return
|
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.hashbus.pub( opts.xrf.string )
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene,href:opts.xrf})
|
|
||||||
})
|
})
|
||||||
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
||||||
let {scene,match,v} = opts
|
let {scene,match,v} = opts
|
||||||
|
|
@ -2642,10 +2637,10 @@ window.AFRAME.registerComponent('xrf', {
|
||||||
|
|
||||||
if( document.location.host.match(/localhost/) ) document.querySelector('a-scene').setAttribute("stats",'')
|
if( document.location.host.match(/localhost/) ) document.querySelector('a-scene').setAttribute("stats",'')
|
||||||
|
|
||||||
document.querySelector('a-scene').addEventListener('loaded', () => {
|
let aScene = document.querySelector('a-scene')
|
||||||
|
aScene.addEventListener('loaded', () => {
|
||||||
|
|
||||||
// enable XR fragments
|
// enable XR fragments
|
||||||
let aScene = document.querySelector('a-scene')
|
|
||||||
let XRF = AFRAME.XRF = xrf.init({
|
let XRF = AFRAME.XRF = xrf.init({
|
||||||
THREE,
|
THREE,
|
||||||
camera: aScene.camera,
|
camera: aScene.camera,
|
||||||
|
|
@ -2658,6 +2653,12 @@ window.AFRAME.registerComponent('xrf', {
|
||||||
})
|
})
|
||||||
if( !XRF.camera ) throw 'xrfragment: no camera detected, please declare <a-entity camera..> ABOVE entities with xrf-attributes'
|
if( !XRF.camera ) throw 'xrfragment: no camera detected, please declare <a-entity camera..> ABOVE entities with xrf-attributes'
|
||||||
|
|
||||||
|
// this is just for convenience (not part of spec): hide/show stuff based on VR/AR tags in 3D model
|
||||||
|
ARbutton = document.querySelector('.a-enter-ar-button')
|
||||||
|
VRbutton = document.querySelector('.a-enter-vr-button')
|
||||||
|
if( ARbutton ) ARbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#AR' ) )
|
||||||
|
if( VRbutton ) VRbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#VR' ) )
|
||||||
|
|
||||||
xrf.addEventListener('navigateLoaded', () => {
|
xrf.addEventListener('navigateLoaded', () => {
|
||||||
setTimeout( () => AFRAME.fade.out(),500)
|
setTimeout( () => AFRAME.fade.out(),500)
|
||||||
|
|
||||||
|
|
|
||||||
31
dist/xrfragment.aframe.js
vendored
31
dist/xrfragment.aframe.js
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* v0.5.1 generated at Thu Dec 7 10:14:06 PM CET 2023
|
* v0.5.1 generated at Fri Dec 8 01:31:41 PM CET 2023
|
||||||
* https://xrfragment.org
|
* https://xrfragment.org
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|
@ -778,7 +778,8 @@ let pub = function( url, model, flags ){ // evaluate fragments in url
|
||||||
return frag
|
return frag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) inside mesh of model
|
// deprecated: (XR Macros) evaluate embedded fragments (metadata) inside mesh of model *REMOVEME*
|
||||||
|
pub.mesh = (mesh,model) => {
|
||||||
if( mesh.userData ){
|
if( mesh.userData ){
|
||||||
let frag = {}
|
let frag = {}
|
||||||
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
||||||
|
|
@ -786,7 +787,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
let opts = {frag, mesh, model, camera: xrf.camera, scene: model.scene, renderer: xrf.renderer, THREE: xrf.THREE, hashbus: xrf.hashbus }
|
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
|
mesh.userData.XRF = frag // allow fragment impl to access XRF obj already
|
||||||
xrf.emit('frag2mesh',opts)
|
xrf.emit('frag2mesh',opts)
|
||||||
.then( () => pub.fragment(k,opts) )
|
.then( () => pub.fragment(k, {...opts, skipXRWG:true}) )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -794,7 +795,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
pub.fragment = (k, opts ) => { // evaluate one fragment
|
pub.fragment = (k, opts ) => { // evaluate one fragment
|
||||||
let frag = opts.frag[k];
|
let frag = opts.frag[k];
|
||||||
|
|
||||||
if( frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG({...opts,frag})
|
if( !opts.skipXRWG && frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG(opts)
|
||||||
|
|
||||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||||
xrf.emit(k,opts)
|
xrf.emit(k,opts)
|
||||||
|
|
@ -986,9 +987,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: 2. init metadata
|
// spec: 2. init metadata
|
||||||
// spec: predefined view(s) from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
||||||
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
hashbus.pub.XRWG({model,scene:model.scene,frag})
|
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.navigator.updateHash(hash)
|
xrf.navigator.updateHash(hash)
|
||||||
|
|
@ -1783,22 +1783,17 @@ xrf.frag.defaultPredefinedViews = (opts) => {
|
||||||
if( n.userData && n.userData['#'] ){
|
if( n.userData && n.userData['#'] ){
|
||||||
let frag = xrf.URI.parse( n.userData['#'] )
|
let frag = xrf.URI.parse( n.userData['#'] )
|
||||||
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
||||||
xrf.hashbus.pub.XRWG({frag,model,scene}) // evaluate dynamic XR fragment using XRWG (see spec)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// react to enduser typing url
|
// react to enduser typing url
|
||||||
xrf.addEventListener('hash', (opts) => {
|
xrf.addEventListener('hash', (opts) => xrf.hashbus.pub( opts.hash ) )
|
||||||
let frag = xrf.URI.parse( opts.hash )
|
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene})
|
|
||||||
})
|
|
||||||
|
|
||||||
// clicking href url with predefined view
|
// clicking href url with predefined view
|
||||||
xrf.addEventListener('href', (opts) => {
|
xrf.addEventListener('href', (opts) => {
|
||||||
if( !opts.click || opts.xrf.string[0] != '#' ) return
|
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.hashbus.pub( opts.xrf.string )
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene,href:opts.xrf})
|
|
||||||
})
|
})
|
||||||
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
||||||
let {scene,match,v} = opts
|
let {scene,match,v} = opts
|
||||||
|
|
@ -2636,10 +2631,10 @@ window.AFRAME.registerComponent('xrf', {
|
||||||
|
|
||||||
if( document.location.host.match(/localhost/) ) document.querySelector('a-scene').setAttribute("stats",'')
|
if( document.location.host.match(/localhost/) ) document.querySelector('a-scene').setAttribute("stats",'')
|
||||||
|
|
||||||
document.querySelector('a-scene').addEventListener('loaded', () => {
|
let aScene = document.querySelector('a-scene')
|
||||||
|
aScene.addEventListener('loaded', () => {
|
||||||
|
|
||||||
// enable XR fragments
|
// enable XR fragments
|
||||||
let aScene = document.querySelector('a-scene')
|
|
||||||
let XRF = AFRAME.XRF = xrf.init({
|
let XRF = AFRAME.XRF = xrf.init({
|
||||||
THREE,
|
THREE,
|
||||||
camera: aScene.camera,
|
camera: aScene.camera,
|
||||||
|
|
@ -2652,6 +2647,12 @@ window.AFRAME.registerComponent('xrf', {
|
||||||
})
|
})
|
||||||
if( !XRF.camera ) throw 'xrfragment: no camera detected, please declare <a-entity camera..> ABOVE entities with xrf-attributes'
|
if( !XRF.camera ) throw 'xrfragment: no camera detected, please declare <a-entity camera..> ABOVE entities with xrf-attributes'
|
||||||
|
|
||||||
|
// this is just for convenience (not part of spec): hide/show stuff based on VR/AR tags in 3D model
|
||||||
|
ARbutton = document.querySelector('.a-enter-ar-button')
|
||||||
|
VRbutton = document.querySelector('.a-enter-vr-button')
|
||||||
|
if( ARbutton ) ARbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#AR' ) )
|
||||||
|
if( VRbutton ) VRbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#VR' ) )
|
||||||
|
|
||||||
xrf.addEventListener('navigateLoaded', () => {
|
xrf.addEventListener('navigateLoaded', () => {
|
||||||
setTimeout( () => AFRAME.fade.out(),500)
|
setTimeout( () => AFRAME.fade.out(),500)
|
||||||
|
|
||||||
|
|
|
||||||
21606
dist/xrfragment.module.js
vendored
21606
dist/xrfragment.module.js
vendored
File diff suppressed because it is too large
Load diff
21
dist/xrfragment.three.js
vendored
21
dist/xrfragment.three.js
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* v0.5.1 generated at Thu Dec 7 10:14:06 PM CET 2023
|
* v0.5.1 generated at Fri Dec 8 01:31:41 PM CET 2023
|
||||||
* https://xrfragment.org
|
* https://xrfragment.org
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|
@ -778,7 +778,8 @@ let pub = function( url, model, flags ){ // evaluate fragments in url
|
||||||
return frag
|
return frag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) inside mesh of model
|
// deprecated: (XR Macros) evaluate embedded fragments (metadata) inside mesh of model *REMOVEME*
|
||||||
|
pub.mesh = (mesh,model) => {
|
||||||
if( mesh.userData ){
|
if( mesh.userData ){
|
||||||
let frag = {}
|
let frag = {}
|
||||||
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
||||||
|
|
@ -786,7 +787,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
let opts = {frag, mesh, model, camera: xrf.camera, scene: model.scene, renderer: xrf.renderer, THREE: xrf.THREE, hashbus: xrf.hashbus }
|
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
|
mesh.userData.XRF = frag // allow fragment impl to access XRF obj already
|
||||||
xrf.emit('frag2mesh',opts)
|
xrf.emit('frag2mesh',opts)
|
||||||
.then( () => pub.fragment(k,opts) )
|
.then( () => pub.fragment(k, {...opts, skipXRWG:true}) )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -794,7 +795,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
pub.fragment = (k, opts ) => { // evaluate one fragment
|
pub.fragment = (k, opts ) => { // evaluate one fragment
|
||||||
let frag = opts.frag[k];
|
let frag = opts.frag[k];
|
||||||
|
|
||||||
if( frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG({...opts,frag})
|
if( !opts.skipXRWG && frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG(opts)
|
||||||
|
|
||||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||||
xrf.emit(k,opts)
|
xrf.emit(k,opts)
|
||||||
|
|
@ -986,9 +987,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: 2. init metadata
|
// spec: 2. init metadata
|
||||||
// spec: predefined view(s) from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
||||||
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
hashbus.pub.XRWG({model,scene:model.scene,frag})
|
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.navigator.updateHash(hash)
|
xrf.navigator.updateHash(hash)
|
||||||
|
|
@ -1783,22 +1783,17 @@ xrf.frag.defaultPredefinedViews = (opts) => {
|
||||||
if( n.userData && n.userData['#'] ){
|
if( n.userData && n.userData['#'] ){
|
||||||
let frag = xrf.URI.parse( n.userData['#'] )
|
let frag = xrf.URI.parse( n.userData['#'] )
|
||||||
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
||||||
xrf.hashbus.pub.XRWG({frag,model,scene}) // evaluate dynamic XR fragment using XRWG (see spec)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// react to enduser typing url
|
// react to enduser typing url
|
||||||
xrf.addEventListener('hash', (opts) => {
|
xrf.addEventListener('hash', (opts) => xrf.hashbus.pub( opts.hash ) )
|
||||||
let frag = xrf.URI.parse( opts.hash )
|
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene})
|
|
||||||
})
|
|
||||||
|
|
||||||
// clicking href url with predefined view
|
// clicking href url with predefined view
|
||||||
xrf.addEventListener('href', (opts) => {
|
xrf.addEventListener('href', (opts) => {
|
||||||
if( !opts.click || opts.xrf.string[0] != '#' ) return
|
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.hashbus.pub( opts.xrf.string )
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene,href:opts.xrf})
|
|
||||||
})
|
})
|
||||||
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
||||||
let {scene,match,v} = opts
|
let {scene,match,v} = opts
|
||||||
|
|
|
||||||
21
dist/xrfragment.three.module.js
vendored
21
dist/xrfragment.three.module.js
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* v0.5.1 generated at Thu Dec 7 10:14:06 PM CET 2023
|
* v0.5.1 generated at Fri Dec 8 01:31:41 PM CET 2023
|
||||||
* https://xrfragment.org
|
* https://xrfragment.org
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|
@ -778,7 +778,8 @@ let pub = function( url, model, flags ){ // evaluate fragments in url
|
||||||
return frag
|
return frag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) inside mesh of model
|
// deprecated: (XR Macros) evaluate embedded fragments (metadata) inside mesh of model *REMOVEME*
|
||||||
|
pub.mesh = (mesh,model) => {
|
||||||
if( mesh.userData ){
|
if( mesh.userData ){
|
||||||
let frag = {}
|
let frag = {}
|
||||||
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
||||||
|
|
@ -786,7 +787,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
let opts = {frag, mesh, model, camera: xrf.camera, scene: model.scene, renderer: xrf.renderer, THREE: xrf.THREE, hashbus: xrf.hashbus }
|
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
|
mesh.userData.XRF = frag // allow fragment impl to access XRF obj already
|
||||||
xrf.emit('frag2mesh',opts)
|
xrf.emit('frag2mesh',opts)
|
||||||
.then( () => pub.fragment(k,opts) )
|
.then( () => pub.fragment(k, {...opts, skipXRWG:true}) )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -794,7 +795,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
pub.fragment = (k, opts ) => { // evaluate one fragment
|
pub.fragment = (k, opts ) => { // evaluate one fragment
|
||||||
let frag = opts.frag[k];
|
let frag = opts.frag[k];
|
||||||
|
|
||||||
if( frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG({...opts,frag})
|
if( !opts.skipXRWG && frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG(opts)
|
||||||
|
|
||||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||||
xrf.emit(k,opts)
|
xrf.emit(k,opts)
|
||||||
|
|
@ -986,9 +987,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: 2. init metadata
|
// spec: 2. init metadata
|
||||||
// spec: predefined view(s) from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
||||||
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
hashbus.pub.XRWG({model,scene:model.scene,frag})
|
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.navigator.updateHash(hash)
|
xrf.navigator.updateHash(hash)
|
||||||
|
|
@ -1783,22 +1783,17 @@ xrf.frag.defaultPredefinedViews = (opts) => {
|
||||||
if( n.userData && n.userData['#'] ){
|
if( n.userData && n.userData['#'] ){
|
||||||
let frag = xrf.URI.parse( n.userData['#'] )
|
let frag = xrf.URI.parse( n.userData['#'] )
|
||||||
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
||||||
xrf.hashbus.pub.XRWG({frag,model,scene}) // evaluate dynamic XR fragment using XRWG (see spec)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// react to enduser typing url
|
// react to enduser typing url
|
||||||
xrf.addEventListener('hash', (opts) => {
|
xrf.addEventListener('hash', (opts) => xrf.hashbus.pub( opts.hash ) )
|
||||||
let frag = xrf.URI.parse( opts.hash )
|
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene})
|
|
||||||
})
|
|
||||||
|
|
||||||
// clicking href url with predefined view
|
// clicking href url with predefined view
|
||||||
xrf.addEventListener('href', (opts) => {
|
xrf.addEventListener('href', (opts) => {
|
||||||
if( !opts.click || opts.xrf.string[0] != '#' ) return
|
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.hashbus.pub( opts.xrf.string )
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene,href:opts.xrf})
|
|
||||||
})
|
})
|
||||||
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
xrf.addEventListener('dynamicKeyValue', (opts) => {
|
||||||
let {scene,match,v} = opts
|
let {scene,match,v} = opts
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>AFRAME - xrfragment sandbox</title>
|
<title>XR Fragments aframe viewer</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
<textarea style="display:none"></textarea>
|
<textarea style="display:none"></textarea>
|
||||||
<canvas id="qrcode" style="display:none" width="300" height="300"></canvas>
|
<canvas id="qrcode" style="display:none" width="300" height="300"></canvas>
|
||||||
|
|
||||||
<a-scene renderer="colorManagement: true; highRefreshRate:true" light="defaultLightsEnabled: false">
|
<a-scene xr-mode-ui="XRMode: xr" renderer="colorManagement: true; highRefreshRate:true" light="defaultLightsEnabled: false">
|
||||||
<a-entity id="player">
|
<a-entity id="player">
|
||||||
<a-entity camera="fov:90" position="0 1.6 0" wasd-controls look-controls id="camera"></a-entity>
|
<a-entity camera="fov:90" position="0 1.6 0" wasd-controls look-controls id="camera"></a-entity>
|
||||||
<a-entity id="left-hand" laser-controls="hand: left" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor">
|
<a-entity id="left-hand" laser-controls="hand: left" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor">
|
||||||
|
|
|
||||||
7
make
7
make
|
|
@ -140,13 +140,14 @@ repos(){
|
||||||
echo " "
|
echo " "
|
||||||
}
|
}
|
||||||
|
|
||||||
release_dir aframe xrfragment-aframe-helloworld aframe
|
release_dir aframe xrfragment-aframe-helloworld
|
||||||
release_dir three xrfragment-three-helloworld three.module
|
release_dir three xrfragment-three-helloworld
|
||||||
release_dir aframe xrfragment-helloworld aframe.all
|
release_dir aframe xrfragment-helloworld
|
||||||
|
|
||||||
# remove aframe reference
|
# remove aframe reference
|
||||||
sed -i 's|<script src="https:\/\/aframe.*||g' ../xrfragment-helloworld/index.html
|
sed -i 's|<script src="https:\/\/aframe.*||g' ../xrfragment-helloworld/index.html
|
||||||
sed -i 's|<script src=".*blink-controls.*||g' ../xrfragment-helloworld/index.html
|
sed -i 's|<script src=".*blink-controls.*||g' ../xrfragment-helloworld/index.html
|
||||||
|
sed -i 's|aframe\.js|aframe.all.js|g' ../xrfragment-helloworld/index.html
|
||||||
}
|
}
|
||||||
|
|
||||||
test -z $1 && build
|
test -z $1 && build
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ window.AFRAME.registerComponent('xrf', {
|
||||||
|
|
||||||
if( document.location.host.match(/localhost/) ) document.querySelector('a-scene').setAttribute("stats",'')
|
if( document.location.host.match(/localhost/) ) document.querySelector('a-scene').setAttribute("stats",'')
|
||||||
|
|
||||||
document.querySelector('a-scene').addEventListener('loaded', () => {
|
let aScene = document.querySelector('a-scene')
|
||||||
|
aScene.addEventListener('loaded', () => {
|
||||||
|
|
||||||
// enable XR fragments
|
// enable XR fragments
|
||||||
let aScene = document.querySelector('a-scene')
|
|
||||||
let XRF = AFRAME.XRF = xrf.init({
|
let XRF = AFRAME.XRF = xrf.init({
|
||||||
THREE,
|
THREE,
|
||||||
camera: aScene.camera,
|
camera: aScene.camera,
|
||||||
|
|
@ -27,6 +27,12 @@ window.AFRAME.registerComponent('xrf', {
|
||||||
})
|
})
|
||||||
if( !XRF.camera ) throw 'xrfragment: no camera detected, please declare <a-entity camera..> ABOVE entities with xrf-attributes'
|
if( !XRF.camera ) throw 'xrfragment: no camera detected, please declare <a-entity camera..> ABOVE entities with xrf-attributes'
|
||||||
|
|
||||||
|
// this is just for convenience (not part of spec): hide/show stuff based on VR/AR tags in 3D model
|
||||||
|
ARbutton = document.querySelector('.a-enter-ar-button')
|
||||||
|
VRbutton = document.querySelector('.a-enter-vr-button')
|
||||||
|
if( ARbutton ) ARbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#AR' ) )
|
||||||
|
if( VRbutton ) VRbutton.addEventListener('click', () => AFRAME.XRF.hashbus.pub( '#VR' ) )
|
||||||
|
|
||||||
xrf.addEventListener('navigateLoaded', () => {
|
xrf.addEventListener('navigateLoaded', () => {
|
||||||
setTimeout( () => AFRAME.fade.out(),500)
|
setTimeout( () => AFRAME.fade.out(),500)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ let pub = function( url, model, flags ){ // evaluate fragments in url
|
||||||
return frag
|
return frag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) inside mesh of model
|
// deprecated: (XR Macros) evaluate embedded fragments (metadata) inside mesh of model *REMOVEME*
|
||||||
|
pub.mesh = (mesh,model) => {
|
||||||
if( mesh.userData ){
|
if( mesh.userData ){
|
||||||
let frag = {}
|
let frag = {}
|
||||||
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
for( let k in mesh.userData ) xrf.Parser.parse( k, mesh.userData[k], frag )
|
||||||
|
|
@ -27,7 +28,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
let opts = {frag, mesh, model, camera: xrf.camera, scene: model.scene, renderer: xrf.renderer, THREE: xrf.THREE, hashbus: xrf.hashbus }
|
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
|
mesh.userData.XRF = frag // allow fragment impl to access XRF obj already
|
||||||
xrf.emit('frag2mesh',opts)
|
xrf.emit('frag2mesh',opts)
|
||||||
.then( () => pub.fragment(k,opts) )
|
.then( () => pub.fragment(k, {...opts, skipXRWG:true}) )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +36,7 @@ pub.mesh = (mesh,model) => { // evaluate embedded fragments (metadata) insid
|
||||||
pub.fragment = (k, opts ) => { // evaluate one fragment
|
pub.fragment = (k, opts ) => { // evaluate one fragment
|
||||||
let frag = opts.frag[k];
|
let frag = opts.frag[k];
|
||||||
|
|
||||||
if( frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG({...opts,frag})
|
if( !opts.skipXRWG && frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG(opts)
|
||||||
|
|
||||||
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
// call native function (xrf/env.js e.g.), or pass it to user decorator
|
||||||
xrf.emit(k,opts)
|
xrf.emit(k,opts)
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: 2. init metadata
|
// spec: 2. init metadata
|
||||||
// spec: predefined view(s) from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
||||||
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
hashbus.pub.XRWG({model,scene:model.scene,frag})
|
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
xrf.navigator.updateHash(hash)
|
xrf.navigator.updateHash(hash)
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,15 @@ xrf.frag.defaultPredefinedViews = (opts) => {
|
||||||
if( n.userData && n.userData['#'] ){
|
if( n.userData && n.userData['#'] ){
|
||||||
let frag = xrf.URI.parse( n.userData['#'] )
|
let frag = xrf.URI.parse( n.userData['#'] )
|
||||||
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
xrf.hashbus.pub( n.userData['#'] ) // evaluate static XR fragments
|
||||||
xrf.hashbus.pub.XRWG({frag,model,scene}) // evaluate dynamic XR fragment using XRWG (see spec)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// react to enduser typing url
|
// react to enduser typing url
|
||||||
xrf.addEventListener('hash', (opts) => {
|
xrf.addEventListener('hash', (opts) => xrf.hashbus.pub( opts.hash ) )
|
||||||
let frag = xrf.URI.parse( opts.hash )
|
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene})
|
|
||||||
})
|
|
||||||
|
|
||||||
// clicking href url with predefined view
|
// clicking href url with predefined view
|
||||||
xrf.addEventListener('href', (opts) => {
|
xrf.addEventListener('href', (opts) => {
|
||||||
if( !opts.click || opts.xrf.string[0] != '#' ) return
|
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.hashbus.pub( opts.xrf.string )
|
||||||
xrf.hashbus.pub.XRWG({frag,scene:xrf.scene,href:opts.xrf})
|
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
xrf.frag.t = function(v, opts){
|
xrf.frag.t = function(v, opts){
|
||||||
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
|
||||||
if( !model.mixer ) return
|
if( !model.mixer ) return
|
||||||
if( !model.animations || model.animations[0] == undefined ) return console.warn('no animation in scene')
|
if( !model.animations || model.animations[0] == undefined ){
|
||||||
|
console.warn('no animations found in model')
|
||||||
|
return xrf.emit( v.x == 0 ? 'stop' : 'play',{isPlaying: v.x != 0 })
|
||||||
|
}
|
||||||
|
|
||||||
xrf.mixers.map ( (mixer) => {
|
xrf.mixers.map ( (mixer) => {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue