forked from mirrors/gecko-dev
		
	Bug 1470527 - Implement Controller support for gfxVRExternal and VRServiceOpenVR,r=daoshengmu
MozReview-Commit-ID: I1xHfmAPMxT --HG-- extra : rebase_source : 5d957ff6172f3e730b61878b9067ec506ea4a383 extra : source : 66c97a5d22efc6436aab76756759b9b51517e940
This commit is contained in:
		
							parent
							
								
									12b5f4ebbe
								
							
						
					
					
						commit
						d0b35a2ff4
					
				
					 19 changed files with 981 additions and 333 deletions
				
			
		|  | @ -285,7 +285,7 @@ VRPose::GetPosition(JSContext* aCx, | ||||||
|                     JS::MutableHandle<JSObject*> aRetval, |                     JS::MutableHandle<JSObject*> aRetval, | ||||||
|                     ErrorResult& aRv) |                     ErrorResult& aRv) | ||||||
| { | { | ||||||
|   SetFloat32Array(aCx, aRetval, mPosition, mVRState.position, 3, |   SetFloat32Array(aCx, aRetval, mPosition, mVRState.pose.position, 3, | ||||||
|     !mPosition && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position), |     !mPosition && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position), | ||||||
|     aRv); |     aRv); | ||||||
| } | } | ||||||
|  | @ -295,7 +295,7 @@ VRPose::GetLinearVelocity(JSContext* aCx, | ||||||
|                           JS::MutableHandle<JSObject*> aRetval, |                           JS::MutableHandle<JSObject*> aRetval, | ||||||
|                           ErrorResult& aRv) |                           ErrorResult& aRv) | ||||||
| { | { | ||||||
|   SetFloat32Array(aCx, aRetval, mLinearVelocity, mVRState.linearVelocity, 3, |   SetFloat32Array(aCx, aRetval, mLinearVelocity, mVRState.pose.linearVelocity, 3, | ||||||
|     !mLinearVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position), |     !mLinearVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position), | ||||||
|     aRv); |     aRv); | ||||||
| } | } | ||||||
|  | @ -305,7 +305,7 @@ VRPose::GetLinearAcceleration(JSContext* aCx, | ||||||
|                               JS::MutableHandle<JSObject*> aRetval, |                               JS::MutableHandle<JSObject*> aRetval, | ||||||
|                               ErrorResult& aRv) |                               ErrorResult& aRv) | ||||||
| { | { | ||||||
|   SetFloat32Array(aCx, aRetval, mLinearAcceleration, mVRState.linearAcceleration, 3, |   SetFloat32Array(aCx, aRetval, mLinearAcceleration, mVRState.pose.linearAcceleration, 3, | ||||||
|     !mLinearAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_LinearAcceleration), |     !mLinearAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_LinearAcceleration), | ||||||
|     aRv); |     aRv); | ||||||
| 
 | 
 | ||||||
