Bug 1299930 - Support OpenVR controller trackpads via Gamepad API; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Sat, 22 Oct 2016 00:01:26 +0800
changeset 429025 bfb0d55ba0352809277576dd7442a2765bc2a380
parent 428736 c845bfd0accb7e0c29b41713255963b08006e701
child 534889 755d8f2971d525e6a7b0222f729d1fb6998c7aea
push id33475
push userbmo:dmu@mozilla.com
push dateTue, 25 Oct 2016 02:54:50 +0000
reviewerskip
bugs1299930
milestone52.0a1
Bug 1299930 - Support OpenVR controller trackpads via Gamepad API; r?kip MozReview-Commit-ID: 41C0rc7fZTi
gfx/vr/gfxVR.cpp
gfx/vr/gfxVR.h
gfx/vr/gfxVROpenVR.cpp
gfx/vr/gfxVROpenVR.h
--- a/gfx/vr/gfxVR.cpp
+++ b/gfx/vr/gfxVR.cpp
@@ -84,8 +84,20 @@ VRControllerManager::NewButtonEvent(uint
 {
   dom::GamepadButtonInformation a(aIndex, dom::GamepadServiceType::VR,
                                   aButton, aPressed, aPressed ? 1.0L : 0.0L);
 
   VRManager* vm = VRManager::Get();
   MOZ_ASSERT(vm);
   vm->NotifyGamepadChange<dom::GamepadButtonInformation>(a);
 }
+
+void
+VRControllerManager::NewAxisMove(uint32_t aIndex, uint32_t aAxis,
+                                 double aValue)
+{
+  dom::GamepadAxisInformation a(aIndex, dom::GamepadServiceType::VR,
+                                aAxis, aValue);
+
+  VRManager* vm = VRManager::Get();
+  MOZ_ASSERT(vm);
+  vm->NotifyGamepadChange<dom::GamepadAxisInformation>(a);
+}
--- a/gfx/vr/gfxVR.h
+++ b/gfx/vr/gfxVR.h
@@ -247,28 +247,31 @@ public:
 
   static uint32_t AllocateControllerID();
   virtual bool Init() = 0;
   virtual void Destroy() = 0;
   virtual void HandleInput() = 0;
   virtual void GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult) = 0;
   virtual void ScanForDevices() = 0;
   void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed);
+  void NewAxisMove(uint32_t aIndex, uint32_t aAxis, double aValue);
   void AddGamepad(const char* aID, dom::GamepadMappingType aMapping,
                   uint32_t aNumButtons, uint32_t aNumAxes);
 
 protected:
   VRControllerManager() : mInstalled(false), mControllerCount(0) {}
   virtual ~VRControllerManager() {}
 
   bool mInstalled;
   uint32_t mControllerCount;
   static Atomic<uint32_t> sControllerBase;
 
 private:
   virtual void HandleButtonPress(uint32_t aControllerIdx,
                                  uint64_t aButtonPressed) = 0;
+  virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
+                              float aValue) = 0;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* GFX_VR_H */
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -67,26 +67,34 @@ const uint64_t gOpenVRButtonMask[] = {
   // vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_A),
   vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_SteamVR_Touchpad),
   vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_SteamVR_Trigger)
 };
 
 const uint32_t gNumOpenVRButtonMask = sizeof(gOpenVRButtonMask) /
                                       sizeof(uint64_t);
 
-const uint64_t gOpenVRAxisMask[] = {
-  vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_Axis0),
-  vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_Axis1),
-  vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_Axis2),
-  vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_Axis3),
-  vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_Axis4)
+enum class VRControllerAxisType : uint16_t {
+  TrackpadXAxis,
+  TrackpadYAxis,
+  Trigger,
+  NumVRControllerAxisType
 };
 
