Bug 1346149 - Part 2: Adjust Oculus Touch button and axis mapping; r=kip
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 16 Mar 2017 15:54:00 +0800
changeset 348321 109db936e344c10543191aceb01a81eec1fa9f3f
parent 348320 5f756281dc146040f0ec7e0b23bbec84239829fe
child 348322 45d7ca77e14763b44ed7d03dd2f2c5d3de87e1c1
push id88187
push userarchaeopteryx@coole-files.de
push dateSat, 18 Mar 2017 15:27:00 +0000
treeherdermozilla-inbound@0b1d3324cffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip
bugs1346149
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1346149 - Part 2: Adjust Oculus Touch button and axis mapping; r=kip MozReview-Commit-ID: H9FxkG0S5OL
gfx/vr/gfxVROculus.cpp
gfx/vr/gfxVROculus.h
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -116,32 +116,42 @@ static pfn_ovr_GetMirrorTextureBufferGL 
 #else
 #define BUILD_BITS 32
 #endif
 
 #define OVR_PRODUCT_VERSION 1
 #define OVR_MAJOR_VERSION   1
 #define OVR_MINOR_VERSION   10
 
-static const ovrButton kOculusTouchLButton[] = {
-  ovrButton_LThumb,
-  ovrButton_X,
-  ovrButton_Y
+enum class OculusLeftControllerButtonType : uint16_t {
+  LThumb,
+  IndexTrigger,
+  HandTrigger,
+  Button_X,
+  Button_Y,
+  LThumbRest,
+  NumButtonType
 };
 
-static const ovrButton kOculusTouchRButton[] = {
-  ovrButton_RThumb,
-  ovrButton_A,
-  ovrButton_B,
+enum class OculusRightControllerButtonType : uint16_t {
+  RThumb,
+  IndexTrigger,
+  HandTrigger,
+  Button_A,
+  Button_B,
+  RThumbRest,
+  NumButtonType
 };
 
-static const uint32_t kNumOculusButton = sizeof(kOculusTouchLButton) /
-                                         sizeof(ovrButton);
+static const uint32_t kNumOculusButton = static_cast<uint32_t>
+                                         (OculusLeftControllerButtonType::
+                                         NumButtonType);
 static const uint32_t kNumOculusHaptcs = 0;  // TODO: Bug 1305892
 
+
 static bool
 InitializeOculusCAPI()
 {
   static PRLibrary *ovrlib = nullptr;
 
   if (!ovrlib) {
     nsTArray<nsCString> libSearchPaths;
     nsCString libName;
@@ -823,16 +833,18 @@ VRDisplayOculus::NotifyVSync()
 {
   ovrSessionStatus sessionStatus;
   ovrResult ovr = ovr_GetSessionStatus(mSession, &sessionStatus);
   mDisplayInfo.mIsConnected = (ovr == ovrSuccess && sessionStatus.HmdPresent);
 }
 
 VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand)
   : VRControllerHost(VRDeviceType::Oculus)
+  , mIndexTrigger(0.0f)
+  , mHandTrigger(0.0f)
 {
   MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
 
   char* touchID = "";
   switch (aHand) {
     case dom::GamepadHand::Left:
       touchID = "Oculus Touch (Left)";
       break;
@@ -841,16 +853,22 @@ VRControllerOculus::VRControllerOculus(d
       break;
     default:
       MOZ_ASSERT(false);
       break;
   }
   mControllerInfo.mControllerName = touchID;
   mControllerInfo.mMappingType = GamepadMappingType::_empty;
   mControllerInfo.mHand = aHand;
+
+  MOZ_ASSERT(kNumOculusButton ==
+             static_cast<uint32_t>(OculusLeftControllerButtonType::NumButtonType)
+             && kNumOculusButton ==
+             static_cast<uint32_t>(OculusRightControllerButtonType::NumButtonType));
+
   mControllerInfo.mNumButtons = kNumOculusButton;
   mControllerInfo.mNumAxes = static_cast<uint32_t>(
                              OculusControllerAxisType::NumVRControllerAxisType);;
 }
 
 float
 VRControllerOculus::GetAxisMove(uint32_t aAxis)
 {
@@ -858,16 +876,40 @@ VRControllerOculus::GetAxisMove(uint32_t
 }
 
 void
 VRControllerOculus::SetAxisMove(uint32_t aAxis, float aValue)
 {
   mAxisMove[aAxis] = aValue;
 }
 
+float
+VRControllerOculus::GetIndexTrigger()
+{
+  return mIndexTrigger;
+}
+
+void
+VRControllerOculus::SetIndexTrigger(float aValue)
+{
+  mIndexTrigger = aValue;
+}
+
+float
+VRControllerOculus::GetHandTrigger()
+{
+  return mHandTrigger;
+}
+
+void
+VRControllerOculus::SetHandTrigger(float aValue)
+{
+  mHandTrigger = aValue;
+}
+
 VRControllerOculus::~VRControllerOculus()
 {
   MOZ_COUNT_DTOR_INHERITED(VRControllerOculus, VRControllerHost);
 }
 
 /*static*/ already_AddRefed<VRSystemManagerOculus>
 VRSystemManagerOculus::Create()
 {
@@ -962,44 +1004,75 @@ VRSystemManagerOculus::HandleInput()
   // at GetHMDs().
   if (!mSession) {
     return;
   }
 
   RefPtr<impl::VRControllerOculus> controller;
   ovrInputState inputState;
   uint32_t axis = 0;
-  bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
-                                         &inputState) == ovrSuccess;
+  const bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
+                                               &inputState) == ovrSuccess;
 
   if (!hasInputState) {
     return;
   }
 
   for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
     controller = mOculusController[i];
-    HandleButtonPress(i, inputState.Buttons);
+    const GamepadHand hand = controller->GetHand();
+    const uint32_t handIdx = static_cast<uint32_t>(hand) - 1;
+    uint32_t buttonIdx = 0;
 
-    axis = static_cast<uint32_t>(OculusControllerAxisType::IndexTrigger);
-    HandleAxisMove(i, axis, inputState.IndexTrigger[i]);
-
-    axis = static_cast<uint32_t>(OculusControllerAxisType::HandTrigger);
-    HandleAxisMove(i, axis, inputState.HandTrigger[i]);
+    switch (hand) {
+      case dom::GamepadHand::Left:
+        HandleButtonPress(i, buttonIdx, ovrButton_LThumb, inputState.Buttons);
+        ++buttonIdx;
+        HandleTriggerPress(i, buttonIdx, inputState.IndexTrigger[handIdx]);
+        ++buttonIdx;
+        HandleTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
+        ++buttonIdx;
+        HandleButtonPress(i, buttonIdx, ovrButton_X, inputState.Buttons);
+        ++buttonIdx;
+        HandleButtonPress(i, buttonIdx, ovrButton_Y, inputState.Buttons);
+        ++buttonIdx;
+        HandleTouchEvent(i, buttonIdx, ovrTouch_LThumbRest, inputState.Touches);
+        ++buttonIdx;
+        break;
+      case dom::GamepadHand::Right:
+        HandleButtonPress(i, buttonIdx, ovrButton_RThumb, inputState.Buttons);
+        ++buttonIdx;
+        HandleTriggerPress(i, buttonIdx, inputState.IndexTrigger[handIdx]);
+        ++buttonIdx;
+        HandleTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
+        ++buttonIdx;
+        HandleButtonPress(i, buttonIdx, ovrButton_A, inputState.Buttons);
+        ++buttonIdx;
+        HandleButtonPress(i, buttonIdx, ovrButton_B, inputState.Buttons);
+        ++buttonIdx;
+        HandleTouchEvent(i, buttonIdx, ovrTouch_RThumbRest, inputState.Touches);
+        ++buttonIdx;
+        break;
+      default:
+        MOZ_ASSERT(false);
+        break;
+    }
+    controller->SetButtonPressed(inputState.Buttons);
 
     axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickXAxis);
     HandleAxisMove(i, axis, inputState.Thumbstick[i].x);
 
     axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickYAxis);
     HandleAxisMove(i, axis, -inputState.Thumbstick[i].y);
 
     // Start to process pose
     ovrTrackingState state = ovr_GetTrackingState(mSession, 0.0, false);
     // HandPoses is ordered by ovrControllerType_LTouch and ovrControllerType_RTouch,
     // therefore, we can't get its state by the index of mOculusController.
-    const uint32_t handIdx = static_cast<uint32_t>(controller->GetHand()) - 1;
+
     ovrPoseStatef& pose(state.HandPoses[handIdx]);
     GamepadPoseState poseState;
 
     if (state.HandStatusFlags[handIdx] & ovrStatus_OrientationTracked) {
       poseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
       poseState.orientation[0] = pose.ThePose.Orientation.x;
       poseState.orientation[1] = pose.ThePose.Orientation.y;
       poseState.orientation[2] = pose.ThePose.Orientation.z;
@@ -1028,45 +1101,67 @@ VRSystemManagerOculus::HandleInput()
       poseState.linearAcceleration[2] = pose.LinearAcceleration.z;
     }
     HandlePoseTracking(i, poseState, controller);
   }
 }
 
 void
 VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
