Bug 1383110 - Force to fetch Oculus Touch tracking data when it is added; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 27 Jul 2017 15:42:59 +0800
changeset 616621 e0f6b26e503df0cbac3510e7209d71b288f76a49
parent 616205 f1693d664f8e8ee4c79801630c181c28095cad56
child 639530 2493d00809ba7e1f9e3f3efccf5f6e800ac92f1a
push id70745
push userbmo:dmu@mozilla.com
push dateThu, 27 Jul 2017 07:46:50 +0000
reviewerskip
bugs1383110
milestone56.0a1
Bug 1383110 - Force to fetch Oculus Touch tracking data when it is added; r?kip MozReview-Commit-ID: 4e8qoV6cDzy
gfx/vr/gfxVROculus.cpp
gfx/vr/gfxVROculus.h
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -1547,60 +1547,67 @@ VRSystemManagerOculus::HandleInput()
     controller->SetButtonTouched(inputState.Touches);
 
     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
+    // Process pose state.
+    GamepadPoseState poseState;
+    GetControllerPoseState(handIdx, poseState);
+    HandlePoseTracking(i, poseState, controller);
+  }
+}
+
+void
+VRSystemManagerOculus::GetControllerPoseState(uint32_t aHandIdx, GamepadPoseState& aPoseState,
+                                              bool aForceUpdate)
+{
     ovrTrackingState state = ovr_GetTrackingState(mSession->Get(), 0.0, false);
 
     // HandPoses is ordered by ovrControllerType_LTouch and ovrControllerType_RTouch,
     // therefore, we can't get its state by the index of mOculusController.
-    ovrPoseStatef& pose(state.HandPoses[handIdx]);
-    GamepadPoseState poseState;
+    ovrPoseStatef& pose(state.HandPoses[aHandIdx]);
 
-    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;
-      poseState.orientation[3] = pose.ThePose.Orientation.w;
-      poseState.angularVelocity[0] = pose.AngularVelocity.x;
-      poseState.angularVelocity[1] = pose.AngularVelocity.y;
-      poseState.angularVelocity[2] = pose.AngularVelocity.z;
+    if (aForceUpdate || state.HandStatusFlags[aHandIdx] & ovrStatus_OrientationTracked) {
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
+      aPoseState.orientation[0] = pose.ThePose.Orientation.x;
+      aPoseState.orientation[1] = pose.ThePose.Orientation.y;
+      aPoseState.orientation[2] = pose.ThePose.Orientation.z;
+      aPoseState.orientation[3] = pose.ThePose.Orientation.w;
+      aPoseState.angularVelocity[0] = pose.AngularVelocity.x;
+      aPoseState.angularVelocity[1] = pose.AngularVelocity.y;
+      aPoseState.angularVelocity[2] = pose.AngularVelocity.z;
 
-      poseState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
-      poseState.angularAcceleration[0] = pose.AngularAcceleration.x;
-      poseState.angularAcceleration[1] = pose.AngularAcceleration.y;
-      poseState.angularAcceleration[2] = pose.AngularAcceleration.z;
-      poseState.isOrientationValid = true;
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
+      aPoseState.angularAcceleration[0] = pose.AngularAcceleration.x;
+      aPoseState.angularAcceleration[1] = pose.AngularAcceleration.y;
+      aPoseState.angularAcceleration[2] = pose.AngularAcceleration.z;
+      aPoseState.isOrientationValid = true;
     }
-    if (state.HandStatusFlags[handIdx] & ovrStatus_PositionTracked) {
-      poseState.flags |= GamepadCapabilityFlags::Cap_Position;
-      poseState.position[0] = pose.ThePose.Position.x;
-      poseState.position[1] = pose.ThePose.Position.y;
-      poseState.position[2] = pose.ThePose.Position.z;
-      poseState.linearVelocity[0] = pose.LinearVelocity.x;
-      poseState.linearVelocity[1] = pose.LinearVelocity.y;
-      poseState.linearVelocity[2] = pose.LinearVelocity.z;
+    if (aForceUpdate || state.HandStatusFlags[aHandIdx] & ovrStatus_PositionTracked) {
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_Position;
+      aPoseState.position[0] = pose.ThePose.Position.x;
+      aPoseState.position[1] = pose.ThePose.Position.y;
+      aPoseState.position[2] = pose.ThePose.Position.z;
+      aPoseState.linearVelocity[0] = pose.LinearVelocity.x;
+      aPoseState.linearVelocity[1] = pose.LinearVelocity.y;
+      aPoseState.linearVelocity[2] = pose.LinearVelocity.z;
 
-      poseState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
-      poseState.linearAcceleration[0] = pose.LinearAcceleration.x;
-      poseState.linearAcceleration[1] = pose.LinearAcceleration.y;
-      poseState.linearAcceleration[2] = pose.LinearAcceleration.z;
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
+      aPoseState.linearAcceleration[0] = pose.LinearAcceleration.x;
+      aPoseState.linearAcceleration[1] = pose.LinearAcceleration.y;
+      aPoseState.linearAcceleration[2] = pose.LinearAcceleration.z;
 
       float eyeHeight = ovr_GetFloat(mSession->Get(), OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT);
-      poseState.position[1] -= eyeHeight;
-      poseState.isPositionValid = true;
+      aPoseState.position[1] -= eyeHeight;
+      aPoseState.isPositionValid = true;
     }
-    HandlePoseTracking(i, poseState, controller);
-  }
 }
 
 void
 VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
                                          uint32_t aButton,
                                          uint64_t aButtonMask,
                                          uint64_t aButtonPressed,
                                          uint64_t aButtonTouched)