-const uint32_t gNumOpenVRAxisMask = sizeof(gOpenVRAxisMask) /
-                                    sizeof(uint64_t);
+#define VRControllerAxis(aButtonId) (aButtonId - vr::EVRButtonId::k_EButton_Axis0)
+
+const uint32_t gOpenVRAxes[] = {
+  VRControllerAxis(vr::EVRButtonId::k_EButton_Axis0),
+  VRControllerAxis(vr::EVRButtonId::k_EButton_Axis0),
+  VRControllerAxis(vr::EVRButtonId::k_EButton_Axis1)
+};
+
+const uint32_t gNumOpenVRAxis = sizeof(gOpenVRAxes) /
+                                sizeof(uint32_t);
+
 
 bool
 LoadOpenVRRuntime()
 {
   static PRLibrary *openvrLib = nullptr;
 
   nsAdoptingCString openvrPath = Preferences::GetCString("gfx.vr.openvr-runtime");
   if (!openvrPath)
@@ -474,17 +482,17 @@ VRDisplayManagerOpenVR::GetHMDs(nsTArray
 
 VRControllerOpenVR::VRControllerOpenVR()
   : VRControllerHost(VRDeviceType::OpenVR)
 {
   MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
   mControllerInfo.mControllerName.AssignLiteral("OpenVR HMD");
   mControllerInfo.mMappingType = dom::GamepadMappingType::_empty;
   mControllerInfo.mNumButtons = gNumOpenVRButtonMask;
-  mControllerInfo.mNumAxes = gNumOpenVRAxisMask;
+  mControllerInfo.mNumAxes = gNumOpenVRAxis;
 }
 
 VRControllerOpenVR::~VRControllerOpenVR()
 {
   MOZ_COUNT_DTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
 }
 
 void
@@ -554,16 +562,17 @@ VRControllerManagerOpenVR::Destroy()
   mOpenVRInstalled = false;
 }
 
 void
 VRControllerManagerOpenVR::HandleInput()
 {
   RefPtr<impl::VRControllerOpenVR> controller;
   vr::VRControllerState_t state;
+  uint32_t axis = 0;
 
   if (!mOpenVRInstalled) {
     return;
   }
 
   MOZ_ASSERT(mVRSystem);
 
   // Process OpenVR controller state
@@ -573,17 +582,27 @@ VRControllerManagerOpenVR::HandleInput()
     MOZ_ASSERT(mVRSystem->GetTrackedDeviceClass(controller->GetTrackedIndex())
                == vr::TrackedDeviceClass_Controller);
 
     if (mVRSystem->GetControllerState(controller->GetTrackedIndex(), &state)) {
       if (state.ulButtonPressed) {
         HandleButtonPress(controller->GetIndex(), state.ulButtonPressed);
       }
 
-      // Handle Axis support in Bug 1299930
+      axis = static_cast<uint32_t>(VRControllerAxisType::TrackpadXAxis);
+      HandleAxisMove(controller->GetIndex(), axis,
+                     state.rAxis[gOpenVRAxes[axis]].x);
+
+      axis = static_cast<uint32_t>(VRControllerAxisType::TrackpadYAxis);
+      HandleAxisMove(controller->GetIndex(), axis,
+                     state.rAxis[gOpenVRAxes[axis]].y);
+
+      axis = static_cast<uint32_t>(VRControllerAxisType::Trigger);
+      HandleAxisMove(controller->GetIndex(), axis,
+                     state.rAxis[gOpenVRAxes[axis]].x);
     }
   }
 }
 
 void
 VRControllerManagerOpenVR::HandleButtonPress(uint32_t aControllerIdx,
                                              uint64_t aButtonPressed)
 {
@@ -591,16 +610,25 @@ VRControllerManagerOpenVR::HandleButtonP
 
   for (uint32_t i = 0; i < gNumOpenVRButtonMask; ++i) {
     buttonMask = gOpenVRButtonMask[i];
     NewButtonEvent(aControllerIdx, i, aButtonPressed & buttonMask);
   }
 }
 
 void
+VRControllerManagerOpenVR::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
+                                          float aValue)
+{
+  if (aValue != 0.0f) {
+    NewAxisMove(aControllerIdx, aAxis, aValue);
+  }
+}
+
+void
 VRControllerManagerOpenVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
 {
   if (!mOpenVRInstalled) {
     return;
   }
 
   aControllerResult.Clear();
   for (uint32_t i = 0; i < mOpenVRController.Length(); ++i) {
@@ -630,12 +658,12 @@ VRControllerManagerOpenVR::ScanForDevice
 
     RefPtr<VRControllerOpenVR> openVRController = new VRControllerOpenVR();
     openVRController->SetIndex(mControllerCount);
     openVRController->SetTrackedIndex(trackedDevice);
     mOpenVRController.AppendElement(openVRController);
 
     // Not already present, add it.
     AddGamepad("OpenVR Gamepad", GamepadMappingType::_empty,
-               gNumOpenVRButtonMask, gNumOpenVRAxisMask);
+               gNumOpenVRButtonMask, gNumOpenVRAxis);
     ++mControllerCount;
   }
 }
\ No newline at end of file
--- a/gfx/vr/gfxVROpenVR.h
+++ b/gfx/vr/gfxVROpenVR.h
@@ -117,16 +117,18 @@ public:
   virtual void ScanForDevices() override;
 
 private:
   VRControllerManagerOpenVR();
   ~VRControllerManagerOpenVR();
 
   virtual void HandleButtonPress(uint32_t aControllerIdx,
                                  uint64_t aButtonPressed) override;
+  virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
+                              float aValue) override;
 
   bool mOpenVRInstalled;
   nsTArray<RefPtr<impl::VRControllerOpenVR>> mOpenVRController;
   vr::IVRSystem *mVRSystem;
 };
 
 } // namespace gfx
 } // namespace mozilla