xrfragment/src/3rd/js/aframe/index.js

164 lines
6.7 KiB
JavaScript
Raw Normal View History

2023-05-09 17:42:29 +02:00
window.AFRAME.registerComponent('xrf', {
schema: {
},
init: function () {
if( !AFRAME.XRF ){
2023-11-08 18:28:18 +01:00
2023-11-29 16:45:21 +01:00
let camera = document.querySelector('[camera]')
2023-11-08 18:28:18 +01:00
// start with black
2023-11-29 16:45:21 +01:00
camera.setAttribute('xrf-fade','')
AFRAME.fade = camera.components['xrf-fade']
2023-11-08 18:28:18 +01:00
2023-11-22 21:03:41 +01:00
if( document.location.host.match(/localhost/) ) document.querySelector('a-scene').setAttribute("stats",'')
document.querySelector('a-scene').addEventListener('loaded', () => {
// enable XR fragments
let aScene = document.querySelector('a-scene')
let XRF = AFRAME.XRF = xrf.init({
THREE,
2023-10-12 17:04:46 +02:00
camera: aScene.camera,
scene: aScene.object3D,
renderer: aScene.renderer,
loaders: {
gltf: THREE.GLTFLoader, // which 3D assets (exts) to check for XR fragments?
glb: THREE.GLTFLoader
}
})
if( !XRF.camera ) throw 'xrfragment: no camera detected, please declare <a-entity camera..> ABOVE entities with xrf-attributes'
2023-05-17 21:31:28 +02:00
xrf.addEventListener('navigateLoaded', () => {
setTimeout( () => AFRAME.fade.out(),500)
// *TODO* this does not really belong here perhaps
let blinkControls = document.querySelector('[blink-controls]')
if( blinkControls ){
2023-11-29 19:39:31 +01:00
let els = xrf.getCollisionMeshes()
els.map( (mesh) => {
mesh.material.visible = false
let el = document.createElement("a-entity")
2023-11-30 13:25:27 +01:00
el.setAttribute("xrf-get", mesh.name )
2023-11-29 19:39:31 +01:00
el.setAttribute("class","floor ray")
$('a-scene').appendChild(el)
})
2023-11-30 13:25:27 +01:00
blinkControls = blinkControls.components['blink-controls'].update({collisionEntities:true})
}
})
2023-11-08 18:28:18 +01:00
xrf.addEventListener('href', (opts) => {
if( opts.click){
2023-11-09 21:43:18 +01:00
let p = opts.promise()
let url = opts.xrf.string
let isLocal = url.match(/^#/)
let hasPos = url.match(/pos=/)
if( isLocal && hasPos ){
// local teleports only
2023-11-08 18:28:18 +01:00
let fastFadeMs = 200
AFRAME.fade.in(fastFadeMs)
setTimeout( () => {
p.resolve()
AFRAME.fade.out(fastFadeMs)
}, fastFadeMs)
}else if( !isLocal ){
2023-11-08 18:28:18 +01:00
AFRAME.fade.in()
setTimeout( () => {
p.resolve()
setTimeout( () => AFRAME.fade.out(), 1000 ) // allow one second to load textures e.g.
}, AFRAME.fade.data.fadetime )
}else p.resolve()
2023-11-08 18:28:18 +01:00
}
})
2023-11-29 16:45:21 +01:00
// patch wasd-controls to affect camera-rig
if( camera.components['wasd-controls'] ){
camera.components['wasd-controls'].tick = function(time,delta){
var data = this.data;
var el = this.el;
var velocity = this.velocity;
function isEmptyObject(keys) {
var key;
for (key in keys) { return false; }
return true;
}
if (!velocity[data.adAxis] && !velocity[data.wsAxis] &&
isEmptyObject(this.keys)) { return; }
// Update velocity.
delta = delta / 1000;
this.updateVelocity(delta);
if (!velocity[data.adAxis] && !velocity[data.wsAxis]) { return; }
// Transform direction relative to heading.
let directionVector = this.getMovementVector(delta)
var rotationEuler = new THREE.Euler(0, 0, 0, 'YXZ');
rotationEuler.set(THREE.MathUtils.degToRad(0), THREE.MathUtils.degToRad(xrf.camera.rotation.y + 45), 0);
directionVector.applyEuler(rotationEuler);
// Get movement vector and translate position to camera-rig (not camera)
xrf.camera.position.add(directionVector);
}.bind( camera.components['wasd-controls'] )
}
2023-05-12 22:40:09 +02:00
// convert href's to a-entity's so AFRAME
// raycaster can find & execute it
AFRAME.XRF.clickableMeshToEntity = (opts) => {
let {mesh,clickHandler} = opts;
let el = document.createElement("a-entity")
el.setAttribute("xrf-get",mesh.name ) // turn into AFRAME entity
el.setAttribute("class","ray") // expose to raycaster
el.setAttribute("pressable", '') // detect hand-controller click
2023-11-08 18:28:18 +01:00
// respond to cursor via laser-controls (https://aframe.io/docs/1.4.0/components/laser-controls.html)
el.addEventListener("click", clickHandler )
2023-11-08 18:28:18 +01:00
el.addEventListener("mouseenter", mesh.userData.XRF.href.selected(true) )
el.addEventListener("mouseleave", mesh.userData.XRF.href.selected(false) )
el.addEventListener("pressedstarted", clickHandler )
$('a-scene').appendChild(el)
}
xrf.addEventListener('interactionReady', AFRAME.XRF.clickableMeshToEntity )
// cleanup xrf-get objects when resetting scene
2023-10-25 11:43:44 +02:00
xrf.addEventListener('reset', (opts) => {
let els = [...document.querySelectorAll('[xrf-get]')]
els.map( (el) => document.querySelector('a-scene').removeChild(el) )
2023-10-25 11:43:44 +02:00
})
2023-11-30 13:25:27 +01:00
// *TODO* workaround no longer needed?
//
// aScene.addEventListener('enter-vr', () => {
// // undo lookup-control shenanigans (which blocks updating camerarig position in VR)
// document.querySelector('[camera]').object3D.parent.matrixAutoUpdate = true
// document.querySelector('[camera]').components['look-controls'].pause() //removeAttribute("look-controls")
// document.querySelector('[camera]').components['wasd-controls'].pause() //removeAttribute("wasd-controls")
// })
// aScene.addEventListener('exit-vr', () => {
// // redo lookup-control shenanigans (which blocks updating camerarig position in VR)
// document.querySelector('[camera]').object3D.parent.matrixAutoUpdate = false
// document.querySelector('[camera]').components['look-controls'].play() //setAttribute("look-controls",'')
// document.querySelector('[camera]').components['wasd-controls'].play() //setAttribute("wasd-controls",'')
// })
2023-06-27 09:42:49 +02:00
AFRAME.XRF.navigator.to(this.data)
.then( (model) => {
let gets = [ ...document.querySelectorAll('[xrf-get]') ]
gets.map( (g) => g.emit('update') )
})
aScene.emit('XRF',{})
2023-10-14 20:10:06 +02:00
// enable gaze-click on Mobile VR
aScene.setAttribute('xrf-gaze','')
})
}
if( typeof this.data == "string" ){
if( document.location.search || document.location.hash.length > 1 ){ // override url
this.data = `${document.location.search.substr(1)}${document.location.hash}`
}
}
},
})