diff --git a/src/components/cursor-controller.js b/src/components/cursor-controller.js index 846c7a32d25efb0d8eba1028eb7ec804773388dc..d4a1cd9cc6fdf38d13ee7e60843bc4144bca0aad 100644 --- a/src/components/cursor-controller.js +++ b/src/components/cursor-controller.js @@ -15,11 +15,7 @@ AFRAME.registerComponent("cursor-controller", { maxDistance: { default: 3 }, minDistance: { default: 0.5 }, cursorColorHovered: { default: "#2F80ED" }, - cursorColorUnhovered: { default: "#FFFFFF" }, - primaryDown: { default: "action_primary_down" }, - primaryUp: { default: "action_primary_up" }, - grabEvent: { default: "action_grab" }, - releaseEvent: { default: "action_release" } + cursorColorUnhovered: { default: "#FFFFFF" } }, init: function() { @@ -27,7 +23,6 @@ AFRAME.registerComponent("cursor-controller", { this.isMobile = AFRAME.utils.device.isMobile(); this.hasPointingDevice = false; this.currentTargetType = TARGET_TYPE_NONE; - this.grabStarting = false; this.currentDistance = this.data.maxDistance; this.currentDistanceMod = 0; this.mousePos = new THREE.Vector2(); @@ -41,17 +36,11 @@ AFRAME.registerComponent("cursor-controller", { this.data.cursor.setAttribute("material", { color: this.data.cursorColorUnhovered }); - window.APP.touchEventsHandler.registerPinchEmitter(this.el); - window.APP.touchEventsHandler.registerCursor(this); - window.APP.mouseEventsHandler.registerCursor(this); - window.APP.primaryActionHandler.registerCursor(this); - this.startInteractionAndForceCursorUpdate = this.startInteractionAndForceCursorUpdate.bind(this); this.startInteraction = this.startInteraction.bind(this); this.moveCursor = this.moveCursor.bind(this); this.endInteraction = this.endInteraction.bind(this); this.handleMouseWheel = this.handleMouseWheel.bind(this); - this._handleEnterVR = this._handleEnterVR.bind(this); this._handleExitVR = this._handleExitVR.bind(this); this._handleModelLoaded = this._handleModelLoaded.bind(this); @@ -80,10 +69,6 @@ AFRAME.registerComponent("cursor-controller", { window.addEventListener("enter-vr", this._handleEnterVR); window.addEventListener("exit-vr", this._handleExitVR); - // this.data.playerRig.addEventListener(this.data.primaryDown, this._handlePrimaryDown); - // this.data.playerRig.addEventListener(this.data.primaryUp, this._handlePrimaryUp); - //this.data.playerRig.addEventListener(this.data.grabEvent, this._handlePrimaryDown); - //this.data.playerRig.addEventListener(this.data.releaseEvent, this._handlePrimaryUp); //this.data.playerRig.addEventListener("cardboardbuttondown", this._handlePrimaryDown); //this.data.playerRig.addEventListener("cardboardbuttonup", this._handlePrimaryUp); this.data.playerRig.addEventListener("model-loaded", this._handleModelLoaded); @@ -96,12 +81,8 @@ AFRAME.registerComponent("cursor-controller", { window.removeEventListener("enter-vr", this._handleEnterVR); window.removeEventListener("exit-vr", this._handleExitVR); - //this.data.playerRig.removeEventListener(this.data.primaryDown, this._handlePrimaryDown); - //this.data.playerRig.removeEventListener(this.data.primaryUp, this._handlePrimaryUp); - //this.data.playerRig.removeEventListener(this.data.grabEvent, this._handlePrimaryDown); - //this.data.playerRig.removeEventListener(this.data.releaseEvent, this._handlePrimaryUp); - this.data.playerRig.removeEventListener("cardboardbuttondown", this._handlePrimaryDown); - this.data.playerRig.removeEventListener("cardboardbuttonup", this._handlePrimaryUp); + //this.data.playerRig.removeEventListener("cardboardbuttondown", this._handlePrimaryDown); + //this.data.playerRig.removeEventListener("cardboardbuttonup", this._handlePrimaryUp); this.data.playerRig.removeEventListener("model-loaded", this._handleModelLoaded); @@ -119,7 +100,9 @@ AFRAME.registerComponent("cursor-controller", { this.currentTargetType = TARGET_TYPE_NONE; } this.wasPhysicalHandGrabbing = isPhysicalHandGrabbing; - if (isPhysicalHandGrabbing) return; + if (isPhysicalHandGrabbing) { + return; + } } //set raycaster origin/direction @@ -223,7 +206,7 @@ AFRAME.registerComponent("cursor-controller", { raycasterComp.checkIntersections(); const intersections = raycasterComp.intersections; if (intersections.length === 0 || intersections[0].distance >= this.data.maxDistance) { - return; + return false; } cursor.object3D.position.copy(intersections[0].point); // Cursor position must be synced to physics before constraint is created diff --git a/src/components/super-spawner.js b/src/components/super-spawner.js index 7bd554f5a5ae07026896c45f0a837f5fb7467be3..2d9ba8d789fcddb4f0453f1a12f7d3c23a37e1b1 100644 --- a/src/components/super-spawner.js +++ b/src/components/super-spawner.js @@ -5,7 +5,7 @@ AFRAME.registerComponent("super-spawner", { spawnPosition: { type: "vec3" }, useCustomSpawnRotation: { default: false }, spawnRotation: { type: "vec4" }, - events: { default: ["cursor-grab", "action_grab"] }, + events: { default: ["cursor-grab", "hand_grab"] }, spawnCooldown: { default: 1 } }, diff --git a/src/hub.html b/src/hub.html index 531b838713b4d6810634f0e5266de24fa3b06e26..b489c7945720a559ea7208bb094d016cae31cc14 100644 --- a/src/hub.html +++ b/src/hub.html @@ -184,9 +184,9 @@ super-hands=" colliderEvent: collisions; colliderEventProperty: els; colliderEndEvent: collisions; colliderEndEventProperty: clearedEls; - grabStartButtons: action_grab; grabEndButtons: action_release; - stretchStartButtons: action_grab; stretchEndButtons: action_release; - dragDropStartButtons: action_grab; dragDropEndButtons: action_release;" + grabStartButtons: hand_grab; grabEndButtons: hand_release; + stretchStartButtons: hand_grab; stretchEndButtons: hand_release; + dragDropStartButtons: hand_grab; dragDropEndButtons: hand_release;" collision-filter="collisionForces: false" physics-collider ></a-mixin> @@ -266,7 +266,7 @@ teleport-controls=" cameraRig: #player-rig; teleportOrigin: #player-camera; - button: cursor-teleport_; + button: gaze-teleport_; collisionEntities: [nav-mesh]; drawIncrementally: true; incrementalDrawMs: 600; diff --git a/src/hub.js b/src/hub.js index d551d546d4940b0253c6d215adf2557697b6b599..23cfc97b179d03df7f70d8969d984071cadfd999 100644 --- a/src/hub.js +++ b/src/hub.js @@ -126,8 +126,6 @@ import ConcurrentLoadDetector from "./utils/concurrent-load-detector.js"; import TouchEventsHandler from "./utils/touch-events-handler.js"; import { MouseEventsHandler, GearVRMouseEventsHandler } from "./utils/mouse-events-handler.js"; import PrimaryActionHandler from "./utils/primary-action-handler.js"; -window.APP.touchEventsHandler = new TouchEventsHandler(); // TODO: Do not create TouchEventsHandler unless on mobile -window.APP.mouseEventsHandler = new MouseEventsHandler(); function qsTruthy(param) { const val = qs[param]; @@ -187,7 +185,6 @@ function mountUI(scene, props = {}) { const onReady = async () => { const scene = document.querySelector("a-scene"); - window.APP.primaryActionHandler = new PrimaryActionHandler(scene); const hubChannel = new HubChannel(store); document.querySelector("canvas").classList.add("blurred"); @@ -240,25 +237,59 @@ const onReady = async () => { if (enterInVR) { scene.enterVR(); + window.APP.primaryActionHandler = new PrimaryActionHandler(scene); + + const cursorEl = document.querySelector("#cursor-controller"); + if (cursorEl && cursorEl.components && cursorEl.components["cursor-controller"]) { + const cursor = cursorEl.components["cursor-controller"]; + window.APP.primaryActionHandler.registerCursor(cursor); + } else { + const registerCursor = e => { + if (e.detail.name !== "cursor-controller") return; + const cursor = cursorEl.components["cursor-controller"]; + window.APP.primaryActionHandler.registerCursor(cursor); + }; + cursorEl.addEventListener("componentinitialized", registerCursor); + } + } else { + window.APP.touchEventsHandler = new TouchEventsHandler(); // TODO: Do not create TouchEventsHandler unless on mobile + window.APP.mouseEventsHandler = new MouseEventsHandler(); + + const camera = document.querySelector("#player-camera"); + const registerCameraController = e => { + if (e.detail.name !== "camera-controller") return; + camera.removeEventListener("componentinitialized", registerCameraController); + + window.APP.touchEventsHandler.registerCameraController(camera.components["camera-controller"]); + scene.components["look-on-mobile"].registerCameraController(camera.components["camera-controller"]); + scene.setAttribute("look-on-mobile", "enabled", true); + + window.APP.mouseEventsHandler.registerCameraController(camera.components["camera-controller"]); + window.APP.mouseEventsHandler.setInverseMouseLook(qsTruthy("invertMouseLook")); + }; + camera.addEventListener("componentinitialized", registerCameraController); + camera.setAttribute("camera-controller", "foo", "bar"); + + const cursorEl = document.querySelector("#cursor-controller"); + if (cursorEl && cursorEl.components && cursorEl.components["cursor-controller"]) { + const cursor = cursorEl.components["cursor-controller"]; + window.APP.touchEventsHandler.registerPinchEmitter(cursorEl); + window.APP.touchEventsHandler.registerCursor(cursor); + window.APP.mouseEventsHandler.registerCursor(cursor); + } else { + const registerCursor = e => { + if (e.detail.name !== "cursor-controller") return; + const cursor = cursorEl.components["cursor-controller"]; + window.APP.touchEventsHandler.registerPinchEmitter(cursorEl); + window.APP.touchEventsHandler.registerCursor(cursor); + window.APP.mouseEventsHandler.registerCursor(cursor); + }; + cursorEl.addEventListener("componentinitialized", registerCursor); + } } AFRAME.registerInputActions(inGameActions, "default"); - const camera = document.querySelector("#player-camera"); - const registerCameraController = e => { - if (e.detail.name !== "camera-controller") return; - camera.removeEventListener("componentinitialized", registerCameraController); - - window.APP.touchEventsHandler.registerCameraController(camera.components["camera-controller"]); - scene.components["look-on-mobile"].registerCameraController(camera.components["camera-controller"]); - scene.setAttribute("look-on-mobile", "enabled", true); - - window.APP.mouseEventsHandler.registerCameraController(camera.components["camera-controller"]); - window.APP.mouseEventsHandler.setInverseMouseLook(qsTruthy("invertMouseLook")); - }; - camera.addEventListener("componentinitialized", registerCameraController); - camera.setAttribute("camera-controller", "foo", "bar"); - scene.setAttribute("networked-scene", { room: hubId, serverURL: process.env.JANUS_SERVER diff --git a/src/utils/primary-action-handler.js b/src/utils/primary-action-handler.js index 2c64d3117c8de3efbcf9e0c90632cb273c16d3ee..aefb8a59543e47730d20042ae49e3286368caf29 100644 --- a/src/utils/primary-action-handler.js +++ b/src/utils/primary-action-handler.js @@ -1,18 +1,16 @@ export default class PrimaryActionHandler { constructor(scene) { - this.cursor = null; - this.handledByCursor = false; - this.handledByTeleport = false; - - this.rightTeleporter = null; - this.leftTeleporter = null; this.scene = scene; + this.cursor = null; + this.isCursorInteracting = false; this.registerCursor = this.registerCursor.bind(this); this.isReady = this.isReady.bind(this); this.addEventListeners = this.addEventListeners.bind(this); this.onPrimaryDown = this.onPrimaryDown.bind(this); this.onPrimaryUp = this.onPrimaryUp.bind(this); + this.onGrab = this.onGrab.bind(this); + this.onRelease = this.onRelease.bind(this); } registerCursor(cursor) { @@ -29,35 +27,69 @@ export default class PrimaryActionHandler { addEventListeners() { this.scene.addEventListener("action_primary_down", this.onPrimaryDown); this.scene.addEventListener("action_primary_up", this.onPrimaryUp); + this.scene.addEventListener("action_grab", this.onGrab); + this.scene.addEventListener("action_release", this.onRelease); } - onPrimaryDown(e) { - this.handledByCursor = this.cursor.startInteraction(); - if (this.handledByCursor) return; - this.cursor.setCursorVisibility(false); + onGrab(e) { + if (e.target.id.match(this.cursor.data.handedness)) { + if (this.isCursorInteracting) { + return; + } else if (e.target.components["super-hands"].state.has("hover-start")) { + e.target.emit("hand_grab"); + return; + } else { + this.isCursorInteracting = this.cursor.startInteraction(); + return; + } + } else { + e.target.emit("hand_grab"); + return; + } + } - // Do teleport things. - if (!e.target.components["teleport-controls"]) { - console.error("no teleport controls"); + onRelease(e) { + if (e.target.id.match(this.cursor.data.handedness) && this.isCursorInteracting) { + this.isCursorInteracting = false; + this.cursor.endInteraction(); + } else { + e.target.emit("hand_release"); } + } + + // "Primary" buttons interact with super hands, the cursor, and teleport controls + onPrimaryDown(e) { + if (e.target.id.match(this.cursor.data.handedness)) { + if (this.isCursorInteracting) { + return; + } else if (e.target.components["super-hands"].state.has("hover-start")) { + e.target.emit("hand_grab"); + return; + } else { + this.isCursorInteracting = this.cursor.startInteraction(); + if (this.isCursorInteracting) return; + } + } + + this.cursor.setCursorVisibility(false); const button = e.target.components["teleport-controls"].data.button; e.target.emit(button + "down"); } onPrimaryUp(e) { - if (this.handledByCursor) { + if (e.target.id.match(this.cursor.data.handedness) && this.isCursorInteracting) { + this.isCursorInteracting = false; this.cursor.endInteraction(); return; } - // Do teleport things. - if (!e.target.components["teleport-controls"]) { - console.error("no teleport controls"); + // TODO: Figure out if this event target is grabbing something, then decide whether to end the teleport or end the grab + if (e.target.components["super-hands"].state.has("grab-start")) { + e.target.emit("hand_release"); } - const button = e.target.components["teleport-controls"].data.button; - e.target.emit(button + "up"); - // Show cursor this.cursor.setCursorVisibility(true); + const button = e.target.components["teleport-controls"].data.button; + e.target.emit(button + "up"); } } diff --git a/src/utils/touch-events-handler.js b/src/utils/touch-events-handler.js index 7f712ff5129324f3d9cf9050ad5ecb9d27ec1601..24f58c5d8d089b3f62c102d944db636f7c80fbf6 100644 --- a/src/utils/touch-events-handler.js +++ b/src/utils/touch-events-handler.js @@ -64,6 +64,8 @@ export default class TouchEventsHandler { } handleTouchStart(e) { + console.log(e); + this.cursor.setCursorVisibility(false); Array.prototype.forEach.call(e.changedTouches, this.singleTouchStart); }