diff --git a/dist/xrfragment.aframe.js b/dist/xrfragment.aframe.js
index adb6c08..d5a0959 100644
--- a/dist/xrfragment.aframe.js
+++ b/dist/xrfragment.aframe.js
@@ -614,6 +614,10 @@ xrfragment.InteractiveGroup = function(THREE,renderer,camera){
super();
if( !renderer || !camera ) return
+
+ // extract camera when camera-rig is passed
+ camera.traverse( (n) => String(n.type).match(/Camera/) ? camera = n : null )
+
const scope = this;
const raycaster = new Raycaster();
@@ -877,7 +881,7 @@ xrf.navigator.to = (url,event) => {
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
console.log("xrfragment: navigating to "+url)
- if( !file || xrf.model.file == file ){ // we're already loaded
+ if( !file || xrf.model.file == file ){ // we're already loaded
document.location.hash = `#${hash}` // just update the hash
xrf.eval( url, xrf.model ) // and eval URI XR fragments
return resolve(xrf.model)
@@ -968,8 +972,6 @@ xrf.frag.env = function(v, opts){
xrf.frag.href = function(v, opts){
let { mesh, model, camera, scene, renderer, THREE} = opts
- console.log("INIT HREF "+mesh.name)
-
const world = {
pos: new THREE.Vector3(),
scale: new THREE.Vector3(),
@@ -1088,9 +1090,48 @@ xrf.frag.pos = function(v, opts){
//if( renderer.xr.isPresenting ) return // too far away
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
console.log(" └ setting camera position to "+v.string)
- camera.position.x = v.x
- camera.position.y = v.y
- camera.position.z = v.z
+
+ if( !frag.q ){
+
+ if( true ){//!renderer.xr.isPresenting ){
+ console.dir(camera)
+ camera.position.x = v.x
+ camera.position.y = v.y
+ camera.position.z = v.z
+ }
+ /*
+ else{ // XR
+ let cameraWorldPosition = new THREE.Vector3()
+ camera.object3D.getWorldPosition(this.cameraWorldPosition)
+ let newRigWorldPosition = new THREE.Vector3(v.x,v.y,x.z)
+
+ // Finally update the cameras position
+ let newRigLocalPosition.copy(this.newRigWorldPosition)
+ if (camera.object3D.parent) {
+ camera.object3D.parent.worldToLocal(newRigLocalPosition)
+ }
+ camera.setAttribute('position', newRigLocalPosition)
+
+ // Also take the headset/camera rotation itself into account
+ if (this.data.rotateOnTeleport) {
+ this.teleportOcamerainQuaternion
+ .setFromEuler(new THREE.Euler(0, this.teleportOcamerain.object3D.rotation.y, 0))
+ this.teleportOcamerainQuaternion.invert()
+ this.teleportOcamerainQuaternion.multiply(this.hitEntityQuaternion)
+ // Rotate the camera based on calculated teleport ocamerain rotation
+ this.cameraRig.object3D.setRotationFromQuaternion(this.teleportOcamerainQuaternion)
+ }
+
+ console.log("XR")
+ const offsetPosition = { x: - v.x, y: - v.y, z: - v.z, w: 1 };
+ const offsetRotation = new THREE.Quaternion();
+ const transform = new XRRigidTransform( offsetPosition, offsetRotation );
+ const teleportSpaceOffset = xrf.baseReferenceSpace.getOffsetReferenceSpace( transform );
+ renderer.xr.setReferenceSpace( teleportSpaceOffset );
+ }
+ */
+
+ }
}
xrf.frag.q = function(v, opts){
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
@@ -1187,6 +1228,7 @@ window.AFRAME.registerComponent('xrf', {
// override the camera-related XR Fragments so the camera-rig is affected
let camOverride = (xrf,v,opts) => {
opts.camera = $('[camera]').object3D.parent
+ console.dir(opts.camera)
xrf(v,opts)
}
@@ -1210,7 +1252,20 @@ window.AFRAME.registerComponent('xrf', {
let els = [...document.querySelectorAll('[xrf-get]')]
els.map( (el) => document.querySelector('a-scene').removeChild(el) )
})(XRF.reset)
-
+
+ // disable cam-controls (which will block updating camerarig position)
+ let coms = ['look-controls','wasd-controls']
+ const setComponents = (com,state) => () => {
+ coms.forEach( (com) => {
+ let el = document.querySelector('['+com+']')
+ if(!el) return
+ el.components[com].enabled = state
+ })
+ }
+ aScene.addEventListener('enter-vr', setComponents(coms,false) )
+ aScene.addEventListener('enter-ar', setComponents(coms,false) )
+ aScene.addEventListener('exit-vr', setComponents(coms,true) )
+ aScene.addEventListener('exit-ar', setComponents(coms,true) )
},
})
diff --git a/dist/xrfragment.three.js b/dist/xrfragment.three.js
index f55a7f9..2302f9f 100644
--- a/dist/xrfragment.three.js
+++ b/dist/xrfragment.three.js
@@ -614,6 +614,10 @@ xrfragment.InteractiveGroup = function(THREE,renderer,camera){
super();
if( !renderer || !camera ) return
+
+ // extract camera when camera-rig is passed
+ camera.traverse( (n) => String(n.type).match(/Camera/) ? camera = n : null )
+
const scope = this;
const raycaster = new Raycaster();
@@ -877,7 +881,7 @@ xrf.navigator.to = (url,event) => {
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
console.log("xrfragment: navigating to "+url)
- if( !file || xrf.model.file == file ){ // we're already loaded
+ if( !file || xrf.model.file == file ){ // we're already loaded
document.location.hash = `#${hash}` // just update the hash
xrf.eval( url, xrf.model ) // and eval URI XR fragments
return resolve(xrf.model)
@@ -968,8 +972,6 @@ xrf.frag.env = function(v, opts){
xrf.frag.href = function(v, opts){
let { mesh, model, camera, scene, renderer, THREE} = opts
- console.log("INIT HREF "+mesh.name)
-
const world = {
pos: new THREE.Vector3(),
scale: new THREE.Vector3(),
@@ -1088,9 +1090,48 @@ xrf.frag.pos = function(v, opts){
//if( renderer.xr.isPresenting ) return // too far away
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
console.log(" └ setting camera position to "+v.string)
- camera.position.x = v.x
- camera.position.y = v.y
- camera.position.z = v.z
+
+ if( !frag.q ){
+
+ if( true ){//!renderer.xr.isPresenting ){
+ console.dir(camera)
+ camera.position.x = v.x
+ camera.position.y = v.y
+ camera.position.z = v.z
+ }
+ /*
+ else{ // XR
+ let cameraWorldPosition = new THREE.Vector3()
+ camera.object3D.getWorldPosition(this.cameraWorldPosition)
+ let newRigWorldPosition = new THREE.Vector3(v.x,v.y,x.z)
+
+ // Finally update the cameras position
+ let newRigLocalPosition.copy(this.newRigWorldPosition)
+ if (camera.object3D.parent) {
+ camera.object3D.parent.worldToLocal(newRigLocalPosition)
+ }
+ camera.setAttribute('position', newRigLocalPosition)
+
+ // Also take the headset/camera rotation itself into account
+ if (this.data.rotateOnTeleport) {
+ this.teleportOcamerainQuaternion
+ .setFromEuler(new THREE.Euler(0, this.teleportOcamerain.object3D.rotation.y, 0))
+ this.teleportOcamerainQuaternion.invert()
+ this.teleportOcamerainQuaternion.multiply(this.hitEntityQuaternion)
+ // Rotate the camera based on calculated teleport ocamerain rotation
+ this.cameraRig.object3D.setRotationFromQuaternion(this.teleportOcamerainQuaternion)
+ }
+
+ console.log("XR")
+ const offsetPosition = { x: - v.x, y: - v.y, z: - v.z, w: 1 };
+ const offsetRotation = new THREE.Quaternion();
+ const transform = new XRRigidTransform( offsetPosition, offsetRotation );
+ const teleportSpaceOffset = xrf.baseReferenceSpace.getOffsetReferenceSpace( transform );
+ renderer.xr.setReferenceSpace( teleportSpaceOffset );
+ }
+ */
+
+ }
}
xrf.frag.q = function(v, opts){
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
diff --git a/example/aframe/sandbox/index.html b/example/aframe/sandbox/index.html
index d096485..00f21a1 100644
--- a/example/aframe/sandbox/index.html
+++ b/example/aframe/sandbox/index.html
@@ -21,8 +21,8 @@
-
-
+
+
@@ -46,8 +46,6 @@
setupConsole( $('textarea') )
setupUrlBar( $('input#uri') )
- // add look-controls at last (otherwise it'll be buggy after scene-updates)
- $('[camera]').setAttribute("look-controls","")
// add screenshot component with camera to capture proper equirects
$('a-scene').setAttribute("screenshot",{camera: "[camera]",width: 4096*2, height:2048*2})
diff --git a/example/threejs/sandbox/index.html b/example/threejs/sandbox/index.html
index 93260bf..2796331 100644
--- a/example/threejs/sandbox/index.html
+++ b/example/threejs/sandbox/index.html
@@ -83,10 +83,16 @@
window.addEventListener( 'resize', onWindowResize );
+ let cameraRig = new THREE.Group()
+ cameraRig.position.set( 0, 0, 0 );
+ cameraRig.add(camera)
+ scene.add(cameraRig)
+
+
// enable XR fragments
let XRF = xrfragment.init({
THREE,
- camera,
+ camera:cameraRig,
scene,
renderer,
debug: true,
@@ -116,7 +122,7 @@
window.XRF = XRF // expose to form
- let file = document.location.search.length > 2 ? document.location.search.substr(1) + document.location.hash : './../../assets/example3.gltf#pos=0,1,15'
+ let file = document.location.search.length > 2 ? document.location.search.substr(1) + document.location.hash : './../../assets/example3.gltf#pos=1,0,4&rot=0,-30,0'
$('#model').setAttribute("href","./../../asset/"+file)
XRF.navigator.to( file )
@@ -134,12 +140,6 @@
//controls.maxPolarAngle = Math.PI / 2;
//controls.target = new THREE.Vector3(0,1.6,0)
- //let cameraRig = new THREE.Group()
- //cameraRig.position.set( 0, 1.6, 15 );
- camera.position.set( 0, 1.6, 15 );
- //cameraRig.add(camera)
- //cameraRig.position.set( 0, 4, 15 );
-
//controls.update()
const geometry = new THREE.BufferGeometry();
@@ -147,22 +147,22 @@
const controller1 = renderer.xr.getController( 0 );
controller1.add( new THREE.Line( geometry ) );
- scene.add( controller1 );
+ cameraRig.add( controller1 );
const controller2 = renderer.xr.getController( 1 );
controller2.add( new THREE.Line( geometry ) );
- scene.add( controller2 );
+ cameraRig.add( controller2 );
const controllerModelFactory = new XRControllerModelFactory();
const controllerGrip1 = renderer.xr.getControllerGrip( 0 );
controllerGrip1.add( controllerModelFactory.createControllerModel( controllerGrip1 ) );
- scene.add( controllerGrip1 );
+ cameraRig.add( controllerGrip1 );
const controllerGrip2 = renderer.xr.getControllerGrip( 1 );
controllerGrip2.add( controllerModelFactory.createControllerModel( controllerGrip2 ) );
- scene.add( controllerGrip2 );
+ cameraRig.add( controllerGrip2 );
setupConsole()
diff --git a/src/3rd/aframe/index.js b/src/3rd/aframe/index.js
index 5ed5394..f4918f6 100644
--- a/src/3rd/aframe/index.js
+++ b/src/3rd/aframe/index.js
@@ -32,6 +32,7 @@ window.AFRAME.registerComponent('xrf', {
// override the camera-related XR Fragments so the camera-rig is affected
let camOverride = (xrf,v,opts) => {
opts.camera = $('[camera]').object3D.parent
+ console.dir(opts.camera)
xrf(v,opts)
}
@@ -50,11 +51,25 @@ window.AFRAME.registerComponent('xrf', {
// cleanup xrf-get objects when resetting scene
XRF.reset = ((reset) => () => {
+ reset()
console.log("aframe reset")
let els = [...document.querySelectorAll('[xrf-get]')]
els.map( (el) => document.querySelector('a-scene').removeChild(el) )
- reset()
})(XRF.reset)
+
+ // disable cam-controls (which block updating camerarig position)
+ let coms = ['look-controls','wasd-controls']
+ const setComponents = (com,state) => () => {
+ coms.forEach( (com) => {
+ let el = document.querySelector('['+com+']')
+ if(!el) return
+ el.components[com].enabled = state
+ })
+ }
+ aScene.addEventListener('enter-vr', setComponents(coms,false) )
+ aScene.addEventListener('enter-ar', setComponents(coms,false) )
+ aScene.addEventListener('exit-vr', setComponents(coms,true) )
+ aScene.addEventListener('exit-ar', setComponents(coms,true) )
},
})
diff --git a/src/3rd/three/InteractiveGroup.js b/src/3rd/three/InteractiveGroup.js
index 597e629..47a03de 100644
--- a/src/3rd/three/InteractiveGroup.js
+++ b/src/3rd/three/InteractiveGroup.js
@@ -19,6 +19,10 @@ xrfragment.InteractiveGroup = function(THREE,renderer,camera){
super();
if( !renderer || !camera ) return
+
+ // extract camera when camera-rig is passed
+ camera.traverse( (n) => String(n.type).match(/Camera/) ? camera = n : null )
+
const scope = this;
const raycaster = new Raycaster();
diff --git a/src/3rd/three/navigator.js b/src/3rd/three/navigator.js
index 56e67e5..1d2744a 100644
--- a/src/3rd/three/navigator.js
+++ b/src/3rd/three/navigator.js
@@ -6,7 +6,7 @@ xrf.navigator.to = (url,event) => {
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
console.log("xrfragment: navigating to "+url)
- if( !file || xrf.model.file == file ){ // we're already loaded
+ if( !file || xrf.model.file == file ){ // we're already loaded
document.location.hash = `#${hash}` // just update the hash
xrf.eval( url, xrf.model ) // and eval URI XR fragments
return resolve(xrf.model)
diff --git a/src/3rd/three/xrf/href.js b/src/3rd/three/xrf/href.js
index c969b7f..fade04c 100644
--- a/src/3rd/three/xrf/href.js
+++ b/src/3rd/three/xrf/href.js
@@ -81,10 +81,10 @@ xrf.frag.href = function(v, opts){
}
let teleport = mesh.userData.XRF.href.exec = (e) => {
- let portalArea = 1 // 2 meter
const meshWorldPosition = new THREE.Vector3();
meshWorldPosition.setFromMatrixPosition(mesh.matrixWorld);
+ let portalArea = 1 // 2 meter
const cameraDirection = new THREE.Vector3();
camera.getWorldPosition(cameraDirection);
cameraDirection.sub(meshWorldPosition);
@@ -93,9 +93,11 @@ xrf.frag.href = function(v, opts){
const newPos = meshWorldPosition.clone().add(cameraDirection);
const distance = camera.position.distanceTo(newPos);
- if( renderer.xr.isPresenting && distance > portalArea ) return // too far away
+ //if( distance > portalArea ){
+ if( !renderer.xr.isPresenting && !confirm("teleport to "+v.string+" ?") ) return
xrf.navigator.to(v.string) // ok let's surf to HREF!
+ console.log("teleport!")
xrf.emit('href',{click:true,mesh,xrf:v})
}
diff --git a/src/3rd/three/xrf/pos.js b/src/3rd/three/xrf/pos.js
index 9adc006..5e4fec3 100644
--- a/src/3rd/three/xrf/pos.js
+++ b/src/3rd/three/xrf/pos.js
@@ -1,7 +1,47 @@
xrf.frag.pos = function(v, opts){
+ //if( renderer.xr.isPresenting ) return // too far away
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
console.log(" └ setting camera position to "+v.string)
- camera.position.x = v.x
- camera.position.y = v.y
- camera.position.z = v.z
+
+ if( !frag.q ){
+
+ if( true ){//!renderer.xr.isPresenting ){
+ console.dir(camera)
+ camera.position.x = v.x
+ camera.position.y = v.y
+ camera.position.z = v.z
+ }
+ /*
+ else{ // XR
+ let cameraWorldPosition = new THREE.Vector3()
+ camera.object3D.getWorldPosition(this.cameraWorldPosition)
+ let newRigWorldPosition = new THREE.Vector3(v.x,v.y,x.z)
+
+ // Finally update the cameras position
+ let newRigLocalPosition.copy(this.newRigWorldPosition)
+ if (camera.object3D.parent) {
+ camera.object3D.parent.worldToLocal(newRigLocalPosition)
+ }
+ camera.setAttribute('position', newRigLocalPosition)
+
+ // Also take the headset/camera rotation itself into account
+ if (this.data.rotateOnTeleport) {
+ this.teleportOcamerainQuaternion
+ .setFromEuler(new THREE.Euler(0, this.teleportOcamerain.object3D.rotation.y, 0))
+ this.teleportOcamerainQuaternion.invert()
+ this.teleportOcamerainQuaternion.multiply(this.hitEntityQuaternion)
+ // Rotate the camera based on calculated teleport ocamerain rotation
+ this.cameraRig.object3D.setRotationFromQuaternion(this.teleportOcamerainQuaternion)
+ }
+
+ console.log("XR")
+ const offsetPosition = { x: - v.x, y: - v.y, z: - v.z, w: 1 };
+ const offsetRotation = new THREE.Quaternion();
+ const transform = new XRRigidTransform( offsetPosition, offsetRotation );
+ const teleportSpaceOffset = xrf.baseReferenceSpace.getOffsetReferenceSpace( transform );
+ renderer.xr.setReferenceSpace( teleportSpaceOffset );
+ }
+ */
+
+ }
}