documentation update: xrsh aria

This commit is contained in:
Leon van Kammen 2025-02-11 18:08:43 +01:00
parent 26123e2833
commit 2bc664af02
16 changed files with 29601 additions and 99 deletions

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,73 @@
/*
* v0.5.1 generated at Tue Feb 11 11:52:02 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:50:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:48:23 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:47:08 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:46:37 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:59 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:48 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:14 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:43:32 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:42:47 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:27:52 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:18:55 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:05:14 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025
* https://xrfragment.org * https://xrfragment.org
@ -2045,7 +2115,6 @@ var xrf = {}
xrf.init = function(opts){ xrf.init = function(opts){
opts = opts || {} opts = opts || {}
xrf.debug = document.location.hostname.match(/^(localhost|[0-9]\.[0-9])/) || document.location.port == '8080' ? 0 : false xrf.debug = document.location.hostname.match(/^(localhost|[0-9]\.[0-9])/) || document.location.port == '8080' ? 0 : false
if( document.location.hash.match(/debug=([0-9])/) ){ if( document.location.hash.match(/debug=([0-9])/) ){
xrf.debug = parseInt( ( document.location.hash.match(/debug=([0-9])/) || [0,'0'] )[1] ) xrf.debug = parseInt( ( document.location.hash.match(/debug=([0-9])/) || [0,'0'] )[1] )
@ -3703,16 +3772,28 @@ xrf.optimize.removeDuplicateLights = () => {
xrf.addEventListener('parseModel', (opts) => { xrf.addEventListener('parseModel', (opts) => {
xrf.optimize(opts) xrf.optimize(opts)
}) })
xrf.sceneToTranscript = (scene, ignoreMesh ) => { xrf.sceneToTranscript = (scene, node, currentPosition ) => {
let transcript = '' let items = []
scene = currentPosition && xrf.frag.pos.last ? xrf.scene.getObjectByName(xrf.frag.pos.last) : (scene || xrf.scene)
scene.traverse( (n) => { scene.traverse( (n) => {
let isSRC = false let isSRC = false
n.traverseAncestors( (m) => m.userData.src ? isSRC = true : false ) n.traverseAncestors( (m) => m.userData.src ? isSRC = true : false )
if( !isSRC && n.userData['aria-description'] && (!ignoreMesh || n.uuid != ignoreMesh.uuid) ){ if( !isSRC && n.userData['aria-description'] && (!node || n.uuid != node.uuid) ){
transcript += `<b>#${n.name}</b> ${n.userData['aria-description']}. ` items.push({name: n.name, description: n.userData['aria-description']})
} }
}) })
return transcript return items
}
xrf.listExits = (scene, currentPosition ) => {
let destinations = []
scene = currentPosition && xrf.frag.pos.last ? xrf.scene.getObjectByName(xrf.frag.pos.last) : scene || xrf.scene
scene.traverse( (n) => {
if( n.userData && n.userData.href && n.userData.href.match(/pos=/) ){
destinations.push({name: n.name, destination: n.userData['aria-label'] || n.userData.href})
}
})
return destinations
} }
// switch camera when multiple cameras for url #mycameraname // switch camera when multiple cameras for url #mycameraname
@ -5595,6 +5676,7 @@ AFRAME.registerSystem('xrf-hands',{
// wait for bones get initialized // wait for bones get initialized
setTimeout( () => { setTimeout( () => {
let bones = handEl.components['hand-tracking-controls'].bones let bones = handEl.components['hand-tracking-controls'].bones
if( !bones ) return // dont bother
let indexFinger let indexFinger
for( let j = 0; j < bones.length; j++){ for( let j = 0; j < bones.length; j++){
if( bones[j].name == "index-finger-tip" ){ if( bones[j].name == "index-finger-tip" ){

70
dist/xrfragment.js vendored
View file

@ -1,3 +1,73 @@
/*
* v0.5.1 generated at Tue Feb 11 11:52:02 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:50:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:48:23 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:47:08 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:46:37 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:59 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:48 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:14 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:43:32 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:42:47 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:27:52 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:18:55 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:05:14 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025
* https://xrfragment.org * https://xrfragment.org

File diff suppressed because one or more lines are too long

28973
dist/xrfragment.module.js vendored

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Tue Feb 11 11:52:02 AM CET 2025
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Tue Feb 11 11:52:02 AM CET 2025
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Tue Feb 11 11:52:02 AM CET 2025
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */
@ -374,9 +374,9 @@ window.accessibility = (opts) => new Proxy({
notify(`${n.userData['aria-description']||''}` + (n.userData.href ? `<br><b>name:</b> ${n.name}<br><b>href:</b> ${n.userData['href']}` :'') ) notify(`${n.userData['aria-description']||''}` + (n.userData.href ? `<br><b>name:</b> ${n.name}<br><b>href:</b> ${n.userData['href']}` :'') )
} }
if( e.key == 'Enter' && objects[cache.current].userData.href ){ //if( e.key == 'Enter' && objects[cache.current]?.userData.href ){
xrf.navigator.to( objects[cache.current].userData.href ) // xrf.navigator.to( objects[cache.current].userData.href )
} //}
// increment to next // increment to next
cache.current = (cache.current + 1) % objects.length cache.current = (cache.current + 1) % objects.length
@ -770,7 +770,13 @@ window.frontend = (opts) => new Proxy({
} }
let root = data.mesh.portal ? data.mesh.portal.stencilObject : data.mesh let root = data.mesh.portal ? data.mesh.portal.stencilObject : data.mesh
let transcript = xrf.sceneToTranscript(root,data.mesh) let transcript = xrf.sceneToTranscript(root,data.mesh)
if( transcript.length ) html += `<br><b>transcript:</b><br><div class="transcript">${transcript}</div>` console.dir(transcript)
if( transcript.length ){
transcript = xrf.sceneToTranscript(false,false,true)
.map( (n) => `<b>${n.name}</b> ${n.description}` )
.join(". ")
html += `<br><b>transcript:</b><br><div class="transcript">${transcript}</div>`
}
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>` 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>`
if( !html ) return if( !html ) return
@ -1049,12 +1055,7 @@ document.addEventListener('chat.command.help', (e) => {
const listExits = (scene) => { const listExits = (scene) => {
let message = '' let message = ''
let destinations = {} let destinations = xrf.sceneListExits(scene, true)
scene.traverse( (n) => {
if( n.userData && n.userData.href && n.userData.href.match(/pos=/) ){
destinations[n.name] = n.userData['aria-label'] || n.userData.href
}
})
for( let destination in destinations ){ for( let destination in destinations ){
message += `<br><b class="badge">${destination}</b> ${destinations[destination]}` message += `<br><b class="badge">${destination}</b> ${destinations[destination]}`
} }
@ -1085,8 +1086,13 @@ document.addEventListener('chat.input', (e) => {
} }
if( e.detail.message.trim() == 'look' ){ if( e.detail.message.trim() == 'look' ){
let scene = xrf.frag.pos.last ? xrf.scene.getObjectByName(xrf.frag.pos.last) : xrf.scene let transcript = xrf.sceneToTranscript(false,false,true)
let message = `<div class="transcript">${xrf.sceneToTranscript(scene)}</div><br>possible destinations in this area:${listExits(scene)}` .map( (n) => `<b>${n.name}</b> ${n.description}` )
.join(". ")
let exits = xrf.listExits(false,true)
.map( (n) => `<b>${n.name}</b>` )
.join("<br>")
let message = `<div class="transcript">${transcript}</div><br>possible destinations in this area:<br>${exits}`
e.detail.halt = true // dont print command to screen e.detail.halt = true // dont print command to screen
$chat.send({message}) $chat.send({message})
} }
@ -1276,4 +1282,56 @@ function createJoystick() {
} }
} }
}); });
window.hrefCycle = (e) => {
if( !xrf || !xrf.scene || e.key != "Tab" && e.key != "Enter" ) return
console.log("ja")
let subScene = xrf.scene.getObjectByName( xrf.frag.pos.last )
if( !subScene ) subScene = xrf.scene
let cache = window.hrefCycle.cache = window.hrefCycle.cache || {current: -1}
let objects = []
subScene.traverse( (n) => (n.userData.href || n.userData['aria-description']) && objects.push(n) )
const highlight = (n) => {
if( this.helper){
if( this.helper.selected == n.uuid ) return // already selected
xrf.scene.remove(this.helper)
}
this.selected = n
this.helper = new THREE.BoxHelper( n, 0xFF00FF )
this.helper.computeLineDistances()
this.helper.material.linewidth = 8
this.helper.material.color = xrf.focusLine.material.color
this.helper.material.dashSize = xrf.focusLine.material.dashSize
this.helper.material.gapSize = xrf.focusLine.material.gapSize
this.helper.selected = n.uuid
xrf.scene.add(this.helper)
const isAction = n.userData.href
if( typeof notify != 'undefined'){
notify(`${n.userData['aria-description']||''}` + (n.userData.href ? `<br><b>name:</b> ${n.name}<br><b>href:</b> ${n.userData['href']}` :'') )
}
if( typeof term != 'undefined'){
term.send(`\n\r${isAction?'press enter for option ':''}${n.userData['aria-description']||n.userData['aria-label']||n.name}`)
}
}
if( e.key == 'Enter' && objects[cache.current]?.userData.href ){
xrf.navigator.to( objects[cache.current].userData.href )
}
// increment to next
cache.current = (cache.current + 1) % objects.length
if( e.key == 'Tab'){
highlight( objects[cache.current] )
}
e.preventDefault()
return false
}
window.addEventListener('keydown', window.hrefCycle )
}).apply({}) }).apply({})

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Tue Feb 11 11:52:03 AM CET 2025
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Tue Feb 11 11:52:03 AM CET 2025
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */
@ -652,6 +652,7 @@ chatComponent.css = `
max-width: 20px; max-width: 20px;
border-radius: 20px 0px 0px 20px; border-radius: 20px 0px 0px 20px;
overflow: hidden; overflow: hidden;
margin:0;
} }
#chatbar input{ #chatbar input{
border:none; border:none;

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Tue Feb 11 11:52:03 AM CET 2025
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */

View file

@ -1,3 +1,73 @@
/*
* v0.5.1 generated at Tue Feb 11 11:52:03 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:50:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:48:23 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:47:08 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:46:37 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:59 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:48 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:14 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:43:32 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:42:47 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:27:52 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:18:55 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:05:14 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025
* https://xrfragment.org * https://xrfragment.org
@ -2045,7 +2115,6 @@ var xrf = {}
xrf.init = function(opts){ xrf.init = function(opts){
opts = opts || {} opts = opts || {}
xrf.debug = document.location.hostname.match(/^(localhost|[0-9]\.[0-9])/) || document.location.port == '8080' ? 0 : false xrf.debug = document.location.hostname.match(/^(localhost|[0-9]\.[0-9])/) || document.location.port == '8080' ? 0 : false
if( document.location.hash.match(/debug=([0-9])/) ){ if( document.location.hash.match(/debug=([0-9])/) ){
xrf.debug = parseInt( ( document.location.hash.match(/debug=([0-9])/) || [0,'0'] )[1] ) xrf.debug = parseInt( ( document.location.hash.match(/debug=([0-9])/) || [0,'0'] )[1] )
@ -3703,16 +3772,28 @@ xrf.optimize.removeDuplicateLights = () => {
xrf.addEventListener('parseModel', (opts) => { xrf.addEventListener('parseModel', (opts) => {
xrf.optimize(opts) xrf.optimize(opts)
}) })
xrf.sceneToTranscript = (scene, ignoreMesh ) => { xrf.sceneToTranscript = (scene, node, currentPosition ) => {
let transcript = '' let items = []
scene = currentPosition && xrf.frag.pos.last ? xrf.scene.getObjectByName(xrf.frag.pos.last) : (scene || xrf.scene)
scene.traverse( (n) => { scene.traverse( (n) => {
let isSRC = false let isSRC = false
n.traverseAncestors( (m) => m.userData.src ? isSRC = true : false ) n.traverseAncestors( (m) => m.userData.src ? isSRC = true : false )
if( !isSRC && n.userData['aria-description'] && (!ignoreMesh || n.uuid != ignoreMesh.uuid) ){ if( !isSRC && n.userData['aria-description'] && (!node || n.uuid != node.uuid) ){
transcript += `<b>#${n.name}</b> ${n.userData['aria-description']}. ` items.push({name: n.name, description: n.userData['aria-description']})
} }
}) })
return transcript return items
}
xrf.listExits = (scene, currentPosition ) => {
let destinations = []
scene = currentPosition && xrf.frag.pos.last ? xrf.scene.getObjectByName(xrf.frag.pos.last) : scene || xrf.scene
scene.traverse( (n) => {
if( n.userData && n.userData.href && n.userData.href.match(/pos=/) ){
destinations.push({name: n.name, destination: n.userData['aria-label'] || n.userData.href})
}
})
return destinations
} }
// switch camera when multiple cameras for url #mycameraname // switch camera when multiple cameras for url #mycameraname

