From bacbdcb2abfd767010082f5baa381b8d3fb12e4b Mon Sep 17 00:00:00 2001 From: joni <johnfshaughnessy@gmail.com> Date: Fri, 1 Jun 2018 19:40:29 -0700 Subject: [PATCH] Remove controller management from the cursor-controller. --- src/components/cursor-controller.js | 113 +-------------------------- src/components/input-configurator.js | 72 ++++++++++++++++- src/utils/primary-action-handler.js | 13 ++- 3 files changed, 79 insertions(+), 119 deletions(-) diff --git a/src/components/cursor-controller.js b/src/components/cursor-controller.js index 616fcf84f..7713b15a8 100644 --- a/src/components/cursor-controller.js +++ b/src/components/cursor-controller.js @@ -3,20 +3,11 @@ const TARGET_TYPE_INTERACTABLE = 2; const TARGET_TYPE_UI = 4; const TARGET_TYPE_INTERACTABLE_OR_UI = TARGET_TYPE_INTERACTABLE | TARGET_TYPE_UI; -/** - * Controls virtual cursor behavior in various modalities to affect teleportation, interatables and UI. - * @namespace user-input - * @component cursor-controller - */ AFRAME.registerComponent("cursor-controller", { dependencies: ["raycaster", "line"], schema: { cursor: { type: "selector" }, camera: { type: "selector" }, - playerRig: { type: "selector" }, - gazeTeleportControls: { type: "selector" }, - physicalHandSelector: { type: "string" }, - handedness: { default: "right", oneOf: ["right", "left"] }, maxDistance: { default: 3 }, minDistance: { default: 0 }, cursorColorHovered: { default: "#2F80ED" }, @@ -27,16 +18,12 @@ AFRAME.registerComponent("cursor-controller", { this.enabled = true; this.inVR = false; this.isMobile = AFRAME.utils.device.isMobile(); - this.hasPointingDevice = false; this.currentTargetType = TARGET_TYPE_NONE; this.currentDistance = this.data.maxDistance; this.currentDistanceMod = 0; this.mousePos = new THREE.Vector2(); this.useMousePos = true; - this.controller = null; - this.controllerQueue = []; this.wasCursorHovered = false; - this.wasPhysicalHandGrabbing = false; this.origin = new THREE.Vector3(); this.direction = new THREE.Vector3(); this.controllerQuaternion = new THREE.Quaternion(); @@ -49,13 +36,7 @@ AFRAME.registerComponent("cursor-controller", { this.endInteraction = this.endInteraction.bind(this); this.changeDistanceMod = this.changeDistanceMod.bind(this); - this._handleEnterVR = this._handleEnterVR.bind(this); - this._handleExitVR = this._handleExitVR.bind(this); - this._handleModelLoaded = this._handleModelLoaded.bind(this); this._handleCursorLoaded = this._handleCursorLoaded.bind(this); - this._handleControllerConnected = this._handleControllerConnected.bind(this); - this._handleControllerDisconnected = this._handleControllerDisconnected.bind(this); - this.data.cursor.addEventListener("loaded", this._handleCursorLoaded); }, @@ -63,36 +44,6 @@ AFRAME.registerComponent("cursor-controller", { this.data.cursor.removeEventListener("loaded", this._handleCursorLoaded); }, - update: function(oldData) { - if (oldData.physicalHandSelector !== this.data.physicalHandSelector) { - this._handleModelLoaded(); - } - - if (oldData.handedness !== this.data.handedness) { - //TODO - } - }, - - play: function() { - window.addEventListener("enter-vr", this._handleEnterVR); - window.addEventListener("exit-vr", this._handleExitVR); - - this.data.playerRig.addEventListener("model-loaded", this._handleModelLoaded); - - this.el.sceneEl.addEventListener("controllerconnected", this._handleControllerConnected); - this.el.sceneEl.addEventListener("controllerdisconnected", this._handleControllerDisconnected); - }, - - pause: function() { - window.removeEventListener("enter-vr", this._handleEnterVR); - window.removeEventListener("exit-vr", this._handleExitVR); - - this.data.playerRig.removeEventListener("model-loaded", this._handleModelLoaded); - - this.el.sceneEl.removeEventListener("controllerconnected", this._handleControllerConnected); - this.el.sceneEl.removeEventListener("controllerdisconnected", this._handleControllerDisconnected); - }, - enable: function() { this.enabled = true; }, @@ -221,70 +172,8 @@ AFRAME.registerComponent("cursor-controller", { this.currentDistanceMod += delta; }, - _handleEnterVR: function() { - this.inVR = true; - this._updateController(); - }, - - _handleExitVR: function() { - this.inVR = false; - this._updateController(); - }, - - _handleModelLoaded: function() { - this.physicalHand = this.data.playerRig.querySelector(this.data.physicalHandSelector); - }, - _handleCursorLoaded: function() { this.data.cursor.object3DMap.mesh.renderOrder = window.APP.RENDER_ORDER.CURSOR; - }, - - _handleControllerConnected: function(e) { - const data = { - controller: e.target, - handedness: e.detail.component.data.hand - }; - - if (data.handedness === this.data.handedness) { - this.controllerQueue.unshift(data); - } else { - this.controllerQueue.push(data); - } - - this._updateController(); - }, - - _handleControllerDisconnected: function(e) { - for (let i = 0; i < this.controllerQueue.length; i++) { - if (e.target === this.controllerQueue[i].controller) { - this.controllerQueue.splice(i, 1); - this._updateController(); - return; - } - } - }, - - _updateController: function() { - this.hasPointingDevice = this.controllerQueue.length > 0 && this.inVR; - - this.setCursorVisibility(this.hasPointingDevice || this.isMobile || (!this.isMobile && !this.inVR)); - - if (this.hasPointingDevice) { - const controllerData = this.controllerQueue[0]; - const hand = controllerData.handedness; - this.el.setAttribute("cursor-controller", { physicalHandSelector: `#player-${hand}-controller` }); - this.controller = controllerData.controller; - this.rayObject = controllerData.controller.querySelector(`#player-${hand}-controller-reverse-z`).object3D; - this.useMousePos = false; - } else { - this.controller = null; - if (this.inVR) { - const camera = this.data.camera.components.camera.camera; - this.rayObject = camera; - this.useMousePos = false; - } else { - this.useMousePos = true; - } - } + this.data.cursor.removeEventListener("loaded", this._handleCursorLoaded); } }); diff --git a/src/components/input-configurator.js b/src/components/input-configurator.js index e600dbdd5..23b582d1a 100644 --- a/src/components/input-configurator.js +++ b/src/components/input-configurator.js @@ -8,15 +8,22 @@ AFRAME.registerComponent("input-configurator", { this.inVR = this.el.sceneEl.is("vr-mode"); this.isMobile = AFRAME.utils.device.isMobile(); this.eventHandlers = []; + this.controller = null; + this.controllerQueue = []; + this.hasPointingDevice = false; this.cursor = document.querySelector("#cursor-controller").components["cursor-controller"]; this.gazeTeleporter = document.querySelector("#gaze-teleport").components["teleport-controls"]; this.cameraController = document.querySelector("#player-camera").components["camera-controller"]; + this.playerRig = document.querySelector("#player-rig"); + this.handedness = "right"; this.onEnterVR = this.onEnterVR.bind(this); this.onExitVR = this.onExitVR.bind(this); this.tearDown = this.tearDown.bind(this); this.configureInput = this.configureInput.bind(this); this.addLookOnMobile = this.addLookOnMobile.bind(this); + this.handleControllerConnected = this.handleControllerConnected.bind(this); + this.handleControllerDisconnected = this.handleControllerDisconnected.bind(this); this.el.sceneEl.addEventListener("enter-vr", this.onEnterVR); this.el.sceneEl.addEventListener("exit-vr", this.onExitVR); @@ -25,20 +32,32 @@ AFRAME.registerComponent("input-configurator", { this.configureInput(); }, + play() { + this.el.sceneEl.addEventListener("controllerconnected", this.handleControllerConnected); + this.el.sceneEl.addEventListener("controllerdisconnected", this.handleControllerDisconnected); + }, + + pause() { + this.el.sceneEl.removeEventListener("controllerconnected", this.handleControllerConnected); + this.el.sceneEl.removeEventListener("controllerdisconnected", this.handleControllerDisconnected); + }, + onEnterVR() { this.inVR = true; this.tearDown(); this.configureInput(); + this.updateController(); }, onExitVR() { this.inVR = false; this.tearDown(); this.configureInput(); + this.updateController(); }, tearDown() { - this.eventHandlers.forEach(handler => handler.tearDown()); + this.eventHandlers.forEach(h => h.tearDown()); this.eventHandlers = []; this.primaryActionHandler = null; if (this.lookOnMobile) { @@ -61,6 +80,7 @@ AFRAME.registerComponent("input-configurator", { configureInput() { if (this.inVR) { + this.cursor.useMousePos = false; this.cursorRequiresManagement = true; this.hovered = false; this.primaryActionHandler = new PrimaryActionHandler(this.el.sceneEl, this.cursor); @@ -70,6 +90,7 @@ AFRAME.registerComponent("input-configurator", { } } else { this.cameraController.play(); + this.cursor.useMousePos = true; if (this.isMobile) { this.eventHandlers.push(new TouchEventsHandler(this.cursor, this.cameraController, this.cursor.el)); this.addLookOnMobile(); @@ -82,8 +103,8 @@ AFRAME.registerComponent("input-configurator", { tick() { if (!this.cursorRequiresManagement) return; - if (this.cursor.physicalHand) { - const state = this.cursor.physicalHand.components["super-hands"].state; + if (this.physicalHand) { + const state = this.physicalHand.components["super-hands"].state; if (!this.hovered && state.has("hover-start") && !this.primaryActionHandler.isCursorInteracting) { this.cursor.disable(); this.hovered = true; @@ -93,5 +114,50 @@ AFRAME.registerComponent("input-configurator", { this.hovered = false; } } + }, + + handleControllerConnected: function(e) { + const data = { + controller: e.target, + handedness: e.detail.component.data.hand + }; + + if (data.handedness === this.handedness) { + this.controllerQueue.unshift(data); + } else { + this.controllerQueue.push(data); + } + + this.updateController(); + }, + + handleControllerDisconnected: function(e) { + for (let i = 0; i < this.controllerQueue.length; i++) { + if (e.target === this.controllerQueue[i].controller) { + this.controllerQueue.splice(i, 1); + this.updateController(); + return; + } + } + }, + + updateController: function() { + this.hasPointingDevice = this.controllerQueue.length > 0 && this.inVR; + + this.cursor.setCursorVisibility(this.hasPointingDevice || this.isMobile || (!this.isMobile && !this.inVR)); + + if (this.hasPointingDevice) { + const controllerData = this.controllerQueue[0]; + const hand = controllerData.handedness; + this.controller = controllerData.controller; + this.physicalHand = this.playerRig.querySelector(`#player-${hand}-controller`); + this.cursor.rayObject = this.controller.querySelector(`#player-${hand}-controller-reverse-z`).object3D; + } else { + this.controller = null; + } + + if (this.primaryActionHandler) { + this.primaryActionHandler.setCursorController(this.controller); + } } }); diff --git a/src/utils/primary-action-handler.js b/src/utils/primary-action-handler.js index 9a22c20ab..e9670acc8 100644 --- a/src/utils/primary-action-handler.js +++ b/src/utils/primary-action-handler.js @@ -4,6 +4,7 @@ export default class PrimaryActionHandler { this.cursor = cursor; this.isCursorInteracting = false; this.isTeleporting = false; + this.cursorController = null; this.addEventListeners = this.addEventListeners.bind(this); this.tearDown = this.tearDown.bind(this); @@ -43,8 +44,12 @@ export default class PrimaryActionHandler { } } + setCursorController(cursorController) { + this.cursorController = cursorController; + } + onGrab(e) { - if (this.cursor.controller && this.cursor.controller === e.target) { + if (this.cursorController && this.cursorController === e.target) { if (this.isCursorInteracting) { return; } else if (e.target.components["super-hands"].state.has("hover-start")) { @@ -61,7 +66,7 @@ export default class PrimaryActionHandler { } onRelease(e) { - if (this.isCursorInteracting && this.cursor.controller && this.cursor.controller === e.target) { + if (this.isCursorInteracting && this.cursorController && this.cursorController === e.target) { this.isCursorInteracting = false; this.cursor.endInteraction(); } else { @@ -70,7 +75,7 @@ export default class PrimaryActionHandler { } onPrimaryDown(e) { - if (this.cursor.controller && this.cursor.controller === e.target) { + if (this.cursorController && this.cursorController === e.target) { if (this.isCursorInteracting) { return; } else if (e.target.components["super-hands"].state.has("hover-start")) { @@ -89,7 +94,7 @@ export default class PrimaryActionHandler { } onPrimaryUp(e) { - const isCursorHand = this.cursor.controller && this.cursor.controller === e.target; + const isCursorHand = this.cursorController && this.cursorController === e.target; if (this.isCursorInteracting && isCursorHand) { this.isCursorInteracting = false; this.cursor.endInteraction(); -- GitLab