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,
 | 
			
		||||
                    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),
 | 
			
		||||
    aRv);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -295,7 +295,7 @@ VRPose::GetLinearVelocity(JSContext* aCx,
 | 
			
		|||
                          JS::MutableHandle<JSObject*> aRetval,
 | 
			
		||||
                          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),
 | 
			
		||||
    aRv);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +305,7 @@ VRPose::GetLinearAcceleration(JSContext* aCx,
 | 
			
		|||
                              JS::MutableHandle<JSObject*> aRetval,
 | 
			
		||||
                              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),
 | 
			
		||||
    aRv);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -316,7 +316,7 @@ VRPose::GetOrientation(JSContext* aCx,
 | 
			
		|||
                       JS::MutableHandle<JSObject*> aRetval,
 | 
			
		||||
                       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),
 | 
			
		||||
    aRv);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -326,7 +326,7 @@ VRPose::GetAngularVelocity(JSContext* aCx,
 | 
			
		|||
                           JS::MutableHandle<JSObject*> aRetval,
 | 
			
		||||
                           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),
 | 
			
		||||
    aRv);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -336,7 +336,7 @@ VRPose::GetAngularAcceleration(JSContext* aCx,
 | 
			
		|||
                               JS::MutableHandle<JSObject*> aRetval,
 | 
			
		||||
                               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),
 | 
			
		||||
    aRv);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,50 +95,50 @@ VRMockDisplay::SetPose(const Nullable<Float32Array>& aPosition,
 | 
			
		|||
    const Float32Array& value = aOrientation.Value();
 | 
			
		||||
    value.ComputeLengthAndData();
 | 
			
		||||
    MOZ_ASSERT(value.Length() == 4);
 | 
			
		||||
    mSensorState.orientation[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.orientation[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.orientation[2] = value.Data()[2];
 | 
			
		||||
    mSensorState.orientation[3] = value.Data()[3];
 | 
			
		||||
    mSensorState.pose.orientation[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.pose.orientation[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.pose.orientation[2] = value.Data()[2];
 | 
			
		||||
    mSensorState.pose.orientation[3] = value.Data()[3];
 | 
			
		||||
  }
 | 
			
		||||
  if (!aAngularVelocity.IsNull()) {
 | 
			
		||||
    const Float32Array& value = aAngularVelocity.Value();
 | 
			
		||||
    value.ComputeLengthAndData();
 | 
			
		||||
    MOZ_ASSERT(value.Length() == 3);
 | 
			
		||||
    mSensorState.angularVelocity[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.angularVelocity[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.angularVelocity[2] = value.Data()[2];
 | 
			
		||||
    mSensorState.pose.angularVelocity[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.pose.angularVelocity[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.pose.angularVelocity[2] = value.Data()[2];
 | 
			
		||||
  }
 | 
			
		||||
  if (!aAngularAcceleration.IsNull()) {
 | 
			
		||||
    const Float32Array& value = aAngularAcceleration.Value();
 | 
			
		||||
    value.ComputeLengthAndData();
 | 
			
		||||
    MOZ_ASSERT(value.Length() == 3);
 | 
			
		||||
    mSensorState.angularAcceleration[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.angularAcceleration[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.angularAcceleration[2] = value.Data()[2];
 | 
			
		||||
    mSensorState.pose.angularAcceleration[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.pose.angularAcceleration[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.pose.angularAcceleration[2] = value.Data()[2];
 | 
			
		||||
  }
 | 
			
		||||
  if (!aPosition.IsNull()) {
 | 
			
		||||
    const Float32Array& value = aPosition.Value();
 | 
			
		||||
    value.ComputeLengthAndData();
 | 
			
		||||
    MOZ_ASSERT(value.Length() == 3);
 | 
			
		||||
    mSensorState.position[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.position[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.position[2] = value.Data()[2];
 | 
			
		||||
    mSensorState.pose.position[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.pose.position[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.pose.position[2] = value.Data()[2];
 | 
			
		||||
  }
 | 
			
		||||
  if (!aLinearVelocity.IsNull()) {
 | 
			
		||||
    const Float32Array& value = aLinearVelocity.Value();
 | 
			
		||||
    value.ComputeLengthAndData();
 | 
			
		||||
    MOZ_ASSERT(value.Length() == 3);
 | 
			
		||||
    mSensorState.linearVelocity[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.linearVelocity[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.linearVelocity[2] = value.Data()[2];
 | 
			
		||||
    mSensorState.pose.linearVelocity[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.pose.linearVelocity[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.pose.linearVelocity[2] = value.Data()[2];
 | 
			
		||||
  }
 | 
			
		||||
  if (!aLinearAcceleration.IsNull()) {
 | 
			
		||||
    const Float32Array& value = aLinearAcceleration.Value();
 | 
			
		||||
    value.ComputeLengthAndData();
 | 
			
		||||
    MOZ_ASSERT(value.Length() == 3);
 | 
			
		||||
    mSensorState.linearAcceleration[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.linearAcceleration[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.linearAcceleration[2] = value.Data()[2];
 | 
			
		||||
    mSensorState.pose.linearAcceleration[0] = value.Data()[0];
 | 
			
		||||
    mSensorState.pose.linearAcceleration[1] = value.Data()[1];
 | 
			
		||||
    mSensorState.pose.linearAcceleration[2] = value.Data()[2];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,10 @@
 | 
			
		|||
#include "prlink.h"
 | 
			
		||||
#include "prenv.h"
 | 
			
		||||
#include "gfxPrefs.h"
 | 
			
		||||
#include "nsIGlobalObject.h"
 | 
			
		||||
#include "nsRefPtrHashtable.h"
 | 
			
		||||
#include "nsString.h"
 | 
			
		||||
#include "mozilla/dom/GamepadManager.h"
 | 
			
		||||
#include "mozilla/Preferences.h"
 | 
			
		||||
#include "mozilla/Unused.h"
 | 
			
		||||
#include "nsServiceManagerUtils.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +37,7 @@ VRDisplayClient::VRDisplayClient(const VRDisplayInfo& aDisplayInfo)
 | 
			
		|||
  , mPresentationCount(0)
 | 
			
		||||
  , mLastEventFrameId(0)
 | 
			
		||||
  , mLastPresentingGeneration(0)
 | 
			
		||||
  , mLastEventControllerState{}
 | 
			
		||||
{
 | 
			
		||||
  MOZ_COUNT_CTOR(VRDisplayClient);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -128,6 +132,140 @@ VRDisplayClient::FireEvents()
 | 
			
		|||
    mLastEventFrameId = mDisplayInfo.mFrameId;
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,7 @@ protected:
 | 
			
		|||
  virtual ~VRDisplayClient();
 | 
			
		||||
 | 
			
		||||
  void FireEvents();
 | 
			
		||||
  void FireGamepadEvents();
 | 
			
		||||
 | 
			
		||||
  VRDisplayInfo mDisplayInfo;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +61,10 @@ protected:
 | 
			
		|||
  int mPresentationCount;
 | 
			
		||||
  uint64_t mLastEventFrameId;
 | 
			
		||||
  uint32_t mLastPresentingGeneration;
 | 
			
		||||
 | 
			
		||||
  // Difference between mDisplayInfo.mControllerState and mLastEventControllerState
 | 
			
		||||
  // determines what gamepad events to fire when updated.
 | 
			
		||||
  VRControllerState mLastEventControllerState[kVRControllerMaxCount];
 | 
			
		||||
private:
 | 
			
		||||
  VRSubmitFrameResultInfo mSubmitFrameResult;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -352,7 +352,7 @@ VRControllerHost::VRControllerHost(VRDeviceType aType, dom::GamepadHand aHand,
 | 
			
		|||
{
 | 
			
		||||
  MOZ_COUNT_CTOR(VRControllerHost);
 | 
			
		||||
  mControllerInfo.mType = aType;
 | 
			
		||||
  mControllerInfo.mControllerState.mHand = aHand;
 | 
			
		||||
  mControllerInfo.mControllerState.hand = aHand;
 | 
			
		||||
  mControllerInfo.mMappingType = dom::GamepadMappingType::_empty;
 | 
			
		||||
  mControllerInfo.mDisplayID = aDisplayID;
 | 
			
		||||
  mControllerInfo.mControllerID = VRSystemManager::AllocateControllerID();
 | 
			
		||||
| 
						 | 
				
			
			@ -372,25 +372,25 @@ VRControllerHost::GetControllerInfo() const
 | 
			
		|||
void
 | 
			
		||||
VRControllerHost::SetButtonPressed(uint64_t aBit)
 | 
			
		||||
{
 | 
			
		||||
  mControllerInfo.mControllerState.mButtonPressed = aBit;
 | 
			
		||||
  mControllerInfo.mControllerState.buttonPressed = aBit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t
 | 
			
		||||
VRControllerHost::GetButtonPressed()
 | 
			
		||||
{
 | 
			
		||||
  return mControllerInfo.mControllerState.mButtonPressed;
 | 
			
		||||
  return mControllerInfo.mControllerState.buttonPressed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
VRControllerHost::SetButtonTouched(uint64_t aBit)
 | 
			
		||||
{
 | 
			
		||||
  mControllerInfo.mControllerState.mButtonTouched = aBit;
 | 
			
		||||
  mControllerInfo.mControllerState.buttonTouched = aBit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t
 | 
			
		||||
VRControllerHost::GetButtonTouched()
 | 
			
		||||
{
 | 
			
		||||
  return mControllerInfo.mControllerState.mButtonTouched;
 | 
			
		||||
  return mControllerInfo.mControllerState.buttonTouched;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -408,7 +408,7 @@ VRControllerHost::GetPose()
 | 
			
		|||
dom::GamepadHand
 | 
			
		||||
VRControllerHost::GetHand()
 | 
			
		||||
{
 | 
			
		||||
  return mControllerInfo.mControllerState.mHand;
 | 
			
		||||
  return mControllerInfo.mControllerState.hand;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,11 +24,12 @@ namespace mozilla {
 | 
			
		|||
#ifdef MOZILLA_INTERNAL_API
 | 
			
		||||
namespace dom {
 | 
			
		||||
  enum class GamepadHand : uint8_t;
 | 
			
		||||
  enum class GamepadCapabilityFlags : uint16_t;
 | 
			
		||||
}
 | 
			
		||||
#endif //  MOZILLA_INTERNAL_API
 | 
			
		||||
namespace gfx {
 | 
			
		||||
 | 
			
		||||
static const int32_t kVRExternalVersion = 0;
 | 
			
		||||
static const int32_t kVRExternalVersion = 1;
 | 
			
		||||
 | 
			
		||||
// We assign VR presentations to groups with a bitmask.
 | 
			
		||||
// 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 kVRControllerNameMaxLen = 256;
 | 
			
		||||
static const int kVRControllerMaxCount = 16;
 | 
			
		||||
static const int kVRControllerMaxTriggers = 16;
 | 
			
		||||
static const int kVRControllerMaxButtons = 64;
 | 
			
		||||
static const int kVRControllerMaxAxis = 16;
 | 
			
		||||
static const int kVRLayerMaxCount = 8;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +83,32 @@ enum class ControllerHand : uint8_t {
 | 
			
		|||
  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
 | 
			
		||||
 | 
			
		||||
enum class VRDisplayCapabilityFlags : uint16_t {
 | 
			
		||||
| 
						 | 
				
			
			@ -140,20 +167,25 @@ enum class VRDisplayCapabilityFlags : uint16_t {
 | 
			
		|||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRDisplayCapabilityFlags)
 | 
			
		||||
#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 {
 | 
			
		||||
  uint64_t inputFrameID;
 | 
			
		||||
  double timestamp;
 | 
			
		||||
  VRDisplayCapabilityFlags flags;
 | 
			
		||||
 | 
			
		||||
  // These members will only change with inputFrameID:
 | 
			
		||||
  float orientation[4];
 | 
			
		||||
  float position[3];
 | 
			
		||||
  VRPose pose;
 | 
			
		||||
  float leftViewMatrix[16];
 | 
			
		||||
  float rightViewMatrix[16];
 | 
			
		||||
  float angularVelocity[3];
 | 
			
		||||
  float angularAcceleration[3];
 | 
			
		||||
  float linearVelocity[3];
 | 
			
		||||
  float linearAcceleration[3];
 | 
			
		||||
 | 
			
		||||
#ifdef MOZILLA_INTERNAL_API
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -248,22 +280,30 @@ struct VRDisplayState
 | 
			
		|||
 | 
			
		||||
struct VRControllerState
 | 
			
		||||
{
 | 
			
		||||
  char mControllerName[kVRControllerNameMaxLen];
 | 
			
		||||
  char controllerName[kVRControllerNameMaxLen];
 | 
			
		||||
#ifdef MOZILLA_INTERNAL_API
 | 
			
		||||
  dom::GamepadHand mHand;
 | 
			
		||||
  dom::GamepadHand hand;
 | 
			
		||||
#else
 | 
			
		||||
  ControllerHand mHand;
 | 
			
		||||
  ControllerHand hand;
 | 
			
		||||
#endif
 | 
			
		||||
  uint32_t mNumButtons;
 | 
			
		||||
  uint32_t mNumAxes;
 | 
			
		||||
  uint32_t mNumTriggers;
 | 
			
		||||
  uint32_t mNumHaptics;
 | 
			
		||||
  uint32_t numButtons;
 | 
			
		||||
  uint32_t numAxes;
 | 
			
		||||
  uint32_t numHaptics;
 | 
			
		||||
  // The current button pressed bit of button mask.
 | 
			
		||||
  uint64_t mButtonPressed;
 | 
			
		||||
  uint64_t buttonPressed;
 | 
			
		||||
  // The current button touched bit of button mask.
 | 
			
		||||
  uint64_t mButtonTouched;
 | 
			
		||||
  float mTriggerValue[kVRControllerMaxTriggers];
 | 
			
		||||
  float mAxisValue[kVRControllerMaxAxis];
 | 
			
		||||
  uint64_t buttonTouched;
 | 
			
		||||
  float triggerValue[kVRControllerMaxButtons];
 | 
			
		||||
  float axisValue[kVRControllerMaxAxis];
 | 
			
		||||
 | 
			
		||||
#ifdef MOZILLA_INTERNAL_API
 | 
			
		||||
  dom::GamepadCapabilityFlags flags;
 | 
			
		||||
#else
 | 
			
		||||
  ControllerCapabilityFlags flags;
 | 
			
		||||
#endif
 | 
			
		||||
  VRPose pose;
 | 
			
		||||
  bool isPositionValid;
 | 
			
		||||
  bool isOrientationValid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct VRLayerEyeRect
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,10 +189,10 @@ VRHMDSensorState::CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms)
 | 
			
		|||
 | 
			
		||||
  gfx::Matrix4x4 matHead;
 | 
			
		||||
  if (flags & VRDisplayCapabilityFlags::Cap_Orientation) {
 | 
			
		||||
    matHead.SetRotationFromQuaternion(gfx::Quaternion(orientation[0], orientation[1],
 | 
			
		||||
                                                      orientation[2], orientation[3]));
 | 
			
		||||
    matHead.SetRotationFromQuaternion(gfx::Quaternion(pose.orientation[0], pose.orientation[1],
 | 
			
		||||
                                                      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];
 | 
			
		||||
  matView.Normalize();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,7 @@ struct VRDisplayInfo
 | 
			
		|||
  uint32_t mGroupMask;
 | 
			
		||||
  uint64_t mFrameId;
 | 
			
		||||
  VRDisplayState mDisplayState;
 | 
			
		||||
  VRControllerState mControllerState[kVRControllerMaxCount];
 | 
			
		||||
 | 
			
		||||
  VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames];
 | 
			
		||||
  const VRHMDSensorState& GetSensorState() const
 | 
			
		||||
| 
						 | 
				
			
			@ -89,10 +90,11 @@ struct VRDisplayInfo
 | 
			
		|||
        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 &&
 | 
			
		||||
           mDisplayID == other.mDisplayID &&
 | 
			
		||||
           memcmp(&mDisplayState, &other.mDisplayState, sizeof(VRDisplayState)) == 0 &&
 | 
			
		||||
           memcmp(mControllerState, other.mControllerState, sizeof(VRControllerState) * kVRControllerMaxCount) == 0 &&
 | 
			
		||||
           mPresentingGroups == other.mPresentingGroups &&
 | 
			
		||||
           mGroupMask == other.mGroupMask &&
 | 
			
		||||
           mFrameId == other.mFrameId;
 | 
			
		||||
| 
						 | 
				
			
			@ -123,13 +125,13 @@ struct VRControllerInfo
 | 
			
		|||
{
 | 
			
		||||
  VRDeviceType GetType() const { return mType; }
 | 
			
		||||
  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; }
 | 
			
		||||
  uint32_t GetDisplayID() const { return mDisplayID; }
 | 
			
		||||
  dom::GamepadHand GetHand() const { return mControllerState.mHand; }
 | 
			
		||||
  uint32_t GetNumButtons() const { return mControllerState.mNumButtons; }
 | 
			
		||||
  uint32_t GetNumAxes() const { return mControllerState.mNumAxes; }
 | 
			
		||||
  uint32_t GetNumHaptics() const { return mControllerState.mNumHaptics; }
 | 
			
		||||
  dom::GamepadHand GetHand() const { return mControllerState.hand; }
 | 
			
		||||
  uint32_t GetNumButtons() const { return mControllerState.numButtons; }
 | 
			
		||||
  uint32_t GetNumAxes() const { return mControllerState.numAxes; }
 | 
			
		||||
  uint32_t GetNumHaptics() const { return mControllerState.numHaptics; }
 | 
			
		||||
 | 
			
		||||
  uint32_t mControllerID;
 | 
			
		||||
  VRDeviceType mType;
 | 
			
		||||
| 
						 | 
				
			
			@ -137,15 +139,12 @@ struct VRControllerInfo
 | 
			
		|||
  uint32_t mDisplayID;
 | 
			
		||||
  VRControllerState mControllerState;
 | 
			
		||||
  bool operator==(const VRControllerInfo& other) const {
 | 
			
		||||
    // Note that mControllerState is asserted to be a POD type, so memcmp is safe
 | 
			
		||||
    return mType == other.mType &&
 | 
			
		||||
           mControllerID == other.mControllerID &&
 | 
			
		||||
           strncmp(mControllerState.mControllerName, other.mControllerState.mControllerName, kVRControllerNameMaxLen) == 0 &&
 | 
			
		||||
           memcmp(&mControllerState, &other.mControllerState, sizeof(VRControllerState)) == 0 &&
 | 
			
		||||
           mMappingType == other.mMappingType &&
 | 
			
		||||
           mDisplayID == other.mDisplayID &&
 | 
			
		||||
           mControllerState.mHand == other.mControllerState.mHand &&
 | 
			
		||||
           mControllerState.mNumButtons == other.mControllerState.mNumButtons &&
 | 
			
		||||
           mControllerState.mNumAxes == other.mControllerState.mNumAxes &&
 | 
			
		||||
           mControllerState.mNumHaptics == other.mControllerState.mNumHaptics;
 | 
			
		||||
           mDisplayID == other.mDisplayID;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator!=(const VRControllerInfo& other) const {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,8 +52,6 @@ using namespace mozilla::gfx::impl;
 | 
			
		|||
using namespace mozilla::layers;
 | 
			
		||||
using namespace mozilla::dom;
 | 
			
		||||
 | 
			
		||||
static const uint32_t kNumExternalHaptcs = 1;
 | 
			
		||||
 | 
			
		||||
int VRDisplayExternal::sPushIndex = 0;
 | 
			
		||||
 | 
			
		||||
VRDisplayExternal::VRDisplayExternal(const VRDisplayState& aDisplayState)
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +63,7 @@ VRDisplayExternal::VRDisplayExternal(const VRDisplayState& aDisplayState)
 | 
			
		|||
  mDisplayInfo.mDisplayState = aDisplayState;
 | 
			
		||||
 | 
			
		||||
  // default to an identity quaternion
 | 
			
		||||
  mLastSensorState.orientation[3] = 1.0f;
 | 
			
		||||
  mLastSensorState.pose.orientation[3] = 1.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VRDisplayExternal::~VRDisplayExternal()
 | 
			
		||||
| 
						 | 
				
			
			@ -78,8 +76,6 @@ void
 | 
			
		|||
VRDisplayExternal::Destroy()
 | 
			
		||||
{
 | 
			
		||||
  StopPresentation();
 | 
			
		||||
 | 
			
		||||
  // TODO - Implement
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +89,7 @@ VRDisplayExternal::Refresh()
 | 
			
		|||
  VRManager *vm = VRManager::Get();
 | 
			
		||||
  VRSystemManagerExternal* manager = vm->GetExternalManager();
 | 
			
		||||
 | 
			
		||||
  manager->PullState(&mDisplayInfo.mDisplayState, &mLastSensorState);
 | 
			
		||||
  manager->PullState(&mDisplayInfo.mDisplayState, &mLastSensorState, mDisplayInfo.mControllerState);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VRHMDSensorState
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +234,7 @@ VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture,
 | 
			
		|||
  VRDisplayState displayState;
 | 
			
		||||
  memset(&displayState, 0, sizeof(VRDisplayState));
 | 
			
		||||
  while (displayState.mLastSubmittedFrameId < aFrameId) {
 | 
			
		||||
    if (manager->PullState(&displayState, &mLastSensorState)) {
 | 
			
		||||
    if (manager->PullState(&displayState, &mLastSensorState, mDisplayInfo.mControllerState)) {
 | 
			
		||||
      if (!displayState.mIsConnected) {
 | 
			
		||||
        // Service has shut down or hardware has been disconnected
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -254,26 +250,6 @@ VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture,
 | 
			
		|||
  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*/)
 | 
			
		||||
 : mExternalShmem(aAPIShmem)
 | 
			
		||||
#if !defined(MOZ_WIDGET_ANDROID)
 | 
			
		||||
| 
						 | 
				
			
			@ -458,7 +434,6 @@ VRSystemManagerExternal::Shutdown()
 | 
			
		|||
  if (mDisplay) {
 | 
			
		||||
    mDisplay = nullptr;
 | 
			
		||||
  }
 | 
			
		||||
  RemoveControllers();
 | 
			
		||||
  CloseShmem();
 | 
			
		||||
#if defined(MOZ_WIDGET_ANDROID)
 | 
			
		||||
  mDoShutdown = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -537,12 +512,6 @@ VRSystemManagerExternal::GetIsPresenting()
 | 
			
		|||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
VRSystemManagerExternal::HandleInput()
 | 
			
		||||
{
 | 
			
		||||
  // TODO - Implement This!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
VRSystemManagerExternal::VibrateHaptic(uint32_t aControllerIdx,
 | 
			
		||||
                                      uint32_t aHapticIndex,
 | 
			
		||||
| 
						 | 
				
			
			@ -562,31 +531,40 @@ VRSystemManagerExternal::StopVibrateHaptic(uint32_t aControllerIdx)
 | 
			
		|||
void
 | 
			
		||||
VRSystemManagerExternal::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
 | 
			
		||||
{
 | 
			
		||||
  // Controller updates are handled in VRDisplayClient for VRSystemManagerExternal
 | 
			
		||||
  aControllerResult.Clear();
 | 
			
		||||
  for (uint32_t i = 0; i < mExternalController.Length(); ++i) {
 | 
			
		||||
    aControllerResult.AppendElement(mExternalController[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
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
 | 
			
		||||
VRSystemManagerExternal::RemoveControllers()
 | 
			
		||||
{
 | 
			
		||||
  // The controller count is changed, removing the existing gamepads first.
 | 
			
		||||
  for (uint32_t i = 0; i < mExternalController.Length(); ++i) {
 | 
			
		||||
    RemoveGamepad(i);
 | 
			
		||||
  }
 | 
			
		||||
  mExternalController.Clear();
 | 
			
		||||
  mControllerCount = 0;
 | 
			
		||||
  // Controller updates are handled in VRDisplayClient for VRSystemManagerExternal
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorState* aSensorState /* = nullptr */)
 | 
			
		||||
VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState,
 | 
			
		||||
                                   VRHMDSensorState* aSensorState /* = nullptr */,
 | 
			
		||||
                                   VRControllerState* aControllerState /* = nullptr */)
 | 
			
		||||
{
 | 
			
		||||
  bool success = false;
 | 
			
		||||
  MOZ_ASSERT(mExternalShmem);
 | 
			
		||||
| 
						 | 
				
			
			@ -597,6 +575,9 @@ VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorSta
 | 
			
		|||
      if (aSensorState) {
 | 
			
		||||
        memcpy(aSensorState, (void*)&(mExternalShmem->state.sensorState), sizeof(VRHMDSensorState));
 | 
			
		||||
      }
 | 
			
		||||
      if (aControllerState) {
 | 
			
		||||
        memcpy(aControllerState, (void*)&(mExternalShmem->state.controllerState), sizeof(VRControllerState) * kVRControllerMaxCount);
 | 
			
		||||
      }
 | 
			
		||||
      success = mExternalShmem->state.enumerationCompleted;
 | 
			
		||||
      pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->systemMutex));
 | 
			
		||||
      mDoShutdown = aDisplayState->shutdown;
 | 
			
		||||
| 
						 | 
				
			
			@ -609,6 +590,9 @@ VRSystemManagerExternal::PullState(VRDisplayState* aDisplayState, VRHMDSensorSta
 | 
			
		|||
      if (aSensorState) {
 | 
			
		||||
        memcpy(aSensorState, &tmp.state.sensorState, sizeof(VRHMDSensorState));
 | 
			
		||||
      }
 | 
			
		||||
      if (aControllerState) {
 | 
			
		||||
        memcpy(aControllerState, (void*)&(mExternalShmem->state.controllerState), sizeof(VRControllerState) * kVRControllerMaxCount);
 | 
			
		||||
      }
 | 
			
		||||
      success = true;
 | 
			
		||||
    }
 | 
			
		||||
#endif // defined(MOZ_WIDGET_ANDROID)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,7 @@ protected:
 | 
			
		|||
public:
 | 
			
		||||
  explicit VRDisplayExternal(const VRDisplayState& aDisplayState);
 | 
			
		||||
  void Refresh();
 | 
			
		||||
  const VRControllerState& GetLastControllerState(uint32_t aStateIndex) const;
 | 
			
		||||
protected:
 | 
			
		||||
  virtual ~VRDisplayExternal();
 | 
			
		||||
  void Destroy();
 | 
			
		||||
| 
						 | 
				
			
			@ -60,17 +61,6 @@ private:
 | 
			
		|||
  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
 | 
			
		||||
 | 
			
		||||
class VRSystemManagerExternal : public VRSystemManager
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +86,9 @@ public:
 | 
			
		|||
                             double aDuration,
 | 
			
		||||
                             const VRManagerPromise& aPromise) 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);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +98,6 @@ protected:
 | 
			
		|||
private:
 | 
			
		||||
  // there can only be one
 | 
			
		||||
  RefPtr<impl::VRDisplayExternal> mDisplay;
 | 
			
		||||
  nsTArray<RefPtr<impl::VRControllerExternal>> mExternalController;
 | 
			
		||||
#if defined(XP_MACOSX)
 | 
			
		||||
  int mShmemFD;
 | 
			
		||||
#elif defined(XP_WIN)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -317,22 +317,22 @@ VRDisplayOSVR::GetSensorState()
 | 
			
		|||
 | 
			
		||||
  if (ret == OSVR_RETURN_SUCCESS) {
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
 | 
			
		||||
    result.orientation[0] = orientation.data[1];
 | 
			
		||||
    result.orientation[1] = orientation.data[2];
 | 
			
		||||
    result.orientation[2] = orientation.data[3];
 | 
			
		||||
    result.orientation[3] = orientation.data[0];
 | 
			
		||||
    result.pose.orientation[0] = orientation.data[1];
 | 
			
		||||
    result.pose.orientation[1] = orientation.data[2];
 | 
			
		||||
    result.pose.orientation[2] = orientation.data[3];
 | 
			
		||||
    result.pose.orientation[3] = orientation.data[0];
 | 
			
		||||
  } else {
 | 
			
		||||
    // default to an identity quaternion
 | 
			
		||||
    result.orientation[3] = 1.0f;
 | 
			
		||||
    result.pose.orientation[3] = 1.0f;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  OSVR_PositionState position;
 | 
			
		||||
  ret = osvr_GetPositionState(*m_iface, ×tamp, &position);
 | 
			
		||||
  if (ret == OSVR_RETURN_SUCCESS) {
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_Position;
 | 
			
		||||
    result.position[0] = position.data[0];
 | 
			
		||||
    result.position[1] = position.data[1];
 | 
			
		||||
    result.position[2] = position.data[2];
 | 
			
		||||
    result.pose.position[0] = position.data[0];
 | 
			
		||||
    result.pose.position[1] = position.data[1];
 | 
			
		||||
    result.pose.position[2] = position.data[2];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  result.CalcViewMatrices(mHeadToEye);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -952,7 +952,7 @@ VRDisplayOculus::GetSensorState()
 | 
			
		|||
      predictedFrameTime = ovr_GetPredictedDisplayTime(mSession->Get(), 0);
 | 
			
		||||
    }
 | 
			
		||||
    result = GetSensorState(predictedFrameTime);
 | 
			
		||||
    result.position[1] -= mEyeHeight;
 | 
			
		||||
    result.pose.position[1] -= mEyeHeight;
 | 
			
		||||
    result.CalcViewMatrices(headToEyeTransforms);
 | 
			
		||||
  }
 | 
			
		||||
  result.inputFrameID = mDisplayInfo.mFrameId;
 | 
			
		||||
| 
						 | 
				
			
			@ -973,41 +973,41 @@ VRDisplayOculus::GetSensorState(double absTime)
 | 
			
		|||
  if (state.StatusFlags & ovrStatus_OrientationTracked) {
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
 | 
			
		||||
 | 
			
		||||
    result.orientation[0] = pose.ThePose.Orientation.x;
 | 
			
		||||
    result.orientation[1] = pose.ThePose.Orientation.y;
 | 
			
		||||
    result.orientation[2] = pose.ThePose.Orientation.z;
 | 
			
		||||
    result.orientation[3] = pose.ThePose.Orientation.w;
 | 
			
		||||
    result.pose.orientation[0] = pose.ThePose.Orientation.x;
 | 
			
		||||
    result.pose.orientation[1] = pose.ThePose.Orientation.y;
 | 
			
		||||
    result.pose.orientation[2] = pose.ThePose.Orientation.z;
 | 
			
		||||
    result.pose.orientation[3] = pose.ThePose.Orientation.w;
 | 
			
		||||
 | 
			
		||||
    result.angularVelocity[0] = pose.AngularVelocity.x;
 | 
			
		||||
    result.angularVelocity[1] = pose.AngularVelocity.y;
 | 
			
		||||
    result.angularVelocity[2] = pose.AngularVelocity.z;
 | 
			
		||||
    result.pose.angularVelocity[0] = pose.AngularVelocity.x;
 | 
			
		||||
    result.pose.angularVelocity[1] = pose.AngularVelocity.y;
 | 
			
		||||
    result.pose.angularVelocity[2] = pose.AngularVelocity.z;
 | 
			
		||||
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
 | 
			
		||||
 | 
			
		||||
    result.angularAcceleration[0] = pose.AngularAcceleration.x;
 | 
			
		||||
    result.angularAcceleration[1] = pose.AngularAcceleration.y;
 | 
			
		||||
    result.angularAcceleration[2] = pose.AngularAcceleration.z;
 | 
			
		||||
    result.pose.angularAcceleration[0] = pose.AngularAcceleration.x;
 | 
			
		||||
    result.pose.angularAcceleration[1] = pose.AngularAcceleration.y;
 | 
			
		||||
    result.pose.angularAcceleration[2] = pose.AngularAcceleration.z;
 | 
			
		||||
  } else {
 | 
			
		||||
    // default to an identity quaternion
 | 
			
		||||
    result.orientation[3] = 1.0f;
 | 
			
		||||
    result.pose.orientation[3] = 1.0f;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (state.StatusFlags & ovrStatus_PositionTracked) {
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_Position;
 | 
			
		||||
 | 
			
		||||
    result.position[0] = pose.ThePose.Position.x;
 | 
			
		||||
    result.position[1] = pose.ThePose.Position.y;
 | 
			
		||||
    result.position[2] = pose.ThePose.Position.z;
 | 
			
		||||
    result.pose.position[0] = pose.ThePose.Position.x;
 | 
			
		||||
    result.pose.position[1] = pose.ThePose.Position.y;
 | 
			
		||||
    result.pose.position[2] = pose.ThePose.Position.z;
 | 
			
		||||
 | 
			
		||||
    result.linearVelocity[0] = pose.LinearVelocity.x;
 | 
			
		||||
    result.linearVelocity[1] = pose.LinearVelocity.y;
 | 
			
		||||
    result.linearVelocity[2] = pose.LinearVelocity.z;
 | 
			
		||||
    result.pose.linearVelocity[0] = pose.LinearVelocity.x;
 | 
			
		||||
    result.pose.linearVelocity[1] = pose.LinearVelocity.y;
 | 
			
		||||
    result.pose.linearVelocity[2] = pose.LinearVelocity.z;
 | 
			
		||||
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
 | 
			
		||||
 | 
			
		||||
    result.linearAcceleration[0] = pose.LinearAcceleration.x;
 | 
			
		||||
    result.linearAcceleration[1] = pose.LinearAcceleration.y;
 | 
			
		||||
    result.linearAcceleration[2] = pose.LinearAcceleration.z;
 | 
			
		||||
    result.pose.linearAcceleration[0] = pose.LinearAcceleration.x;
 | 
			
		||||
    result.pose.linearAcceleration[1] = pose.LinearAcceleration.y;
 | 
			
		||||
    result.pose.linearAcceleration[2] = pose.LinearAcceleration.z;
 | 
			
		||||
  }
 | 
			
		||||
  result.flags |= VRDisplayCapabilityFlags::Cap_External;
 | 
			
		||||
  result.flags |= VRDisplayCapabilityFlags::Cap_MountDetection;
 | 
			
		||||
| 
						 | 
				
			
			@ -1330,17 +1330,17 @@ VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand, uint32_t aDisplay
 | 
			
		|||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  strncpy(state.mControllerName, touchID, kVRControllerNameMaxLen);
 | 
			
		||||
  strncpy(state.controllerName, touchID, kVRControllerNameMaxLen);
 | 
			
		||||
 | 
			
		||||
  MOZ_ASSERT(kNumOculusButton ==
 | 
			
		||||
             static_cast<uint32_t>(OculusLeftControllerButtonType::NumButtonType)
 | 
			
		||||
             && kNumOculusButton ==
 | 
			
		||||
             static_cast<uint32_t>(OculusRightControllerButtonType::NumButtonType));
 | 
			
		||||
 | 
			
		||||
  state.mNumButtons = kNumOculusButton;
 | 
			
		||||
  state.mNumAxes = static_cast<uint32_t>(
 | 
			
		||||
  state.numButtons = kNumOculusButton;
 | 
			
		||||
  state.numAxes = static_cast<uint32_t>(
 | 
			
		||||
                   OculusControllerAxisType::NumVRControllerAxisType);
 | 
			
		||||
  state.mNumHaptics = kNumOculusHaptcs;
 | 
			
		||||
  state.numHaptics = kNumOculusHaptcs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -287,24 +287,24 @@ VRDisplayOpenVR::GetSensorState()
 | 
			
		|||
    rot.Invert();
 | 
			
		||||
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
 | 
			
		||||
    result.orientation[0] = rot.x;
 | 
			
		||||
    result.orientation[1] = rot.y;
 | 
			
		||||
    result.orientation[2] = rot.z;
 | 
			
		||||
    result.orientation[3] = rot.w;
 | 
			
		||||
    result.angularVelocity[0] = pose.vAngularVelocity.v[0];
 | 
			
		||||
    result.angularVelocity[1] = pose.vAngularVelocity.v[1];
 | 
			
		||||
    result.angularVelocity[2] = pose.vAngularVelocity.v[2];
 | 
			
		||||
    result.pose.orientation[0] = rot.x;
 | 
			
		||||
    result.pose.orientation[1] = rot.y;
 | 
			
		||||
    result.pose.orientation[2] = rot.z;
 | 
			
		||||
    result.pose.orientation[3] = rot.w;
 | 
			
		||||
    result.pose.angularVelocity[0] = pose.vAngularVelocity.v[0];
 | 
			
		||||
    result.pose.angularVelocity[1] = pose.vAngularVelocity.v[1];
 | 
			
		||||
    result.pose.angularVelocity[2] = pose.vAngularVelocity.v[2];
 | 
			
		||||
 | 
			
		||||
    result.flags |= VRDisplayCapabilityFlags::Cap_Position;
 | 
			
		||||
    result.position[0] = m._41;
 | 
			
		||||
    result.position[1] = m._42;
 | 
			
		||||
    result.position[2] = m._43;
 | 
			
		||||
    result.linearVelocity[0] = pose.vVelocity.v[0];
 | 
			
		||||
    result.linearVelocity[1] = pose.vVelocity.v[1];
 | 
			
		||||
    result.linearVelocity[2] = pose.vVelocity.v[2];
 | 
			
		||||
    result.pose.position[0] = m._41;
 | 
			
		||||
    result.pose.position[1] = m._42;
 | 
			
		||||
    result.pose.position[2] = m._43;
 | 
			
		||||
    result.pose.linearVelocity[0] = pose.vVelocity.v[0];
 | 
			
		||||
    result.pose.linearVelocity[1] = pose.vVelocity.v[1];
 | 
			
		||||
    result.pose.linearVelocity[2] = pose.vVelocity.v[2];
 | 
			
		||||
  } else {
 | 
			
		||||
    // default to an identity quaternion
 | 
			
		||||
    result.orientation[3] = 1.0f;
 | 
			
		||||
    result.pose.orientation[3] = 1.0f;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  result.CalcViewMatrices(headToEyeTransforms);
 | 
			
		||||
| 
						 | 
				
			
			@ -438,11 +438,10 @@ VRControllerOpenVR::VRControllerOpenVR(dom::GamepadHand aHand, uint32_t aDisplay
 | 
			
		|||
  MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
 | 
			
		||||
 | 
			
		||||
  VRControllerState& state = mControllerInfo.mControllerState;
 | 
			
		||||
  strncpy(state.mControllerName, aId.BeginReading(), kVRControllerNameMaxLen);
 | 
			
		||||
  state.mNumButtons = aNumButtons;
 | 
			
		||||
  state.mNumAxes = aNumAxes;
 | 
			
		||||
  state.mNumTriggers = aNumTriggers;
 | 
			
		||||
  state.mNumHaptics = kNumOpenVRHaptcs;
 | 
			
		||||
  strncpy(state.controllerName, aId.BeginReading(), kVRControllerNameMaxLen);
 | 
			
		||||
  state.numButtons = aNumButtons;
 | 
			
		||||
  state.numAxes = aNumAxes;
 | 
			
		||||
  state.numHaptics = kNumOpenVRHaptcs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VRControllerOpenVR::~VRControllerOpenVR()
 | 
			
		||||
| 
						 | 
				
			
			@ -466,31 +465,31 @@ VRControllerOpenVR::GetTrackedIndex()
 | 
			
		|||
float
 | 
			
		||||
VRControllerOpenVR::GetAxisMove(uint32_t aAxis)
 | 
			
		||||
{
 | 
			
		||||
  return mControllerInfo.mControllerState.mAxisValue[aAxis];
 | 
			
		||||
  return mControllerInfo.mControllerState.axisValue[aAxis];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
VRControllerOpenVR::SetAxisMove(uint32_t aAxis, float aValue)
 | 
			
		||||
{
 | 
			
		||||
  mControllerInfo.mControllerState.mAxisValue[aAxis] = aValue;
 | 
			
		||||
  mControllerInfo.mControllerState.axisValue[aAxis] = aValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
VRControllerOpenVR::SetTrigger(uint32_t aButton, float aValue)
 | 
			
		||||
{
 | 
			
		||||
  mControllerInfo.mControllerState.mTriggerValue[aButton] = aValue;
 | 
			
		||||
  mControllerInfo.mControllerState.triggerValue[aButton] = aValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float
 | 
			
		||||
VRControllerOpenVR::GetTrigger(uint32_t aButton)
 | 
			
		||||
{
 | 
			
		||||
  return mControllerInfo.mControllerState.mTriggerValue[aButton];
 | 
			
		||||
  return mControllerInfo.mControllerState.triggerValue[aButton];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
VRControllerOpenVR::SetHand(dom::GamepadHand aHand)
 | 
			
		||||
{
 | 
			
		||||
  mControllerInfo.mControllerState.mHand = aHand;
 | 
			
		||||
  mControllerInfo.mControllerState.hand = aHand;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,21 +104,21 @@ VRDisplayPuppet::VRDisplayPuppet()
 | 
			
		|||
  gfx::Quaternion rot;
 | 
			
		||||
 | 
			
		||||
  mSensorState.flags |= VRDisplayCapabilityFlags::Cap_Orientation;
 | 
			
		||||
  mSensorState.orientation[0] = rot.x;
 | 
			
		||||
  mSensorState.orientation[1] = rot.y;
 | 
			
		||||
  mSensorState.orientation[2] = rot.z;
 | 
			
		||||
  mSensorState.orientation[3] = rot.w;
 | 
			
		||||
  mSensorState.angularVelocity[0] = 0.0f;
 | 
			
		||||
  mSensorState.angularVelocity[1] = 0.0f;
 | 
			
		||||
  mSensorState.angularVelocity[2] = 0.0f;
 | 
			
		||||
  mSensorState.pose.orientation[0] = rot.x;
 | 
			
		||||
  mSensorState.pose.orientation[1] = rot.y;
 | 
			
		||||
  mSensorState.pose.orientation[2] = rot.z;
 | 
			
		||||
  mSensorState.pose.orientation[3] = rot.w;
 | 
			
		||||
  mSensorState.pose.angularVelocity[0] = 0.0f;
 | 
			
		||||
  mSensorState.pose.angularVelocity[1] = 0.0f;
 | 
			
		||||
  mSensorState.pose.angularVelocity[2] = 0.0f;
 | 
			
		||||
 | 
			
		||||
  mSensorState.flags |= VRDisplayCapabilityFlags::Cap_Position;
 | 
			
		||||
  mSensorState.position[0] = 0.0f;
 | 
			
		||||
  mSensorState.position[1] = 0.0f;
 | 
			
		||||
  mSensorState.position[2] = 0.0f;
 | 
			
		||||
  mSensorState.linearVelocity[0] = 0.0f;
 | 
			
		||||
  mSensorState.linearVelocity[1] = 0.0f;
 | 
			
		||||
  mSensorState.linearVelocity[2] = 0.0f;
 | 
			
		||||
  mSensorState.pose.position[0] = 0.0f;
 | 
			
		||||
  mSensorState.pose.position[1] = 0.0f;
 | 
			
		||||
  mSensorState.pose.position[2] = 0.0f;
 | 
			
		||||
  mSensorState.pose.linearVelocity[0] = 0.0f;
 | 
			
		||||
  mSensorState.pose.linearVelocity[1] = 0.0f;
 | 
			
		||||
  mSensorState.pose.linearVelocity[2] = 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VRDisplayPuppet::~VRDisplayPuppet()
 | 
			
		||||
| 
						 | 
				
			
			@ -585,10 +585,10 @@ VRControllerPuppet::VRControllerPuppet(dom::GamepadHand aHand, uint32_t aDisplay
 | 
			
		|||
{
 | 
			
		||||
  MOZ_COUNT_CTOR_INHERITED(VRControllerPuppet, VRControllerHost);
 | 
			
		||||
  VRControllerState& state = mControllerInfo.mControllerState;
 | 
			
		||||
  strncpy(state.mControllerName, "Puppet Gamepad", kVRControllerNameMaxLen);
 | 
			
		||||
  state.mNumButtons = kNumPuppetButtonMask;
 | 
			
		||||
  state.mNumAxes = kNumPuppetAxis;
 | 
			
		||||
  state.mNumHaptics = kNumPuppetHaptcs;
 | 
			
		||||
  strncpy(state.controllerName, "Puppet Gamepad", kVRControllerNameMaxLen);
 | 
			
		||||
  state.numButtons = kNumPuppetButtonMask;
 | 
			
		||||
  state.numAxes = kNumPuppetAxis;
 | 
			
		||||
  state.numHaptics = kNumPuppetHaptcs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VRControllerPuppet::~VRControllerPuppet()
 | 
			
		||||
| 
						 | 
				
			
			@ -672,13 +672,13 @@ VRControllerPuppet::GetPoseMoveState()
 | 
			
		|||
float
 | 
			
		||||
VRControllerPuppet::GetAxisMove(uint32_t aAxis)
 | 
			
		||||
{
 | 
			
		||||
  return mControllerInfo.mControllerState.mAxisValue[aAxis];
 | 
			
		||||
  return mControllerInfo.mControllerState.axisValue[aAxis];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
VRControllerPuppet::SetAxisMove(uint32_t aAxis, float aValue)
 | 
			
		||||
{
 | 
			
		||||
  mControllerInfo.mControllerState.mAxisValue[aAxis] = aValue;
 | 
			
		||||
  mControllerInfo.mControllerState.axisValue[aAxis] = aValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VRSystemManagerPuppet::VRSystemManagerPuppet()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,7 @@ VRManagerChild::VRManagerChild()
 | 
			
		|||
  , mBackend(layers::LayersBackend::LAYERS_NONE)
 | 
			
		||||
  , mPromiseID(0)
 | 
			
		||||
  , mVRMockDisplay(nullptr)
 | 
			
		||||
  , mLastControllerState{}
 | 
			
		||||
{
 | 
			
		||||
  MOZ_ASSERT(NS_IsMainThread());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,6 +139,7 @@ private:
 | 
			
		|||
  uint32_t mPromiseID;
 | 
			
		||||
  nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mPromiseList;
 | 
			
		||||
  RefPtr<dom::VRMockDisplay> mVRMockDisplay;
 | 
			
		||||
  VRControllerState mLastControllerState[kVRControllerMaxCount];
 | 
			
		||||
 | 
			
		||||
  DISALLOW_COPY_AND_ASSIGN(VRManagerChild);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
#define mozilla_gfx_vr_VRMessageUtils_h
 | 
			
		||||
 | 
			
		||||
#include "ipc/IPCMessageUtils.h"
 | 
			
		||||
#include "mozilla/ArrayUtils.h"
 | 
			
		||||
#include "mozilla/GfxMessageUtils.h"
 | 
			
		||||
#include "VRManager.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -109,9 +110,12 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo>
 | 
			
		|||
    WriteParam(aMsg, aParam.mGroupMask);
 | 
			
		||||
    WriteParam(aMsg, aParam.mFrameId);
 | 
			
		||||
    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]);
 | 
			
		||||
    }
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -124,26 +128,28 @@ struct ParamTraits<mozilla::gfx::VRDisplayInfo>
 | 
			
		|||
        !ReadParam(aMsg, aIter, &(aResult->mDisplayState))) {
 | 
			
		||||
      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]))) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < mozilla::ArrayLength(aResult->mControllerState); i++) {
 | 
			
		||||
      if (!ReadParam(aMsg, aIter, &(aResult->mControllerState[i]))) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
  {
 | 
			
		||||
    WriteParam(aMsg, aParam.timestamp);
 | 
			
		||||
    WriteParam(aMsg, aParam.inputFrameID);
 | 
			
		||||
    WriteParam(aMsg, aParam.flags);
 | 
			
		||||
    WriteParam(aMsg, aParam.orientation[0]);
 | 
			
		||||
    WriteParam(aMsg, aParam.orientation[1]);
 | 
			
		||||
    WriteParam(aMsg, aParam.orientation[2]);
 | 
			
		||||
| 
						 | 
				
			
			@ -163,20 +169,11 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState>
 | 
			
		|||
    WriteParam(aMsg, aParam.linearAcceleration[0]);
 | 
			
		||||
    WriteParam(aMsg, aParam.linearAcceleration[1]);
 | 
			
		||||
    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)
 | 
			
		||||
  {
 | 
			
		||||
    if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->inputFrameID)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->flags)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->orientation[0])) ||
 | 
			
		||||
    if (!ReadParam(aMsg, aIter, &(aResult->orientation[0])) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->orientation[1])) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->orientation[2])) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->orientation[3])) ||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,12 +194,43 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState>
 | 
			
		|||
        !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) {
 | 
			
		||||
      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]))) {
 | 
			
		||||
        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]))) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -246,19 +274,23 @@ struct ParamTraits<mozilla::gfx::VRControllerState>
 | 
			
		|||
  static void Write(Message* aMsg, const paramType& aParam)
 | 
			
		||||
  {
 | 
			
		||||
    nsCString controllerName;
 | 
			
		||||
    controllerName.Assign(aParam.mControllerName); // FINDME!! HACK! - Bounds checking?
 | 
			
		||||
    controllerName.Assign(aParam.controllerName); // FINDME!! HACK! - Bounds checking?
 | 
			
		||||
    WriteParam(aMsg, controllerName);
 | 
			
		||||
    WriteParam(aMsg, aParam.mNumButtons);
 | 
			
		||||
    WriteParam(aMsg, aParam.mNumAxes);
 | 
			
		||||
    WriteParam(aMsg, aParam.mNumTriggers);
 | 
			
		||||
    WriteParam(aMsg, aParam.mNumHaptics);
 | 
			
		||||
    WriteParam(aMsg, aParam.mButtonPressed);
 | 
			
		||||
    WriteParam(aMsg, aParam.mButtonTouched);
 | 
			
		||||
    for (int i=0; i < mozilla::gfx::kVRControllerMaxAxis; i++) {
 | 
			
		||||
      WriteParam(aMsg, aParam.mAxisValue[i]);
 | 
			
		||||
    WriteParam(aMsg, aParam.hand);
 | 
			
		||||
    WriteParam(aMsg, aParam.numButtons);
 | 
			
		||||
    WriteParam(aMsg, aParam.numAxes);
 | 
			
		||||
    WriteParam(aMsg, aParam.numHaptics);
 | 
			
		||||
    WriteParam(aMsg, aParam.buttonPressed);
 | 
			
		||||
    WriteParam(aMsg, aParam.buttonTouched);
 | 
			
		||||
    WriteParam(aMsg, aParam.flags);
 | 
			
		||||
    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++) {
 | 
			
		||||
      WriteParam(aMsg, aParam.mTriggerValue[i]);
 | 
			
		||||
    for (size_t i = 0; i < mozilla::ArrayLength(aParam.triggerValue); i++) {
 | 
			
		||||
      WriteParam(aMsg, aParam.triggerValue[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -266,25 +298,29 @@ struct ParamTraits<mozilla::gfx::VRControllerState>
 | 
			
		|||
  {
 | 
			
		||||
    nsCString controllerName;
 | 
			
		||||
    if (!ReadParam(aMsg, aIter, &(controllerName)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->mNumButtons)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->mNumAxes)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->mNumTriggers)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->mNumHaptics)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->mButtonPressed)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->mButtonTouched))) {
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->hand)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->numButtons)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->numAxes)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->numHaptics)) ||
 | 
			
		||||
        !ReadParam(aMsg, aIter, &(aResult->buttonPressed)) ||
 | 
			
		||||
        !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;
 | 
			
		||||
    }
 | 
			
		||||
    for (int i=0; i < mozilla::gfx::kVRControllerMaxAxis; i++) {
 | 
			
		||||
      if (!ReadParam(aMsg, aIter, &(aResult->mAxisValue[i]))) {
 | 
			
		||||
    for (size_t i = 0; i < mozilla::ArrayLength(aResult->axisValue); i++) {
 | 
			
		||||
      if (!ReadParam(aMsg, aIter, &(aResult->axisValue[i]))) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    for (int i=0; i < mozilla::gfx::kVRControllerMaxTriggers; i++) {
 | 
			
		||||
      if (!ReadParam(aMsg, aIter, &(aResult->mTriggerValue[i]))) {
 | 
			
		||||
    for (size_t i = 0; i < mozilla::ArrayLength(aResult->triggerValue); i++) {
 | 
			
		||||
      if (!ReadParam(aMsg, aIter, &(aResult->triggerValue[i]))) {
 | 
			
		||||
        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;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,13 @@
 | 
			
		|||
#include "OpenVRSession.h"
 | 
			
		||||
#include "gfxPrefs.h"
 | 
			
		||||
 | 
			
		||||
#if defined(XP_WIN)
 | 
			
		||||
#include <d3d11.h>
 | 
			
		||||
#include "mozilla/gfx/DeviceManagerDx.h"
 | 
			
		||||
#endif // defined(XP_WIN)
 | 
			
		||||
 | 
			
		||||
#if defined(MOZILLA_INTERNAL_API)
 | 
			
		||||
#include "mozilla/dom/GamepadEventTypes.h"
 | 
			
		||||
#include "mozilla/dom/GamepadBinding.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(M_PI)
 | 
			
		||||
#define M_PI 3.14159265358979323846264338327950288
 | 
			
		||||
| 
						 | 
				
			
			@ -17,17 +16,91 @@
 | 
			
		|||
#define BTN_MASK_FROM_ID(_id) \
 | 
			
		||||
  ::vr::ButtonMaskFromId(vr::EVRButtonId::_id)
 | 
			
		||||
 | 
			
		||||
static const uint32_t kNumOpenVRHaptcs = 1;
 | 
			
		||||
 | 
			
		||||
using namespace mozilla::gfx;
 | 
			
		||||
 | 
			
		||||
namespace mozilla {
 | 
			
		||||
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()
 | 
			
		||||
  : VRSession()
 | 
			
		||||
  , mVRSystem(nullptr)
 | 
			
		||||
  , mVRChaperone(nullptr)
 | 
			
		||||
  , mVRCompositor(nullptr)
 | 
			
		||||
  , mControllerDeviceIndex{0}
 | 
			
		||||
  , mShouldQuit(false)
 | 
			
		||||
  , mIsWindowsMR(false)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,8 +116,10 @@ OpenVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState)
 | 
			
		|||
    // Already initialized
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  if (!::vr::VR_IsRuntimeInstalled()) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (!::vr::VR_IsHmdPresent()) {
 | 
			
		||||
    fprintf(stderr, "No HMD detected, VR_IsHmdPresent returned false.\n");
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,121 +218,121 @@ OpenVRSession::InitState(VRSystemState& aSystemState)
 | 
			
		|||
  state.mEyeResolution.height = h;
 | 
			
		||||
 | 
			
		||||
  // default to an identity quaternion
 | 
			
		||||
  aSystemState.sensorState.orientation[3] = 1.0f;
 | 
			
		||||
  aSystemState.sensorState.pose.orientation[3] = 1.0f;
 | 
			
		||||
 | 
			
		||||
  UpdateStageParameters(state);
 | 
			
		||||
  UpdateEyeParameters(state);
 | 
			
		||||
  UpdateEyeParameters(aSystemState);
 | 
			
		||||
 | 
			
		||||
  VRHMDSensorState& sensorState = aSystemState.sensorState;
 | 
			
		||||
  sensorState.flags = (VRDisplayCapabilityFlags)(
 | 
			
		||||
    (int)VRDisplayCapabilityFlags::Cap_Orientation |
 | 
			
		||||
    (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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
OpenVRSession::UpdateStageParameters(VRDisplayState& state)
 | 
			
		||||
OpenVRSession::UpdateStageParameters(VRDisplayState& aState)
 | 
			
		||||
{
 | 
			
		||||
  float sizeX = 0.0f;
 | 
			
		||||
  float sizeZ = 0.0f;
 | 
			
		||||
  if (mVRChaperone->GetPlayAreaSize(&sizeX, &sizeZ)) {
 | 
			
		||||
    ::vr::HmdMatrix34_t t = mVRSystem->GetSeatedZeroPoseToStandingAbsoluteTrackingPose();
 | 
			
		||||
    state.mStageSize.width = sizeX;
 | 
			
		||||
    state.mStageSize.height = sizeZ;
 | 
			
		||||
    aState.mStageSize.width = sizeX;
 | 
			
		||||
    aState.mStageSize.height = sizeZ;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[0] = t.m[0][0];
 | 
			
		||||
    state.mSittingToStandingTransform[1] = t.m[1][0];
 | 
			
		||||
    state.mSittingToStandingTransform[2] = t.m[2][0];
 | 
			
		||||
    state.mSittingToStandingTransform[3] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[0] = t.m[0][0];
 | 
			
		||||
    aState.mSittingToStandingTransform[1] = t.m[1][0];
 | 
			
		||||
    aState.mSittingToStandingTransform[2] = t.m[2][0];
 | 
			
		||||
    aState.mSittingToStandingTransform[3] = 0.0f;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[4] = t.m[0][1];
 | 
			
		||||
    state.mSittingToStandingTransform[5] = t.m[1][1];
 | 
			
		||||
    state.mSittingToStandingTransform[6] = t.m[2][1];
 | 
			
		||||
    state.mSittingToStandingTransform[7] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[4] = t.m[0][1];
 | 
			
		||||
    aState.mSittingToStandingTransform[5] = t.m[1][1];
 | 
			
		||||
    aState.mSittingToStandingTransform[6] = t.m[2][1];
 | 
			
		||||
    aState.mSittingToStandingTransform[7] = 0.0f;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[8] = t.m[0][2];
 | 
			
		||||
    state.mSittingToStandingTransform[9] = t.m[1][2];
 | 
			
		||||
    state.mSittingToStandingTransform[10] = t.m[2][2];
 | 
			
		||||
    state.mSittingToStandingTransform[11] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[8] = t.m[0][2];
 | 
			
		||||
    aState.mSittingToStandingTransform[9] = t.m[1][2];
 | 
			
		||||
    aState.mSittingToStandingTransform[10] = t.m[2][2];
 | 
			
		||||
    aState.mSittingToStandingTransform[11] = 0.0f;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[12] = t.m[0][3];
 | 
			
		||||
    state.mSittingToStandingTransform[13] = t.m[1][3];
 | 
			
		||||
    state.mSittingToStandingTransform[14] = t.m[2][3];
 | 
			
		||||
    state.mSittingToStandingTransform[15] = 1.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[12] = t.m[0][3];
 | 
			
		||||
    aState.mSittingToStandingTransform[13] = t.m[1][3];
 | 
			
		||||
    aState.mSittingToStandingTransform[14] = t.m[2][3];
 | 
			
		||||
    aState.mSittingToStandingTransform[15] = 1.0f;
 | 
			
		||||
  } else {
 | 
			
		||||
    // If we fail, fall back to reasonable defaults.
 | 
			
		||||
    // 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;
 | 
			
		||||
    state.mStageSize.height = 1.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[0] = 1.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[1] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[2] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[3] = 0.0f;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[0] = 1.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[1] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[2] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[3] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[4] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[5] = 1.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[6] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[7] = 0.0f;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[4] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[5] = 1.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[6] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[7] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[8] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[9] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[10] = 1.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[11] = 0.0f;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[8] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[9] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[10] = 1.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[11] = 0.0f;
 | 
			
		||||
 | 
			
		||||
    state.mSittingToStandingTransform[12] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[13] = 0.75f;
 | 
			
		||||
    state.mSittingToStandingTransform[14] = 0.0f;
 | 
			
		||||
    state.mSittingToStandingTransform[15] = 1.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[12] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[13] = 0.75f;
 | 
			
		||||
    aState.mSittingToStandingTransform[14] = 0.0f;
 | 
			
		||||
    aState.mSittingToStandingTransform[15] = 1.0f;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
    ::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye));
 | 
			
		||||
    state.mEyeTranslation[eye].x = eyeToHead.m[0][3];
 | 
			
		||||
    state.mEyeTranslation[eye].y = eyeToHead.m[1][3];
 | 
			
		||||
    state.mEyeTranslation[eye].z = eyeToHead.m[2][3];
 | 
			
		||||
    aState.displayState.mEyeTranslation[eye].x = eyeToHead.m[0][3];
 | 
			
		||||
    aState.displayState.mEyeTranslation[eye].y = eyeToHead.m[1][3];
 | 
			
		||||
    aState.displayState.mEyeTranslation[eye].z = eyeToHead.m[2][3];
 | 
			
		||||
 | 
			
		||||
    float 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;
 | 
			
		||||
    state.mEyeFOV[eye].rightDegrees = atan(right) * 180.0 / M_PI;
 | 
			
		||||
    state.mEyeFOV[eye].downDegrees = atan(down) * 180.0 / M_PI;
 | 
			
		||||
    state.mEyeFOV[eye].leftDegrees = atan(-left) * 180.0 / M_PI;
 | 
			
		||||
    aState.displayState.mEyeFOV[eye].upDegrees = atan(-up) * 180.0 / M_PI;
 | 
			
		||||
    aState.displayState.mEyeFOV[eye].rightDegrees = atan(right) * 180.0 / M_PI;
 | 
			
		||||
    aState.displayState.mEyeFOV[eye].downDegrees = atan(down) * 180.0 / M_PI;
 | 
			
		||||
    aState.displayState.mEyeFOV[eye].leftDegrees = atan(-left) * 180.0 / M_PI;
 | 
			
		||||
 | 
			
		||||
    if (headToEyeTransforms) {
 | 
			
		||||
      Matrix4x4 pose;
 | 
			
		||||
      // NOTE! eyeToHead.m 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.
 | 
			
		||||
      memcpy(&pose._11, &eyeToHead.m, sizeof(eyeToHead.m));
 | 
			
		||||
      pose.Transpose();
 | 
			
		||||
      pose.Invert();
 | 
			
		||||
      headToEyeTransforms[eye] = pose;
 | 
			
		||||
    }
 | 
			
		||||
    Matrix4x4 pose;
 | 
			
		||||
    // NOTE! eyeToHead.m 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.
 | 
			
		||||
    memcpy(&pose._11, &eyeToHead.m, sizeof(eyeToHead.m));
 | 
			
		||||
    pose.Transpose();
 | 
			
		||||
    pose.Invert();
 | 
			
		||||
    headToEyeTransforms[eye] = pose;
 | 
			
		||||
  }
 | 
			
		||||
  aState.sensorState.CalcViewMatrices(headToEyeTransforms);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
OpenVRSession::GetSensorState(VRSystemState& state)
 | 
			
		||||
OpenVRSession::UpdateHeadsetPose(VRSystemState& aState)
 | 
			
		||||
{
 | 
			
		||||
  const uint32_t posesSize = ::vr::k_unTrackedDeviceIndex_Hmd + 1;
 | 
			
		||||
  ::vr::TrackedDevicePose_t poses[posesSize];
 | 
			
		||||
  // Note: We *must* call WaitGetPoses in order for any rendering to happen at all.
 | 
			
		||||
  mVRCompositor->WaitGetPoses(nullptr, 0, poses, posesSize);
 | 
			
		||||
  gfx::Matrix4x4 headToEyeTransforms[2];
 | 
			
		||||
  UpdateEyeParameters(state.displayState, headToEyeTransforms);
 | 
			
		||||
 | 
			
		||||
  ::vr::Compositor_FrameTiming timing;
 | 
			
		||||
  timing.m_nSize = sizeof(::vr::Compositor_FrameTiming);
 | 
			
		||||
  if (mVRCompositor->GetFrameTiming(&timing)) {
 | 
			
		||||
    state.sensorState.timestamp = timing.m_flSystemTimeInSeconds;
 | 
			
		||||
    aState.sensorState.timestamp = timing.m_flSystemTimeInSeconds;
 | 
			
		||||
  } else {
 | 
			
		||||
    // This should not happen, but log it just in case
 | 
			
		||||
    fprintf(stderr, "OpenVR - IVRCompositor::GetFrameTiming failed");
 | 
			
		||||
| 
						 | 
				
			
			@ -281,39 +356,411 @@ OpenVRSession::GetSensorState(VRSystemState& state)
 | 
			
		|||
    rot.SetFromRotationMatrix(m);
 | 
			
		||||
    rot.Invert();
 | 
			
		||||
 | 
			
		||||
    state.sensorState.flags = (VRDisplayCapabilityFlags)((int)state.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Orientation);
 | 
			
		||||
    state.sensorState.orientation[0] = rot.x;
 | 
			
		||||
    state.sensorState.orientation[1] = rot.y;
 | 
			
		||||
    state.sensorState.orientation[2] = rot.z;
 | 
			
		||||
    state.sensorState.orientation[3] = rot.w;
 | 
			
		||||
    state.sensorState.angularVelocity[0] = pose.vAngularVelocity.v[0];
 | 
			
		||||
    state.sensorState.angularVelocity[1] = pose.vAngularVelocity.v[1];
 | 
			
		||||
    state.sensorState.angularVelocity[2] = pose.vAngularVelocity.v[2];
 | 
			
		||||
    aState.sensorState.flags = (VRDisplayCapabilityFlags)((int)aState.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Orientation);
 | 
			
		||||
    aState.sensorState.pose.orientation[0] = rot.x;
 | 
			
		||||
    aState.sensorState.pose.orientation[1] = rot.y;
 | 
			
		||||
    aState.sensorState.pose.orientation[2] = rot.z;
 | 
			
		||||
    aState.sensorState.pose.orientation[3] = rot.w;
 | 
			
		||||
    aState.sensorState.pose.angularVelocity[0] = pose.vAngularVelocity.v[0];
 | 
			
		||||
    aState.sensorState.pose.angularVelocity[1] = pose.vAngularVelocity.v[1];
 | 
			
		||||
    aState.sensorState.pose.angularVelocity[2] = pose.vAngularVelocity.v[2];
 | 
			
		||||
 | 
			
		||||
    state.sensorState.flags =(VRDisplayCapabilityFlags)((int)state.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Position);
 | 
			
		||||
    state.sensorState.position[0] = m._41;
 | 
			
		||||
    state.sensorState.position[1] = m._42;
 | 
			
		||||
    state.sensorState.position[2] = m._43;
 | 
			
		||||
    state.sensorState.linearVelocity[0] = pose.vVelocity.v[0];
 | 
			
		||||
    state.sensorState.linearVelocity[1] = pose.vVelocity.v[1];
 | 
			
		||||
    state.sensorState.linearVelocity[2] = pose.vVelocity.v[2];
 | 
			
		||||
    aState.sensorState.flags =(VRDisplayCapabilityFlags)((int)aState.sensorState.flags | (int)VRDisplayCapabilityFlags::Cap_Position);
 | 
			
		||||
    aState.sensorState.pose.position[0] = m._41;
 | 
			
		||||
    aState.sensorState.pose.position[1] = m._42;
 | 
			
		||||
    aState.sensorState.pose.position[2] = m._43;
 | 
			
		||||
    aState.sensorState.pose.linearVelocity[0] = pose.vVelocity.v[0];
 | 
			
		||||
    aState.sensorState.pose.linearVelocity[1] = pose.vVelocity.v[1];
 | 
			
		||||
    aState.sensorState.pose.linearVelocity[2] = pose.vVelocity.v[2];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  state.sensorState.CalcViewMatrices(headToEyeTransforms);
 | 
			
		||||
  state.sensorState.inputFrameID++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
OpenVRSession::StartFrame(mozilla::gfx::VRSystemState& aSystemState)
 | 
			
		||||
{
 | 
			
		||||
  GetSensorState(aSystemState);
 | 
			
		||||
  GetControllerState(aSystemState);
 | 
			
		||||
  UpdateHeadsetPose(aSystemState);
 | 
			
		||||
  UpdateEyeParameters(aSystemState);
 | 
			
		||||
  EnumerateControllers(aSystemState);
 | 
			
		||||
  UpdateControllerButtons(aSystemState);
 | 
			
		||||
  UpdateControllerPoses(aSystemState);
 | 
			
		||||
  aSystemState.sensorState.inputFrameID++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,13 +42,17 @@ private:
 | 
			
		|||
  ::vr::IVRSystem* mVRSystem = nullptr;
 | 
			
		||||
  ::vr::IVRChaperone* mVRChaperone = nullptr;
 | 
			
		||||
  ::vr::IVRCompositor* mVRCompositor = nullptr;
 | 
			
		||||
  ::vr::TrackedDeviceIndex_t mControllerDeviceIndex[kVRControllerMaxCount];
 | 
			
		||||
  bool mShouldQuit;
 | 
			
		||||
  bool mIsWindowsMR;
 | 
			
		||||
 | 
			
		||||
  bool InitState(mozilla::gfx::VRSystemState& aSystemState);
 | 
			
		||||
  void UpdateStageParameters(mozilla::gfx::VRDisplayState& state);
 | 
			
		||||
  void UpdateEyeParameters(mozilla::gfx::VRDisplayState& state, gfx::Matrix4x4* headToEyeTransforms = nullptr);
 | 
			
		||||
  void GetSensorState(mozilla::gfx::VRSystemState& state);
 | 
			
		||||
  void GetControllerState(VRSystemState &state);
 | 
			
		||||
  void UpdateStageParameters(mozilla::gfx::VRDisplayState& aState);
 | 
			
		||||
  void UpdateEyeParameters(mozilla::gfx::VRSystemState& aState);
 | 
			
		||||
  void UpdateHeadsetPose(mozilla::gfx::VRSystemState& aState);
 | 
			
		||||
  void EnumerateControllers(VRSystemState& aState);
 | 
			
		||||
  void UpdateControllerPoses(VRSystemState& aState);
 | 
			
		||||
  void UpdateControllerButtons(VRSystemState& aState);
 | 
			
		||||
 | 
			
		||||
  bool SubmitFrame(void* aTextureHandle,
 | 
			
		||||
                   ::vr::ETextureType aTextureType,
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +61,9 @@ private:
 | 
			
		|||
#if defined(XP_WIN)
 | 
			
		||||
  bool CreateD3DObjects();
 | 
			
		||||
#endif
 | 
			
		||||
  void GetControllerDeviceId(::vr::ETrackedDeviceClass aDeviceType,
 | 
			
		||||
                             ::vr::TrackedDeviceIndex_t aDeviceIndex,
 | 
			
		||||
                             nsCString& aId);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace mozilla
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue