From 890b705cbc9076db1b179a6f47b18747e1b782d8 Mon Sep 17 00:00:00 2001 From: Kevin Ngo Date: Thu, 15 Nov 2018 18:42:11 -0800 Subject: [PATCH] recenter --- src/components/recenter.js | 77 ++++++++++++++------------------------ src/index.html | 2 +- 2 files changed, 29 insertions(+), 50 deletions(-) diff --git a/src/components/recenter.js b/src/components/recenter.js index 800e6f8..be6cc08 100644 --- a/src/components/recenter.js +++ b/src/components/recenter.js @@ -1,72 +1,51 @@ /** - * Pivot the scene when user enters VR to face the links. + * Recenter camera back to facing down negative Z axis at 0, 0, 0. */ AFRAME.registerComponent('recenter', { schema: { - enabled: {default: true}, - target: {default: ''} + enabled: {default: true} }, init: function () { var sceneEl = this.el.sceneEl; - this.matrix = new THREE.Matrix4(); - this.frustum = new THREE.Frustum(); - this.rotationOffset = 0; - this.euler = new THREE.Euler(); - this.euler.order = 'YXZ'; - this.menuPosition = new THREE.Vector3(); this.recenter = this.recenter.bind(this); - this.checkInViewAfterRecenter = this.checkInViewAfterRecenter.bind(this); - this.target = document.querySelector(this.data.target); // Delay to make sure we have a valid pose. - sceneEl.addEventListener('enter-vr', () => setTimeout(this.recenter, 100)); - // User can also recenter the menu manually. - sceneEl.addEventListener('menudown', this.recenter); - sceneEl.addEventListener('thumbstickdown', this.recenter); + this.el.addEventListener('enter-vr', () => setTimeout(this.recenter, 100)); + document.querySelectorAll('[tracked-controls]').forEach(controlEl => { + controlEl.addEventListener('menudown', this.recenter); + controlEl.addEventListener('thumbstickdown', this.recenter); + }); window.addEventListener('vrdisplaypresentchange', this.recenter); }, - recenter: function () { - var euler = this.euler; - if (!this.data.enabled) { return; } - euler.setFromRotationMatrix(this.el.sceneEl.camera.el.object3D.matrixWorld, 'YXZ'); - this.el.object3D.rotation.y = euler.y + this.rotationOffset; - // Check if the menu is in camera frustum in next tick after a frame has rendered. - setTimeout(this.checkInViewAfterRecenter, 0); - }, - - /* - * Sometimes the quaternion returns the yaw in the [-180, 180] range. - * Check if the menu is in the camera frustum after recenter it to - * decide if we apply an offset or not. - */ - checkInViewAfterRecenter: (function () { - var bottomVec3 = new THREE.Vector3(); - var topVec3 = new THREE.Vector3(); + recenter: (function () { + var euler = new THREE.Euler(); + var matrix = new THREE.Matrix4(); + var rotationMatrix = new THREE.Matrix4(); + var translationMatrix = new THREE.Matrix4(); return function () { - var camera = this.el.sceneEl.camera; - var frustum = this.frustum; - var menuPosition = this.menuPosition; + const el = this.el; - camera.updateMatrix(); - camera.updateMatrixWorld(); - frustum.setFromMatrix(this.matrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)); + if (!this.data.enabled) { return; } - // Check if menu position (and its bounds) are within the frustum. - // Check bounds in case looking angled up or down, rather than menu central. - menuPosition.setFromMatrixPosition(this.target.object3D.matrixWorld); - bottomVec3.copy(menuPosition).y -= 3; - topVec3.copy(menuPosition).y += 3; + const camera = el.sceneEl.camera.el.object3D; - if (frustum.containsPoint(menuPosition) || - frustum.containsPoint(bottomVec3) || - frustum.containsPoint(topVec3)) { return; } + // Reset matrix. + matrix.identity(); - this.rotationOffset = this.rotationOffset === 0 ? Math.PI : 0; - // Recenter again with the new offset. - this.recenter(); + // Create matrix to reset Y rotation. + euler.set(0, -1 * camera.rotation.y, 0); + rotationMatrix.makeRotationFromEuler(euler); + + // Create matrix to zero position. + translationMatrix.makeTranslation(-1 * camera.position.x, 0, -1 * camera.position.z); + + // Multiply and decompose back to object3D. + matrix.multiply(rotationMatrix).multiply(translationMatrix); + matrix.decompose(el.object3D.position, el.object3D.quaternion, el.object3D.scale); + el.object3D.updateMatrixWorld(true); }; })(), diff --git a/src/index.html b/src/index.html index 3b53a75..1f59e1d 100644 --- a/src/index.html +++ b/src/index.html @@ -96,7 +96,7 @@ id="cursorMesh" material="shader: flat; transparent: true; src: #cursorMeshImg; depthTest: false" sub-object="from: #cursorLaser; name: glow"> - +