From 56acd879e0a79411cd333b24ab91d2008579e1b7 Mon Sep 17 00:00:00 2001
From: joni <johnfshaughnessy@gmail.com>
Date: Mon, 4 Jun 2018 11:01:59 -0700
Subject: [PATCH] Ensure gaze cursor on VR desktop works with mouse

---
 src/components/cursor-controller.js           | 12 ++++++++--
 src/components/input-configurator.js          | 24 +++++++++++--------
 ...camera-controller.js => pitch-yaw-rotator} | 10 ++++----
 src/hub.html                                  |  3 ++-
 src/hub.js                                    |  2 +-
 ...ion-handler.js => action-event-handler.js} |  8 +++----
 src/utils/mouse-events-handler.js             |  3 ---
 7 files changed, 36 insertions(+), 26 deletions(-)
 rename src/components/{camera-controller.js => pitch-yaw-rotator} (58%)
 rename src/utils/{primary-action-handler.js => action-event-handler.js} (98%)

diff --git a/src/components/cursor-controller.js b/src/components/cursor-controller.js
index 650e6746d..be2763119 100644
--- a/src/components/cursor-controller.js
+++ b/src/components/cursor-controller.js
@@ -117,7 +117,7 @@ AFRAME.registerComponent("cursor-controller", {
 
   setCursorVisibility(visible) {
     this.data.cursor.setAttribute("visible", visible);
-    this.el.setAttribute("line", { visible: visible && this.hasPointingDevice });
+    this.el.setAttribute("line", { visible: visible && this.drawLine });
   },
 
   forceCursorUpdate: function() {
@@ -162,7 +162,15 @@ AFRAME.registerComponent("cursor-controller", {
   },
 
   changeDistanceMod: function(delta) {
-    this.currentDistanceMod += delta;
+    const { minDistance, maxDistance } = this.data;
+    const targetDistanceMod = this.currentDistanceMod + delta;
+    if (this.currentDistance - targetDistanceMod > maxDistance) {
+      return;
+    }
+    if (this.currentDistance - targetDistanceMod < minDistance) {
+      return;
+    }
+    this.currentDistanceMod = targetDistanceMod;
   },
 
   _handleCursorLoaded: function() {
diff --git a/src/components/input-configurator.js b/src/components/input-configurator.js
index a10a0648c..1ea4796fb 100644
--- a/src/components/input-configurator.js
+++ b/src/components/input-configurator.js
@@ -1,7 +1,7 @@
 import TouchEventsHandler from "../utils/touch-events-handler.js";
 import MouseEventsHandler from "../utils/mouse-events-handler.js";
 import GearVRMouseEventsHandler from "../utils/gearvr-mouse-events-handler.js";
-import PrimaryActionHandler from "../utils/primary-action-handler.js";
+import ActionEventHandler from "../utils/action-event-handler.js";
 
 AFRAME.registerComponent("input-configurator", {
   init() {
@@ -11,9 +11,10 @@ AFRAME.registerComponent("input-configurator", {
     this.controller = null;
     this.controllerQueue = [];
     this.hasPointingDevice = false;
+    this.gazeCursorRayObject = document.querySelector("#player-camera-reverse-z");
     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.cameraController = document.querySelector("#player-camera").components["pitch-yaw-rotator"];
     this.playerRig = document.querySelector("#player-rig");
     this.handedness = "right";
 
@@ -59,7 +60,7 @@ AFRAME.registerComponent("input-configurator", {
   tearDown() {
     this.eventHandlers.forEach(h => h.tearDown());
     this.eventHandlers = [];
-    this.primaryActionHandler = null;
+    this.actionEventHandler = null;
     if (this.lookOnMobile) {
       this.lookOnMobile.el.removeComponent("look-on-mobile");
       this.lookOnMobile = null;
@@ -83,10 +84,12 @@ AFRAME.registerComponent("input-configurator", {
       this.cursor.useMousePos = false;
       this.cursorRequiresManagement = true;
       this.hovered = false;
-      this.primaryActionHandler = new PrimaryActionHandler(this.el.sceneEl, this.cursor);
-      this.eventHandlers.push(this.primaryActionHandler);
+      this.actionEventHandler = new ActionEventHandler(this.el.sceneEl, this.cursor);
+      this.eventHandlers.push(this.actionEventHandler);
       if (this.isMobile) {
         this.eventHandlers.push(new GearVRMouseEventsHandler(this.cursor, this.gazeTeleporter));
+      } else {
+        this.eventHandlers.push(new MouseEventsHandler(this.cursor, this.cameraController));
       }
     } else {
       this.cameraController.play();
@@ -105,12 +108,12 @@ AFRAME.registerComponent("input-configurator", {
 
     if (this.physicalHand) {
       const state = this.physicalHand.components["super-hands"].state;
-      if (!this.hovered && state.has("hover-start") && !this.primaryActionHandler.isCursorInteracting) {
+      if (!this.hovered && state.has("hover-start") && !this.actionEventHandler.isCursorInteracting) {
         this.cursor.disable();
         this.hovered = true;
       } else if (this.hovered === true && !state.has("hover-start") && !state.has("grab-start")) {
         this.cursor.enable();
-        this.cursor.setCursorVisibility(!this.primaryActionHandler.isTeleporting);
+        this.cursor.setCursorVisibility(!this.actionEventHandler.isTeleporting);
         this.hovered = false;
       }
     }
@@ -145,7 +148,7 @@ AFRAME.registerComponent("input-configurator", {
     this.hasPointingDevice = this.controllerQueue.length > 0 && this.inVR;
     this.cursor.drawLine = this.hasPointingDevice;
 
-    this.cursor.setCursorVisibility(this.hasPointingDevice || this.isMobile || (!this.isMobile && !this.inVR));
+    this.cursor.setCursorVisibility(true);
 
     if (this.hasPointingDevice) {
       const controllerData = this.controllerQueue[0];
@@ -155,10 +158,11 @@ AFRAME.registerComponent("input-configurator", {
       this.cursor.rayObject = this.controller.querySelector(`#player-${hand}-controller-reverse-z`).object3D;
     } else {
       this.controller = null;
+      this.cursor.rayObject = this.gazeCursorRayObject.object3D;
     }
 
-    if (this.primaryActionHandler) {
-      this.primaryActionHandler.setCursorController(this.controller);
+    if (this.actionEventHandler) {
+      this.actionEventHandler.setCursorController(this.controller);
     }
   }
 });
diff --git a/src/components/camera-controller.js b/src/components/pitch-yaw-rotator
similarity index 58%
rename from src/components/camera-controller.js
rename to src/components/pitch-yaw-rotator
index 7e4fe975c..cc62dd1c5 100644
--- a/src/components/camera-controller.js
+++ b/src/components/pitch-yaw-rotator
@@ -1,7 +1,7 @@
-AFRAME.registerComponent("camera-controller", {
+AFRAME.registerComponent("pitch-yaw-rotator", {
   schema: {
-    lookDownLimit: { default: -50 },
-    lookUpLimit: { default: 50 }
+    minPitch: { default: -50 },
+    maxPitch: { default: 50 }
   },
 
   init() {
@@ -11,9 +11,9 @@ AFRAME.registerComponent("camera-controller", {
   },
 
   look(deltaPitch, deltaYaw) {
-    const { lookDownLimit, lookUpLimit } = this.data;
+    const { minPitch, maxPitch } = this.data;
     this.pitch += deltaPitch;
-    this.pitch = Math.max(lookDownLimit, Math.min(lookUpLimit, this.pitch));
+    this.pitch = Math.max(minPitch, Math.min(maxPitch, this.pitch));
     this.yaw += deltaYaw;
   },
 
diff --git a/src/hub.html b/src/hub.html
index d61dc3333..36708f681 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -263,7 +263,7 @@
                 camera
                 position="0 1.6 0"
                 personal-space-bubble="radius: 0.4"
-                camera-controller
+                pitch-yaw-rotator
             >
                 <a-entity
                     id="gaze-teleport"
@@ -278,6 +278,7 @@
                     hitOpacity: 0.3;
                     missOpacity: 0.2;"
                 ></a-entity>
+                <a-entity id="player-camera-reverse-z" rotation="0 180 0"></a-entity>
             </a-entity>
 
             <a-entity
diff --git a/src/hub.js b/src/hub.js
index 0dbd43739..76b202b3d 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -64,7 +64,7 @@ import "./components/scene-shadow";
 import "./components/avatar-replay";
 import "./components/pinch-to-move";
 import "./components/look-on-mobile";
-import "./components/camera-controller";
+import "./components/pitch-yaw-rotator";
 import "./components/input-configurator";
 
 import ReactDOM from "react-dom";
diff --git a/src/utils/primary-action-handler.js b/src/utils/action-event-handler.js
similarity index 98%
rename from src/utils/primary-action-handler.js
rename to src/utils/action-event-handler.js
index e9670acc8..8f500eacd 100644
--- a/src/utils/primary-action-handler.js
+++ b/src/utils/action-event-handler.js
@@ -1,4 +1,4 @@
-export default class PrimaryActionHandler {
+export default class ActionEventHandler {
   constructor(scene, cursor) {
     this.scene = scene;
     this.cursor = cursor;
@@ -23,9 +23,9 @@ export default class PrimaryActionHandler {
     this.scene.addEventListener("action_primary_up", this.onPrimaryUp);
     this.scene.addEventListener("action_grab", this.onGrab);
     this.scene.addEventListener("action_release", this.onRelease);
-    this.scene.addEventListener("cardboardbuttondown", this.onCardboardButtonDown);
-    this.scene.addEventListener("cardboardbuttonup", this.onCardboardButtonUp);
     this.scene.addEventListener("move_duck", this.onMoveDuck);
+    this.scene.addEventListener("cardboardbuttondown", this.onCardboardButtonDown); // TODO: These should be actions
+    this.scene.addEventListener("cardboardbuttonup", this.onCardboardButtonUp);
   }
 
   tearDown() {
@@ -33,9 +33,9 @@ export default class PrimaryActionHandler {
     this.scene.removeEventListener("action_primary_up", this.onPrimaryUp);
     this.scene.removeEventListener("action_grab", this.onGrab);
     this.scene.removeEventListener("action_release", this.onRelease);
+    this.scene.removeEventListener("move_duck", this.onMoveDuck);
     this.scene.removeEventListener("cardboardbuttondown", this.onCardboardButtonDown);
     this.scene.removeEventListener("cardboardbuttonup", this.onCardboardButtonUp);
-    this.scene.removeEventListener("move_duck", this.onMoveDuck);
   }
 
   onMoveDuck(e) {
diff --git a/src/utils/mouse-events-handler.js b/src/utils/mouse-events-handler.js
index 43c92f11e..54856666c 100644
--- a/src/utils/mouse-events-handler.js
+++ b/src/utils/mouse-events-handler.js
@@ -59,9 +59,6 @@ export default class MouseEventsHandler {
   onLeftButtonDown() {
     this.isLeftButtonDown = true;
     this.isLeftButtonHandledByCursor = this.cursor.startInteraction();
-    if (this.isLeftButtonHandledByCursor) {
-      return;
-    }
   }
 
   onRightButtonDown() {
-- 
GitLab