diff --git a/example/aframe/sandbox/index.html b/example/aframe/sandbox/index.html
index ebaf27b..5774ba5 100644
--- a/example/aframe/sandbox/index.html
+++ b/example/aframe/sandbox/index.html
@@ -39,7 +39,7 @@
-
+
@@ -58,7 +58,6 @@
// reroute console messages to snackbar notifications
console.log = ( (log) => function(str){
- if( str.match(/URL:/) ) str += "
(use back-button to go back)"
if( String(str).match(/:.*#/) ) window.notify(str)
log(str)
})(console.log)
diff --git a/example/assets/index.glb b/example/assets/index.glb
index 7e89f5b..5b049a5 100644
Binary files a/example/assets/index.glb and b/example/assets/index.glb differ
diff --git a/src/3rd/js/aframe/index.js b/src/3rd/js/aframe/index.js
index 0f6b61a..01c5509 100644
--- a/src/3rd/js/aframe/index.js
+++ b/src/3rd/js/aframe/index.js
@@ -37,11 +37,11 @@ window.AFRAME.registerComponent('xrf', {
els.map( (mesh) => {
mesh.material.visible = false
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")
$('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) )
})
- 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]').removeAttribute("look-controls")
- document.querySelector('[camera]').removeAttribute("wasd-controls")
- })
+ // *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",'')
+ // })
AFRAME.XRF.navigator.to(this.data)
.then( (model) => {
diff --git a/src/3rd/js/pubsub.js b/src/3rd/js/pubsub.js
index 86c4988..a0044e2 100644
--- a/src/3rd/js/pubsub.js
+++ b/src/3rd/js/pubsub.js
@@ -73,3 +73,9 @@ xrf.emit.promise = function(e, opts){
delete opts.promise
})
}
+
+xrf.addEventListener('reset', () => {
+// *TODO* do this nicely
+// xrf._listeners['renderPost'] = []
+// xrf._listeners['render'] = []
+})
diff --git a/src/3rd/js/three/index.js b/src/3rd/js/three/index.js
index 6a80602..d54206d 100644
--- a/src/3rd/js/three/index.js
+++ b/src/3rd/js/three/index.js
@@ -80,6 +80,8 @@ xrf.reset = () => {
xrf.interactive = xrf.interactiveGroup( xrf.THREE, xrf.renderer, xrf.camera)
xrf.add( xrf.interactive )
xrf.layers = 0
+
+ // reset certain events
xrf.emit('reset',{})
// remove mixers
xrf.mixers.map( (m) => m.stop())
diff --git a/src/3rd/js/three/xrf/dynamic/XRWG-lines.js b/src/3rd/js/three/xrf/dynamic/XRWG-lines.js
index eac1024..708bd52 100644
--- a/src/3rd/js/three/xrf/dynamic/XRWG-lines.js
+++ b/src/3rd/js/three/xrf/dynamic/XRWG-lines.js
@@ -51,14 +51,16 @@ xrf.drawLineToMesh = (opts) => {
}
}
-xrf.addEventListener('render', (opts) => {
- // update focusline
- let {time,model} = opts
- if( !xrf.clock ) return
- xrf.focusLine.material.color.r = (1.0 + Math.sin( xrf.clock.getElapsedTime()*10 ))/2
- xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( xrf.clock.getElapsedTime() )
- xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( xrf.clock.getElapsedTime() *3 )
- 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 -= time*0.2
- if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0
+xrf.addEventListener('navigateLoaded', (opts) => {
+ xrf.addEventListener('render', (opts) => {
+ // update focusline
+ let {time,model} = opts
+ if( !xrf.clock ) return
+ xrf.focusLine.material.color.r = (1.0 + Math.sin( xrf.clock.getElapsedTime()*10 ))/2
+ xrf.focusLine.material.dashSize = 0.2 + 0.02*Math.sin( xrf.clock.getElapsedTime() )
+ xrf.focusLine.material.gapSize = 0.1 + 0.02*Math.sin( xrf.clock.getElapsedTime() *3 )
+ 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 -= time*0.2
+ if( xrf.focusLine.opacity < 0.0 ) xrf.focusLine.opacity = 0
+ })
})
diff --git a/src/3rd/js/three/xrf/src/non-euclidian.js b/src/3rd/js/three/xrf/src/non-euclidian.js
index 076de4e..c631cdb 100644
--- a/src/3rd/js/three/xrf/src/non-euclidian.js
+++ b/src/3rd/js/three/xrf/src/non-euclidian.js
@@ -14,22 +14,24 @@ xrf.portalNonEuclidian = function(opts){
cameraPosition: new THREE.Vector3(),
raycaster: new THREE.Raycaster(),
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)
const addStencilFeature = (n) => {
if( n.stencil ) return n // run once
- n.stencil = ( (pos,scale) => (sRef,newPos, newScale) => {
- if( !mesh.portal.isLens ){
- n.position.copy( sRef == 0 ? pos : newPos )
- if( sRef > 0 ) n.scale.multiply( newScale )
- else n.scale.copy( scale )
- n.updateMatrixWorld(true)
- }
- xrf.portalNonEuclidian.selectStencil(n, sRef )
- }
- )( n.position.clone(), n.scale.clone() )
+
+ n.stencil = (sRef ) => xrf.portalNonEuclidian.selectStencil(n, sRef )
+ n.positionAtStencil = (pos,scale) => (newPos,newScale) => {
+ n.position.copy( newPos || pos )
+ n.scale.copy( scale )
+ n.updateMatrixWorld(true)
+ }
+ // curry function
+ n.positionAtStencil = n.positionAtStencil( n.position.clone(), n.scale.clone() )
return n
}
@@ -89,22 +91,23 @@ xrf.portalNonEuclidian = function(opts){
xrf.addEventListener('renderPost', (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 newPos = mesh.portal.posWorld
let stencilObject = mesh.portal.stencilObject
let newScale = mesh.scale
- let cameraDirection = mesh.portal.cameraDirection
- let cameraPosition = mesh.portal.cameraPosition
let raycaster = mesh.portal.raycaster
+
let cam = xrf.camera.getCam ? xrf.camera.getCam() : camera
cam.getWorldPosition(cameraPosition)
- if( cameraPosition.distanceTo(newPos) > 20.0 ) return // dont render far portals
cam.getWorldDirection(cameraDirection)
+ if( cameraPosition.distanceTo(newPos) > 20.0 ) return // dont render far portals
// init
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.autoClearDepth = false
renderer.autoClearColor = false
@@ -116,7 +119,7 @@ xrf.portalNonEuclidian = function(opts){
renderer.autoClearDepth = true
renderer.autoClearColor = 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
@@ -134,6 +137,9 @@ xrf.portalNonEuclidian = function(opts){
}
mesh.portal.needUpdate = false
})
+
+
+
return this
}
@@ -147,6 +153,8 @@ xrf.portalNonEuclidian = function(opts){
.setupListeners()
.setupStencilObjects(scene,opts)
+ // move portal objects to portalposition
+ mesh.portal.positionObjectsIfNeeded(mesh.portal.posWorld, mesh.scale)
}
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