@@ -1761,16 +1768,21 @@ VRSystemManagerOculus::ScanForController
   // at GetHMDs().
   if (!mSession || !mSession->IsTrackingReady()) {
     return;
   }
 
   ovrInputState inputState;
   bool hasInputState = ovr_GetInputState(mSession->Get(), ovrControllerType_Touch,
                                          &inputState) == ovrSuccess;
+
+  if (!hasInputState) {
+    return;
+  }
+
   ovrControllerType activeControllerArray[2];
   uint32_t newControllerCount = 0;
 
   if (inputState.ControllerType & ovrControllerType_LTouch) {
     activeControllerArray[newControllerCount] = ovrControllerType_LTouch;
     ++newControllerCount;
   }
 
@@ -1795,16 +1807,26 @@ VRSystemManagerOculus::ScanForController
           break;
       }
       RefPtr<VRControllerOculus> oculusController = new VRControllerOculus(hand,
                                                       mDisplay->GetDisplayInfo().GetDisplayID());
       mOculusController.AppendElement(oculusController);
 
       // Not already present, add it.
       AddGamepad(oculusController->GetControllerInfo());
+
+      // Process pose state.
+      // We wanna Oculus Touch has the right position when it shows up,
+      // so we force to update the pose no matter if it has OrientationTracked
+      // or PositionTracked.
+      const uint32_t handIdx = static_cast<uint32_t>(hand) - 1;
+      GamepadPoseState poseState;
+      GetControllerPoseState(handIdx, poseState, true);
+      HandlePoseTracking(i, poseState, oculusController);
+
       ++mControllerCount;
     }
   }
 }
 
 void
 VRSystemManagerOculus::RemoveControllers()
 {
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -197,16 +197,19 @@ private:
                       float aValue);
   void HandlePoseTracking(uint32_t aControllerIdx,
                           const dom::GamepadPoseState& aPose,
                           VRControllerHost* aController);
   void HandleIndexTriggerPress(uint32_t aControllerIdx, uint32_t aButton, float aValue);
   void HandleHandTriggerPress(uint32_t aControllerIdx, uint32_t aButton, float aValue);
   void HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
                         uint64_t aTouchMask, uint64_t aTouched);
+  void GetControllerPoseState(uint32_t aHandIdx, dom::GamepadPoseState& aPoseState,
+                              bool aForceUpdate = false);
+
   RefPtr<impl::VRDisplayOculus> mDisplay;
   nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
   RefPtr<impl::VROculusSession> mSession;
 };
 
 } // namespace gfx
 } // namespace mozilla