From ee80fc5778455fea3bab6546079eef6bf4100e66 Mon Sep 17 00:00:00 2001
From: joni <johnfshaughnessy@gmail.com>
Date: Tue, 21 Nov 2017 14:40:42 -0800
Subject: [PATCH] Add dpad and pressed dpad on vive.

---
 src/components/character-controller.js |   4 +-
 src/components/split-axis-events.js    | 103 ++++++++++++++++++++-----
 src/input-mappings.js                  |  25 ++----
 templates/room.hbs                     |   9 ++-
 4 files changed, 98 insertions(+), 43 deletions(-)

diff --git a/src/components/character-controller.js b/src/components/character-controller.js
index 141b056c3..4d73bb9d9 100644
--- a/src/components/character-controller.js
+++ b/src/components/character-controller.js
@@ -5,7 +5,7 @@ const MAX_DELTA = 0.2;
 AFRAME.registerComponent("character-controller", {
   schema: {
     groundAcc: { default: 7 },
-    easing: { default: 8 },
+    easing: { default: 10 },
     pivot: { type: "selector" },
     snapRotationRadian: { default: THREE.Math.DEG2RAD * 45 },
     wasdSpeed: { default: 0.8 },
@@ -291,7 +291,7 @@ AFRAME.registerComponent("character-controller", {
     velocity.x += dvx;
     velocity.z += dvz;
 
-    const decay = 0.9;
+    const decay = 0.7;
     this.accelerationInput.x = this.accelerationInput.x * decay;
     this.accelerationInput.z = this.accelerationInput.z * decay;
   }
diff --git a/src/components/split-axis-events.js b/src/components/split-axis-events.js
index 40c3bf4df..62c2e7def 100644
--- a/src/components/split-axis-events.js
+++ b/src/components/split-axis-events.js
@@ -32,7 +32,8 @@ const angleTo8Direction = function(angle) {
 AFRAME.registerComponent("dpad-as-axes", {
   schema: {
     inputName: { default: "dpad" },
-    name: { default: "dpad_axes" }
+    name: { default: "dpad_axes" },
+    emitter: { default: "#left-hand" }
   },
 
   init: function() {
@@ -97,9 +98,9 @@ AFRAME.registerComponent("dpad-as-axes", {
   emitAxes: function(axes) {
     const name = this.data.name;
     const inputName = this.data.inputName;
-    const el = this.el;
+    const emitter = document.querySelector(this.data.emitter);
     return function(event) {
-      event.target.emit(name, { axis: [axes[0], axes[1]] });
+      emitter.emit(name, { axis: [axes[0], axes[1]] });
     };
   }
 });
@@ -257,39 +258,103 @@ AFRAME.registerComponent("haptic-feedback", {
   }
 });
 
-AFRAME.registerComponent("split-axis-events", {
+AFRAME.registerComponent("vive-controls-extended", {
+  schema: {
+    hand: { default: "left" },
+    dpad: { default: false },
+    dpad_livezone: { default: 0.3 },
+    dpad_deadzone: { default: 0.8 },
+    dpad_directions: { default: 4 },
+    dpad_turbo: { default: true },
+    dpad_pressed_turbo: { default: false },
+    center_zone: { default: 0.3 }
+  },
+
   init: function() {
-    this.pressed = false;
+    this.dpadCanFire = true;
+    this.dpadPressedCanFire = true;
+    this.trackpadPressed = false;
     this.onAxisMove = this.onAxisMove.bind(this);
+    this.lastSeenAxes = [0, 0];
     this.onButtonChanged = this.onButtonChanged.bind(this);
   },
 
   play: function() {
     this.el.addEventListener("axismove", this.onAxisMove);
-    this.el.addEventListener("buttonchanged", this.onButtonChanged);
+    this.el.addEventListener("trackpadchanged", this.onButtonChanged);
   },
 
   pause: function() {
     this.el.removeEventListener("axismove", this.onAxisMove);
-    this.el.removeEventListener("buttonchanged", this.onButtonChanged);
+    this.el.removeEventListener("trackpadchanged", this.onButtonChanged);
   },
 
   onAxisMove: function(event) {
-    var hand = "right";
-    this.el.emit(
-      `${hand}_touchpad${this.pressed ? "_pressed" : ""}_axismove_x`,
-      { value: event.detail.axis[0] }
-    );
-    this.el.emit(
-      `${hand}_touchpad${this.pressed ? "_pressed" : ""}_axismove_y`,
-      { value: event.detail.axis[1] }
-    );
+    var x = event.detail.axis[0];
+    var y = event.detail.axis[1];
+    this.lastSeenAxes = [x, y];
+    var hand = this.data.hand;
+    const axisMoveEvent = `${hand}_trackpad${this.trackpadPressed
+      ? "_pressed"
+      : ""}_axismove`;
+    this.el.emit(axisMoveEvent, {
+      axis: [x, y]
+    });
+
+    var deadzone = this.data.dpad_deadzone;
+    var turbo = this.data.dpad_turbo;
+    var pressedTurbo = this.data.dpad_pressed_turbo;
+    var livezone = this.data.dpad_livezone;
+    var directions = this.data.dpad_directions;
+    var haptic_intensity = this.data.dpad_haptic_intensity;
+
+    if (!turbo && Math.abs(x) < livezone && Math.abs(y) < livezone) {
+      this.dpadCanFire = true;
+    }
+
+    x = Math.abs(x) < deadzone ? 0 : x;
+    y = Math.abs(y) < deadzone ? 0 : y;
+    if (x == 0 && y == 0) return;
+    var angle = Math.atan2(x, y);
+    var direction =
+      directions === 4 ? angleTo4Direction(angle) : angleTo8Direction(angle);
+
+    if (!this.dpadCanFire && !this.trackpadPressed) {
+      return;
+    }
+    if (this.trackpadPressed && !this.dpadPressedCanFire) {
+      return;
+    }
+    var dpadEvent = `${hand}_trackpad_dpad${this.trackpadPressed
+      ? "_pressed"
+      : ""}_${direction}`;
+    event.target.emit(dpadEvent);
+    event.target.emit(`${hand}_haptic_pulse`, { intensity: haptic_intensity }); // TODO: Catch these events an make the controller rumble.
+    if (!this.trackpadPressed && !turbo) {
+      this.dpadCanFire = false;
+    }
+    if (this.trackpadPressed && !pressedTurbo) {
+      this.dpadPressedCanFire = false;
+    }
   },
 
   onButtonChanged: function(event) {
-    if (this.pressed && !event.detail.state.pressed) {
-      this.el.emit("touchpadbuttonup");
+    const x = this.lastSeenAxes[0];
+    const y = this.lastSeenAxes[1];
+    const hand = this.data.hand;
+    const centerZone = this.data.center_zone;
+    const down = !this.trackpadPressed && event.detail.pressed;
+    const up = this.trackpadPressed && !event.detail.pressed;
+    const center =
+      Math.abs(x) < centerZone && Math.abs(y) < centerZone ? "_center" : "";
+    const eventName = `${hand}_trackpad${center}${up ? "_up" : ""}${down
+      ? "_down"
+      : ""}`;
+    this.el.emit(eventName);
+    if (up) {
+      this.dpadPressedCanFire = true;
     }
-    this.pressed = event.detail.state.pressed;
+
+    this.trackpadPressed = event.detail.pressed;
   }
 });
diff --git a/src/input-mappings.js b/src/input-mappings.js
index 59253960a..9193c3d43 100644
--- a/src/input-mappings.js
+++ b/src/input-mappings.js
@@ -3,17 +3,15 @@ export default function registerInputMappings() {
     mappings: {
       default: {
         common: {
-          // @TODO these dpad events are emmited by an axis-dpad component. This should probalby move into either tracked-controller or input-mapping
+          dpad_axes: "move" // This won't get received by the character controller if it is in the "keyboard" section, but this dpad is powered by wasd.
         },
         "vive-controls": {
           menudown: "action_mute",
-          left_touchpad_pressed_axismove_x: "translateX",
-          left_touchpad_pressed_axismove_y: "translateZ",
-          touchpadbuttonup: "stop_moving",
-          rightdpadleftdown: "action_snap_rotate_left",
-          rightdpadrightdown: "action_snap_rotate_right",
-          rightdpadcenterdown: "action_teleport_down", // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_aim"
-          rightdpadcenterup: "action_teleport_up" // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_teleport"
+          left_trackpad_pressed_axismove: "move",
+          right_trackpad_dpad_pressed_west: "action_snap_rotate_left",
+          right_trackpad_dpad_pressed_east: "action_snap_rotate_right",
+          right_trackpad_center_down: "action_teleport_down", // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_aim"
+          right_trackpad_center_up: "action_teleport_up" // @TODO once once #30 lands in aframe-teleport controls this just maps to "action_teleport_teleport"
         },
         "oculus-touch-controls": {
           xbuttondown: "action_mute",
@@ -36,16 +34,7 @@ export default function registerInputMappings() {
           m_press: "action_mute",
           q_press: "action_snap_rotate_left",
           e_press: "action_snap_rotate_right",
-          v_press: "action_share_screen",
-          w_down: "action_move_forward",
-          w_up: "action_dont_move_forward",
-          a_down: "action_move_left",
-          a_up: "action_dont_move_left",
-          s_down: "action_move_backward",
-          s_up: "action_dont_move_backward",
-          d_down: "action_move_right",
-          d_up: "action_dont_move_right",
-          dpad_axes: "move" // Why is the character controller not able to receive this one?
+          v_press: "action_share_screen"
         }
       }
     }
diff --git a/templates/room.hbs b/templates/room.hbs
index 7385b1aea..848d549a1 100644
--- a/templates/room.hbs
+++ b/templates/room.hbs
@@ -123,7 +123,7 @@
             spawn-controller="radius: 4;"
             character-controller="pivot: #head"
             wasd-dpad
-            dpad-as-axes="inputName:dpad; name:dpad_axes"
+            dpad-as-axes="inputName:dpad; name:dpad_axes; emitter: #left-hand"
         >
             <a-sphere scale="0.1 0.1 0.1"></a-sphere>
 
@@ -132,7 +132,7 @@
                 camera="userHeight: 1.6"
                 personal-space-bubble
                 look-controls
-                networked="template: #head-template; showLocalTemplate: false;" 
+                networked="template: #head-template; showLocalTemplate: false;"
             ></a-entity>
 
             <a-entity
@@ -140,7 +140,6 @@
                 body-controller="eyeNeckOffset: 0 -0.11 0.09; neckHeight: 0.05"
                 networked="template: #body-template;"
             ></a-entity>
-             
             <a-entity
                 id="nametag"
                 networked="template: #nametag-template; showLocalTemplate: false;"
@@ -152,7 +151,8 @@
                 tracked-controls
                 haptic-feedback
                 oculus-touch-controls-extended="dpad: true; dpad_deadzone: 0.8; dpad_livezone: 0.3; dpad_directions: 8; dpad_turbo: true"
-                dpad-as-axes="inputName:left_dpad; name:left_dpad_axes"
+                vive-controls-extended="hand:left"
+                dpad-as-axes="inputName:left_dpad; name:left_dpad_axes; emitter: #left-hand"
                 teleport-controls="cameraRig: #player-rig; teleportOrigin: #head; button: action_teleport_"
                 networked="template: #left-hand-template;"
             >
@@ -170,6 +170,7 @@
                 id="right-hand"
                 hand-controls2="right"
                 oculus-touch-controls-extended="hand:right; dpad: true; dpad_livezone: 0.3; dpad_deadzone: 0.8; dpad_directions: 4; dpad_turbo: false"
+                vive-controls-extended="hand:right; dpad: true; dpad_livezone: 1.0; dpad_deadzone: 0.6; dpad_directions: 4; dpad_turbo: false;"
                 teleport-controls="cameraRig: #player-rig;
                                     teleportOrigin: #head;
                                     hitEntity: #telepor-indicator;
-- 
GitLab