+                                         uint32_t aButton,
+                                         uint64_t aButtonMask,
                                          uint64_t aButtonPressed)
 {
-  MOZ_ASSERT(sizeof(kOculusTouchLButton) / sizeof(ovrButton) ==
-             sizeof(kOculusTouchRButton) / sizeof(ovrButton));
+  RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
+  MOZ_ASSERT(controller);
+  const uint64_t diff = (controller->GetButtonPressed() ^ aButtonPressed);
 
+  if (diff & aButtonMask) {
+    NewButtonEvent(aControllerIdx, aButton, aButtonMask & aButtonPressed,
+                   (aButtonMask & aButtonPressed) ? 1.0L : 0.0L);
+  }
+}
+
+void
+VRSystemManagerOculus::HandleTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
+                                          float aValue)
+{
   RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
   MOZ_ASSERT(controller);
-  GamepadHand hand = controller->GetHand();
-  uint64_t diff = (controller->GetButtonPressed() ^ aButtonPressed);
-  uint32_t buttonMask = 0;
+  const uint32_t indexTrigger = static_cast<const uint32_t>
+                                (OculusLeftControllerButtonType::IndexTrigger);
+  const uint32_t handTrigger =  static_cast<const uint32_t>
+                                (OculusLeftControllerButtonType::HandTrigger);
+  float oldValue = 0.0f;
 
-  for (uint32_t i = 0; i < kNumOculusButton; ++i) {
-    switch (hand) {
-      case dom::GamepadHand::Left:
-        buttonMask = kOculusTouchLButton[i];
-        break;
-      case dom::GamepadHand::Right:
-        buttonMask = kOculusTouchRButton[i];
-        break;
-      default:
-        MOZ_ASSERT(false);
-        break;
+  // Avoid sending duplicated events in IPC channels.
+  if (aButton == indexTrigger) {
+    oldValue = controller->GetIndexTrigger();
+    if (oldValue == aValue) {
+      return;
     }
-    if (diff & buttonMask) {
-      NewButtonEvent(aControllerIdx, i, diff & aButtonPressed);
+    controller->SetIndexTrigger(aValue);
+  } else if (aButton == handTrigger) {
+    oldValue = controller->GetHandTrigger();
+    if (oldValue == aValue) {
+      return;
     }
+    controller->SetHandTrigger(aValue);
+  } else {
+    MOZ_ASSERT(false, "We only support indexTrigger and handTrigger in Oculus.");
   }
 
-  controller->SetButtonPressed(aButtonPressed);
+  NewButtonEvent(aControllerIdx, aButton, aValue > 0.1f, aValue);
+}
+
+void
+VRSystemManagerOculus::HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
+                                        uint64_t aTouchMask, uint64_t aTouched)
+{
+  // TODO: Bug 1336003
 }
 
 void
 VRSystemManagerOculus::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
                                       float aValue)
 {
   RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
   MOZ_ASSERT(controller);
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -25,18 +25,16 @@ struct VertexShaderConstants;
 struct PixelShaderConstants;
 }
 namespace gfx {
 namespace impl {
 
 enum class OculusControllerAxisType : uint16_t {
   ThumbstickXAxis,
   ThumbstickYAxis,
-  IndexTrigger,
-  HandTrigger,
   NumVRControllerAxisType
 };
 
 class VRDisplayOculus : public VRDisplayHost
 {
 public:
   virtual void NotifyVSync() override;
   virtual VRHMDSensorState GetSensorState() override;
@@ -94,21 +92,29 @@ protected:
 };
 
 class VRControllerOculus : public VRControllerHost
 {
 public:
   explicit VRControllerOculus(dom::GamepadHand aHand);
   float GetAxisMove(uint32_t aAxis);
   void SetAxisMove(uint32_t aAxis, float aValue);
+  float GetIndexTrigger();
+  void SetIndexTrigger(float aValue);
+  float GetHandTrigger();
+  void SetHandTrigger(float aValue);
 
 protected:
   virtual ~VRControllerOculus();
+
+private:
   float mAxisMove[static_cast<uint32_t>(
                   OculusControllerAxisType::NumVRControllerAxisType)];
+  float mIndexTrigger;
+  float mHandTrigger;
 };
 
 } // namespace impl
 
 class VRSystemManagerOculus : public VRSystemManager
 {
 public:
   static already_AddRefed<VRSystemManagerOculus> Create();
@@ -122,23 +128,29 @@ public:
   virtual void RemoveControllers() override;
 
 protected:
   VRSystemManagerOculus()
     : mSession(nullptr), mOculusInitialized(false)
   { }
 
 private:
-  virtual void HandleButtonPress(uint32_t aControllerIdx,
-                                 uint64_t aButtonPressed) override;
-  virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
-                              float aValue) override;
-  virtual void HandlePoseTracking(uint32_t aControllerIdx,
-                                  const dom::GamepadPoseState& aPose,
-                                  VRControllerHost* aController) override;
+  void HandleButtonPress(uint32_t aControllerIdx,
+                         uint32_t aButton,
+                         uint64_t aButtonMask,
+                         uint64_t aButtonPressed);
+  void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
+                      float aValue);
+  void HandlePoseTracking(uint32_t aControllerIdx,
+                          const dom::GamepadPoseState& aPose,
+                          VRControllerHost* aController);
+  void HandleTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
+                          float aValue);
+  void HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
+                        uint64_t aTouchMask, uint64_t aTouched);
 
   RefPtr<impl::VRDisplayOculus> mHMDInfo;
   nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
   RefPtr<nsIThread> mOculusThread;
   ovrSession mSession;
   bool mOculusInitialized;
 };