better gyroscope + touchsupport
This commit is contained in:
parent
720b17f75c
commit
f508d1e262
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Wed Jun 12 08:50:44 AM UTC 2024
|
||||
* v0.5.1 generated at Sat Jun 15 05:22:38 PM CEST 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
@ -1942,6 +1942,39 @@ xrf.parseModel = function(model,url){
|
|||
xrf.emit('parseModel',{model,url,file})
|
||||
}
|
||||
|
||||
xrf.loadModel = function(model,url,noadd){
|
||||
let URI = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let {directory,file,fragment,fileExt} = URI;
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
if( !noadd ) xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
}
|
||||
|
||||
|
||||
xrf.parseModel.metadataInMesh = (mesh,model) => {
|
||||
if( mesh.userData ){
|
||||
let frag = {}
|
||||
|
@ -2065,34 +2098,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
|
||||
loader = loader || new Loader().setPath( URI.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
xrf.loadModel(model,url)
|
||||
resolve(model)
|
||||
}
|
||||
|
||||
|
@ -2996,6 +3002,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
element.addEventListener( 'mousemove', onPointerEvent );
|
||||
element.addEventListener( 'click', onPointerEvent );
|
||||
element.addEventListener( 'mouseup', onPointerEvent );
|
||||
element.addEventListener( 'touchstart', onPointerEvent );
|
||||
|
||||
// WebXR Controller Events
|
||||
// TODO: Dispatch pointerevents too
|
||||
|
@ -3003,6 +3010,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
const eventsMapper = {
|
||||
'move': 'mousemove',
|
||||
'select': 'click',
|
||||
'touchstart': 'click',
|
||||
'selectstart': 'mousedown',
|
||||
'selectend': 'mouseup'
|
||||
};
|
||||
|
@ -3951,7 +3959,7 @@ xrf.portalNonEuclidian = function(opts){
|
|||
if( mesh.userData.XRF.href ){
|
||||
raycaster.far = 0.35
|
||||
raycaster.set(cameraPosition, cameraDirection )
|
||||
intersects = raycaster.intersectObjects([mesh], false)
|
||||
let intersects = raycaster.intersectObjects([mesh], false)
|
||||
if (intersects.length > 0 && !mesh.portal.teleporting ){
|
||||
mesh.portal.teleporting = true
|
||||
mesh.userData.XRF.href.exec({nocommit:true})
|
||||
|
@ -4847,7 +4855,7 @@ AFRAME.registerComponent('xrf-gaze',{
|
|||
}
|
||||
},
|
||||
setGazer: function(state, fuse){
|
||||
if( !AFRAME.utils.device.isMobile() ) return
|
||||
if( this.el.sceneEl.getAttribute("xrf-gaze-always") == undefined && !AFRAME.utils.device.isMobile() ) return
|
||||
let cam = document.querySelector("[camera]")
|
||||
if( state ){
|
||||
if( cam.innerHTML.match(/cursor/) ) return; // avoid duplicate calls
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Wed Jun 12 08:50:44 AM UTC 2024
|
||||
* v0.5.1 generated at Sat Jun 15 05:22:37 PM CEST 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
@ -1940,6 +1940,39 @@ xrf.parseModel = function(model,url){
|
|||
xrf.emit('parseModel',{model,url,file})
|
||||
}
|
||||
|
||||
xrf.loadModel = function(model,url,noadd){
|
||||
let URI = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let {directory,file,fragment,fileExt} = URI;
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
if( !noadd ) xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
}
|
||||
|
||||
|
||||
xrf.parseModel.metadataInMesh = (mesh,model) => {
|
||||
if( mesh.userData ){
|
||||
let frag = {}
|
||||
|
@ -2063,34 +2096,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
|
||||
loader = loader || new Loader().setPath( URI.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
xrf.loadModel(model,url)
|
||||
resolve(model)
|
||||
}
|
||||
|
||||
|
@ -2994,6 +3000,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
element.addEventListener( 'mousemove', onPointerEvent );
|
||||
element.addEventListener( 'click', onPointerEvent );
|
||||
element.addEventListener( 'mouseup', onPointerEvent );
|
||||
element.addEventListener( 'touchstart', onPointerEvent );
|
||||
|
||||
// WebXR Controller Events
|
||||
// TODO: Dispatch pointerevents too
|
||||
|
@ -3001,6 +3008,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
const eventsMapper = {
|
||||
'move': 'mousemove',
|
||||
'select': 'click',
|
||||
'touchstart': 'click',
|
||||
'selectstart': 'mousedown',
|
||||
'selectend': 'mouseup'
|
||||
};
|
||||
|
@ -3949,7 +3957,7 @@ xrf.portalNonEuclidian = function(opts){
|
|||
if( mesh.userData.XRF.href ){
|
||||
raycaster.far = 0.35
|
||||
raycaster.set(cameraPosition, cameraDirection )
|
||||
intersects = raycaster.intersectObjects([mesh], false)
|
||||
let intersects = raycaster.intersectObjects([mesh], false)
|
||||
if (intersects.length > 0 && !mesh.portal.teleporting ){
|
||||
mesh.portal.teleporting = true
|
||||
mesh.userData.XRF.href.exec({nocommit:true})
|
||||
|
@ -4845,7 +4853,7 @@ AFRAME.registerComponent('xrf-gaze',{
|
|||
}
|
||||
},
|
||||
setGazer: function(state, fuse){
|
||||
if( !AFRAME.utils.device.isMobile() ) return
|
||||
if( this.el.sceneEl.getAttribute("xrf-gaze-always") == undefined && !AFRAME.utils.device.isMobile() ) return
|
||||
let cam = document.querySelector("[camera]")
|
||||
if( state ){
|
||||
if( cam.innerHTML.match(/cursor/) ) return; // avoid duplicate calls
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -357,7 +357,7 @@ window.accessibility = (opts) => new Proxy({
|
|||
|
||||
setTimeout( () => this.initCommands(), 200 )
|
||||
// auto-enable if previously enabled
|
||||
if( window.localStorage.getItem("accessibility") === 'true' ){
|
||||
if( window.localStorage.getItem("accessibility") === 'true' || xrf.navigator.URI.XRF.accessible ){
|
||||
setTimeout( () => {
|
||||
this.enabled = true
|
||||
this.setFontSize()
|
||||
|
@ -437,7 +437,6 @@ window.accessibility = (opts) => new Proxy({
|
|||
switch( k ){
|
||||
case "enabled": {
|
||||
let message = "accessibility mode has been "+(v?"activated":"disabled")+".<br>Type /help for help."
|
||||
if( v ) message = "<img src='https://i.imgur.com/wedtUSs.png' style='width:100%;border-radius:6px'/><br>" + message
|
||||
$('#accessibility.btn').style.filter= v ? 'brightness(1.0)' : 'brightness(0.5)'
|
||||
if( v ) $chat.visible = true
|
||||
$chat.send({message,class:['info']})
|
||||
|
@ -467,8 +466,8 @@ document.addEventListener('$menu:ready', (e) => {
|
|||
document.querySelector('head').innerHTML += `
|
||||
<style type="text/css">
|
||||
.accessibility #messages * {
|
||||
font-size:24px !important;
|
||||
line-height:40px;
|
||||
font-size:20px !important;
|
||||
line-height:35px;
|
||||
}
|
||||
.accessibility #messages .msg.self {
|
||||
background:var(--xrf-gray);
|
||||
|
@ -682,8 +681,7 @@ window.frontend = (opts) => new Proxy({
|
|||
let root = data.mesh.portal ? data.mesh.portal.stencilObject : data.mesh
|
||||
let transcript = xrf.sceneToTranscript(root,data.mesh)
|
||||
if( transcript.length ) html += `<br><b>transcript:</b><br><div class="transcript">${transcript}</div>`
|
||||
|
||||
if (hasMeta && !data.mesh.portal ) html += `<br><br><a class="btn" style="float:right" onclick="xrf.navigator.to('${data.mesh.userData.href}')">Visit embedded scene</a>`
|
||||
if (hasMeta && !data.mesh.portal && metadata.XRF.src ) html += `<br><br><a class="btn" style="float:right" onclick="xrf.navigator.to('${data.mesh.userData.href}')">Visit embedded scene</a>`
|
||||
window.notify(html,{timeout: 7000 * (hasMeta ? 1.5 : 1) })
|
||||
})
|
||||
|
||||
|
@ -694,7 +692,6 @@ window.frontend = (opts) => new Proxy({
|
|||
setupNetworkListeners(){
|
||||
|
||||
document.addEventListener('network.connect', (e) => {
|
||||
console.log("network.connect")
|
||||
window.notify("🪐 connecting to awesomeness..")
|
||||
$chat.send({message:`🪐 connecting to awesomeness..`,class:['info'], timeout:5000})
|
||||
})
|
||||
|
|
|
@ -660,8 +660,8 @@ chatComponent.css = `
|
|||
/*
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 91%;
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
max-width: 40%;
|
||||
*/
|
||||
width:100%;
|
||||
box-sizing:border-box;
|
||||
|
@ -816,8 +816,8 @@ chatComponent.css = `
|
|||
|
||||
.envelope{
|
||||
margin-right:15px;
|
||||
width:50%;
|
||||
max-width:700px;
|
||||
width:100%;
|
||||
max-width:40%;
|
||||
}
|
||||
|
||||
.envelope,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Wed Jun 12 08:50:44 AM UTC 2024
|
||||
* v0.5.1 generated at Sat Jun 15 05:22:38 PM CEST 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
@ -1940,6 +1940,39 @@ xrf.parseModel = function(model,url){
|
|||
xrf.emit('parseModel',{model,url,file})
|
||||
}
|
||||
|
||||
xrf.loadModel = function(model,url,noadd){
|
||||
let URI = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let {directory,file,fragment,fileExt} = URI;
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
if( !noadd ) xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
}
|
||||
|
||||
|
||||
xrf.parseModel.metadataInMesh = (mesh,model) => {
|
||||
if( mesh.userData ){
|
||||
let frag = {}
|
||||
|
@ -2063,34 +2096,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
|
||||
loader = loader || new Loader().setPath( URI.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
xrf.loadModel(model,url)
|
||||
resolve(model)
|
||||
}
|
||||
|
||||
|
@ -2994,6 +3000,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
element.addEventListener( 'mousemove', onPointerEvent );
|
||||
element.addEventListener( 'click', onPointerEvent );
|
||||
element.addEventListener( 'mouseup', onPointerEvent );
|
||||
element.addEventListener( 'touchstart', onPointerEvent );
|
||||
|
||||
// WebXR Controller Events
|
||||
// TODO: Dispatch pointerevents too
|
||||
|
@ -3001,6 +3008,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
const eventsMapper = {
|
||||
'move': 'mousemove',
|
||||
'select': 'click',
|
||||
'touchstart': 'click',
|
||||
'selectstart': 'mousedown',
|
||||
'selectend': 'mouseup'
|
||||
};
|
||||
|
@ -3949,7 +3957,7 @@ xrf.portalNonEuclidian = function(opts){
|
|||
if( mesh.userData.XRF.href ){
|
||||
raycaster.far = 0.35
|
||||
raycaster.set(cameraPosition, cameraDirection )
|
||||
intersects = raycaster.intersectObjects([mesh], false)
|
||||
let intersects = raycaster.intersectObjects([mesh], false)
|
||||
if (intersects.length > 0 && !mesh.portal.teleporting ){
|
||||
mesh.portal.teleporting = true
|
||||
mesh.userData.XRF.href.exec({nocommit:true})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* v0.5.1 generated at Wed Jun 12 08:50:44 AM UTC 2024
|
||||
* v0.5.1 generated at Sat Jun 15 05:22:38 PM CEST 2024
|
||||
* https://xrfragment.org
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
@ -1940,6 +1940,39 @@ xrf.parseModel = function(model,url){
|
|||
xrf.emit('parseModel',{model,url,file})
|
||||
}
|
||||
|
||||
xrf.loadModel = function(model,url,noadd){
|
||||
let URI = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let {directory,file,fragment,fileExt} = URI;
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
if( !noadd ) xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
}
|
||||
|
||||
|
||||
xrf.parseModel.metadataInMesh = (mesh,model) => {
|
||||
if( mesh.userData ){
|
||||
let frag = {}
|
||||
|
@ -2063,34 +2096,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
|
||||
loader = loader || new Loader().setPath( URI.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = URI.file
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
// spec: 1. generate the XRWG
|
||||
xrf.XRWG.generate({model,scene:model.scene})
|
||||
|
||||
// spec: 2. init metadata inside model for non-SRC data
|
||||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
const defaultFragment = xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
xrf.add( model.scene )
|
||||
|
||||
// only change url when loading *another* file
|
||||
fragment = fragment || defaultFragment || ''
|
||||
xrf.navigator.pushState( URI.external ? URI.URN + URI.file : URI.file, fragment.replace(/^#/,'') )
|
||||
//if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
xrf.loadModel(model,url)
|
||||
resolve(model)
|
||||
}
|
||||
|
||||
|
@ -2994,6 +3000,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
element.addEventListener( 'mousemove', onPointerEvent );
|
||||
element.addEventListener( 'click', onPointerEvent );
|
||||
element.addEventListener( 'mouseup', onPointerEvent );
|
||||
element.addEventListener( 'touchstart', onPointerEvent );
|
||||
|
||||
// WebXR Controller Events
|
||||
// TODO: Dispatch pointerevents too
|
||||
|
@ -3001,6 +3008,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
const eventsMapper = {
|
||||
'move': 'mousemove',
|
||||
'select': 'click',
|
||||
'touchstart': 'click',
|
||||
'selectstart': 'mousedown',
|
||||
'selectend': 'mouseup'
|
||||
};
|
||||
|
@ -3949,7 +3957,7 @@ xrf.portalNonEuclidian = function(opts){
|
|||
if( mesh.userData.XRF.href ){
|
||||
raycaster.far = 0.35
|
||||
raycaster.set(cameraPosition, cameraDirection )
|
||||
intersects = raycaster.intersectObjects([mesh], false)
|
||||
let intersects = raycaster.intersectObjects([mesh], false)
|
||||
if (intersects.length > 0 && !mesh.portal.teleporting ){
|
||||
mesh.portal.teleporting = true
|
||||
mesh.userData.XRF.href.exec({nocommit:true})
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
<body>
|
||||
<a-scene xr-mode-ui="XRMode: xr"
|
||||
renderer="colorManagement: false; antialias:true; highRefreshRate:true; foveationLevel: 0.5; toneMapping: ACESFilmic; exposure: 3.0"
|
||||
device-orientation-permission-ui
|
||||
light="defaultLightsEnabled: false">
|
||||
<a-entity id="player" movement-controls touch-controls wasd-controls="fly:false" look-controls>
|
||||
<a-entity id="player" movement-controls touch-controls wasd-controls="fly:false" look-controls="magicWindowTrackingEnabled:true">
|
||||
<a-entity camera="fov:90" position="0 1.6 0" id="camera"></a-entity>
|
||||
<a-entity id="left-hand" hand-tracking-grab-controls="hand:left;modelColor:#cccccc" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor">
|
||||
<a-entity rotation="-35 0 0" position="0 0.1 0" id="navigator">
|
||||
|
@ -69,6 +70,7 @@
|
|||
<br><br>
|
||||
`,{timeout:false})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ AFRAME.registerComponent('xrf-gaze',{
|
|||
}
|
||||
},
|
||||
setGazer: function(state, fuse){
|
||||
if( !AFRAME.utils.device.isMobile() ) return
|
||||
if( this.el.sceneEl.getAttribute("xrf-gaze-always") == undefined && !AFRAME.utils.device.isMobile() ) return
|
||||
let cam = document.querySelector("[camera]")
|
||||
if( state ){
|
||||
if( cam.innerHTML.match(/cursor/) ) return; // avoid duplicate calls
|
||||
|
|
|
@ -275,8 +275,8 @@ chatComponent.css = `
|
|||
/*
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 91%;
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
max-width: 40%;
|
||||
*/
|
||||
width:100%;
|
||||
box-sizing:border-box;
|
||||
|
@ -431,8 +431,8 @@ chatComponent.css = `
|
|||
|
||||
.envelope{
|
||||
margin-right:15px;
|
||||
width:50%;
|
||||
max-width:700px;
|
||||
width:100%;
|
||||
max-width:40%;
|
||||
}
|
||||
|
||||
.envelope,
|
||||
|
|
|
@ -105,7 +105,7 @@ window.accessibility = (opts) => new Proxy({
|
|||
|
||||
setTimeout( () => this.initCommands(), 200 )
|
||||
// auto-enable if previously enabled
|
||||
if( window.localStorage.getItem("accessibility") === 'true' ){
|
||||
if( window.localStorage.getItem("accessibility") === 'true' || xrf.navigator.URI.XRF.accessible ){
|
||||
setTimeout( () => {
|
||||
this.enabled = true
|
||||
this.setFontSize()
|
||||
|
@ -185,7 +185,6 @@ window.accessibility = (opts) => new Proxy({
|
|||
switch( k ){
|
||||
case "enabled": {
|
||||
let message = "accessibility mode has been "+(v?"activated":"disabled")+".<br>Type /help for help."
|
||||
if( v ) message = "<img src='https://i.imgur.com/wedtUSs.png' style='width:100%;border-radius:6px'/><br>" + message
|
||||
$('#accessibility.btn').style.filter= v ? 'brightness(1.0)' : 'brightness(0.5)'
|
||||
if( v ) $chat.visible = true
|
||||
$chat.send({message,class:['info']})
|
||||
|
@ -215,8 +214,8 @@ document.addEventListener('$menu:ready', (e) => {
|
|||
document.querySelector('head').innerHTML += `
|
||||
<style type="text/css">
|
||||
.accessibility #messages * {
|
||||
font-size:24px !important;
|
||||
line-height:40px;
|
||||
font-size:20px !important;
|
||||
line-height:35px;
|
||||
}
|
||||
.accessibility #messages .msg.self {
|
||||
background:var(--xrf-gray);
|
||||
|
|
|
@ -122,8 +122,7 @@ window.frontend = (opts) => new Proxy({
|
|||
let root = data.mesh.portal ? data.mesh.portal.stencilObject : data.mesh
|
||||
let transcript = xrf.sceneToTranscript(root,data.mesh)
|
||||
if( transcript.length ) html += `<br><b>transcript:</b><br><div class="transcript">${transcript}</div>`
|
||||
|
||||
if (hasMeta && !data.mesh.portal ) html += `<br><br><a class="btn" style="float:right" onclick="xrf.navigator.to('${data.mesh.userData.href}')">Visit embedded scene</a>`
|
||||
if (hasMeta && !data.mesh.portal && metadata.XRF.src ) html += `<br><br><a class="btn" style="float:right" onclick="xrf.navigator.to('${data.mesh.userData.href}')">Visit embedded scene</a>`
|
||||
window.notify(html,{timeout: 7000 * (hasMeta ? 1.5 : 1) })
|
||||
})
|
||||
|
||||
|
@ -134,7 +133,6 @@ window.frontend = (opts) => new Proxy({
|
|||
setupNetworkListeners(){
|
||||
|
||||
document.addEventListener('network.connect', (e) => {
|
||||
console.log("network.connect")
|
||||
window.notify("🪐 connecting to awesomeness..")
|
||||
$chat.send({message:`🪐 connecting to awesomeness..`,class:['info'], timeout:5000})
|
||||
})
|
||||
|
|
|
@ -85,6 +85,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
element.addEventListener( 'mousemove', onPointerEvent );
|
||||
element.addEventListener( 'click', onPointerEvent );
|
||||
element.addEventListener( 'mouseup', onPointerEvent );
|
||||
element.addEventListener( 'touchstart', onPointerEvent );
|
||||
|
||||
// WebXR Controller Events
|
||||
// TODO: Dispatch pointerevents too
|
||||
|
@ -92,6 +93,7 @@ xrf.interactiveGroup = function(THREE,renderer,camera){
|
|||
const eventsMapper = {
|
||||
'move': 'mousemove',
|
||||
'select': 'click',
|
||||
'touchstart': 'click',
|
||||
'selectstart': 'mousedown',
|
||||
'selectend': 'mouseup'
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue