This commit is contained in:
Leon van Kammen 2023-11-30 13:25:27 +01:00
parent e38eea1859
commit 796790990d
7 changed files with 78 additions and 37 deletions

View file

@ -39,7 +39,7 @@
<a-entity id="next" xrf-button="label: >; width:0.05; action: history.forward()" position=" 0.025 0 0" class="ray"></a-entity> <a-entity id="next" xrf-button="label: >; width:0.05; action: history.forward()" position=" 0.025 0 0" class="ray"></a-entity>
</a-entity> </a-entity>
</a-entity> </a-entity>
<a-entity id="right-hand" laser-controls="hand: right" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor"></a-entity> <a-entity id="right-hand" laser-controls="hand: right" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #player; collisionEntities: .floor"></a-entity>
</a-entity> </a-entity>
<a-entity id="home" xrf="index.glb"></a-entity> <a-entity id="home" xrf="index.glb"></a-entity>
@ -58,7 +58,6 @@
// reroute console messages to snackbar notifications // reroute console messages to snackbar notifications
console.log = ( (log) => function(str){ console.log = ( (log) => function(str){
if( str.match(/URL:/) ) str += "<br><br>(use back-button to go back)"
if( String(str).match(/:.*#/) ) window.notify(str) if( String(str).match(/:.*#/) ) window.notify(str)
log(str) log(str)
})(console.log) })(console.log)

Binary file not shown.

View file

@ -37,11 +37,11 @@ window.AFRAME.registerComponent('xrf', {
els.map( (mesh) => { els.map( (mesh) => {
mesh.material.visible = false mesh.material.visible = false
let el = document.createElement("a-entity") let el = document.createElement("a-entity")
el.setAttribute("xrf-get", `name: ${mesh.name};reparent:true` ) el.setAttribute("xrf-get", mesh.name )
el.setAttribute("class","floor ray") el.setAttribute("class","floor ray")
$('a-scene').appendChild(el) $('a-scene').appendChild(el)
}) })
blinkControls = blinkControls.components['blink-controls'].queryCollisionEntities() blinkControls = blinkControls.components['blink-controls'].update({collisionEntities:true})
} }
}) })
@ -124,12 +124,20 @@ window.AFRAME.registerComponent('xrf', {
els.map( (el) => document.querySelector('a-scene').removeChild(el) ) els.map( (el) => document.querySelector('a-scene').removeChild(el) )
}) })
aScene.addEventListener('enter-vr', () => { // *TODO* workaround no longer needed?
// undo lookup-control shenanigans (which blocks updating camerarig position in VR) //
document.querySelector('[camera]').object3D.parent.matrixAutoUpdate = true // aScene.addEventListener('enter-vr', () => {
document.querySelector('[camera]').removeAttribute("look-controls") // // undo lookup-control shenanigans (which blocks updating camerarig position in VR)
document.querySelector('[camera]').removeAttribute("wasd-controls") // 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",'')
// })
AFRAME.XRF.navigator.to(this.data) AFRAME.XRF.navigator.to(this.data)
.then( (model) => { .then( (model) => {

View file

@ -73,3 +73,9 @@ xrf.emit.promise = function(e, opts){
delete opts.promise delete opts.promise
}) })
} }
xrf.addEventListener('reset', () => {
// *TODO* do this nicely
// xrf._listeners['renderPost'] = []
// xrf._listeners['render'] = []
})

View file

@ -80,6 +80,8 @@ xrf.reset = () => {
xrf.interactive = xrf.interactiveGroup( xrf.THREE, xrf.renderer, xrf.camera) xrf.interactive = xrf.interactiveGroup( xrf.THREE, xrf.renderer, xrf.camera)
xrf.add( xrf.interactive ) xrf.add( xrf.interactive )
xrf.layers = 0 xrf.layers = 0
// reset certain events
xrf.emit('reset',{}) xrf.emit('reset',{})
// remove mixers // remove mixers
xrf.mixers.map( (m) => m.stop()) xrf.mixers.map( (m) => m.stop())

View file

@ -51,14 +51,16 @@ xrf.drawLineToMesh = (opts) => {
} }
} }
xrf.addEventListener('render', (opts) => { xrf.addEventListener('navigateLoaded', (opts) => {
// update focusline xrf.addEventListener('render', (opts) => {
let {time,model} = opts // update focusline
if( !xrf.clock ) return let {time,model} = opts
xrf.focusLine.material.color.r = (1.0 + Math.sin( xrf.clock.getElapsedTime()*10 ))/2 if( !xrf.clock ) return
xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( xrf.clock.getElapsedTime() ) xrf.focusLine.material.color.r = (1.0 + Math.sin( xrf.clock.getElapsedTime()*10 ))/2
xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( xrf.clock.getElapsedTime() *3 ) xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( xrf.clock.getElapsedTime() )
xrf.focusLine.material.opacity = (0.25 + 0.15*Math.sin( xrf.clock.getElapsedTime() * 3 )) * xrf.focusLine.opacity; xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( xrf.clock.getElapsedTime() *3 )
if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.2 xrf.focusLine.material.opacity = (0.25 + 0.15*Math.sin( xrf.clock.getElapsedTime() * 3 )) * xrf.focusLine.opacity;
if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0 if( xrf.focusLine.opacity > 0.0 ) xrf.focusLine.opacity -= time*0.2
if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0
})
}) })