|  | @ -316,7 +316,7 @@ VRPose::GetOrientation(JSContext* aCx, | ||||||
|                        JS::MutableHandle<JSObject*> aRetval, |                        JS::MutableHandle<JSObject*> aRetval, | ||||||
|                        ErrorResult& aRv) |                        ErrorResult& aRv) | ||||||
| { | { | ||||||
|   SetFloat32Array(aCx, aRetval, mOrientation, mVRState.orientation, 4, |   SetFloat32Array(aCx, aRetval, mOrientation, mVRState.pose.orientation, 4, | ||||||
|     !mOrientation && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation), |     !mOrientation && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation), | ||||||
|     aRv); |     aRv); | ||||||
| } | } | ||||||
|  | @ -326,7 +326,7 @@ VRPose::GetAngularVelocity(JSContext* aCx, | ||||||
|                            JS::MutableHandle<JSObject*> aRetval, |                            JS::MutableHandle<JSObject*> aRetval, | ||||||
|                            ErrorResult& aRv) |                            ErrorResult& aRv) | ||||||
| { | { | ||||||
|   SetFloat32Array(aCx, aRetval, mAngularVelocity, mVRState.angularVelocity, 3, |   SetFloat32Array(aCx, aRetval, mAngularVelocity, mVRState.pose.angularVelocity, 3, | ||||||
|     !mAngularVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation), |     !mAngularVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation), | ||||||
|     aRv); |     aRv); | ||||||
| } | } | ||||||
|  | @ -336,7 +336,7 @@ VRPose::GetAngularAcceleration(JSContext* aCx, | ||||||
|                                JS::MutableHandle<JSObject*> aRetval, |                                JS::MutableHandle<JSObject*> aRetval, | ||||||
|                                ErrorResult& aRv) |                                ErrorResult& aRv) | ||||||
| { | { | ||||||
|   SetFloat32Array(aCx, aRetval, mAngularAcceleration, mVRState.angularAcceleration, 3, |   SetFloat32Array(aCx, aRetval, mAngularAcceleration, mVRState.pose.angularAcceleration, 3, | ||||||
|     !mAngularAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_AngularAcceleration), |     !mAngularAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_AngularAcceleration), | ||||||
|     aRv); |     aRv); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -95,50 +95,50 @@ VRMockDisplay::SetPose(const Nullable<Float32Array>& aPosition, | ||||||
|     const Float32Array& value = aOrientation.Value(); |     const Float32Array& value = aOrientation.Value(); | ||||||
|     value.ComputeLengthAndData(); |     value.ComputeLengthAndData(); | ||||||
|     MOZ_ASSERT(value.Length() == 4); |     MOZ_ASSERT(value.Length() == 4); | ||||||
|     mSensorState.orientation[0] = value.Data()[0]; |     mSensorState.pose.orientation[0] = value.Data()[0]; | ||||||
|     mSensorState.orientation[1] = value.Data()[1]; |     mSensorState.pose.orientation[1] = value.Data()[1]; | ||||||
|     mSensorState.orientation[2] = value.Data()[2]; |     mSensorState.pose.orientation[2] = value.Data()[2]; | ||||||
|     mSensorState.orientation[3] = value.Data()[3]; |     mSensorState.pose.orientation[3] = value.Data()[3]; | ||||||
|   } |   } | ||||||
|   if (!aAngularVelocity.IsNull()) { |   if (!aAngularVelocity.IsNull()) { | ||||||
|     const Float32Array& value = aAngularVelocity.Value(); |     const Float32Array& value = aAngularVelocity.Value(); | ||||||
|     value.ComputeLengthAndData(); |     value.ComputeLengthAndData(); | ||||||
|     MOZ_ASSERT(value.Length() == 3); |     MOZ_ASSERT(value.Length() == 3); | ||||||
|     mSensorState.angularVelocity[0] = value.Data()[0]; |     mSensorState.pose.angularVelocity[0] = value.Data()[0]; | ||||||
|     mSensorState.angularVelocity[1] = value.Data()[1]; |     mSensorState.pose.angularVelocity[1] = value.Data()[1]; | ||||||
|     mSensorState.angularVelocity[2] = value.Data()[2]; |     mSensorState.pose.angularVelocity[2] = value.Data()[2]; | ||||||
|   } |   } | ||||||
|   if (!aAngularAcceleration.IsNull()) { |   if (!aAngularAcceleration.IsNull()) { | ||||||
|     const Float32Array& value = aAngularAcceleration.Value(); |     const Float32Array& value = aAngularAcceleration.Value(); | ||||||
|     value.ComputeLengthAndData(); |     value.ComputeLengthAndData(); | ||||||
|     MOZ_ASSERT(value.Length() == 3); |     MOZ_ASSERT(value.Length() == 3); | ||||||
|     mSensorState.angularAcceleration[0] = value.Data()[0]; |     mSensorState.pose.angularAcceleration[0] = value.Data()[0]; | ||||||
|     mSensorState.angularAcceleration[1] = value.Data()[1]; |     mSensorState.pose.angularAcceleration[1] = value.Data()[1]; | ||||||
|     mSensorState.angularAcceleration[2] = value.Data()[2]; |     mSensorState.pose.angularAcceleration[2] = value.Data()[2]; | ||||||
|   } |   } | ||||||
|   if (!aPosition.IsNull()) { |   if (!aPosition.IsNull()) { | ||||||
|     const Float32Array& value = aPosition.Value(); |     const Float32Array& value = aPosition.Value(); | ||||||
|     value.ComputeLengthAndData(); |     value.ComputeLengthAndData(); | ||||||
|     MOZ_ASSERT(value.Length() == 3); |     MOZ_ASSERT(value.Length() == 3); | ||||||
|     mSensorState.position[0] = value.Data()[0]; |     mSensorState.pose.position[0] = value.Data()[0]; | ||||||
|     mSensorState.position[1] = value.Data()[1]; |     mSensorState.pose.position[1] = value.Data()[1]; | ||||||
|     mSensorState.position[2] = value.Data()[2]; |     mSensorState.pose.position[2] = value.Data()[2]; | ||||||
|   } |   } | ||||||
|   if (!aLinearVelocity.IsNull()) { |   if (!aLinearVelocity.IsNull()) { | ||||||
|     const Float32Array& value = aLinearVelocity.Value(); |     const Float32Array& value = aLinearVelocity.Value(); | ||||||
|     value.ComputeLengthAndData(); |     value.ComputeLengthAndData(); | ||||||
|     MOZ_ASSERT(value.Length() == 3); |     MOZ_ASSERT(value.Length() == 3); | ||||||
|     mSensorState.linearVelocity[0] = value.Data()[0]; |     mSensorState.pose.linearVelocity[0] = value.Data()[0]; | ||||||
|     mSensorState.linearVelocity[1] = value.Data()[1]; |     mSensorState.pose.linearVelocity[1] = value.Data()[1]; | ||||||
|     mSensorState.linearVelocity[2] = value.Data()[2]; |     mSensorState.pose.linearVelocity[2] = value.Data()[2]; | ||||||
|   } |   } | ||||||
|   if (!aLinearAcceleration.IsNull()) { |   if (!aLinearAcceleration.IsNull()) { | ||||||
|     const Float32Array& value = aLinearAcceleration.Value(); |     const Float32Array& value = aLinearAcceleration.Value(); | ||||||
|     value.ComputeLengthAndData(); |     value.ComputeLengthAndData(); | ||||||
|     MOZ_ASSERT(value.Length() == 3); |     MOZ_ASSERT(value.Length() == 3); | ||||||
|     mSensorState.linearAcceleration[0] = value.Data()[0]; |     mSensorState.pose.linearAcceleration[0] = value.Data()[0]; | ||||||
|     mSensorState.linearAcceleration[1] = value.Data()[1]; |     mSensorState.pose.linearAcceleration[1] = value.Data()[1]; | ||||||
|     mSensorState.linearAcceleration[2] = value.Data()[2]; |     mSensorState.pose.linearAcceleration[2] = value.Data()[2]; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,7 +9,10 @@ | ||||||
| #include "prlink.h" | #include "prlink.h" | ||||||
| #include "prenv.h" | #include "prenv.h" | ||||||
| #include "gfxPrefs.h" | #include "gfxPrefs.h" | ||||||
|  | #include "nsIGlobalObject.h" | ||||||
|  | #include "nsRefPtrHashtable.h" | ||||||
| #include "nsString.h" | #include "nsString.h" | ||||||
|  | #include "mozilla/dom/GamepadManager.h" | ||||||
| #include "mozilla/Preferences.h" | #include "mozilla/Preferences.h" | ||||||
| #include "mozilla/Unused.h" | #include "mozilla/Unused.h" | ||||||
| #include "nsServiceManagerUtils.h" | #include "nsServiceManagerUtils.h" | ||||||
|  | @ -34,6 +37,7 @@ VRDisplayClient::VRDisplayClient(const VRDisplayInfo& aDisplayInfo) | ||||||
|   , mPresentationCount(0) |   , mPresentationCount(0) | ||||||
|   , mLastEventFrameId(0) |   , mLastEventFrameId(0) | ||||||
|   , mLastPresentingGeneration(0) |   , mLastPresentingGeneration(0) | ||||||
|  |   , mLastEventControllerState{} | ||||||
| { | { | ||||||
|   MOZ_COUNT_CTOR(VRDisplayClient); |   MOZ_COUNT_CTOR(VRDisplayClient); | ||||||
| } | } | ||||||
|  | @ -128,6 +132,140 @@ VRDisplayClient::FireEvents() | ||||||
|     mLastEventFrameId = mDisplayInfo.mFrameId; |     mLastEventFrameId = mDisplayInfo.mFrameId; | ||||||
|     vm->RunFrameRequestCallbacks(); |     vm->RunFrameRequestCallbacks(); | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   FireGamepadEvents(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | VRDisplayClient::FireGamepadEvents() | ||||||
|  | { | ||||||
|  |   RefPtr<dom::GamepadManager> gamepadManager(dom::GamepadManager::GetService()); | ||||||
|  |   if (!gamepadManager) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   for (int stateIndex=0; stateIndex < kVRControllerMaxCount; stateIndex++) { | ||||||
|  |     const VRControllerState& state = mDisplayInfo.mControllerState[stateIndex]; | ||||||
|  |     const VRControllerState& lastState = mLastEventControllerState[stateIndex]; | ||||||
|  |     uint32_t gamepadId = mDisplayInfo.mDisplayID * kVRControllerMaxCount + stateIndex; | ||||||
|  |     bool bIsNew = false; | ||||||
|  | 
 | ||||||
|  |     // Send events to notify that controllers are removed
 | ||||||
|  |     if (state.controllerName[0] == '\0') { | ||||||
|  |       // Controller is not present
 | ||||||
|  |       if (lastState.controllerName[0] != '\0') { | ||||||
|  |         // Controller has been removed
 | ||||||
|  |         dom::GamepadRemoved info; | ||||||
|  |         dom::GamepadChangeEventBody body(info); | ||||||
|  |         dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR, body); | ||||||
|  |         gamepadManager->Update(event); | ||||||
|  |       } | ||||||
|  |       // Do not process any further events for removed controllers
 | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Send events to notify that new controllers are added
 | ||||||
|  |     if (lastState.controllerName[0] == '\0') { | ||||||
|  |       dom::GamepadAdded info(NS_ConvertUTF8toUTF16(state.controllerName), | ||||||
|  |                              dom::GamepadMappingType::_empty, | ||||||
|  |                              state.hand, | ||||||
|  |                              mDisplayInfo.mDisplayID, | ||||||
|  |                              state.numButtons, | ||||||
|  |                              state.numAxes, | ||||||
|  |                              state.numHaptics); | ||||||
|  |       dom::GamepadChangeEventBody body(info); | ||||||
|  |       dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR, body); | ||||||
|  |       gamepadManager->Update(event); | ||||||
|  |       bIsNew = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Send events for handedness changes
 | ||||||
|  |     if (state.hand != lastState.hand) { | ||||||
|  |       dom::GamepadHandInformation info(state.hand); | ||||||
|  |       dom::GamepadChangeEventBody body(info); | ||||||
|  |       dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR, body); | ||||||
|  |       gamepadManager->Update(event); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Send events for axis value changes
 | ||||||
|  |     for (uint32_t axisIndex = 0; axisIndex < state.numAxes; axisIndex++) { | ||||||
|  |       if (state.axisValue[axisIndex] != lastState.axisValue[axisIndex]) { | ||||||
|  |         dom::GamepadAxisInformation info(axisIndex, state.axisValue[axisIndex]); | ||||||
|  |         dom::GamepadChangeEventBody body(info); | ||||||
|  |         dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR, body); | ||||||
|  |         gamepadManager->Update(event); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Send events for trigger, touch, and button value changes
 | ||||||
|  |     if (!bIsNew) { | ||||||
|  |       // When a new controller is added, we do not emit button events for
 | ||||||
|  |       // the initial state of the inputs.
 | ||||||
|  |       for (uint32_t buttonIndex = 0; buttonIndex < state.numButtons; buttonIndex++) { | ||||||
|  |         bool bPressed = (state.buttonPressed & (1ULL << buttonIndex)) != 0; | ||||||
|  |         bool bTouched = (state.buttonTouched & (1ULL << buttonIndex)) != 0; | ||||||
|  |         bool bLastPressed = (lastState.buttonPressed & (1ULL << buttonIndex)) != 0; | ||||||
|  |         bool bLastTouched = (lastState.buttonTouched & (1ULL << buttonIndex)) != 0; | ||||||
|  | 
 | ||||||
|  |         if (state.triggerValue[buttonIndex] != lastState.triggerValue[buttonIndex] || | ||||||
|  |             bPressed != bLastPressed || | ||||||
|  |             bTouched != bLastTouched) { | ||||||
|  |           dom::GamepadButtonInformation info(buttonIndex, state.triggerValue[buttonIndex], bPressed, bTouched); | ||||||
|  |           dom::GamepadChangeEventBody body(info); | ||||||
|  |           dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR, body); | ||||||
|  |           gamepadManager->Update(event); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Send events for pose changes
 | ||||||
|  |     // Note that VRPose is asserted to be a POD type so memcmp is safe
 | ||||||
|  |     if (state.flags != lastState.flags || | ||||||
|  |         state.isPositionValid != lastState.isPositionValid || | ||||||
|  |         state.isOrientationValid != lastState.isOrientationValid || | ||||||
|  |         memcmp(&state.pose, &lastState.pose, sizeof(VRPose)) != 0) { | ||||||
|  | 
 | ||||||
|  |       // Convert pose to GamepadPoseState
 | ||||||
|  |       dom::GamepadPoseState poseState; | ||||||
|  |       poseState.Clear(); | ||||||
|  |       poseState.flags = state.flags; | ||||||
|  | 
 | ||||||
|  |       // Orientation values
 | ||||||
|  |       poseState.isOrientationValid = state.isOrientationValid; | ||||||
|  |       poseState.orientation[0] = state.pose.orientation[0]; | ||||||
|  |       poseState.orientation[1] = state.pose.orientation[1]; | ||||||
|  |       poseState.orientation[2] = state.pose.orientation[2]; | ||||||
|  |       poseState.orientation[3] = state.pose.orientation[3]; | ||||||
|  |       poseState.angularVelocity[0] = state.pose.angularVelocity[0]; | ||||||
|  |       poseState.angularVelocity[1] = state.pose.angularVelocity[1]; | ||||||
|  |       poseState.angularVelocity[2] = state.pose.angularVelocity[2]; | ||||||
|  |       poseState.angularAcceleration[0] = state.pose.angularAcceleration[0]; | ||||||
|  |       poseState.angularAcceleration[1] = state.pose.angularAcceleration[1]; | ||||||
|  |       poseState.angularAcceleration[2] = state.pose.angularAcceleration[2]; | ||||||
|  | 
 | ||||||
|  |       // Position values
 | ||||||
|  |       poseState.isPositionValid = state.isPositionValid; | ||||||
|  |       poseState.position[0] = state.pose.position[0]; | ||||||
|  |       poseState.position[1] = state.pose.position[1]; | ||||||
|  |       poseState.position[2] = state.pose.position[2]; | ||||||
|  |       poseState.linearVelocity[0] = state.pose.linearVelocity[0]; | ||||||
|  |       poseState.linearVelocity[1] = state.pose.linearVelocity[1]; | ||||||
|  |       poseState.linearVelocity[2] = state.pose.linearVelocity[2]; | ||||||
|  |       poseState.linearAcceleration[0] = state.pose.linearAcceleration[0]; | ||||||
|  |       poseState.linearAcceleration[1] = state.pose.linearAcceleration[1]; | ||||||
|  |       poseState.linearAcceleration[2] = state.pose.linearAcceleration[2]; | ||||||
|  | 
 | ||||||
|  |       // Send the event
 | ||||||
|  |       dom::GamepadPoseInformation info(poseState); | ||||||
|  |       dom::GamepadChangeEventBody body(info); | ||||||
|  |       dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR, body); | ||||||
|  |       gamepadManager->Update(event); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Note that VRControllerState is asserted to be a POD type and memcpy is safe.
 | ||||||
|  |   memcpy(mLastEventControllerState, | ||||||
|  |          mDisplayInfo.mControllerState, | ||||||
|  |          sizeof(VRControllerState) * kVRControllerMaxCount); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRHMDSensorState | VRHMDSensorState | ||||||
|  |  | ||||||
|  | @ -51,6 +51,7 @@ protected: | ||||||
|   virtual ~VRDisplayClient(); |   virtual ~VRDisplayClient(); | ||||||
| 
 | 
 | ||||||
|   void FireEvents(); |   void FireEvents(); | ||||||
|  |   void FireGamepadEvents(); | ||||||
| 
 | 
 | ||||||
|   VRDisplayInfo mDisplayInfo; |   VRDisplayInfo mDisplayInfo; | ||||||
| 
 | 
 | ||||||
|  | @ -60,6 +61,10 @@ protected: | ||||||
|   int mPresentationCount; |   int mPresentationCount; | ||||||
|   uint64_t mLastEventFrameId; |   uint64_t mLastEventFrameId; | ||||||
|   uint32_t mLastPresentingGeneration; |   uint32_t mLastPresentingGeneration; | ||||||
|  | 
 | ||||||
|  |   // Difference between mDisplayInfo.mControllerState and mLastEventControllerState
 | ||||||
|  |   // determines what gamepad events to fire when updated.
 | ||||||
|  |   VRControllerState mLastEventControllerState[kVRControllerMaxCount]; | ||||||
| private: | private: | ||||||
|   VRSubmitFrameResultInfo mSubmitFrameResult; |   VRSubmitFrameResultInfo mSubmitFrameResult; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -352,7 +352,7 @@ VRControllerHost::VRControllerHost(VRDeviceType aType, dom::GamepadHand aHand, | ||||||
| { | { | ||||||
|   MOZ_COUNT_CTOR(VRControllerHost); |   MOZ_COUNT_CTOR(VRControllerHost); | ||||||
|   mControllerInfo.mType = aType; |   mControllerInfo.mType = aType; | ||||||
|   mControllerInfo.mControllerState.mHand = aHand; |   mControllerInfo.mControllerState.hand = aHand; | ||||||
|   mControllerInfo.mMappingType = dom::GamepadMappingType::_empty; |   mControllerInfo.mMappingType = dom::GamepadMappingType::_empty; | ||||||
|   mControllerInfo.mDisplayID = aDisplayID; |   mControllerInfo.mDisplayID = aDisplayID; | ||||||
|   mControllerInfo.mControllerID = VRSystemManager::AllocateControllerID(); |   mControllerInfo.mControllerID = VRSystemManager::AllocateControllerID(); | ||||||
|  | @ -372,25 +372,25 @@ VRControllerHost::GetControllerInfo() const | ||||||
| void | void | ||||||
| VRControllerHost::SetButtonPressed(uint64_t aBit) | VRControllerHost::SetButtonPressed(uint64_t aBit) | ||||||
| { | { | ||||||
|   mControllerInfo.mControllerState.mButtonPressed = aBit; |   mControllerInfo.mControllerState.buttonPressed = aBit; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint64_t | uint64_t | ||||||
| VRControllerHost::GetButtonPressed() | VRControllerHost::GetButtonPressed() | ||||||
| { | { | ||||||
|   return mControllerInfo.mControllerState.mButtonPressed; |   return mControllerInfo.mControllerState.buttonPressed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| VRControllerHost::SetButtonTouched(uint64_t aBit) | VRControllerHost::SetButtonTouched(uint64_t aBit) | ||||||
| { | { | ||||||
|   mControllerInfo.mControllerState.mButtonTouched = aBit; |   mControllerInfo.mControllerState.buttonTouched = aBit; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint64_t | uint64_t | ||||||
| VRControllerHost::GetButtonTouched() | VRControllerHost::GetButtonTouched() | ||||||
| { | { | ||||||
|   return mControllerInfo.mControllerState.mButtonTouched; |   return mControllerInfo.mControllerState.buttonTouched; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
|  | @ -408,7 +408,7 @@ VRControllerHost::GetPose() | ||||||
| dom::GamepadHand | dom::GamepadHand | ||||||
| VRControllerHost::GetHand() | VRControllerHost::GetHand() | ||||||
| { | { | ||||||
|   return mControllerInfo.mControllerState.mHand; |   return mControllerInfo.mControllerState.hand; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
|  |  | ||||||
|  | @ -24,11 +24,12 @@ namespace mozilla { | ||||||
| #ifdef MOZILLA_INTERNAL_API | #ifdef MOZILLA_INTERNAL_API | ||||||
| namespace dom { | namespace dom { | ||||||
|   enum class GamepadHand : uint8_t; |   enum class GamepadHand : uint8_t; | ||||||
|  |   enum class GamepadCapabilityFlags : uint16_t; | ||||||
| } | } | ||||||
| #endif //  MOZILLA_INTERNAL_API
 | #endif //  MOZILLA_INTERNAL_API
 | ||||||
| namespace gfx { | namespace gfx { | ||||||
| 
 | 
 | ||||||
| static const int32_t kVRExternalVersion = 0; | static const int32_t kVRExternalVersion = 1; | ||||||
| 
 | 
 | ||||||
| // We assign VR presentations to groups with a bitmask.
 | // We assign VR presentations to groups with a bitmask.
 | ||||||
| // Currently, we will only display either content or chrome.
 | // Currently, we will only display either content or chrome.
 | ||||||
|  | @ -44,7 +45,7 @@ static const uint32_t kVRGroupAll = 0xffffffff; | ||||||
| static const int kVRDisplayNameMaxLen = 256; | static const int kVRDisplayNameMaxLen = 256; | ||||||
| static const int kVRControllerNameMaxLen = 256; | static const int kVRControllerNameMaxLen = 256; | ||||||
| static const int kVRControllerMaxCount = 16; | static const int kVRControllerMaxCount = 16; | ||||||
| static const int kVRControllerMaxTriggers = 16; | static const int kVRControllerMaxButtons = 64; | ||||||
| static const int kVRControllerMaxAxis = 16; | static const int kVRControllerMaxAxis = 16; | ||||||
| static const int kVRLayerMaxCount = 8; | static const int kVRLayerMaxCount = 8; | ||||||
| 
 | 
 | ||||||
|  | @ -82,6 +83,32 @@ enum class ControllerHand : uint8_t { | ||||||
|   EndGuard_ |   EndGuard_ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum class ControllerCapabilityFlags : uint16_t { | ||||||
|  |   Cap_None = 0, | ||||||
|  |   /**
 | ||||||
|  |    * Cap_Position is set if the Gamepad is capable of tracking its position. | ||||||
|  |    */ | ||||||
|  |   Cap_Position = 1 << 1, | ||||||
|  |   /**
 | ||||||
|  |     * Cap_Orientation is set if the Gamepad is capable of tracking its orientation. | ||||||
|  |     */ | ||||||
|  |   Cap_Orientation = 1 << 2, | ||||||
|  |   /**
 | ||||||
|  |    * Cap_AngularAcceleration is set if the Gamepad is capable of tracking its | ||||||
|  |    * angular acceleration. | ||||||
|  |    */ | ||||||
|  |   Cap_AngularAcceleration = 1 << 3, | ||||||
|  |   /**
 | ||||||
|  |    * Cap_LinearAcceleration is set if the Gamepad is capable of tracking its | ||||||
|  |    * linear acceleration. | ||||||
|  |    */ | ||||||
|  |   Cap_LinearAcceleration = 1 << 4, | ||||||
|  |   /**
 | ||||||
|  |    * Cap_All used for validity checking during IPC serialization | ||||||
|  |    */ | ||||||
|  |   Cap_All = (1 << 5) - 1 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| #endif // ifndef MOZILLA_INTERNAL_API
 | #endif // ifndef MOZILLA_INTERNAL_API
 | ||||||
| 
 | 
 | ||||||
| enum class VRDisplayCapabilityFlags : uint16_t { | enum class VRDisplayCapabilityFlags : uint16_t { | ||||||
|  | @ -140,20 +167,25 @@ enum class VRDisplayCapabilityFlags : uint16_t { | ||||||
| MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRDisplayCapabilityFlags) | MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRDisplayCapabilityFlags) | ||||||
| #endif // MOZILLA_INTERNAL_API
 | #endif // MOZILLA_INTERNAL_API
 | ||||||
| 
 | 
 | ||||||
|  | struct VRPose | ||||||
|  | { | ||||||
|  |   float orientation[4]; | ||||||
|  |   float position[3]; | ||||||
|  |   float angularVelocity[3]; | ||||||
|  |   float angularAcceleration[3]; | ||||||
|  |   float linearVelocity[3]; | ||||||
|  |   float linearAcceleration[3]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct VRHMDSensorState { | struct VRHMDSensorState { | ||||||
|   uint64_t inputFrameID; |   uint64_t inputFrameID; | ||||||
|   double timestamp; |   double timestamp; | ||||||
|   VRDisplayCapabilityFlags flags; |   VRDisplayCapabilityFlags flags; | ||||||
| 
 | 
 | ||||||
|   // These members will only change with inputFrameID:
 |   // These members will only change with inputFrameID:
 | ||||||
|   float orientation[4]; |   VRPose pose; | ||||||
|   float position[3]; |  | ||||||
|   float leftViewMatrix[16]; |   float leftViewMatrix[16]; | ||||||
|   float rightViewMatrix[16]; |   float rightViewMatrix[16]; | ||||||
|   float angularVelocity[3]; |  | ||||||
|   float angularAcceleration[3]; |  | ||||||
|   float linearVelocity[3]; |  | ||||||
|   float linearAcceleration[3]; |  | ||||||
| 
 | 
 | ||||||
| #ifdef MOZILLA_INTERNAL_API | #ifdef MOZILLA_INTERNAL_API | ||||||
| 
 | 
 | ||||||
|  | @ -248,22 +280,30 @@ struct VRDisplayState | ||||||
| 
 | 
 | ||||||
| struct VRControllerState | struct VRControllerState | ||||||
| { | { | ||||||
|   char mControllerName[kVRControllerNameMaxLen]; |   char controllerName[kVRControllerNameMaxLen]; | ||||||
| #ifdef MOZILLA_INTERNAL_API | #ifdef MOZILLA_INTERNAL_API | ||||||
|   dom::GamepadHand mHand; |   dom::GamepadHand hand; | ||||||
| #else | #else | ||||||
|   ControllerHand mHand; |   ControllerHand hand; | ||||||
| #endif | #endif | ||||||
|   uint32_t mNumButtons; |   uint32_t numButtons; | ||||||
|   uint32_t mNumAxes; |   uint32_t numAxes; | ||||||
|   uint32_t mNumTriggers; |   uint32_t numHaptics; | ||||||
|   uint32_t mNumHaptics; |  | ||||||
|   // The current button pressed bit of button mask.
 |   // The current button pressed bit of button mask.
 | ||||||
|   uint64_t mButtonPressed; |   uint64_t buttonPressed; | ||||||
|   // The current button touched bit of button mask.
 |   // The current button touched bit of button mask.
 | ||||||
|   uint64_t mButtonTouched; |   uint64_t buttonTouched; | ||||||
|   float mTriggerValue[kVRControllerMaxTriggers]; |   float triggerValue[kVRControllerMaxButtons]; | ||||||
|   float mAxisValue[kVRControllerMaxAxis]; |   float axisValue[kVRControllerMaxAxis]; | ||||||
|  | 
 | ||||||
|  | #ifdef MOZILLA_INTERNAL_API | ||||||
|  |   dom::GamepadCapabilityFlags flags; | ||||||
|  | #else | ||||||
|  |   ControllerCapabilityFlags flags; | ||||||
|  | #endif | ||||||
|  |   VRPose pose; | ||||||
|  |   bool isPositionValid; | ||||||
|  |   bool isOrientationValid; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct VRLayerEyeRect | struct VRLayerEyeRect | ||||||
|  |  | ||||||
|  | @ -189,10 +189,10 @@ VRHMDSensorState::CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms) | ||||||
| 
 | 
 | ||||||
|   gfx::Matrix4x4 matHead; |   gfx::Matrix4x4 matHead; | ||||||
|   if (flags & VRDisplayCapabilityFlags::Cap_Orientation) { |   if (flags & VRDisplayCapabilityFlags::Cap_Orientation) { | ||||||
|     matHead.SetRotationFromQuaternion(gfx::Quaternion(orientation[0], orientation[1], |     matHead.SetRotationFromQuaternion(gfx::Quaternion(pose.orientation[0], pose.orientation[1], | ||||||
|                                                       orientation[2], orientation[3])); |                                                       pose.orientation[2], pose.orientation[3])); | ||||||
|   } |   } | ||||||
|   matHead.PreTranslate(-position[0], -position[1], -position[2]); |   matHead.PreTranslate(-pose.position[0], -pose.position[1], -pose.position[2]); | ||||||
| 
 | 
 | ||||||
|   gfx::Matrix4x4 matView = matHead * aHeadToEyeTransforms[VRDisplayState::Eye_Left]; |   gfx::Matrix4x4 matView = matHead * aHeadToEyeTransforms[VRDisplayState::Eye_Left]; | ||||||
|   matView.Normalize(); |   matView.Normalize(); | ||||||
|  |  | ||||||
|  | @ -60,6 +60,7 @@ struct VRDisplayInfo | ||||||
|   uint32_t mGroupMask; |   uint32_t mGroupMask; | ||||||
|   uint64_t mFrameId; |   uint64_t mFrameId; | ||||||
|   VRDisplayState mDisplayState; |   VRDisplayState mDisplayState; | ||||||
|  |   VRControllerState mControllerState[kVRControllerMaxCount]; | ||||||
| 
 | 
 | ||||||
|   VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames]; |   VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames]; | ||||||
|   const VRHMDSensorState& GetSensorState() const |   const VRHMDSensorState& GetSensorState() const | ||||||
|  | @ -89,10 +90,11 @@ struct VRDisplayInfo | ||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     // Note that mDisplayState is asserted to be a POD type, so memcmp is safe
 |     // Note that mDisplayState and mControllerState are asserted to be POD types, so memcmp is safe
 | ||||||
|     return mType == other.mType && |     return mType == other.mType && | ||||||
|            mDisplayID == other.mDisplayID && |            mDisplayID == other.mDisplayID && | ||||||
|            memcmp(&mDisplayState, &other.mDisplayState, sizeof(VRDisplayState)) == 0 && |            memcmp(&mDisplayState, &other.mDisplayState, sizeof(VRDisplayState)) == 0 && | ||||||
|  |            memcmp(mControllerState, other.mControllerState, sizeof(VRControllerState) * kVRControllerMaxCount) == 0 && | ||||||
|            mPresentingGroups == other.mPresentingGroups && |            mPresentingGroups == other.mPresentingGroups && | ||||||
|            mGroupMask == other.mGroupMask && |            mGroupMask == other.mGroupMask && | ||||||
|            mFrameId == other.mFrameId; |            mFrameId == other.mFrameId; | ||||||
|  | @ -123,13 +125,13 @@ struct VRControllerInfo | ||||||
| { | { | ||||||
|   VRDeviceType GetType() const { return mType; } |   VRDeviceType GetType() const { return mType; } | ||||||
|   uint32_t GetControllerID() const { return mControllerID; } |   uint32_t GetControllerID() const { return mControllerID; } | ||||||
|   const char* GetControllerName() const { return mControllerState.mControllerName; } |   const char* GetControllerName() const { return mControllerState.controllerName; } | ||||||
|   dom::GamepadMappingType GetMappingType() const { return mMappingType; } |   dom::GamepadMappingType GetMappingType() const { return mMappingType; } | ||||||
|   uint32_t GetDisplayID() const { return mDisplayID; } |   uint32_t GetDisplayID() const { return mDisplayID; } | ||||||
|   dom::GamepadHand GetHand() const { return mControllerState.mHand; } |   dom::GamepadHand GetHand() const { return mControllerState.hand; } | ||||||
|   uint32_t GetNumButtons() const { return mControllerState.mNumButtons; } |   uint32_t GetNumButtons() const { return mControllerState.numButtons; } | ||||||
|   uint32_t GetNumAxes() const { return mControllerState.mNumAxes; } |   uint32_t GetNumAxes() const { return mControllerState.numAxes; } | ||||||
|   uint32_t GetNumHaptics() const { return mControllerState.mNumHaptics; } |   uint32_t GetNumHaptics() const { return mControllerState.numHaptics; } | ||||||
| 
 | 
 | ||||||
|   uint32_t mControllerID; |   uint32_t mControllerID; | ||||||
|   VRDeviceType mType; |   VRDeviceType mType; | ||||||
|  | @ -137,15 +139,12 @@ struct VRControllerInfo | ||||||
|   uint32_t mDisplayID; |   uint32_t mDisplayID; | ||||||
|   VRControllerState mControllerState; |   VRControllerState mControllerState; | ||||||
|   bool operator==(const VRControllerInfo& other) const { |   bool operator==(const VRControllerInfo& other) const { | ||||||
|  |     // Note that mControllerState is asserted to be a POD type, so memcmp is safe
 | ||||||
|     return mType == other.mType && |     return mType == other.mType && | ||||||
|            mControllerID == other.mControllerID && |            mControllerID == other.mControllerID && | ||||||
|            strncmp(mControllerState.mControllerName, other.mControllerState.mControllerName, kVRControllerNameMaxLen) == 0 && |            memcmp(&mControllerState, &other.mControllerState, sizeof(VRControllerState)) == 0 && | ||||||
|            mMappingType == other.mMappingType && |            mMappingType == other.mMappingType && | ||||||
|            mDisplayID == other.mDisplayID && |            mDisplayID == other.mDisplayID; | ||||||
|            mControllerState.mHand == other.mControllerState.mHand && |  | ||||||
|            mControllerState.mNumButtons == other.mControllerState.mNumButtons && |  | ||||||
|            mControllerState.mNumAxes == other.mControllerState.mNumAxes && |  | ||||||
|            mControllerState.mNumHaptics == other.mControllerState.mNumHaptics; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   bool operator!=(const VRControllerInfo& other) const { |   bool operator!=(const VRControllerInfo& other) const { | ||||||
|  |  | ||||||
|  | @ -52,8 +52,6 @@ using namespace mozilla::gfx::impl; | ||||||
| using namespace mozilla::layers; | using namespace mozilla::layers; | ||||||
| using namespace mozilla::dom; | using namespace mozilla::dom; | ||||||
| 
 | 
 | ||||||
| static const uint32_t kNumExternalHaptcs = 1; |  | ||||||
| 
 |  | ||||||
| int VRDisplayExternal::sPushIndex = 0; | int VRDisplayExternal::sPushIndex = 0; | ||||||
| 
 | 
 | ||||||
| VRDisplayExternal::VRDisplayExternal(const VRDisplayState& aDisplayState) | VRDisplayExternal::VRDisplayExternal(const VRDisplayState& aDisplayState) | ||||||
|  | @ -65,7 +63,7 @@ VRDisplayExternal::VRDisplayExternal(const VRDisplayState& aDisplayState) | ||||||
|   mDisplayInfo.mDisplayState = aDisplayState; |   mDisplayInfo.mDisplayState = aDisplayState; | ||||||
| 
 | 
 | ||||||
|   // default to an identity quaternion
 |   // default to an identity quaternion
 | ||||||
|   mLastSensorState.orientation[3] = 1.0f; |   mLastSensorState.pose.orientation[3] = 1.0f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRDisplayExternal::~VRDisplayExternal() | VRDisplayExternal::~VRDisplayExternal() | ||||||
|  | @ -78,8 +76,6 @@ void | ||||||
| VRDisplayExternal::Destroy() | VRDisplayExternal::Destroy() | ||||||
| { | { | ||||||
|   StopPresentation(); |   StopPresentation(); | ||||||
| 
 |  | ||||||
|   // TODO - Implement
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
|  | @ -93,7 +89,7 @@ VRDisplayExternal::Refresh() | ||||||
|   VRManager *vm = VRManager::Get(); |   VRManager *vm = VRManager::Get(); | ||||||
|   VRSystemManagerExternal* manager = vm->GetExternalManager(); |   VRSystemManagerExternal* manager = vm->GetExternalManager(); | ||||||
| 
 | 
 | ||||||
|   manager->PullState(&mDisplayInfo.mDisplayState, &mLastSensorState); |   manager->PullState(&mDisplayInfo.mDisplayState, &mLastSensorState, mDisplayInfo.mControllerState); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRHMDSensorState | VRHMDSensorState | ||||||
|  | @ -238,7 +234,7 @@ VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture, | ||||||
|   VRDisplayState displayState; |   VRDisplayState displayState; | ||||||
|   memset(&displayState, 0, sizeof(VRDisplayState)); |   memset(&displayState, 0, sizeof(VRDisplayState)); | ||||||
|   while (displayState.mLastSubmittedFrameId < aFrameId) { |   while (displayState.mLastSubmittedFrameId < aFrameId) { | ||||||
|     if (manager->PullState(&displayState, &mLastSensorState)) { |     if (manager->PullState(&displayState, &mLastSensorState, mDisplayInfo.mControllerState)) { | ||||||
|       if (!displayState.mIsConnected) { |       if (!displayState.mIsConnected) { | ||||||
|         // Service has shut down or hardware has been disconnected
 |         // Service has shut down or hardware has been disconnected
 | ||||||
|         return false; |         return false; | ||||||
|  | @ -254,26 +250,6 @@ VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture, | ||||||
|   return displayState.mLastSubmittedFrameSuccessful; |   return displayState.mLastSubmittedFrameSuccessful; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRControllerExternal::VRControllerExternal(dom::GamepadHand aHand, uint32_t aDisplayID, |  | ||||||
|                                        uint32_t aNumButtons, uint32_t aNumTriggers, |  | ||||||
|                                        uint32_t aNumAxes, const nsCString& aId) |  | ||||||
|   : VRControllerHost(VRDeviceType::External, aHand, aDisplayID) |  | ||||||
| { |  | ||||||
|   MOZ_COUNT_CTOR_INHERITED(VRControllerExternal, VRControllerHost); |  | ||||||
| 
 |  | ||||||
|   VRControllerState& state = mControllerInfo.mControllerState; |  | ||||||
|   strncpy(state.mControllerName, aId.BeginReading(), kVRControllerNameMaxLen); |  | ||||||
|   state.mNumButtons = aNumButtons; |  | ||||||
|   state.mNumAxes = aNumAxes; |  | ||||||
|   state.mNumTriggers = aNumTriggers; |  | ||||||
|   state.mNumHaptics = kNumExternalHaptcs; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| VRControllerExternal::~VRControllerExternal() |  | ||||||
| { |  | ||||||
|   MOZ_COUNT_DTOR_INHERITED(VRControllerExternal, VRControllerHost); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| VRSystemManagerExternal::VRSystemManagerExternal(VRExternalShmem* aAPIShmem /* = nullptr*/) | VRSystemManagerExternal::VRSystemManagerExternal(VRExternalShmem* aAPIShmem /* = nullptr*/) | ||||||
|  : mExternalShmem(aAPIShmem) |  : mExternalShmem(aAPIShmem) | ||||||
| #if !defined(MOZ_WIDGET_ANDROID) | #if !defined(MOZ_WIDGET_ANDROID) | ||||||
|  | @ -458,7 +434,6 @@ VRSystemManagerExternal::Shutdown() | ||||||
|   if (mDisplay) { |   if (mDisplay) { | ||||||
|     mDisplay = nullptr; |     mDisplay = nullptr; | ||||||
|   } |   } | ||||||
|   RemoveControllers(); |  | ||||||
|   CloseShmem(); |   CloseShmem(); | ||||||
| #if defined(MOZ_WIDGET_ANDROID) | #if defined(MOZ_WIDGET_ANDROID) | ||||||
|   mDoShutdown = false; |   mDoShutdown = false; | ||||||
|  | @ -537,12 +512,6 @@ VRSystemManagerExternal::GetIsPresenting() | ||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void |  | ||||||
| VRSystemManagerExternal::HandleInput() |  | ||||||
| { |  | ||||||
|   // TODO - Implement This!
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void | void | ||||||
| VRSystemManagerExternal::VibrateHaptic(uint32_t aControllerIdx, | VRSystemManagerExternal::VibrateHaptic(uint32_t aControllerIdx, | ||||||
|                                       uint32_t aHapticIndex, |                                       uint32_t aHapticIndex, | ||||||
|  | @ -562,31 +531,40 @@ VRSystemManagerExternal::StopVibrateHaptic(uint32_t aControllerIdx) | ||||||
| void | void | ||||||
| VRSystemManagerExternal::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult) | VRSystemManagerExternal::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult) | ||||||
| { | { | ||||||
|  |   // Controller updates are handled in VRDisplayClient for VRSystemManagerExternal
 | ||||||
|   aControllerResult.Clear(); |   aControllerResult.Clear(); | ||||||
|   for (uint32_t i = 0; i < mExternalController.Length(); ++i) { |  | ||||||
|     aControllerResult.AppendElement(mExternalController[i]); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| VRSystemManagerExternal::ScanForControllers() | VRSystemManagerExternal::ScanForControllers() | ||||||
| { | { | ||||||
|   // TODO - Implement this
 |   // Controller updates are handled in VRDisplayClient for VRSystemManagerExternal
 | ||||||
|  |   if (mDisplay) { | ||||||
|  |     mDisplay->Refresh(); | ||||||
|  |   } | ||||||
|  |   return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | VRSystemManagerExternal::HandleInput() | ||||||
|  | { | ||||||
|  |   // Controller updates are handled in VRDisplayClient for VRSystemManagerExternal
 | ||||||
|  |   if (mDisplay) { | ||||||
|  |     mDisplay->Refresh(); | ||||||
|  |   } | ||||||
|  |   return; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| VRSystemManagerExternal::RemoveControllers() | VRSystemManagerExternal::RemoveControllers() | ||||||
| { | { | ||||||
|   // The controller count is changed, removing the existing gamepads first.
 |   // Controller updates are handled in VRDisplayClient for VRSystemManagerExternal
 | ||||||
|   for (uint32_t i = 0; i < mExternalController.Length(); ++i) { |  | ||||||
|     RemoveGamepad(i); |  | ||||||
|   } |  | ||||||
|   mExternalController.Clear(); |  | ||||||
|   mControllerCount = 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool | bool | ||||||
| VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState /* = nullptr */) | VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, | ||||||
|  |                                    VRHMDSensorState* aSensorState /* = nullptr */, | ||||||
|  |                                    VRControllerState* aControllerState /* = nullptr */) | ||||||
| { | { | ||||||
|   bool success = false; |   bool success = false; | ||||||
|   MOZ_ASSERT(mExternalShmem); |   MOZ_ASSERT(mExternalShmem); | ||||||
|  | @ -597,6 +575,9 @@ VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorSta | ||||||
|       if (aSensorState) { |       if (aSensorState) { | ||||||
|         memcpy(aSensorState, (void*)&(mExternalShmem->state.sensorState), sizeof(VRHMDSensorState)); |         memcpy(aSensorState, (void*)&(mExternalShmem->state.sensorState), sizeof(VRHMDSensorState)); | ||||||
|       } |       } | ||||||
|  |       if (aControllerState) { | ||||||
|  |         memcpy(aControllerState, (void*)&(mExternalShmem->state.controllerState), sizeof(VRControllerState) * kVRControllerMaxCount); | ||||||
|  |       } | ||||||
|       success = mExternalShmem->state.enumerationCompleted; |       success = mExternalShmem->state.enumerationCompleted; | ||||||
|       pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->systemMutex)); |       pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->systemMutex)); | ||||||
|       mDoShutdown = aDisplayState->shutdown; |       mDoShutdown = aDisplayState->shutdown; | ||||||
|  | @ -609,6 +590,9 @@ VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorSta | ||||||
|       if (aSensorState) { |       if (aSensorState) { | ||||||
|         memcpy(aSensorState, &tmp.state.sensorState, sizeof(VRHMDSensorState)); |         memcpy(aSensorState, &tmp.state.sensorState, sizeof(VRHMDSensorState)); | ||||||
|       } |       } | ||||||
|  |       if (aControllerState) { | ||||||
|  |         memcpy(aControllerState, (void*)&(mExternalShmem->state.controllerState), sizeof(VRControllerState) * kVRControllerMaxCount); | ||||||
|  |       } | ||||||
|       success = true; |       success = true; | ||||||
|     } |     } | ||||||
| #endif // defined(MOZ_WIDGET_ANDROID)
 | #endif // defined(MOZ_WIDGET_ANDROID)
 | ||||||
|  |  | ||||||
|  | @ -46,6 +46,7 @@ protected: | ||||||
| public: | public: | ||||||
|   explicit VRDisplayExternal(const VRDisplayState& aDisplayState); |   explicit VRDisplayExternal(const VRDisplayState& aDisplayState); | ||||||
|   void Refresh(); |   void Refresh(); | ||||||
|  |   const VRControllerState& GetLastControllerState(uint32_t aStateIndex) const; | ||||||
| protected: | protected: | ||||||
|   virtual ~VRDisplayExternal(); |   virtual ~VRDisplayExternal(); | ||||||
|   void Destroy(); |   void Destroy(); | ||||||
|  | @ -60,17 +61,6 @@ private: | ||||||
|   VRHMDSensorState mLastSensorState; |   VRHMDSensorState mLastSensorState; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class VRControllerExternal : public VRControllerHost |  | ||||||
| { |  | ||||||
| public: |  | ||||||
|   explicit VRControllerExternal(dom::GamepadHand aHand, uint32_t aDisplayID, uint32_t aNumButtons, |  | ||||||
|                               uint32_t aNumTriggers, uint32_t aNumAxes, |  | ||||||
|                               const nsCString& aId); |  | ||||||
| 
 |  | ||||||
| protected: |  | ||||||
|   virtual ~VRControllerExternal(); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| } // namespace impl
 | } // namespace impl
 | ||||||
| 
 | 
 | ||||||
| class VRSystemManagerExternal : public VRSystemManager | class VRSystemManagerExternal : public VRSystemManager | ||||||
|  | @ -96,7 +86,9 @@ public: | ||||||
|                              double aDuration, |                              double aDuration, | ||||||
|                              const VRManagerPromise& aPromise) override; |                              const VRManagerPromise& aPromise) override; | ||||||
|   virtual void StopVibrateHaptic(uint32_t aControllerIdx) override; |   virtual void StopVibrateHaptic(uint32_t aControllerIdx) override; | ||||||
|   bool PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState = nullptr); |   bool PullState(VRDisplayState* aDisplayState, | ||||||
|  |                  VRHMDSensorState* aSensorState = nullptr, | ||||||
|  |                  VRControllerState* aControllerState = nullptr); | ||||||
|   void PushState(VRBrowserState* aBrowserState, const bool aNotifyCond = false); |   void PushState(VRBrowserState* aBrowserState, const bool aNotifyCond = false); | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  | @ -106,7 +98,6 @@ protected: | ||||||
| private: | private: | ||||||
|   // there can only be one
 |   // there can only be one
 | ||||||
|   RefPtr<impl::VRDisplayExternal> mDisplay; |   RefPtr<impl::VRDisplayExternal> mDisplay; | ||||||
|   nsTArray<RefPtr<impl::VRControllerExternal>> mExternalController; |  | ||||||
| #if defined(XP_MACOSX) | #if defined(XP_MACOSX) | ||||||
|   int mShmemFD; |   int mShmemFD; | ||||||
| #elif defined(XP_WIN) | #elif defined(XP_WIN) | ||||||
|  |  | ||||||
|  | @ -317,22 +317,22 @@ VRDisplayOSVR::GetSensorState() | ||||||
| 
 | 
 | ||||||
|   if (ret == OSVR_RETURN_SUCCESS) { |   if (ret == OSVR_RETURN_SUCCESS) { | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; |     result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; | ||||||
|     result.orientation[0] = orientation.data[1]; |     result.pose.orientation[0] = orientation.data[1]; | ||||||
|     result.orientation[1] = orientation.data[2]; |     result.pose.orientation[1] = orientation.data[2]; | ||||||
|     result.orientation[2] = orientation.data[3]; |     result.pose.orientation[2] = orientation.data[3]; | ||||||
|     result.orientation[3] = orientation.data[0]; |     result.pose.orientation[3] = orientation.data[0]; | ||||||
|   } else { |   } else { | ||||||
|     // default to an identity quaternion
 |     // default to an identity quaternion
 | ||||||
|     result.orientation[3] = 1.0f; |     result.pose.orientation[3] = 1.0f; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   OSVR_PositionState position; |   OSVR_PositionState position; | ||||||
|   ret = osvr_GetPositionState(*m_iface, ×tamp, &position); |   ret = osvr_GetPositionState(*m_iface, ×tamp, &position); | ||||||
|   if (ret == OSVR_RETURN_SUCCESS) { |   if (ret == OSVR_RETURN_SUCCESS) { | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_Position; |     result.flags |= VRDisplayCapabilityFlags::Cap_Position; | ||||||
|     result.position[0] = position.data[0]; |     result.pose.position[0] = position.data[0]; | ||||||
|     result.position[1] = position.data[1]; |     result.pose.position[1] = position.data[1]; | ||||||
|     result.position[2] = position.data[2]; |     result.pose.position[2] = position.data[2]; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   result.CalcViewMatrices(mHeadToEye); |   result.CalcViewMatrices(mHeadToEye); | ||||||
|  |  | ||||||
|  | @ -952,7 +952,7 @@ VRDisplayOculus::GetSensorState() | ||||||
|       predictedFrameTime = ovr_GetPredictedDisplayTime(mSession->Get(), 0); |       predictedFrameTime = ovr_GetPredictedDisplayTime(mSession->Get(), 0); | ||||||
|     } |     } | ||||||
|     result = GetSensorState(predictedFrameTime); |     result = GetSensorState(predictedFrameTime); | ||||||
|     result.position[1] -= mEyeHeight; |     result.pose.position[1] -= mEyeHeight; | ||||||
|     result.CalcViewMatrices(headToEyeTransforms); |     result.CalcViewMatrices(headToEyeTransforms); | ||||||
|   } |   } | ||||||
|   result.inputFrameID = mDisplayInfo.mFrameId; |   result.inputFrameID = mDisplayInfo.mFrameId; | ||||||
|  | @ -973,41 +973,41 @@ VRDisplayOculus::GetSensorState(double absTime) | ||||||
|   if (state.StatusFlags & ovrStatus_OrientationTracked) { |   if (state.StatusFlags & ovrStatus_OrientationTracked) { | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; |     result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; | ||||||
| 
 | 
 | ||||||
|     result.orientation[0] = pose.ThePose.Orientation.x; |     result.pose.orientation[0] = pose.ThePose.Orientation.x; | ||||||
|     result.orientation[1] = pose.ThePose.Orientation.y; |     result.pose.orientation[1] = pose.ThePose.Orientation.y; | ||||||
|     result.orientation[2] = pose.ThePose.Orientation.z; |     result.pose.orientation[2] = pose.ThePose.Orientation.z; | ||||||
|     result.orientation[3] = pose.ThePose.Orientation.w; |     result.pose.orientation[3] = pose.ThePose.Orientation.w; | ||||||
| 
 | 
 | ||||||
|     result.angularVelocity[0] = pose.AngularVelocity.x; |     result.pose.angularVelocity[0] = pose.AngularVelocity.x; | ||||||
|     result.angularVelocity[1] = pose.AngularVelocity.y; |     result.pose.angularVelocity[1] = pose.AngularVelocity.y; | ||||||
|     result.angularVelocity[2] = pose.AngularVelocity.z; |     result.pose.angularVelocity[2] = pose.AngularVelocity.z; | ||||||
| 
 | 
 | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration; |     result.flags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration; | ||||||
| 
 | 
 | ||||||
|     result.angularAcceleration[0] = pose.AngularAcceleration.x; |     result.pose.angularAcceleration[0] = pose.AngularAcceleration.x; | ||||||
|     result.angularAcceleration[1] = pose.AngularAcceleration.y; |     result.pose.angularAcceleration[1] = pose.AngularAcceleration.y; | ||||||
|     result.angularAcceleration[2] = pose.AngularAcceleration.z; |     result.pose.angularAcceleration[2] = pose.AngularAcceleration.z; | ||||||
|   } else { |   } else { | ||||||
|     // default to an identity quaternion
 |     // default to an identity quaternion
 | ||||||
|     result.orientation[3] = 1.0f; |     result.pose.orientation[3] = 1.0f; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (state.StatusFlags & ovrStatus_PositionTracked) { |   if (state.StatusFlags & ovrStatus_PositionTracked) { | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_Position; |     result.flags |= VRDisplayCapabilityFlags::Cap_Position; | ||||||
| 
 | 
 | ||||||
|     result.position[0] = pose.ThePose.Position.x; |     result.pose.position[0] = pose.ThePose.Position.x; | ||||||
|     result.position[1] = pose.ThePose.Position.y; |     result.pose.position[1] = pose.ThePose.Position.y; | ||||||
|     result.position[2] = pose.ThePose.Position.z; |     result.pose.position[2] = pose.ThePose.Position.z; | ||||||
| 
 | 
 | ||||||
|     result.linearVelocity[0] = pose.LinearVelocity.x; |     result.pose.linearVelocity[0] = pose.LinearVelocity.x; | ||||||
|     result.linearVelocity[1] = pose.LinearVelocity.y; |     result.pose.linearVelocity[1] = pose.LinearVelocity.y; | ||||||
|     result.linearVelocity[2] = pose.LinearVelocity.z; |     result.pose.linearVelocity[2] = pose.LinearVelocity.z; | ||||||
| 
 | 
 | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration; |     result.flags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration; | ||||||
| 
 | 
 | ||||||
|     result.linearAcceleration[0] = pose.LinearAcceleration.x; |     result.pose.linearAcceleration[0] = pose.LinearAcceleration.x; | ||||||
|     result.linearAcceleration[1] = pose.LinearAcceleration.y; |     result.pose.linearAcceleration[1] = pose.LinearAcceleration.y; | ||||||
|     result.linearAcceleration[2] = pose.LinearAcceleration.z; |     result.pose.linearAcceleration[2] = pose.LinearAcceleration.z; | ||||||
|   } |   } | ||||||
|   result.flags |= VRDisplayCapabilityFlags::Cap_External; |   result.flags |= VRDisplayCapabilityFlags::Cap_External; | ||||||
|   result.flags |= VRDisplayCapabilityFlags::Cap_MountDetection; |   result.flags |= VRDisplayCapabilityFlags::Cap_MountDetection; | ||||||
|  | @ -1330,17 +1330,17 @@ VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand, uint32_t aDisplay | ||||||
|       break; |       break; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   strncpy(state.mControllerName, touchID, kVRControllerNameMaxLen); |   strncpy(state.controllerName, touchID, kVRControllerNameMaxLen); | ||||||
| 
 | 
 | ||||||
|   MOZ_ASSERT(kNumOculusButton == |   MOZ_ASSERT(kNumOculusButton == | ||||||
|              static_cast<uint32_t>(OculusLeftControllerButtonType::NumButtonType) |              static_cast<uint32_t>(OculusLeftControllerButtonType::NumButtonType) | ||||||
|              && kNumOculusButton == |              && kNumOculusButton == | ||||||
|              static_cast<uint32_t>(OculusRightControllerButtonType::NumButtonType)); |              static_cast<uint32_t>(OculusRightControllerButtonType::NumButtonType)); | ||||||
| 
 | 
 | ||||||
|   state.mNumButtons = kNumOculusButton; |   state.numButtons = kNumOculusButton; | ||||||
|   state.mNumAxes = static_cast<uint32_t>( |   state.numAxes = static_cast<uint32_t>( | ||||||
|                    OculusControllerAxisType::NumVRControllerAxisType); |                    OculusControllerAxisType::NumVRControllerAxisType); | ||||||
|   state.mNumHaptics = kNumOculusHaptcs; |   state.numHaptics = kNumOculusHaptcs; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float | float | ||||||
|  |  | ||||||
|  | @ -287,24 +287,24 @@ VRDisplayOpenVR::GetSensorState() | ||||||
|     rot.Invert(); |     rot.Invert(); | ||||||
| 
 | 
 | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; |     result.flags |= VRDisplayCapabilityFlags::Cap_Orientation; | ||||||
|     result.orientation[0] = rot.x; |     result.pose.orientation[0] = rot.x; | ||||||
|     result.orientation[1] = rot.y; |     result.pose.orientation[1] = rot.y; | ||||||
|     result.orientation[2] = rot.z; |     result.pose.orientation[2] = rot.z; | ||||||
|     result.orientation[3] = rot.w; |     result.pose.orientation[3] = rot.w; | ||||||
|     result.angularVelocity[0] = pose.vAngularVelocity.v[0]; |     result.pose.angularVelocity[0] = pose.vAngularVelocity.v[0]; | ||||||
|     result.angularVelocity[1] = pose.vAngularVelocity.v[1]; |     result.pose.angularVelocity[1] = pose.vAngularVelocity.v[1]; | ||||||
|     result.angularVelocity[2] = pose.vAngularVelocity.v[2]; |     result.pose.angularVelocity[2] = pose.vAngularVelocity.v[2]; | ||||||
| 
 | 
 | ||||||
|     result.flags |= VRDisplayCapabilityFlags::Cap_Position; |     result.flags |= VRDisplayCapabilityFlags::Cap_Position; | ||||||
|     result.position[0] = m._41; |     result.pose.position[0] = m._41; | ||||||
|     result.position[1] = m._42; |     result.pose.position[1] = m._42; | ||||||
|     result.position[2] = m._43; |     result.pose.position[2] = m._43; | ||||||
|     result.linearVelocity[0] = pose.vVelocity.v[0]; |     result.pose.linearVelocity[0] = pose.vVelocity.v[0]; | ||||||
|     result.linearVelocity[1] = pose.vVelocity.v[1]; |     result.pose.linearVelocity[1] = pose.vVelocity.v[1]; | ||||||
|     result.linearVelocity[2] = pose.vVelocity.v[2]; |     result.pose.linearVelocity[2] = pose.vVelocity.v[2]; | ||||||
|   } else { |   } else { | ||||||
|     // default to an identity quaternion
 |     // default to an identity quaternion
 | ||||||
|     result.orientation[3] = 1.0f; |     result.pose.orientation[3] = 1.0f; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   result.CalcViewMatrices(headToEyeTransforms); |   result.CalcViewMatrices(headToEyeTransforms); | ||||||
|  | @ -438,11 +438,10 @@ VRControllerOpenVR::VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aDisplay | ||||||
|   MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost); |   MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost); | ||||||
| 
 | 
 | ||||||
|   VRControllerState& state = mControllerInfo.mControllerState; |   VRControllerState& state = mControllerInfo.mControllerState; | ||||||
|   strncpy(state.mControllerName, aId.BeginReading(), kVRControllerNameMaxLen); |   strncpy(state.controllerName, aId.BeginReading(), kVRControllerNameMaxLen); | ||||||
|   state.mNumButtons = aNumButtons; |   state.numButtons = aNumButtons; | ||||||
|   state.mNumAxes = aNumAxes; |   state.numAxes = aNumAxes; | ||||||
|   state.mNumTriggers = aNumTriggers; |   state.numHaptics = kNumOpenVRHaptcs; | ||||||
|   state.mNumHaptics = kNumOpenVRHaptcs; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRControllerOpenVR::~VRControllerOpenVR() | VRControllerOpenVR::~VRControllerOpenVR() | ||||||
|  | @ -466,31 +465,31 @@ VRControllerOpenVR::GetTrackedIndex() | ||||||
| float | float | ||||||
| VRControllerOpenVR::GetAxisMove(uint32_t aAxis) | VRControllerOpenVR::GetAxisMove(uint32_t aAxis) | ||||||
| { | { | ||||||
|   return mControllerInfo.mControllerState.mAxisValue[aAxis]; |   return mControllerInfo.mControllerState.axisValue[aAxis]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| VRControllerOpenVR::SetAxisMove(uint32_t aAxis, float aValue) | VRControllerOpenVR::SetAxisMove(uint32_t aAxis, float aValue) | ||||||
| { | { | ||||||
|   mControllerInfo.mControllerState.mAxisValue[aAxis] = aValue; |   mControllerInfo.mControllerState.axisValue[aAxis] = aValue; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| VRControllerOpenVR::SetTrigger(uint32_t aButton, float aValue) | VRControllerOpenVR::SetTrigger(uint32_t aButton, float aValue) | ||||||
| { | { | ||||||
|   mControllerInfo.mControllerState.mTriggerValue[aButton] = aValue; |   mControllerInfo.mControllerState.triggerValue[aButton] = aValue; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float | float | ||||||
| VRControllerOpenVR::GetTrigger(uint32_t aButton) | VRControllerOpenVR::GetTrigger(uint32_t aButton) | ||||||
| { | { | ||||||
|   return mControllerInfo.mControllerState.mTriggerValue[aButton]; |   return mControllerInfo.mControllerState.triggerValue[aButton]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| VRControllerOpenVR::SetHand(dom::GamepadHand aHand) | VRControllerOpenVR::SetHand(dom::GamepadHand aHand) | ||||||
| { | { | ||||||
|   mControllerInfo.mControllerState.mHand = aHand; |   mControllerInfo.mControllerState.hand = aHand; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
|  |  | ||||||
|  | @ -104,21 +104,21 @@ VRDisplayPuppet::VRDisplayPuppet() | ||||||
|   gfx::Quaternion rot; |   gfx::Quaternion rot; | ||||||
| 
 | 
 | ||||||
|   mSensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation; |   mSensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation; | ||||||
|   mSensorState.orientation[0] = rot.x; |   mSensorState.pose.orientation[0] = rot.x; | ||||||
|   mSensorState.orientation[1] = rot.y; |   mSensorState.pose.orientation[1] = rot.y; | ||||||
|   mSensorState.orientation[2] = rot.z; |   mSensorState.pose.orientation[2] = rot.z; | ||||||
|   mSensorState.orientation[3] = rot.w; |   mSensorState.pose.orientation[3] = rot.w; | ||||||
|   mSensorState.angularVelocity[0] = 0.0f; |   mSensorState.pose.angularVelocity[0] = 0.0f; | ||||||
|   mSensorState.angularVelocity[1] = 0.0f; |   mSensorState.pose.angularVelocity[1] = 0.0f; | ||||||
|   mSensorState.angularVelocity[2] = 0.0f; |   mSensorState.pose.angularVelocity[2] = 0.0f; | ||||||
| 
 | 
 | ||||||
|   mSensorState.flags |= VRDisplayCapabilityFlags::Cap_Position; |   mSensorState.flags |= VRDisplayCapabilityFlags::Cap_Position; | ||||||
|   mSensorState.position[0] = 0.0f; |   mSensorState.pose.position[0] = 0.0f; | ||||||
|   mSensorState.position[1] = 0.0f; |   mSensorState.pose.position[1] = 0.0f; | ||||||
|   mSensorState.position[2] = 0.0f; |   mSensorState.pose.position[2] = 0.0f; | ||||||
|   mSensorState.linearVelocity[0] = 0.0f; |   mSensorState.pose.linearVelocity[0] = 0.0f; | ||||||
|   mSensorState.linearVelocity[1] = 0.0f; |   mSensorState.pose.linearVelocity[1] = 0.0f; | ||||||
|   mSensorState.linearVelocity[2] = 0.0f; |   mSensorState.pose.linearVelocity[2] = 0.0f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRDisplayPuppet::~VRDisplayPuppet() | VRDisplayPuppet::~VRDisplayPuppet() | ||||||
|  | @ -585,10 +585,10 @@ VRControllerPuppet::VRControllerPuppet(dom::GamepadHand aHand, uint32_t aDisplay | ||||||
| { | { | ||||||
|   MOZ_COUNT_CTOR_INHERITED(VRControllerPuppet, VRControllerHost); |   MOZ_COUNT_CTOR_INHERITED(VRControllerPuppet, VRControllerHost); | ||||||
|   VRControllerState& state = mControllerInfo.mControllerState; |   VRControllerState& state = mControllerInfo.mControllerState; | ||||||
|   strncpy(state.mControllerName, "Puppet Gamepad", kVRControllerNameMaxLen); |   strncpy(state.controllerName, "Puppet Gamepad", kVRControllerNameMaxLen); | ||||||
|   state.mNumButtons = kNumPuppetButtonMask; |   state.numButtons = kNumPuppetButtonMask; | ||||||
|   state.mNumAxes = kNumPuppetAxis; |   state.numAxes = kNumPuppetAxis; | ||||||
|   state.mNumHaptics = kNumPuppetHaptcs; |   state.numHaptics = kNumPuppetHaptcs; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRControllerPuppet::~VRControllerPuppet() | VRControllerPuppet::~VRControllerPuppet() | ||||||
|  | @ -672,13 +672,13 @@ VRControllerPuppet::GetPoseMoveState() | ||||||
| float | float | ||||||
| VRControllerPuppet::GetAxisMove(uint32_t aAxis) | VRControllerPuppet::GetAxisMove(uint32_t aAxis) | ||||||
| { | { | ||||||
|   return mControllerInfo.mControllerState.mAxisValue[aAxis]; |   return mControllerInfo.mControllerState.axisValue[aAxis]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| VRControllerPuppet::SetAxisMove(uint32_t aAxis, float aValue) | VRControllerPuppet::SetAxisMove(uint32_t aAxis, float aValue) | ||||||
| { | { | ||||||
|   mControllerInfo.mControllerState.mAxisValue[aAxis] = aValue; |   mControllerInfo.mControllerState.axisValue[aAxis] = aValue; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VRSystemManagerPuppet::VRSystemManagerPuppet() | VRSystemManagerPuppet::VRSystemManagerPuppet() | ||||||
|  |  | ||||||
|  | @ -44,6 +44,7 @@ VRManagerChild::VRManagerChild() | ||||||
|   , mBackend(layers::LayersBackend::LAYERS_NONE) |   , mBackend(layers::LayersBackend::LAYERS_NONE) | ||||||
|   , mPromiseID(0) |   , mPromiseID(0) | ||||||
|   , mVRMockDisplay(nullptr) |   , mVRMockDisplay(nullptr) | ||||||
|  |   , mLastControllerState{} | ||||||
| { | { | ||||||
|   MOZ_ASSERT(NS_IsMainThread()); |   MOZ_ASSERT(NS_IsMainThread()); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -139,6 +139,7 @@ private: | ||||||
|   uint32_t mPromiseID; |   uint32_t mPromiseID; | ||||||
|   nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mPromiseList; |   nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mPromiseList; | ||||||
|   RefPtr<dom::VRMockDisplay> mVRMockDisplay; |   RefPtr<dom::VRMockDisplay> mVRMockDisplay; | ||||||
|  |   VRControllerState mLastControllerState[kVRControllerMaxCount]; | ||||||
| 
 | 
 | ||||||
|   DISALLOW_COPY_AND_ASSIGN(VRManagerChild); |   DISALLOW_COPY_AND_ASSIGN(VRManagerChild); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
| #define mozilla_gfx_vr_VRMessageUtils_h | #define mozilla_gfx_vr_VRMessageUtils_h | ||||||
| 
 | 
 | ||||||
| #include "ipc/IPCMessageUtils.h" | #include "ipc/IPCMessageUtils.h" | ||||||
|  | #include "mozilla/ArrayUtils.h" | ||||||
| #include "mozilla/GfxMessageUtils.h" | #include "mozilla/GfxMessageUtils.h" | ||||||
| #include "VRManager.h" | #include "VRManager.h" | ||||||
| 
 | 
 | ||||||
|  | @ -109,9 +110,12 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo> | ||||||
|     WriteParam(aMsg, aParam.mGroupMask); |     WriteParam(aMsg, aParam.mGroupMask); | ||||||
|     WriteParam(aMsg, aParam.mFrameId); |     WriteParam(aMsg, aParam.mFrameId); | ||||||
|     WriteParam(aMsg, aParam.mDisplayState); |     WriteParam(aMsg, aParam.mDisplayState); | ||||||
|     for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) { |     for (size_t i = 0; i < mozilla::ArrayLength(aParam.mLastSensorState); i++) { | ||||||
|       WriteParam(aMsg, aParam.mLastSensorState[i]); |       WriteParam(aMsg, aParam.mLastSensorState[i]); | ||||||
|     } |     } | ||||||
|  |     for (size_t i = 0; i < mozilla::ArrayLength(aParam.mControllerState); i++) { | ||||||
|  |       WriteParam(aMsg, aParam.mControllerState[i]); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) |   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) | ||||||
|  | @ -124,26 +128,28 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo> | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->mDisplayState))) { |         !ReadParam(aMsg, aIter, &(aResult->mDisplayState))) { | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|     for (int i = 0; i < mozilla::gfx::kVRMaxLatencyFrames; i++) { |     for (size_t i = 0; i < mozilla::ArrayLength(aResult->mLastSensorState); i++) { | ||||||
|       if (!ReadParam(aMsg, aIter, &(aResult->mLastSensorState[i]))) { |       if (!ReadParam(aMsg, aIter, &(aResult->mLastSensorState[i]))) { | ||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| 
 |     for (size_t i = 0; i < mozilla::ArrayLength(aResult->mControllerState); i++) { | ||||||
|  |       if (!ReadParam(aMsg, aIter, &(aResult->mControllerState[i]))) { | ||||||
|  |         return false; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| template <> | template <> | ||||||
| struct ParamTraits<mozilla::gfx::VRHMDSensorState> | struct ParamTraits<mozilla::gfx::VRPose> | ||||||
| { | { | ||||||
|   typedef mozilla::gfx::VRHMDSensorState paramType; |   typedef mozilla::gfx::VRPose paramType; | ||||||
| 
 | 
 | ||||||
|   static void Write(Message* aMsg, const paramType& aParam) |   static void Write(Message* aMsg, const paramType& aParam) | ||||||
|   { |   { | ||||||
|     WriteParam(aMsg, aParam.timestamp); |  | ||||||
|     WriteParam(aMsg, aParam.inputFrameID); |  | ||||||
|     WriteParam(aMsg, aParam.flags); |  | ||||||
|     WriteParam(aMsg, aParam.orientation[0]); |     WriteParam(aMsg, aParam.orientation[0]); | ||||||
|     WriteParam(aMsg, aParam.orientation[1]); |     WriteParam(aMsg, aParam.orientation[1]); | ||||||
|     WriteParam(aMsg, aParam.orientation[2]); |     WriteParam(aMsg, aParam.orientation[2]); | ||||||
|  | @ -163,20 +169,11 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState> | ||||||
|     WriteParam(aMsg, aParam.linearAcceleration[0]); |     WriteParam(aMsg, aParam.linearAcceleration[0]); | ||||||
|     WriteParam(aMsg, aParam.linearAcceleration[1]); |     WriteParam(aMsg, aParam.linearAcceleration[1]); | ||||||
|     WriteParam(aMsg, aParam.linearAcceleration[2]); |     WriteParam(aMsg, aParam.linearAcceleration[2]); | ||||||
|     for (int i=0; i < 16; i++) { |  | ||||||
|       WriteParam(aMsg, aParam.leftViewMatrix[i]); |  | ||||||
|     } |  | ||||||
|     for (int i=0; i < 16; i++) { |  | ||||||
|       WriteParam(aMsg, aParam.rightViewMatrix[i]); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) |   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) | ||||||
|   { |   { | ||||||
|     if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) || |     if (!ReadParam(aMsg, aIter, &(aResult->orientation[0])) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->inputFrameID)) || |  | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->flags)) || |  | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->orientation[0])) || |  | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->orientation[1])) || |         !ReadParam(aMsg, aIter, &(aResult->orientation[1])) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->orientation[2])) || |         !ReadParam(aMsg, aIter, &(aResult->orientation[2])) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->orientation[3])) || |         !ReadParam(aMsg, aIter, &(aResult->orientation[3])) || | ||||||
|  | @ -197,12 +194,43 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState> | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) { |         !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) { | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|     for (int i=0; i < 16; i++) { |     return true; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template <> | ||||||
|  | struct ParamTraits<mozilla::gfx::VRHMDSensorState> | ||||||
|  | { | ||||||
|  |   typedef mozilla::gfx::VRHMDSensorState paramType; | ||||||
|  | 
 | ||||||
|  |   static void Write(Message* aMsg, const paramType& aParam) | ||||||
|  |   { | ||||||
|  |     WriteParam(aMsg, aParam.timestamp); | ||||||
|  |     WriteParam(aMsg, aParam.inputFrameID); | ||||||
|  |     WriteParam(aMsg, aParam.flags); | ||||||
|  |     WriteParam(aMsg, aParam.pose); | ||||||
|  |     for (size_t i = 0; i < mozilla::ArrayLength(aParam.leftViewMatrix); i++) { | ||||||
|  |       WriteParam(aMsg, aParam.leftViewMatrix[i]); | ||||||
|  |     } | ||||||
|  |     for (size_t i = 0; i < mozilla::ArrayLength(aParam.rightViewMatrix); i++) { | ||||||
|  |       WriteParam(aMsg, aParam.rightViewMatrix[i]); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) | ||||||
|  |   { | ||||||
|  |     if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) || | ||||||
|  |         !ReadParam(aMsg, aIter, &(aResult->inputFrameID)) || | ||||||
|  |         !ReadParam(aMsg, aIter, &(aResult->flags)) || | ||||||
|  |         !ReadParam(aMsg, aIter, &(aResult->pose))) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     for (size_t i = 0; i < mozilla::ArrayLength(aResult->leftViewMatrix); i++) { | ||||||
|       if (!ReadParam(aMsg, aIter, &(aResult->leftViewMatrix[i]))) { |       if (!ReadParam(aMsg, aIter, &(aResult->leftViewMatrix[i]))) { | ||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     for (int i=0; i < 16; i++) { |     for (size_t i = 0; i < mozilla::ArrayLength(aResult->rightViewMatrix); i++) { | ||||||
|       if (!ReadParam(aMsg, aIter, &(aResult->rightViewMatrix[i]))) { |       if (!ReadParam(aMsg, aIter, &(aResult->rightViewMatrix[i]))) { | ||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|  | @ -246,19 +274,23 @@ struct ParamTraits<mozilla::gfx::VRControllerState> | ||||||
|   static void Write(Message* aMsg, const paramType& aParam) |   static void Write(Message* aMsg, const paramType& aParam) | ||||||
|   { |   { | ||||||
|     nsCString controllerName; |     nsCString controllerName; | ||||||
|     controllerName.Assign(aParam.mControllerName); // FINDME!! HACK! - Bounds checking?
 |     controllerName.Assign(aParam.controllerName); // FINDME!! HACK! - Bounds checking?
 | ||||||
|     WriteParam(aMsg, controllerName); |     WriteParam(aMsg, controllerName); | ||||||
|     WriteParam(aMsg, aParam.mNumButtons); |     WriteParam(aMsg, aParam.hand); | ||||||
|     WriteParam(aMsg, aParam.mNumAxes); |     WriteParam(aMsg, aParam.numButtons); | ||||||
|     WriteParam(aMsg, aParam.mNumTriggers); |     WriteParam(aMsg, aParam.numAxes); | ||||||
|     WriteParam(aMsg, aParam.mNumHaptics); |     WriteParam(aMsg, aParam.numHaptics); | ||||||
|     WriteParam(aMsg, aParam.mButtonPressed); |     WriteParam(aMsg, aParam.buttonPressed); | ||||||
|     WriteParam(aMsg, aParam.mButtonTouched); |     WriteParam(aMsg, aParam.buttonTouched); | ||||||
|     for (int i=0; i < mozilla::gfx::kVRControllerMaxAxis; i++) { |     WriteParam(aMsg, aParam.flags); | ||||||
|       WriteParam(aMsg, aParam.mAxisValue[i]); |     WriteParam(aMsg, aParam.pose); | ||||||
|  |     WriteParam(aMsg, aParam.isPositionValid); | ||||||
|  |     WriteParam(aMsg, aParam.isOrientationValid); | ||||||
|  |     for (size_t i = 0; i < mozilla::ArrayLength(aParam.axisValue); i++) { | ||||||
|  |       WriteParam(aMsg, aParam.axisValue[i]); | ||||||
|     } |     } | ||||||
|     for (int i=0; i < mozilla::gfx::kVRControllerMaxTriggers; i++) { |     for (size_t i = 0; i < mozilla::ArrayLength(aParam.triggerValue); i++) { | ||||||
|       WriteParam(aMsg, aParam.mTriggerValue[i]); |       WriteParam(aMsg, aParam.triggerValue[i]); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -266,25 +298,29 @@ struct ParamTraits<mozilla::gfx::VRControllerState> | ||||||
|   { |   { | ||||||
|     nsCString controllerName; |     nsCString controllerName; | ||||||
|     if (!ReadParam(aMsg, aIter, &(controllerName)) || |     if (!ReadParam(aMsg, aIter, &(controllerName)) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->mNumButtons)) || |         !ReadParam(aMsg, aIter, &(aResult->hand)) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->mNumAxes)) || |         !ReadParam(aMsg, aIter, &(aResult->numButtons)) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->mNumTriggers)) || |         !ReadParam(aMsg, aIter, &(aResult->numAxes)) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->mNumHaptics)) || |         !ReadParam(aMsg, aIter, &(aResult->numHaptics)) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->mButtonPressed)) || |         !ReadParam(aMsg, aIter, &(aResult->buttonPressed)) || | ||||||
|         !ReadParam(aMsg, aIter, &(aResult->mButtonTouched))) { |         !ReadParam(aMsg, aIter, &(aResult->buttonTouched)) || | ||||||
|  |         !ReadParam(aMsg, aIter, &(aResult->flags)) || | ||||||
|  |         !ReadParam(aMsg, aIter, &(aResult->pose)) || | ||||||
|  |         !ReadParam(aMsg, aIter, &(aResult->isPositionValid)) || | ||||||
|  |         !ReadParam(aMsg, aIter, &(aResult->isOrientationValid))) { | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|     for (int i=0; i < mozilla::gfx::kVRControllerMaxAxis; i++) { |     for (size_t i = 0; i < mozilla::ArrayLength(aResult->axisValue); i++) { | ||||||
|       if (!ReadParam(aMsg, aIter, &(aResult->mAxisValue[i]))) { |       if (!ReadParam(aMsg, aIter, &(aResult->axisValue[i]))) { | ||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     for (int i=0; i < mozilla::gfx::kVRControllerMaxTriggers; i++) { |     for (size_t i = 0; i < mozilla::ArrayLength(aResult->triggerValue); i++) { | ||||||
|       if (!ReadParam(aMsg, aIter, &(aResult->mTriggerValue[i]))) { |       if (!ReadParam(aMsg, aIter, &(aResult->triggerValue[i]))) { | ||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     strncpy(aResult->mControllerName, controllerName.BeginReading(), mozilla::gfx::kVRControllerNameMaxLen); // FINDME! TODO! HACK!  Safe? Better way?
 |     strncpy(aResult->controllerName, controllerName.BeginReading(), mozilla::gfx::kVRControllerNameMaxLen); // FINDME! TODO! HACK!  Safe? Better way?
 | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,14 +1,13 @@ | ||||||
| #include "OpenVRSession.h" | #include "OpenVRSession.h" | ||||||
|  | #include "gfxPrefs.h" | ||||||
| 
 | 
 | ||||||
| #if defined(XP_WIN) | #if defined(XP_WIN) | ||||||
| #include <d3d11.h> | #include <d3d11.h> | ||||||
| #include "mozilla/gfx/DeviceManagerDx.h" | #include "mozilla/gfx/DeviceManagerDx.h" | ||||||
| #endif // defined(XP_WIN)
 | #endif // defined(XP_WIN)
 | ||||||
| 
 | 
 | ||||||
| #if defined(MOZILLA_INTERNAL_API) |  | ||||||
| #include "mozilla/dom/GamepadEventTypes.h" | #include "mozilla/dom/GamepadEventTypes.h" | ||||||
| #include "mozilla/dom/GamepadBinding.h" | #include "mozilla/dom/GamepadBinding.h" | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| #if !defined(M_PI) | #if !defined(M_PI) | ||||||
| #define M_PI 3.14159265358979323846264338327950288 | #define M_PI 3.14159265358979323846264338327950288 | ||||||
|  | @ -17,17 +16,91 @@ | ||||||
| #define BTN_MASK_FROM_ID(_id) \ | #define BTN_MASK_FROM_ID(_id) \ | ||||||
|   ::vr::ButtonMaskFromId(vr::EVRButtonId::_id) |   ::vr::ButtonMaskFromId(vr::EVRButtonId::_id) | ||||||
| 
 | 
 | ||||||
|  | static const uint32_t kNumOpenVRHaptcs = 1; | ||||||
|  | 
 | ||||||
| using namespace mozilla::gfx; | using namespace mozilla::gfx; | ||||||
| 
 | 
 | ||||||
| namespace mozilla { | namespace mozilla { | ||||||
| namespace gfx { | namespace gfx { | ||||||
| 
 | 
 | ||||||
|  | namespace { | ||||||
|  | 
 | ||||||
|  | dom::GamepadHand | ||||||
|  | GetControllerHandFromControllerRole(::vr::ETrackedControllerRole aRole) | ||||||
|  | { | ||||||
|  |   dom::GamepadHand hand; | ||||||
|  | 
 | ||||||
|  |   switch(aRole) { | ||||||
|  |     case ::vr::ETrackedControllerRole::TrackedControllerRole_Invalid: | ||||||
|  |     case ::vr::ETrackedControllerRole::TrackedControllerRole_OptOut: | ||||||
|  |       hand = dom::GamepadHand::_empty; | ||||||
|  |       break; | ||||||
|  |     case ::vr::ETrackedControllerRole::TrackedControllerRole_LeftHand: | ||||||
|  |       hand = dom::GamepadHand::Left; | ||||||
|  |       break; | ||||||
|  |     case ::vr::ETrackedControllerRole::TrackedControllerRole_RightHand: | ||||||
|  |       hand = dom::GamepadHand::Right; | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       hand = dom::GamepadHand::_empty; | ||||||
|  |       MOZ_ASSERT(false); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return hand; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | UpdateButton(VRControllerState& aState, const ::vr::VRControllerState_t& aControllerState, uint32_t aButtonIndex, uint64_t aButtonMask) | ||||||
|  | { | ||||||
|  |   uint64_t mask = (1ULL << aButtonIndex); | ||||||
|  |   if ((aControllerState.ulButtonPressed & aButtonMask) == 0) { | ||||||
|  |     // not pressed
 | ||||||
|  |     aState.buttonPressed &= ~mask; | ||||||
|  |     aState.triggerValue[aButtonIndex] = 0.0f; | ||||||
|  |   } else { | ||||||
|  |     // pressed
 | ||||||
|  |     aState.buttonPressed |= mask; | ||||||
|  |     aState.triggerValue[aButtonIndex] = 1.0f; | ||||||
|  |   } | ||||||
|  |   if ((aControllerState.ulButtonTouched & aButtonMask) == 0) { | ||||||
|  |     // not touched
 | ||||||
|  |     aState.buttonTouched &= ~mask; | ||||||
|  |   } else { | ||||||
|  |     // touched
 | ||||||
|  |     aState.buttonTouched |= mask; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | UpdateTrigger(VRControllerState& aState, uint32_t aButtonIndex, float aValue, float aThreshold) | ||||||
|  | { | ||||||
|  |   // For OpenVR, the threshold value of ButtonPressed and ButtonTouched is 0.55.
 | ||||||
|  |   // We prefer to let developers to set their own threshold for the adjustment.
 | ||||||
|  |   // Therefore, we don't check ButtonPressed and ButtonTouched with ButtonMask here.
 | ||||||
|  |   // we just check the button value is larger than the threshold value or not.
 | ||||||
|  |   uint64_t mask = (1ULL << aButtonIndex); | ||||||
|  |   aState.triggerValue[aButtonIndex] = aValue; | ||||||
|  |   if (aValue > aThreshold) { | ||||||
|  |     aState.buttonPressed |= mask; | ||||||
|  |     aState.buttonTouched |= mask; | ||||||
|  |   } else { | ||||||
|  |     aState.buttonPressed &= ~mask; | ||||||
|  |     aState.buttonTouched &= ~mask; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | }; // anonymous namespace
 | ||||||
|  | 
 | ||||||
| OpenVRSession::OpenVRSession() | OpenVRSession::OpenVRSession() | ||||||
|   : VRSession() |   : VRSession() | ||||||
|   , mVRSystem(nullptr) |   , mVRSystem(nullptr) | ||||||
|   , mVRChaperone(nullptr) |   , mVRChaperone(nullptr) | ||||||
|   , mVRCompositor(nullptr) |   , mVRCompositor(nullptr) | ||||||
|  |   , mControllerDeviceIndex{0} | ||||||
|   , mShouldQuit(false) |   , mShouldQuit(false) | ||||||
|  |   , mIsWindowsMR(false) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -43,8 +116,10 @@ OpenVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState) | ||||||
|     // Already initialized
 |     // Already initialized
 | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |   if (!::vr::VR_IsRuntimeInstalled()) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|   if (!::vr::VR_IsHmdPresent()) { |   if (!::vr::VR_IsHmdPresent()) { | ||||||
|     fprintf(stderr, "No HMD detected, VR_IsHmdPresent returned false.\n"); |  | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -143,121 +218,121 @@ OpenVRSession::InitState(VRSystemState& aSystemState) | ||||||
|   state.mEyeResolution.height = h; |   state.mEyeResolution.height = h; | ||||||
| 
 | 
 | ||||||
|   // default to an identity quaternion
 |   // default to an identity quaternion
 | ||||||
|   aSystemState.sensorState.orientation[3] = 1.0f; |   aSystemState.sensorState.pose.orientation[3] = 1.0f; | ||||||
| 
 | 
 | ||||||
|   UpdateStageParameters(state); |   UpdateStageParameters(state); | ||||||
|   UpdateEyeParameters(state); |   UpdateEyeParameters(aSystemState); | ||||||
| 
 | 
 | ||||||
|   VRHMDSensorState& sensorState = aSystemState.sensorState; |   VRHMDSensorState& sensorState = aSystemState.sensorState; | ||||||
|   sensorState.flags = (VRDisplayCapabilityFlags)( |   sensorState.flags = (VRDisplayCapabilityFlags)( | ||||||
|     (int)VRDisplayCapabilityFlags::Cap_Orientation | |     (int)VRDisplayCapabilityFlags::Cap_Orientation | | ||||||
|     (int)VRDisplayCapabilityFlags::Cap_Position); |     (int)VRDisplayCapabilityFlags::Cap_Position); | ||||||
|   sensorState.orientation[3] = 1.0f; // Default to an identity quaternion
 |   sensorState.pose.orientation[3] = 1.0f; // Default to an identity quaternion
 | ||||||
| 
 | 
 | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| OpenVRSession::UpdateStageParameters(VRDisplayState& state) | OpenVRSession::UpdateStageParameters(VRDisplayState& aState) | ||||||
| { | { | ||||||
|   float sizeX = 0.0f; |   float sizeX = 0.0f; | ||||||
|   float sizeZ = 0.0f; |   float sizeZ = 0.0f; | ||||||
|   if (mVRChaperone->GetPlayAreaSize(&sizeX, &sizeZ)) { |   if (mVRChaperone->GetPlayAreaSize(&sizeX, &sizeZ)) { | ||||||
|     ::vr::HmdMatrix34_t t = mVRSystem->GetSeatedZeroPoseToStandingAbsoluteTrackingPose(); |     ::vr::HmdMatrix34_t t = mVRSystem->GetSeatedZeroPoseToStandingAbsoluteTrackingPose(); | ||||||
|     state.mStageSize.width = sizeX; |     aState.mStageSize.width = sizeX; | ||||||
|     state.mStageSize.height = sizeZ; |     aState.mStageSize.height = sizeZ; | ||||||
| 
 | 
 | ||||||
|     state.mSittingToStandingTransform[0] = t.m[0][0]; |     aState.mSittingToStandingTransform[0] = t.m[0][0]; | ||||||
|     state.mSittingToStandingTransform[1] = t.m[1][0]; |     aState.mSittingToStandingTransform[1] = t.m[1][0]; | ||||||
|     state.mSittingToStandingTransform[2] = t.m[2][0]; |     aState.mSittingToStandingTransform[2] = t.m[2][0]; | ||||||
|     state.mSittingToStandingTransform[3] = 0.0f; |     aState.mSittingToStandingTransform[3] = 0.0f; | ||||||
| 
 | 
 | ||||||
|     state.mSittingToStandingTransform[4] = t.m[0][1]; |     aState.mSittingToStandingTransform[4] = t.m[0][1]; | ||||||
|     state.mSittingToStandingTransform[5] = t.m[1][1]; |     aState.mSittingToStandingTransform[5] = t.m[1][1]; | ||||||
|     state.mSittingToStandingTransform[6] = t.m[2][1]; |     aState.mSittingToStandingTransform[6] = t.m[2][1]; | ||||||
|     state.mSittingToStandingTransform[7] = 0.0f; |     aState.mSittingToStandingTransform[7] = 0.0f; | ||||||
| 
 | 
 | ||||||
|     state.mSittingToStandingTransform[8] = t.m[0][2]; |     aState.mSittingToStandingTransform[8] = t.m[0][2]; | ||||||
|     state.mSittingToStandingTransform[9] = t.m[1][2]; |     aState.mSittingToStandingTransform[9] = t.m[1][2]; | ||||||
|     state.mSittingToStandingTransform[10] = t.m[2][2]; |     aState.mSittingToStandingTransform[10] = t.m[2][2]; | ||||||
|     state.mSittingToStandingTransform[11] = 0.0f; |     aState.mSittingToStandingTransform[11] = 0.0f; | ||||||
| 
 | 
 | ||||||
|     state.mSittingToStandingTransform[12] = t.m[0][3]; |     aState.mSittingToStandingTransform[12] = t.m[0][3]; | ||||||
|     state.mSittingToStandingTransform[13] = t.m[1][3]; |     aState.mSittingToStandingTransform[13] = t.m[1][3]; | ||||||
|     state.mSittingToStandingTransform[14] = t.m[2][3]; |     aState.mSittingToStandingTransform[14] = t.m[2][3]; | ||||||
|     state.mSittingToStandingTransform[15] = 1.0f; |     aState.mSittingToStandingTransform[15] = 1.0f; | ||||||
|   } else { |   } else { | ||||||
|     // If we fail, fall back to reasonable defaults.
 |     // If we fail, fall back to reasonable defaults.
 | ||||||
|     // 1m x 1m space, 0.75m high in seated position
 |     // 1m x 1m space, 0.75m high in seated position
 | ||||||
|  |     aState.mStageSize.width = 1.0f; | ||||||
|  |     aState.mStageSize.height = 1.0f; | ||||||
| 
 | 
 | ||||||
|     state.mStageSize.width = 1.0f; |     aState.mSittingToStandingTransform[0] = 1.0f; | ||||||
|     state.mStageSize.height = 1.0f; |     aState.mSittingToStandingTransform[1] = 0.0f; | ||||||
|  |     aState.mSittingToStandingTransform[2] = 0.0f; | ||||||
|  |     aState.mSittingToStandingTransform[3] = 0.0f; | ||||||
| 
 | 
 | ||||||
|     state.mSittingToStandingTransform[0] = 1.0f; |     aState.mSittingToStandingTransform[4] = 0.0f; | ||||||
|     state.mSittingToStandingTransform[1] = 0.0f; |     aState.mSittingToStandingTransform[5] = 1.0f; | ||||||
|     state.mSittingToStandingTransform[2] = 0.0f; |     aState.mSittingToStandingTransform[6] = 0.0f; | ||||||
|     state.mSittingToStandingTransform[3] = 0.0f; |     aState.mSittingToStandingTransform[7] = 0.0f; | ||||||
| 
 | 
 | ||||||
|     state.mSittingToStandingTransform[4] = 0.0f; |     aState.mSittingToStandingTransform[8] = 0.0f; | ||||||
|     state.mSittingToStandingTransform[5] = 1.0f; |     aState.mSittingToStandingTransform[9] = 0.0f; | ||||||
|     state.mSittingToStandingTransform[6] = 0.0f; |     aState.mSittingToStandingTransform[10] = 1.0f; | ||||||
|     state.mSittingToStandingTransform[7] = 0.0f; |     aState.mSittingToStandingTransform[11] = 0.0f; | ||||||
| 
 | 
 | ||||||
|     state.mSittingToStandingTransform[8] = 0.0f; |     aState.mSittingToStandingTransform[12] = 0.0f; | ||||||
|     state.mSittingToStandingTransform[9] = 0.0f; |     aState.mSittingToStandingTransform[13] = 0.75f; | ||||||
|     state.mSittingToStandingTransform[10] = 1.0f; |     aState.mSittingToStandingTransform[14] = 0.0f; | ||||||
|     state.mSittingToStandingTransform[11] = 0.0f; |     aState.mSittingToStandingTransform[15] = 1.0f; | ||||||
| 
 |  | ||||||
|     state.mSittingToStandingTransform[12] = 0.0f; |  | ||||||
|     state.mSittingToStandingTransform[13] = 0.75f; |  | ||||||
|     state.mSittingToStandingTransform[14] = 0.0f; |  | ||||||
|     state.mSittingToStandingTransform[15] = 1.0f; |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| OpenVRSession::UpdateEyeParameters(VRDisplayState& state, gfx::Matrix4x4* headToEyeTransforms /* = nullptr */) | OpenVRSession::UpdateEyeParameters(VRSystemState& aState) | ||||||
| { | { | ||||||
|  |   // This must be called every frame in order to
 | ||||||
|  |   // account for continuous adjustments to ipd.
 | ||||||
|  |   gfx::Matrix4x4 headToEyeTransforms[2]; | ||||||
|  | 
 | ||||||
|   for (uint32_t eye = 0; eye < 2; ++eye) { |   for (uint32_t eye = 0; eye < 2; ++eye) { | ||||||
|     ::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye)); |     ::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye)); | ||||||
|     state.mEyeTranslation[eye].x = eyeToHead.m[0][3]; |     aState.displayState.mEyeTranslation[eye].x = eyeToHead.m[0][3]; | ||||||
|     state.mEyeTranslation[eye].y = eyeToHead.m[1][3]; |     aState.displayState.mEyeTranslation[eye].y = eyeToHead.m[1][3]; | ||||||
|     state.mEyeTranslation[eye].z = eyeToHead.m[2][3]; |     aState.displayState.mEyeTranslation[eye].z = eyeToHead.m[2][3]; | ||||||
| 
 | 
 | ||||||
|     float left, right, up, down; |     float left, right, up, down; | ||||||
|     mVRSystem->GetProjectionRaw(static_cast<::vr::Hmd_Eye>(eye), &left, &right, &up, &down); |     mVRSystem->GetProjectionRaw(static_cast<::vr::Hmd_Eye>(eye), &left, &right, &up, &down); | ||||||
|     state.mEyeFOV[eye].upDegrees = atan(-up) * 180.0 / M_PI; |     aState.displayState.mEyeFOV[eye].upDegrees = atan(-up) * 180.0 / M_PI; | ||||||
|     state.mEyeFOV[eye].rightDegrees = atan(right) * 180.0 / M_PI; |     aState.displayState.mEyeFOV[eye].rightDegrees = atan(right) * 180.0 / M_PI; | ||||||
|     state.mEyeFOV[eye].downDegrees = atan(down) * 180.0 / M_PI; |     aState.displayState.mEyeFOV[eye].downDegrees = atan(down) * 180.0 / M_PI; | ||||||
|     state.mEyeFOV[eye].leftDegrees = atan(-left) * 180.0 / M_PI; |     aState.displayState.mEyeFOV[eye].leftDegrees = atan(-left) * 180.0 / M_PI; | ||||||
| 
 | 
 | ||||||
|     if (headToEyeTransforms) { |     Matrix4x4 pose; | ||||||
|       Matrix4x4 pose; |     // NOTE! eyeToHead.m is a 3x4 matrix, not 4x4.  But
 | ||||||
|       // NOTE! eyeToHead.m is a 3x4 matrix, not 4x4.  But
 |     // because of its arrangement, we can copy the 12 elements in and
 | ||||||
|       // because of its arrangement, we can copy the 12 elements in and
 |     // then transpose them to the right place.
 | ||||||
|       // then transpose them to the right place.
 |     memcpy(&pose._11, &eyeToHead.m, sizeof(eyeToHead.m)); | ||||||
|       memcpy(&pose._11, &eyeToHead.m, sizeof(eyeToHead.m)); |     pose.Transpose(); | ||||||
|       pose.Transpose(); |     pose.Invert(); | ||||||
|       pose.Invert(); |     headToEyeTransforms[eye] = pose; | ||||||
|       headToEyeTransforms[eye] = pose; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |   aState.sensorState.CalcViewMatrices(headToEyeTransforms); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| OpenVRSession::GetSensorState(VRSystemState& state) | OpenVRSession::UpdateHeadsetPose(VRSystemState& aState) | ||||||
| { | { | ||||||
|   const uint32_t posesSize = ::vr::k_unTrackedDeviceIndex_Hmd + 1; |   const uint32_t posesSize = ::vr::k_unTrackedDeviceIndex_Hmd + 1; | ||||||
|   ::vr::TrackedDevicePose_t poses[posesSize]; |   ::vr::TrackedDevicePose_t poses[posesSize]; | ||||||
|   // Note: We *must* call WaitGetPoses in order for any rendering to happen at all.
 |   // Note: We *must* call WaitGetPoses in order for any rendering to happen at all.
 | ||||||
|   mVRCompositor->WaitGetPoses(nullptr, 0, poses, posesSize); |   mVRCompositor->WaitGetPoses(nullptr, 0, poses, posesSize); | ||||||
|   gfx::Matrix4x4 headToEyeTransforms[2]; |  | ||||||
|   UpdateEyeParameters(state.displayState, headToEyeTransforms); |  | ||||||
| 
 | 
 | ||||||
|   ::vr::Compositor_FrameTiming timing; |   ::vr::Compositor_FrameTiming timing; | ||||||
|   timing.m_nSize = sizeof(::vr::Compositor_FrameTiming); |   timing.m_nSize = sizeof(::vr::Compositor_FrameTiming); | ||||||
|   if (mVRCompositor->GetFrameTiming(&timing)) { |   if (mVRCompositor->GetFrameTiming(&timing)) { | ||||||
|     state.sensorState.timestamp = timing.m_flSystemTimeInSeconds; |     aState.sensorState.timestamp = timing.m_flSystemTimeInSeconds; | ||||||
|   } else { |   } else { | ||||||
|     // This should not happen, but log it just in case
 |     // This should not happen, but log it just in case
 | ||||||
|     fprintf(stderr, "OpenVR - IVRCompositor::GetFrameTiming failed"); |     fprintf(stderr, "OpenVR - IVRCompositor::GetFrameTiming failed"); | ||||||
|  | @ -281,39 +356,411 @@ OpenVRSession::GetSensorState(VRSystemState& state) | ||||||
|     rot.SetFromRotationMatrix(m); |     rot.SetFromRotationMatrix(m); | ||||||
|     rot.Invert(); |     rot.Invert(); | ||||||
| 
 | 
 | ||||||
|     state.sensorState.flags = (VRDisplayCapabilityFlags)((int)state.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Orientation); |     aState.sensorState.flags = (VRDisplayCapabilityFlags)((int)aState.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Orientation); | ||||||
|     state.sensorState.orientation[0] = rot.x; |     aState.sensorState.pose.orientation[0] = rot.x; | ||||||
|     state.sensorState.orientation[1] = rot.y; |     aState.sensorState.pose.orientation[1] = rot.y; | ||||||
|     state.sensorState.orientation[2] = rot.z; |     aState.sensorState.pose.orientation[2] = rot.z; | ||||||
|     state.sensorState.orientation[3] = rot.w; |     aState.sensorState.pose.orientation[3] = rot.w; | ||||||
|     state.sensorState.angularVelocity[0] = pose.vAngularVelocity.v[0]; |     aState.sensorState.pose.angularVelocity[0] = pose.vAngularVelocity.v[0]; | ||||||
|     state.sensorState.angularVelocity[1] = pose.vAngularVelocity.v[1]; |     aState.sensorState.pose.angularVelocity[1] = pose.vAngularVelocity.v[1]; | ||||||
|     state.sensorState.angularVelocity[2] = pose.vAngularVelocity.v[2]; |     aState.sensorState.pose.angularVelocity[2] = pose.vAngularVelocity.v[2]; | ||||||
| 
 | 
 | ||||||
|     state.sensorState.flags =(VRDisplayCapabilityFlags)((int)state.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Position); |     aState.sensorState.flags =(VRDisplayCapabilityFlags)((int)aState.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Position); | ||||||
|     state.sensorState.position[0] = m._41; |     aState.sensorState.pose.position[0] = m._41; | ||||||
|     state.sensorState.position[1] = m._42; |     aState.sensorState.pose.position[1] = m._42; | ||||||
|     state.sensorState.position[2] = m._43; |     aState.sensorState.pose.position[2] = m._43; | ||||||
|     state.sensorState.linearVelocity[0] = pose.vVelocity.v[0]; |     aState.sensorState.pose.linearVelocity[0] = pose.vVelocity.v[0]; | ||||||
|     state.sensorState.linearVelocity[1] = pose.vVelocity.v[1]; |     aState.sensorState.pose.linearVelocity[1] = pose.vVelocity.v[1]; | ||||||
|     state.sensorState.linearVelocity[2] = pose.vVelocity.v[2]; |     aState.sensorState.pose.linearVelocity[2] = pose.vVelocity.v[2]; | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   state.sensorState.CalcViewMatrices(headToEyeTransforms); |  | ||||||
|   state.sensorState.inputFrameID++; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| OpenVRSession::GetControllerState(VRSystemState &state) | OpenVRSession::EnumerateControllers(VRSystemState& aState) | ||||||
| { | { | ||||||
|   // TODO - Implement
 |   MOZ_ASSERT(mVRSystem); | ||||||
|  | 
 | ||||||
|  |   bool controllerPresent[kVRControllerMaxCount] = { false }; | ||||||
|  | 
 | ||||||
|  |   // Basically, we would have HMDs in the tracked devices,
 | ||||||
|  |   // but we are just interested in the controllers.
 | ||||||
|  |   for (::vr::TrackedDeviceIndex_t trackedDevice = ::vr::k_unTrackedDeviceIndex_Hmd + 1; | ||||||
|  |        trackedDevice < ::vr::k_unMaxTrackedDeviceCount; ++trackedDevice) { | ||||||
|  | 
 | ||||||
|  |     if (!mVRSystem->IsTrackedDeviceConnected(trackedDevice)) { | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const ::vr::ETrackedDeviceClass deviceType = mVRSystem-> | ||||||
|  |                                                  GetTrackedDeviceClass(trackedDevice); | ||||||
|  |     if (deviceType != ::vr::TrackedDeviceClass_Controller | ||||||
|  |         && deviceType != ::vr::TrackedDeviceClass_GenericTracker) { | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uint32_t stateIndex = 0; | ||||||
|  |     uint32_t firstEmptyIndex = kVRControllerMaxCount; | ||||||
|  | 
 | ||||||
|  |     // Find the existing controller
 | ||||||
|  |     for (stateIndex = 0; stateIndex < kVRControllerMaxCount; stateIndex++) { | ||||||
|  |       if (mControllerDeviceIndex[stateIndex] == 0 && firstEmptyIndex == kVRControllerMaxCount) { | ||||||
|  |         firstEmptyIndex = stateIndex; | ||||||
|  |       } | ||||||
|  |       if (mControllerDeviceIndex[stateIndex] == trackedDevice) { | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     if (stateIndex == kVRControllerMaxCount) { | ||||||
|  |       // This is a new controller, let's add it
 | ||||||
|  |       if (firstEmptyIndex == kVRControllerMaxCount) { | ||||||
|  |         NS_WARNING("OpenVR - Too many controllers, need to increase kVRControllerMaxCount."); | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|  |       stateIndex = firstEmptyIndex; | ||||||
|  |       mControllerDeviceIndex[stateIndex] = trackedDevice; | ||||||
|  |       VRControllerState& controllerState = aState.controllerState[stateIndex]; | ||||||
|  |       uint32_t numButtons = 0; | ||||||
|  |       uint32_t numAxes = 0; | ||||||
|  | 
 | ||||||
|  |       // Scan the axes that the controllers support
 | ||||||
|  |       for (uint32_t j = 0; j < ::vr::k_unControllerStateAxisCount; ++j) { | ||||||
|  |         const uint32_t supportAxis = mVRSystem->GetInt32TrackedDeviceProperty(trackedDevice, | ||||||
|  |                                       static_cast<vr::TrackedDeviceProperty>( | ||||||
|  |                                       ::vr::Prop_Axis0Type_Int32 + j)); | ||||||
|  |         switch (supportAxis) { | ||||||
|  |           case ::vr::EVRControllerAxisType::k_eControllerAxis_Joystick: | ||||||
|  |           case ::vr::EVRControllerAxisType::k_eControllerAxis_TrackPad: | ||||||
|  |             numAxes += 2; // It has x and y axes.
 | ||||||
|  |             ++numButtons; | ||||||
|  |             break; | ||||||
|  |           case ::vr::k_eControllerAxis_Trigger: | ||||||
|  |             if (j <= 2) { | ||||||
|  |               ++numButtons; | ||||||
|  |             } else { | ||||||
|  |           #ifdef DEBUG | ||||||
|  |               // SteamVR Knuckles is the only special case for using 2D axis values on triggers.
 | ||||||
|  |               ::vr::ETrackedPropertyError err; | ||||||
|  |               uint32_t requiredBufferLen; | ||||||
|  |               char charBuf[128]; | ||||||
|  |               requiredBufferLen = mVRSystem->GetStringTrackedDeviceProperty(trackedDevice, | ||||||
|  |                                   ::vr::Prop_RenderModelName_String, charBuf, 128, &err); | ||||||
|  |               MOZ_ASSERT(requiredBufferLen && err == ::vr::TrackedProp_Success); | ||||||
|  |               nsCString deviceId(charBuf); | ||||||
|  |               MOZ_ASSERT(deviceId.Find("knuckles") != kNotFound); | ||||||
|  |           #endif // #ifdef DEBUG
 | ||||||
|  |               numButtons += 2; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Scan the buttons that the controllers support
 | ||||||
|  |       const uint64_t supportButtons = mVRSystem->GetUint64TrackedDeviceProperty( | ||||||
|  |                                        trackedDevice, ::vr::Prop_SupportedButtons_Uint64); | ||||||
|  |       if (supportButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_A)) { | ||||||
|  |         ++numButtons; | ||||||
|  |       } | ||||||
|  |       if (supportButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_Grip)) { | ||||||
|  |         ++numButtons; | ||||||
|  |       } | ||||||
|  |       if (supportButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_ApplicationMenu)) { | ||||||
|  |         ++numButtons; | ||||||
|  |       } | ||||||
|  |       if (supportButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Left)) { | ||||||
|  |         ++numButtons; | ||||||
|  |       } | ||||||
|  |       if (supportButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Up)) { | ||||||
|  |         ++numButtons; | ||||||
|  |       } | ||||||
|  |       if (supportButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Right)) { | ||||||
|  |         ++numButtons; | ||||||
|  |       } | ||||||
|  |       if (supportButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Down)) { | ||||||
|  |         ++numButtons; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       nsCString deviceId; | ||||||
|  |       GetControllerDeviceId(deviceType, trackedDevice, deviceId); | ||||||
|  | 
 | ||||||
|  |       strncpy(controllerState.controllerName, deviceId.BeginReading(), kVRControllerNameMaxLen); | ||||||
|  |       controllerState.numButtons = numButtons; | ||||||
|  |       controllerState.numAxes = numAxes; | ||||||
|  |       controllerState.numHaptics = kNumOpenVRHaptcs; | ||||||
|  | 
 | ||||||
|  |       // If the Windows MR controller doesn't has the amount
 | ||||||
|  |       // of buttons or axes as our expectation, switching off
 | ||||||
|  |       // the workaround for Windows MR.
 | ||||||
|  |       if (mIsWindowsMR && (numAxes < 4 || numButtons < 5)) { | ||||||
|  |         mIsWindowsMR = false; | ||||||
|  |         NS_WARNING("OpenVR - Switching off Windows MR mode."); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     controllerPresent[stateIndex] = true; | ||||||
|  |   } | ||||||
|  |   // Clear out entries for disconnected controllers
 | ||||||
|  |   for (uint32_t stateIndex = 0; stateIndex < kVRControllerMaxCount; stateIndex++) { | ||||||
|  |     if (!controllerPresent[stateIndex] && mControllerDeviceIndex[stateIndex] != 0) { | ||||||
|  |       mControllerDeviceIndex[stateIndex] = 0; | ||||||
|  |       memset(&aState.controllerState[stateIndex], 0, sizeof(VRControllerState)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | OpenVRSession::UpdateControllerButtons(VRSystemState& aState) | ||||||
|  | { | ||||||
|  |   MOZ_ASSERT(mVRSystem); | ||||||
|  | 
 | ||||||
|  |   // Compared to Edge, we have a wrong implementation for the vertical axis value.
 | ||||||
|  |   // In order to not affect the current VR content, we add a workaround for yAxis.
 | ||||||
|  |   const float yAxisInvert = (mIsWindowsMR) ? -1.0f : 1.0f; | ||||||
|  |   const float triggerThreshold = gfxPrefs::VRControllerTriggerThreshold(); | ||||||
|  | 
 | ||||||
|  |   for (uint32_t stateIndex = 0; stateIndex < kVRControllerMaxCount; stateIndex++) { | ||||||
|  |     ::vr::TrackedDeviceIndex_t trackedDevice = mControllerDeviceIndex[stateIndex]; | ||||||
|  |     if (trackedDevice == 0) { | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  |     VRControllerState& controllerState = aState.controllerState[stateIndex]; | ||||||
|  |     const ::vr::ETrackedControllerRole role = mVRSystem-> | ||||||
|  |                                           GetControllerRoleForTrackedDeviceIndex( | ||||||
|  |                                           trackedDevice); | ||||||
|  |     dom::GamepadHand hand = GetControllerHandFromControllerRole(role); | ||||||
|  |     controllerState.hand = hand; | ||||||
|  | 
 | ||||||
|  |     ::vr::VRControllerState_t vrControllerState; | ||||||
|  |     if (mVRSystem->GetControllerState(trackedDevice, &vrControllerState, sizeof(vrControllerState))) { | ||||||
|  |       uint32_t axisIdx = 0; | ||||||
|  |       uint32_t buttonIdx = 0; | ||||||
|  |       for (uint32_t j = 0; j < ::vr::k_unControllerStateAxisCount; ++j) { | ||||||
|  |         const uint32_t axisType = mVRSystem->GetInt32TrackedDeviceProperty( | ||||||
|  |                                    trackedDevice, | ||||||
|  |                                    static_cast<::vr::TrackedDeviceProperty>( | ||||||
|  |                                    ::vr::Prop_Axis0Type_Int32 + j)); | ||||||
|  |         switch (axisType) { | ||||||
|  |           case ::vr::EVRControllerAxisType::k_eControllerAxis_Joystick: | ||||||
|  |           case ::vr::EVRControllerAxisType::k_eControllerAxis_TrackPad: | ||||||
|  |           { | ||||||
|  |             if (mIsWindowsMR) { | ||||||
|  |               // Adjust the input mapping for Windows MR which has
 | ||||||
|  |               // different order.
 | ||||||
|  |               axisIdx = (axisIdx == 0) ? 2 : 0; | ||||||
|  |               buttonIdx = (buttonIdx == 0) ? 4 : 0; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             controllerState.axisValue[axisIdx] = vrControllerState.rAxis[j].x; | ||||||
|  |             ++axisIdx; | ||||||
|  |             controllerState.axisValue[axisIdx] = vrControllerState.rAxis[j].y * yAxisInvert; | ||||||
|  |             ++axisIdx; | ||||||
|  |             uint64_t buttonMask = ::vr::ButtonMaskFromId( | ||||||
|  |                                  static_cast<::vr::EVRButtonId>(::vr::k_EButton_Axis0 + j)); | ||||||
|  | 
 | ||||||
|  |             UpdateButton(controllerState, vrControllerState, buttonIdx, buttonMask); | ||||||
|  |             ++buttonIdx; | ||||||
|  | 
 | ||||||
|  |             if (mIsWindowsMR) { | ||||||
|  |               axisIdx = (axisIdx == 4) ? 2 : 4; | ||||||
|  |               buttonIdx = (buttonIdx == 5) ? 1 : 2; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |           case vr::EVRControllerAxisType::k_eControllerAxis_Trigger: | ||||||
|  |           { | ||||||
|  |             if (j <= 2) { | ||||||
|  |               UpdateTrigger(controllerState, buttonIdx, vrControllerState.rAxis[j].x, triggerThreshold); | ||||||
|  |               ++buttonIdx; | ||||||
|  |             } else { | ||||||
|  |               // For SteamVR Knuckles.
 | ||||||
|  |               UpdateTrigger(controllerState, buttonIdx, vrControllerState.rAxis[j].x, triggerThreshold); | ||||||
|  |               ++buttonIdx; | ||||||
|  |               UpdateTrigger(controllerState, buttonIdx, vrControllerState.rAxis[j].y, triggerThreshold); | ||||||
|  |               ++buttonIdx; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       const uint64_t supportedButtons = mVRSystem->GetUint64TrackedDeviceProperty( | ||||||
|  |                                          trackedDevice, ::vr::Prop_SupportedButtons_Uint64); | ||||||
|  |       if (supportedButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_A)) { | ||||||
|  |         UpdateButton(controllerState, vrControllerState, buttonIdx, BTN_MASK_FROM_ID(k_EButton_A)); | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |       if (supportedButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_Grip)) { | ||||||
|  |         UpdateButton(controllerState, vrControllerState, buttonIdx, BTN_MASK_FROM_ID(k_EButton_Grip)); | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |       if (supportedButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_ApplicationMenu)) { | ||||||
|  |         UpdateButton(controllerState, vrControllerState, buttonIdx, BTN_MASK_FROM_ID(k_EButton_ApplicationMenu)); | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |       if (mIsWindowsMR) { | ||||||
|  |         // button 4 in Windows MR has already been assigned
 | ||||||
|  |         // to k_eControllerAxis_TrackPad.
 | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |       if (supportedButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Left)) { | ||||||
|  |         UpdateButton(controllerState, vrControllerState, buttonIdx, BTN_MASK_FROM_ID(k_EButton_DPad_Left)); | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |       if (supportedButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Up)) { | ||||||
|  |         UpdateButton(controllerState, vrControllerState, buttonIdx, BTN_MASK_FROM_ID(k_EButton_DPad_Up)); | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |       if (supportedButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Right)) { | ||||||
|  |         UpdateButton(controllerState, vrControllerState, buttonIdx, BTN_MASK_FROM_ID(k_EButton_DPad_Right)); | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |       if (supportedButtons & | ||||||
|  |           BTN_MASK_FROM_ID(k_EButton_DPad_Down)) { | ||||||
|  |         UpdateButton(controllerState, vrControllerState, buttonIdx, BTN_MASK_FROM_ID(k_EButton_DPad_Down)); | ||||||
|  |         ++buttonIdx; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | OpenVRSession::UpdateControllerPoses(VRSystemState& aState) | ||||||
|  | { | ||||||
|  |   MOZ_ASSERT(mVRSystem); | ||||||
|  | 
 | ||||||
|  |   ::vr::TrackedDevicePose_t poses[::vr::k_unMaxTrackedDeviceCount]; | ||||||
|  |   mVRSystem->GetDeviceToAbsoluteTrackingPose(::vr::TrackingUniverseSeated, 0.0f, | ||||||
|  |                                              poses, ::vr::k_unMaxTrackedDeviceCount); | ||||||
|  | 
 | ||||||
|  |   for (uint32_t stateIndex = 0; stateIndex < kVRControllerMaxCount; stateIndex++) { | ||||||
|  |     ::vr::TrackedDeviceIndex_t trackedDevice = mControllerDeviceIndex[stateIndex]; | ||||||
|  |     if (trackedDevice == 0) { | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  |     VRControllerState& controllerState = aState.controllerState[stateIndex]; | ||||||
|  |     const ::vr::TrackedDevicePose_t& pose = poses[trackedDevice]; | ||||||
|  | 
 | ||||||
|  |     if (pose.bDeviceIsConnected) { | ||||||
|  |       controllerState.flags = (dom::GamepadCapabilityFlags::Cap_Orientation | | ||||||
|  |                                dom::GamepadCapabilityFlags::Cap_Position); | ||||||
|  |     } else { | ||||||
|  |       controllerState.flags =  dom::GamepadCapabilityFlags::Cap_None; | ||||||
|  |     } | ||||||
|  |     if (pose.bPoseIsValid && | ||||||
|  |         pose.eTrackingResult == ::vr::TrackingResult_Running_OK) { | ||||||
|  |       gfx::Matrix4x4 m; | ||||||
|  | 
 | ||||||
|  |       // NOTE! mDeviceToAbsoluteTracking is a 3x4 matrix, not 4x4.  But
 | ||||||
|  |       // because of its arrangement, we can copy the 12 elements in and
 | ||||||
|  |       // then transpose them to the right place.  We do this so we can
 | ||||||
|  |       // pull out a Quaternion.
 | ||||||
|  |       memcpy(&m.components, &pose.mDeviceToAbsoluteTracking, sizeof(pose.mDeviceToAbsoluteTracking)); | ||||||
|  |       m.Transpose(); | ||||||
|  | 
 | ||||||
|  |       gfx::Quaternion rot; | ||||||
|  |       rot.SetFromRotationMatrix(m); | ||||||
|  |       rot.Invert(); | ||||||
|  | 
 | ||||||
|  |       controllerState.pose.orientation[0] = rot.x; | ||||||
|  |       controllerState.pose.orientation[1] = rot.y; | ||||||
|  |       controllerState.pose.orientation[2] = rot.z; | ||||||
|  |       controllerState.pose.orientation[3] = rot.w; | ||||||
|  |       controllerState.pose.angularVelocity[0] = pose.vAngularVelocity.v[0]; | ||||||
|  |       controllerState.pose.angularVelocity[1] = pose.vAngularVelocity.v[1]; | ||||||
|  |       controllerState.pose.angularVelocity[2] = pose.vAngularVelocity.v[2]; | ||||||
|  |       controllerState.pose.angularAcceleration[0] = 0.0f; | ||||||
|  |       controllerState.pose.angularAcceleration[1] = 0.0f; | ||||||
|  |       controllerState.pose.angularAcceleration[2] = 0.0f; | ||||||
|  |       controllerState.isOrientationValid = true; | ||||||
|  | 
 | ||||||
|  |       controllerState.pose.position[0] = m._41; | ||||||
|  |       controllerState.pose.position[1] = m._42; | ||||||
|  |       controllerState.pose.position[2] = m._43; | ||||||
|  |       controllerState.pose.linearVelocity[0] = pose.vVelocity.v[0]; | ||||||
|  |       controllerState.pose.linearVelocity[1] = pose.vVelocity.v[1]; | ||||||
|  |       controllerState.pose.linearVelocity[2] = pose.vVelocity.v[2]; | ||||||
|  |       controllerState.pose.linearAcceleration[0] = 0.0f; | ||||||
|  |       controllerState.pose.linearAcceleration[1] = 0.0f; | ||||||
|  |       controllerState.pose.linearAcceleration[2] = 0.0f; | ||||||
|  |       controllerState.isPositionValid = true; | ||||||
|  |     } else { | ||||||
|  |       controllerState.isOrientationValid = false; | ||||||
|  |       controllerState.isPositionValid = false; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | OpenVRSession::GetControllerDeviceId(::vr::ETrackedDeviceClass aDeviceType, | ||||||
|  |                                      ::vr::TrackedDeviceIndex_t aDeviceIndex, | ||||||
|  |                                      nsCString& aId) | ||||||
|  | { | ||||||
|  |   switch (aDeviceType) { | ||||||
|  |     case ::vr::TrackedDeviceClass_Controller: | ||||||
|  |     { | ||||||
|  |       ::vr::ETrackedPropertyError err; | ||||||
|  |       uint32_t requiredBufferLen; | ||||||
|  |       bool isFound = false; | ||||||
|  |       char charBuf[128]; | ||||||
|  |       requiredBufferLen = mVRSystem->GetStringTrackedDeviceProperty(aDeviceIndex, | ||||||
|  |                           ::vr::Prop_RenderModelName_String, charBuf, 128, &err); | ||||||
|  |       if (requiredBufferLen > 128) { | ||||||
|  |         MOZ_CRASH("Larger than the buffer size."); | ||||||
|  |       } | ||||||
|  |       MOZ_ASSERT(requiredBufferLen && err == ::vr::TrackedProp_Success); | ||||||
|  |       nsCString deviceId(charBuf); | ||||||
|  |       if (deviceId.Find("knuckles") != kNotFound) { | ||||||
|  |         aId.AssignLiteral("OpenVR Knuckles"); | ||||||
|  |         isFound = true; | ||||||
|  |       } | ||||||
|  |       requiredBufferLen = mVRSystem->GetStringTrackedDeviceProperty(aDeviceIndex, | ||||||
|  |         ::vr::Prop_SerialNumber_String, charBuf, 128, &err); | ||||||
|  |       if (requiredBufferLen > 128) { | ||||||
|  |         MOZ_CRASH("Larger than the buffer size."); | ||||||
|  |       } | ||||||
|  |       MOZ_ASSERT(requiredBufferLen && err == ::vr::TrackedProp_Success); | ||||||
|  |       deviceId.Assign(charBuf); | ||||||
|  |       if (deviceId.Find("MRSOURCE") != kNotFound) { | ||||||
|  |         aId.AssignLiteral("Spatial Controller (Spatial Interaction Source) "); | ||||||
|  |         mIsWindowsMR = true; | ||||||
|  |         isFound = true; | ||||||
|  |       } | ||||||
|  |       if (!isFound) { | ||||||
|  |         aId.AssignLiteral("OpenVR Gamepad"); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |     case ::vr::TrackedDeviceClass_GenericTracker: | ||||||
|  |     { | ||||||
|  |       aId.AssignLiteral("OpenVR Tracker"); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |     default: | ||||||
|  |       MOZ_ASSERT(false); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| OpenVRSession::StartFrame(mozilla::gfx::VRSystemState& aSystemState) | OpenVRSession::StartFrame(mozilla::gfx::VRSystemState& aSystemState) | ||||||
| { | { | ||||||
|   GetSensorState(aSystemState); |   UpdateHeadsetPose(aSystemState); | ||||||
|   GetControllerState(aSystemState); |   UpdateEyeParameters(aSystemState); | ||||||
|  |   EnumerateControllers(aSystemState); | ||||||
|  |   UpdateControllerButtons(aSystemState); | ||||||
|  |   UpdateControllerPoses(aSystemState); | ||||||
|  |   aSystemState.sensorState.inputFrameID++; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool | bool | ||||||
|  |  | ||||||
|  | @ -42,13 +42,17 @@ private: | ||||||
|   ::vr::IVRSystem* mVRSystem = nullptr; |   ::vr::IVRSystem* mVRSystem = nullptr; | ||||||
|   ::vr::IVRChaperone* mVRChaperone = nullptr; |   ::vr::IVRChaperone* mVRChaperone = nullptr; | ||||||
|   ::vr::IVRCompositor* mVRCompositor = nullptr; |   ::vr::IVRCompositor* mVRCompositor = nullptr; | ||||||
|  |   ::vr::TrackedDeviceIndex_t mControllerDeviceIndex[kVRControllerMaxCount]; | ||||||
|   bool mShouldQuit; |   bool mShouldQuit; | ||||||
|  |   bool mIsWindowsMR; | ||||||
| 
 | 
 | ||||||
|   bool InitState(mozilla::gfx::VRSystemState& aSystemState); |   bool InitState(mozilla::gfx::VRSystemState& aSystemState); | ||||||
|   void UpdateStageParameters(mozilla::gfx::VRDisplayState& state); |   void UpdateStageParameters(mozilla::gfx::VRDisplayState& aState); | ||||||
|   void UpdateEyeParameters(mozilla::gfx::VRDisplayState& state, gfx::Matrix4x4* headToEyeTransforms = nullptr); |   void UpdateEyeParameters(mozilla::gfx::VRSystemState& aState); | ||||||
|   void GetSensorState(mozilla::gfx::VRSystemState& state); |   void UpdateHeadsetPose(mozilla::gfx::VRSystemState& aState); | ||||||
|   void GetControllerState(VRSystemState &state); |   void EnumerateControllers(VRSystemState& aState); | ||||||
|  |   void UpdateControllerPoses(VRSystemState& aState); | ||||||
|  |   void UpdateControllerButtons(VRSystemState& aState); | ||||||
| 
 | 
 | ||||||
|   bool SubmitFrame(void* aTextureHandle, |   bool SubmitFrame(void* aTextureHandle, | ||||||
|                    ::vr::ETextureType aTextureType, |                    ::vr::ETextureType aTextureType, | ||||||
|  | @ -57,6 +61,9 @@ private: | ||||||
| #if defined(XP_WIN) | #if defined(XP_WIN) | ||||||
|   bool CreateD3DObjects(); |   bool CreateD3DObjects(); | ||||||
| #endif | #endif | ||||||
|  |   void GetControllerDeviceId(::vr::ETrackedDeviceClass aDeviceType, | ||||||
|  |                              ::vr::TrackedDeviceIndex_t aDeviceIndex, | ||||||
|  |                              nsCString& aId); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace mozilla
 | } // namespace mozilla
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Kearwood Gilbert
						Kearwood Gilbert