View file

@ -1,3 +1,73 @@
/*
* v0.5.1 generated at Tue Feb 11 11:52:03 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:50:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:48:23 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:47:08 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:46:37 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:59 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:48 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:30 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:44:14 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:43:32 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:42:47 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Tue Feb 11 11:27:52 AM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:18:55 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/*
* v0.5.1 generated at Mon Feb 10 08:05:14 PM CET 2025
* https://xrfragment.org
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/* /*
* v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025 * v0.5.1 generated at Sun Feb 9 12:52:39 PM CET 2025
* https://xrfragment.org * https://xrfragment.org
@ -2045,7 +2115,6 @@ var xrf = {}
xrf.init = function(opts){ xrf.init = function(opts){
opts = opts || {} opts = opts || {}
xrf.debug = document.location.hostname.match(/^(localhost|[0-9]\.[0-9])/) || document.location.port == '8080' ? 0 : false xrf.debug = document.location.hostname.match(/^(localhost|[0-9]\.[0-9])/) || document.location.port == '8080' ? 0 : false
if( document.location.hash.match(/debug=([0-9])/) ){ if( document.location.hash.match(/debug=([0-9])/) ){
xrf.debug = parseInt( ( document.location.hash.match(/debug=([0-9])/) || [0,'0'] )[1] ) xrf.debug = parseInt( ( document.location.hash.match(/debug=([0-9])/) || [0,'0'] )[1] )
@ -3703,16 +3772,28 @@ xrf.optimize.removeDuplicateLights = () => {
xrf.addEventListener('parseModel', (opts) => { xrf.addEventListener('parseModel', (opts) => {
xrf.optimize(opts) xrf.optimize(opts)
}) })
xrf.sceneToTranscript = (scene, ignoreMesh ) => { xrf.sceneToTranscript = (scene, node, currentPosition ) => {
let transcript = '' let items = []
scene = currentPosition && xrf.frag.pos.last ? xrf.scene.getObjectByName(xrf.frag.pos.last) : (scene || xrf.scene)
scene.traverse( (n) => { scene.traverse( (n) => {
let isSRC = false let isSRC = false
n.traverseAncestors( (m) => m.userData.src ? isSRC = true : false ) n.traverseAncestors( (m) => m.userData.src ? isSRC = true : false )
if( !isSRC && n.userData['aria-description'] && (!ignoreMesh || n.uuid != ignoreMesh.uuid) ){ if( !isSRC && n.userData['aria-description'] && (!node || n.uuid != node.uuid) ){
transcript += `<b>#${n.name}</b> ${n.userData['aria-description']}. ` items.push({name: n.name, description: n.userData['aria-description']})
} }
}) })
return transcript return items
}
xrf.listExits = (scene, currentPosition ) => {
let destinations = []
scene = currentPosition && xrf.frag.pos.last ? xrf.scene.getObjectByName(xrf.frag.pos.last) : scene || xrf.scene
scene.traverse( (n) => {
if( n.userData && n.userData.href && n.userData.href.match(/pos=/) ){
destinations.push({name: n.name, destination: n.userData['aria-label'] || n.userData.href})
}
})
return destinations
} }
// switch camera when multiple cameras for url #mycameraname // switch camera when multiple cameras for url #mycameraname

View file

@ -45,23 +45,17 @@
const isoterminal = document.querySelector('[isoterminal]').components.isoterminal const isoterminal = document.querySelector('[isoterminal]').components.isoterminal
const sanitizeTranscript = (str) => {
return str
.replaceAll("<[^>]*>", "") // strip html
.split('\n')
.map( (l) => String(l+'.').replace(/(^|:|;|!|\?|\.)\.$/g,'\$1') ) // add dot if needed
.join('. ')
}
const transcriptToText = (t) => t.map( (o) => `${o.name} ${o.description}`).join(" ") const transcriptToText = (t) => t.map( (o) => `${o.name} ${o.description}`).join(" ")
// describe current scene const describeScene = () => {
xrf.addEventListener('navigateLoaded', () => {
let subscene = xrf.frag.pos.last || xrf.navigator.URI.XRF?.pos?.string let subscene = xrf.frag.pos.last || xrf.navigator.URI.XRF?.pos?.string
subscene = subscene ? subscene = xrf.scene.getObjectByName( subscene ) : false subscene = subscene ? subscene = xrf.scene.getObjectByName( subscene ) : false
let transcript = transcriptToText( xrf.sceneToTranscript(subscene) ) let transcript = transcriptToText( xrf.sceneToTranscript(subscene) )
term.send(`\r${transcript}\n\r`) term.send(`\r${transcript}\n\n\r`)
}) }
// describe current scene
xrf.addEventListener('navigateLoaded', () => setTimeout( () => describeScene(),100) )
isoterminal.el.addEventListener('init', () => { isoterminal.el.addEventListener('init', () => {
// clear bootmenu-array // clear bootmenu-array
@ -73,25 +67,32 @@
// describe mouseover button (and scene to be teleported to, if any) // describe mouseover button (and scene to be teleported to, if any)
xrf.addEventListener('href', (e) => { xrf.addEventListener('href', (e) => {
if( typeof e.selected == 'undefined' || !e.mesh ) return; // only process mouse-overs if( !e.selected || !e.mesh ) return; // only process mouse-overs
let name = "object" let name = "object"
let info = "" let info = ""
let subscene = false let subscene = false
if( e.click ){
return setTimeout( () => {
if( lastPos != xrf.frag.pos.last ) return
describeScene()
}, 100 )
lastPos = xrf.frag.pos.last
}
if( e.mesh.userData ){ if( e.mesh.userData ){
if( e.mesh.userData.href && e.mesh.userData.href.match("pos=") ){ if( e.mesh.userData.href && e.mesh.userData.href.match("pos=") ){
name = "action: " name = "action: "
subscene = xrfragment.URI.parse( e.mesh.userData.href ).XRF.pos.string subscene = xrfragment.URI.parse( e.mesh.userData.href ).XRF.pos.string
info = "to "+ subscene
} }
if( e.mesh.userData['aria-description'] ){ if( e.mesh.userData['aria-label'] ){
info += "\n\r"+sanitizeTranscript(e.mesh.userData['aria-description']) info = e.mesh.userData['aria-label']
} }else if( e.mesh.userData['aria-description'] ){
if( subscene ){ info = e.mesh.userData['aria-description']
info += `\n\r${transcriptToText( xrf.sceneToTranscript(subscene,false,true) )}` }else if( subscene ){
info = `${transcriptToText( xrf.sceneToTranscript(subscene,false,true) )}`
} }
if( !info && e.mesh.name ) name = e.mesh.name if( !info && e.mesh.name ) name = e.mesh.name
} }
term.send(`\r\n${name} ${info}\n\r`) term.send(`${name} ${info}\n\r`)
}) })
}) })

Binary file not shown.

File diff suppressed because one or more lines are too long