View file

@ -14,22 +14,24 @@ xrf.portalNonEuclidian = function(opts){
cameraPosition: new THREE.Vector3(), cameraPosition: new THREE.Vector3(),
raycaster: new THREE.Raycaster(), raycaster: new THREE.Raycaster(),
isLocal: opts.isLocal, isLocal: opts.isLocal,
isLens: false isLens: false,
isInside: false,
setStencil: (stencilRef) => mesh.portal.stencilObjects.traverse( (n) => showPortal(n, stencilRef == 0) && n.stencil && n.stencil(stencilRef) ),
positionObjectsIfNeeded: (pos,scale) => !mesh.portal.isLens && mesh.portal.stencilObjects.traverse( (n) => n.positionAtStencil && (n.positionAtStencil(pos,scale)) )
} }
// allow objects to flip between original and stencil position (which puts them behind stencilplane) // allow objects to flip between original and stencil position (which puts them behind stencilplane)
const addStencilFeature = (n) => { const addStencilFeature = (n) => {
if( n.stencil ) return n // run once if( n.stencil ) return n // run once
n.stencil = ( (pos,scale) => (sRef,newPos, newScale) => {
if( !mesh.portal.isLens ){ n.stencil = (sRef ) => xrf.portalNonEuclidian.selectStencil(n, sRef )
n.position.copy( sRef == 0 ? pos : newPos ) n.positionAtStencil = (pos,scale) => (newPos,newScale) => {
if( sRef > 0 ) n.scale.multiply( newScale ) n.position.copy( newPos || pos )
else n.scale.copy( scale ) n.scale.copy( scale )
n.updateMatrixWorld(true) n.updateMatrixWorld(true)
} }
xrf.portalNonEuclidian.selectStencil(n, sRef ) // curry function
} n.positionAtStencil = n.positionAtStencil( n.position.clone(), n.scale.clone() )
)( n.position.clone(), n.scale.clone() )
return n return n
} }
@ -89,22 +91,23 @@ xrf.portalNonEuclidian = function(opts){
xrf.addEventListener('renderPost', (opts) => { xrf.addEventListener('renderPost', (opts) => {
let {scene,camera,time,render,renderer} = opts let {scene,camera,time,render,renderer} = opts
if( mesh.portal && mesh.portal.stencilObjects ){ if( mesh.portal.needUpdate && mesh.portal && mesh.portal.stencilObjects ){
let cameraDirection = mesh.portal.cameraDirection
let cameraPosition = mesh.portal.cameraPosition
let stencilRef = mesh.portal.stencilRef let stencilRef = mesh.portal.stencilRef
let newPos = mesh.portal.posWorld let newPos = mesh.portal.posWorld
let stencilObject = mesh.portal.stencilObject let stencilObject = mesh.portal.stencilObject
let newScale = mesh.scale let newScale = mesh.scale
let cameraDirection = mesh.portal.cameraDirection
let cameraPosition = mesh.portal.cameraPosition
let raycaster = mesh.portal.raycaster let raycaster = mesh.portal.raycaster
let cam = xrf.camera.getCam ? xrf.camera.getCam() : camera let cam = xrf.camera.getCam ? xrf.camera.getCam() : camera
cam.getWorldPosition(cameraPosition) cam.getWorldPosition(cameraPosition)
if( cameraPosition.distanceTo(newPos) > 20.0 ) return // dont render far portals
cam.getWorldDirection(cameraDirection) cam.getWorldDirection(cameraDirection)
if( cameraPosition.distanceTo(newPos) > 20.0 ) return // dont render far portals
// init // init
if( !mesh.portal.isLocal || mesh.portal.isLens ) stencilObject.visible = true if( !mesh.portal.isLocal || mesh.portal.isLens ) stencilObject.visible = true
mesh.portal.stencilObjects.traverse( (n) => showPortal(n,false) && n.stencil && n.stencil(stencilRef,newPos,newScale) ) mesh.portal.setStencil(stencilRef)
renderer.autoClear = false renderer.autoClear = false
renderer.autoClearDepth = false renderer.autoClearDepth = false
renderer.autoClearColor = false renderer.autoClearColor = false
@ -116,7 +119,7 @@ xrf.portalNonEuclidian = function(opts){
renderer.autoClearDepth = true renderer.autoClearDepth = true
renderer.autoClearColor = true renderer.autoClearColor = true
renderer.autoClearStencil = true renderer.autoClearStencil = true
mesh.portal.stencilObjects.traverse( (n) => showPortal(n,true) && n.stencil && (n.stencil(0)) ) mesh.portal.setStencil(0)
if( !mesh.portal.isLocal || mesh.portal.isLens ) stencilObject.visible = false if( !mesh.portal.isLocal || mesh.portal.isLens ) stencilObject.visible = false
@ -134,6 +137,9 @@ xrf.portalNonEuclidian = function(opts){
} }
mesh.portal.needUpdate = false mesh.portal.needUpdate = false
}) })
return this return this
} }
@ -147,6 +153,8 @@ xrf.portalNonEuclidian = function(opts){
.setupListeners() .setupListeners()
.setupStencilObjects(scene,opts) .setupStencilObjects(scene,opts)
// move portal objects to portalposition
mesh.portal.positionObjectsIfNeeded(mesh.portal.posWorld, mesh.scale)
} }
xrf.portalNonEuclidian.selectStencil = (n, stencilRef, nested) => { xrf.portalNonEuclidian.selectStencil = (n, stencilRef, nested) => {
@ -179,4 +187,20 @@ xrf.addEventListener('parseModel',(opts) => {
}) })
// (re)set portalObject when entering/leaving a portal
xrf.addEventListener('href', (opts) => {
let {mesh,v} = opts
if( opts.click && mesh.portal ){
if( !opts.click ) return
xrf.scene.traverse( (n) => {
if( !n.portal ) return
// since we're leaving this portal destination, lets move objects back to the portal
if( n.portal.isInside ) n.portal.positionObjectsIfNeeded( n.portal.posWorld, n.scale )
n.portal.isInside = false
})
mesh.portal.isInside = true
mesh.portal.positionObjectsIfNeeded() // move objects back to original pos (since we are going there)
}
})
xrf.portalNonEuclidian.stencilRef = 1 xrf.portalNonEuclidian.stencilRef = 1