--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -116,32 +116,42 @@ static pfn_ovr_GetMirrorTextureBufferGL
#else
#define BUILD_BITS 32
#endif
#define OVR_PRODUCT_VERSION 1
#define OVR_MAJOR_VERSION 1
#define OVR_MINOR_VERSION 10
-static const ovrButton kOculusTouchLButton[] = {
- ovrButton_LThumb,
- ovrButton_X,
- ovrButton_Y
+enum class OculusLeftControllerButtonType : uint16_t {
+ LThumb,
+ IndexTrigger,
+ HandTrigger,
+ Button_X,
+ Button_Y,
+ LThumbRest,
+ NumButtonType
};
-static const ovrButton kOculusTouchRButton[] = {
- ovrButton_RThumb,
- ovrButton_A,
- ovrButton_B,
+enum class OculusRightControllerButtonType : uint16_t {
+ RThumb,
+ IndexTrigger,
+ HandTrigger,
+ Button_A,
+ Button_B,
+ RThumbRest,
+ NumButtonType
};
-static const uint32_t kNumOculusButton = sizeof(kOculusTouchLButton) /
- sizeof(ovrButton);
+static const uint32_t kNumOculusButton = static_cast<uint32_t>
+ (OculusLeftControllerButtonType::
+ NumButtonType);
static const uint32_t kNumOculusHaptcs = 0; // TODO: Bug 1305892
+
static bool
InitializeOculusCAPI()
{
static PRLibrary *ovrlib = nullptr;
if (!ovrlib) {
nsTArray<nsCString> libSearchPaths;
nsCString libName;
@@ -829,16 +839,18 @@ VRDisplayOculus::NotifyVSync()
{
ovrSessionStatus sessionStatus;
ovrResult ovr = ovr_GetSessionStatus(mSession, &sessionStatus);
mDisplayInfo.mIsConnected = (ovr == ovrSuccess && sessionStatus.HmdPresent);
}
VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand)
: VRControllerHost(VRDeviceType::Oculus)
+ , mIndexTrigger(0.0f)
+ , mHandTrigger(0.0f)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
char* touchID = "";
switch (aHand) {
case dom::GamepadHand::Left:
touchID = "Oculus Touch (Left)";
break;
@@ -847,16 +859,22 @@ VRControllerOculus::VRControllerOculus(d
break;
default:
MOZ_ASSERT(false);
break;
}
mControllerInfo.mControllerName = touchID;
mControllerInfo.mMappingType = GamepadMappingType::_empty;
mControllerInfo.mHand = aHand;
+
+ MOZ_ASSERT(kNumOculusButton ==
+ static_cast<uint32_t>(OculusLeftControllerButtonType::NumButtonType)
+ && kNumOculusButton ==
+ static_cast<uint32_t>(OculusRightControllerButtonType::NumButtonType));
+
mControllerInfo.mNumButtons = kNumOculusButton;
mControllerInfo.mNumAxes = static_cast<uint32_t>(
OculusControllerAxisType::NumVRControllerAxisType);;
}
float
VRControllerOculus::GetAxisMove(uint32_t aAxis)
{
@@ -864,16 +882,40 @@ VRControllerOculus::GetAxisMove(uint32_t
}
void
VRControllerOculus::SetAxisMove(uint32_t aAxis, float aValue)
{
mAxisMove[aAxis] = aValue;
}
+float
+VRControllerOculus::GetIndexTrigger()
+{
+ return mIndexTrigger;
+}
+
+void
+VRControllerOculus::SetIndexTrigger(float aValue)
+{
+ mIndexTrigger = aValue;
+}
+
+float
+VRControllerOculus::GetHandTrigger()
+{
+ return mHandTrigger;
+}
+
+void
+VRControllerOculus::SetHandTrigger(float aValue)
+{
+ mHandTrigger = aValue;
+}
+
VRControllerOculus::~VRControllerOculus()
{
MOZ_COUNT_DTOR_INHERITED(VRControllerOculus, VRControllerHost);
}
/*static*/ already_AddRefed<VRSystemManagerOculus>
VRSystemManagerOculus::Create()
{
@@ -968,44 +1010,75 @@ VRSystemManagerOculus::HandleInput()
// at GetHMDs().
if (!mSession) {
return;
}
RefPtr<impl::VRControllerOculus> controller;
ovrInputState inputState;
uint32_t axis = 0;
- bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
- &inputState) == ovrSuccess;
+ const bool hasInputState = ovr_GetInputState(mSession, ovrControllerType_Touch,
+ &inputState) == ovrSuccess;
if (!hasInputState) {
return;
}
for (uint32_t i = 0; i < mOculusController.Length(); ++i) {
controller = mOculusController[i];
- HandleButtonPress(i, inputState.Buttons);
+ const GamepadHand hand = controller->GetHand();
+ const uint32_t handIdx = static_cast<uint32_t>(hand) - 1;
+ uint32_t buttonIdx = 0;
- axis = static_cast<uint32_t>(OculusControllerAxisType::IndexTrigger);
- HandleAxisMove(i, axis, inputState.IndexTrigger[i]);
-
- axis = static_cast<uint32_t>(OculusControllerAxisType::HandTrigger);
- HandleAxisMove(i, axis, inputState.HandTrigger[i]);
+ switch (hand) {
+ case dom::GamepadHand::Left:
+ HandleButtonPress(i, buttonIdx, ovrButton_LThumb, inputState.Buttons);
+ ++buttonIdx;
+ HandleTriggerPress(i, buttonIdx, inputState.IndexTrigger[handIdx]);
+ ++buttonIdx;
+ HandleTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
+ ++buttonIdx;
+ HandleButtonPress(i, buttonIdx, ovrButton_X, inputState.Buttons);
+ ++buttonIdx;
+ HandleButtonPress(i, buttonIdx, ovrButton_Y, inputState.Buttons);
+ ++buttonIdx;
+ HandleTouchEvent(i, buttonIdx, ovrTouch_LThumbRest, inputState.Touches);
+ ++buttonIdx;
+ break;
+ case dom::GamepadHand::Right:
+ HandleButtonPress(i, buttonIdx, ovrButton_RThumb, inputState.Buttons);
+ ++buttonIdx;
+ HandleTriggerPress(i, buttonIdx, inputState.IndexTrigger[handIdx]);
+ ++buttonIdx;
+ HandleTriggerPress(i, buttonIdx, inputState.HandTrigger[handIdx]);
+ ++buttonIdx;
+ HandleButtonPress(i, buttonIdx, ovrButton_A, inputState.Buttons);
+ ++buttonIdx;
+ HandleButtonPress(i, buttonIdx, ovrButton_B, inputState.Buttons);
+ ++buttonIdx;
+ HandleTouchEvent(i, buttonIdx, ovrTouch_RThumbRest, inputState.Touches);
+ ++buttonIdx;
+ break;
+ default:
+ MOZ_ASSERT(false);
+ break;
+ }
+ controller->SetButtonPressed(inputState.Buttons);
axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickXAxis);
HandleAxisMove(i, axis, inputState.Thumbstick[i].x);
axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickYAxis);
HandleAxisMove(i, axis, -inputState.Thumbstick[i].y);
// Start to process pose
ovrTrackingState state = ovr_GetTrackingState(mSession, 0.0, false);
// HandPoses is ordered by ovrControllerType_LTouch and ovrControllerType_RTouch,
// therefore, we can't get its state by the index of mOculusController.
- const uint32_t handIdx = static_cast<uint32_t>(controller->GetHand()) - 1;
+
ovrPoseStatef& pose(state.HandPoses[handIdx]);
GamepadPoseState poseState;
if (state.HandStatusFlags[handIdx] & ovrStatus_OrientationTracked) {
poseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
poseState.orientation[0] = pose.ThePose.Orientation.x;
poseState.orientation[1] = pose.ThePose.Orientation.y;
poseState.orientation[2] = pose.ThePose.Orientation.z;
@@ -1034,45 +1107,67 @@ VRSystemManagerOculus::HandleInput()
poseState.linearAcceleration[2] = pose.LinearAcceleration.z;
}
HandlePoseTracking(i, poseState, controller);
}
}
void
VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
+ uint32_t aButton,
+ uint64_t aButtonMask,
uint64_t aButtonPressed)
{
- MOZ_ASSERT(sizeof(kOculusTouchLButton) / sizeof(ovrButton) ==
- sizeof(kOculusTouchRButton) / sizeof(ovrButton));
+ RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
+ MOZ_ASSERT(controller);
+ const uint64_t diff = (controller->GetButtonPressed() ^ aButtonPressed);
+ if (diff & aButtonMask) {
+ NewButtonEvent(aControllerIdx, aButton, aButtonMask & aButtonPressed,
+ (aButtonMask & aButtonPressed) ? 1.0L : 0.0L);
+ }
+}
+
+void
+VRSystemManagerOculus::HandleTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
+ float aValue)
+{
RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
MOZ_ASSERT(controller);
- GamepadHand hand = controller->GetHand();
- uint64_t diff = (controller->GetButtonPressed() ^ aButtonPressed);
- uint32_t buttonMask = 0;
+ const uint32_t indexTrigger = static_cast<const uint32_t>
+ (OculusLeftControllerButtonType::IndexTrigger);
+ const uint32_t handTrigger = static_cast<const uint32_t>
+ (OculusLeftControllerButtonType::HandTrigger);
+ float oldValue = 0.0f;
- for (uint32_t i = 0; i < kNumOculusButton; ++i) {
- switch (hand) {
- case dom::GamepadHand::Left:
- buttonMask = kOculusTouchLButton[i];
- break;
- case dom::GamepadHand::Right:
- buttonMask = kOculusTouchRButton[i];
- break;
- default:
- MOZ_ASSERT(false);
- break;
+ // Avoid sending duplicated events in IPC channels.
+ if (aButton == indexTrigger) {
+ oldValue = controller->GetIndexTrigger();
+ if (oldValue == aValue) {
+ return;
}
- if (diff & buttonMask) {
- NewButtonEvent(aControllerIdx, i, diff & aButtonPressed);
+ controller->SetIndexTrigger(aValue);
+ } else if (aButton == handTrigger) {
+ oldValue = controller->GetHandTrigger();
+ if (oldValue == aValue) {
+ return;
}
+ controller->SetHandTrigger(aValue);
+ } else {
+ MOZ_ASSERT(false, "We only support indexTrigger and handTrigger in Oculus.");
}
- controller->SetButtonPressed(aButtonPressed);
+ NewButtonEvent(aControllerIdx, aButton, aValue > 0.1f, aValue);
+}
+
+void
+VRSystemManagerOculus::HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
+ uint64_t aTouchMask, uint64_t aTouched)
+{
+ // TODO: Bug 1336003
}
void
VRSystemManagerOculus::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
float aValue)
{
RefPtr<impl::VRControllerOculus> controller(mOculusController[aControllerIdx]);
MOZ_ASSERT(controller);
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -25,18 +25,16 @@ struct VertexShaderConstants;
struct PixelShaderConstants;
}
namespace gfx {
namespace impl {
enum class OculusControllerAxisType : uint16_t {
ThumbstickXAxis,
ThumbstickYAxis,
- IndexTrigger,
- HandTrigger,
NumVRControllerAxisType
};
class VRDisplayOculus : public VRDisplayHost
{
public:
virtual void NotifyVSync() override;
virtual VRHMDSensorState GetSensorState() override;
@@ -95,21 +93,29 @@ protected:
};
class VRControllerOculus : public VRControllerHost
{
public:
explicit VRControllerOculus(dom::GamepadHand aHand);
float GetAxisMove(uint32_t aAxis);
void SetAxisMove(uint32_t aAxis, float aValue);
+ float GetIndexTrigger();
+ void SetIndexTrigger(float aValue);
+ float GetHandTrigger();
+ void SetHandTrigger(float aValue);
protected:
virtual ~VRControllerOculus();
+
+private:
float mAxisMove[static_cast<uint32_t>(
OculusControllerAxisType::NumVRControllerAxisType)];
+ float mIndexTrigger;
+ float mHandTrigger;
};
} // namespace impl
class VRSystemManagerOculus : public VRSystemManager
{
public:
static already_AddRefed<VRSystemManagerOculus> Create();
@@ -123,23 +129,29 @@ public:
virtual void RemoveControllers() override;
protected:
VRSystemManagerOculus()
: mSession(nullptr), mOculusInitialized(false)
{ }
private:
- virtual void HandleButtonPress(uint32_t aControllerIdx,
- uint64_t aButtonPressed) override;
- virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
- float aValue) override;
- virtual void HandlePoseTracking(uint32_t aControllerIdx,
- const dom::GamepadPoseState& aPose,
- VRControllerHost* aController) override;
+ void HandleButtonPress(uint32_t aControllerIdx,
+ uint32_t aButton,
+ uint64_t aButtonMask,
+ uint64_t aButtonPressed);
+ void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
+ float aValue);
+ void HandlePoseTracking(uint32_t aControllerIdx,
+ const dom::GamepadPoseState& aPose,
+ VRControllerHost* aController);
+ void HandleTriggerPress(uint32_t aControllerIdx, uint32_t aButton,
+ float aValue);
+ void HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
+ uint64_t aTouchMask, uint64_t aTouched);
RefPtr<impl::VRDisplayOculus> mHMDInfo;
nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
RefPtr<nsIThread> mOculusThread;
ovrSession mSession;
bool mOculusInitialized;
};