diff --git a/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/SessionUtils.java b/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/SessionUtils.java index 62694a5eb..ac8ccfad1 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/SessionUtils.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/browser/engine/SessionUtils.java @@ -30,6 +30,7 @@ public static void vrPrefsWorkAround(Context aContext, Bundle aExtras) { Log.i(LOGTAG, "Creating file: " + prefFileName); try (FileOutputStream out = new FileOutputStream(prefFileName)) { out.write("pref(\"dom.vr.enabled\", true);\n".getBytes()); + out.write("pref(\"dom.vr.webxr.enabled\", true);\n".getBytes()); out.write("pref(\"dom.vr.external.enabled\", true);\n".getBytes()); out.write("pref(\"webgl.enable-surface-texture\", true);\n".getBytes()); // Enable MultiView draft extension diff --git a/app/src/main/cpp/BrowserWorld.cpp b/app/src/main/cpp/BrowserWorld.cpp index 52e239615..f40a8e2bb 100644 --- a/app/src/main/cpp/BrowserWorld.cpp +++ b/app/src/main/cpp/BrowserWorld.cpp @@ -873,6 +873,9 @@ BrowserWorld::Draw() { m.externalVR->PullBrowserState(); m.externalVR->SetHapticState(m.controllers); + const uint64_t frameId = m.externalVR->GetFrameId(); + m.controllers->SetFrameId(frameId); + m.CheckExitImmersive(); if (m.splashAnimation) { DrawSplashAnimation(); diff --git a/app/src/main/cpp/Controller.cpp b/app/src/main/cpp/Controller.cpp index a5fb2dff7..6acee58cc 100644 --- a/app/src/main/cpp/Controller.cpp +++ b/app/src/main/cpp/Controller.cpp @@ -65,6 +65,11 @@ Controller::operator=(const Controller& aController) { leftHanded = aController.leftHanded; inDeadZone = aController.inDeadZone; lastHoverEvent = aController.lastHoverEvent; + profile = aController.profile; + selectActionStartFrameId = aController.selectActionStartFrameId; + selectActionStartFrameId = aController.selectActionStopFrameId; + squeezeActionStartFrameId = aController.squeezeActionStartFrameId; + squeezeActionStopFrameId = aController.squeezeActionStopFrameId; return *this; } @@ -102,6 +107,10 @@ Controller::Reset() { leftHanded = false; inDeadZone = true; lastHoverEvent = 0.0; + selectActionStartFrameId = 0; + selectActionStopFrameId = 0; + squeezeActionStartFrameId = 0; + squeezeActionStopFrameId = 0; } vrb::Vector Controller::StartPoint() const { diff --git a/app/src/main/cpp/Controller.h b/app/src/main/cpp/Controller.h index c311fa333..44a890b56 100644 --- a/app/src/main/cpp/Controller.h +++ b/app/src/main/cpp/Controller.h @@ -10,6 +10,7 @@ #include "Device.h" #include "vrb/Forward.h" #include "vrb/Matrix.h" +#include "moz_external_vr.h" namespace crow { @@ -61,6 +62,12 @@ struct Controller { double lastHoverEvent; device::CapabilityFlags deviceCapabilities; + std::string profile; + uint64_t selectActionStartFrameId; + uint64_t selectActionStopFrameId; + uint64_t squeezeActionStartFrameId; + uint64_t squeezeActionStopFrameId; + vrb::Vector StartPoint() const; vrb::Vector Direction() const; diff --git a/app/src/main/cpp/ControllerContainer.cpp b/app/src/main/cpp/ControllerContainer.cpp index 9b022a8f5..f438383dc 100644 --- a/app/src/main/cpp/ControllerContainer.cpp +++ b/app/src/main/cpp/ControllerContainer.cpp @@ -32,12 +32,16 @@ struct ControllerContainer::State { GeometryPtr beamModel; bool visible = false; vrb::Color pointerColor; + uint64_t immersiveFrameId; + uint64_t lastImmersiveFrameId; void Initialize(vrb::CreationContextPtr& aContext) { context = aContext; root = Toggle::Create(aContext); visible = true; pointerColor = vrb::Color(1.0f, 1.0f, 1.0f, 1.0f); + immersiveFrameId = 0; + lastImmersiveFrameId = 0; } bool Contains(const int32_t aControllerIndex) { @@ -380,6 +384,63 @@ ControllerContainer::GetHapticFeedback(const int32_t aControllerIndex, uint64_t aPulseIntensity = m.list[aControllerIndex].pulseIntensity; } +void +ControllerContainer::SetProfile(const int32_t aControllerIndex, const std::string& aProfile) { + if (!m.Contains(aControllerIndex)) { + return; + } + + m.list[aControllerIndex].profile = aProfile; +} + +void +ControllerContainer::SetSelectActionStart(const int32_t aControllerIndex) { + if (!m.Contains(aControllerIndex) || !m.immersiveFrameId) { + return; + } + + if (m.list[aControllerIndex].selectActionStopFrameId >= + m.list[aControllerIndex].selectActionStartFrameId) { + m.list[aControllerIndex].selectActionStartFrameId = m.immersiveFrameId; + } +} + +void +ControllerContainer::SetSelectActionStop(const int32_t aControllerIndex) { + if (!m.Contains(aControllerIndex) || !m.lastImmersiveFrameId) { + return; + } + + if (m.list[aControllerIndex].selectActionStartFrameId > + m.list[aControllerIndex].selectActionStopFrameId) { + m.list[aControllerIndex].selectActionStopFrameId = m.lastImmersiveFrameId; + } +} + +void +ControllerContainer::SetSqueezeActionStart(const int32_t aControllerIndex) { + if (!m.Contains(aControllerIndex) || !m.immersiveFrameId) { + return; + } + + if (m.list[aControllerIndex].squeezeActionStopFrameId >= + m.list[aControllerIndex].squeezeActionStartFrameId) { + m.list[aControllerIndex].squeezeActionStartFrameId = m.immersiveFrameId; + } +} + +void +ControllerContainer::SetSqueezeActionStop(const int32_t aControllerIndex) { + if (!m.Contains(aControllerIndex) || !m.lastImmersiveFrameId) { + return; + } + + if (m.list[aControllerIndex].squeezeActionStartFrameId > + m.list[aControllerIndex].squeezeActionStopFrameId) { + m.list[aControllerIndex].squeezeActionStopFrameId = m.lastImmersiveFrameId; + } +} + void ControllerContainer::SetLeftHanded(const int32_t aControllerIndex, const bool aLeftHanded) { if (!m.Contains(aControllerIndex)) { @@ -442,6 +503,16 @@ ControllerContainer::SetVisible(const bool aVisible) { } } +void +ControllerContainer::SetFrameId(const uint64_t aFrameId) { + if (m.immersiveFrameId) { + m.lastImmersiveFrameId = aFrameId ? aFrameId : m.immersiveFrameId; + } else { + m.lastImmersiveFrameId = 0; + } + m.immersiveFrameId = aFrameId; +} + ControllerContainer::ControllerContainer(State& aState, vrb::CreationContextPtr& aContext) : m(aState) { m.Initialize(aContext); } diff --git a/app/src/main/cpp/ControllerContainer.h b/app/src/main/cpp/ControllerContainer.h index c821e3471..4fb6698a0 100644 --- a/app/src/main/cpp/ControllerContainer.h +++ b/app/src/main/cpp/ControllerContainer.h @@ -47,12 +47,18 @@ class ControllerContainer : public crow::ControllerDelegate { uint32_t GetHapticCount(const int32_t aControllerIndex) override; void SetHapticFeedback(const int32_t aControllerIndex, const uint64_t aInputFrameID, const float aPulseDuration, const float aPulseIntensity) override; void GetHapticFeedback(const int32_t aControllerIndex, uint64_t &aInputFrameID, float& aPulseDuration, float& aPulseIntensity) override; + void SetProfile(const int32_t aControllerIndex, const std::string& aProfile) override; + void SetSelectActionStart(const int32_t aControllerIndex) override; + void SetSelectActionStop(const int32_t aControllerIndex) override; + void SetSqueezeActionStart(const int32_t aControllerIndex) override; + void SetSqueezeActionStop(const int32_t aControllerIndex) override; void SetLeftHanded(const int32_t aControllerIndex, const bool aLeftHanded) override; void SetTouchPosition(const int32_t aControllerIndex, const float aTouchX, const float aTouchY) override; void EndTouch(const int32_t aControllerIndex) override; void SetScrolledDelta(const int32_t aControllerIndex, const float aScrollDeltaX, const float aScrollDeltaY) override; void SetPointerColor(const vrb::Color& color) const; void SetVisible(const bool aVisible); + void SetFrameId(const uint64_t aFrameId); protected: struct State; ControllerContainer(State& aState, vrb::CreationContextPtr& aContext); diff --git a/app/src/main/cpp/ControllerDelegate.h b/app/src/main/cpp/ControllerDelegate.h index 0e1243b04..3b474b75c 100644 --- a/app/src/main/cpp/ControllerDelegate.h +++ b/app/src/main/cpp/ControllerDelegate.h @@ -12,6 +12,7 @@ #include "GestureDelegate.h" #include +#include namespace crow { @@ -46,6 +47,11 @@ class ControllerDelegate { virtual uint32_t GetHapticCount(const int32_t aControllerIndex) = 0; virtual void SetHapticFeedback(const int32_t aControllerIndex, const uint64_t aInputFrameID, const float aPulseDuration, const float aPulseIntensity) = 0; virtual void GetHapticFeedback(const int32_t aControllerIndex, uint64_t & aInputFrameID, float& aPulseDuration, float& aPulseIntensity) = 0; + virtual void SetProfile(const int32_t aControllerIndex, const std::string& aProfile) = 0; + virtual void SetSelectActionStart(const int32_t aControllerIndex) = 0; + virtual void SetSelectActionStop(const int32_t aControllerIndex) = 0; + virtual void SetSqueezeActionStart(const int32_t aControllerIndex) = 0; + virtual void SetSqueezeActionStop(const int32_t aControllerIndex) = 0; virtual void SetLeftHanded(const int32_t aControllerIndex, const bool aLeftHanded) = 0; virtual void SetTouchPosition(const int32_t aControllerIndex, const float aTouchX, const float aTouchY) = 0; virtual void EndTouch(const int32_t aControllerIndex) = 0; diff --git a/app/src/main/cpp/ExternalVR.cpp b/app/src/main/cpp/ExternalVR.cpp index 55172c9e8..06fe018a9 100644 --- a/app/src/main/cpp/ExternalVR.cpp +++ b/app/src/main/cpp/ExternalVR.cpp @@ -317,6 +317,11 @@ ExternalVR::SetSourceBrowser(VRBrowserType aBrowser) { m.SetSourceBrowser(aBrowser); } +uint64_t +ExternalVR::GetFrameId() const { + return m.lastFrameId; +} + void ExternalVR::SetCompositorEnabled(bool aEnabled) { if (aEnabled == m.compositorEnabled) { @@ -431,6 +436,17 @@ ExternalVR::PushFramePoses(const vrb::Matrix& aHeadTransform, const std::vector< vrb::Vector position(controller.transformMatrix.GetTranslation()); memcpy(&(immersiveController.pose.position), position.Data(), sizeof(immersiveController.pose.position)); } + + immersiveController.targetRayMode = mozilla::gfx::TargetRayMode::TrackedPointer; + immersiveController.mappingType = mozilla::gfx::GamepadMappingType ::XRStandard; + if (controller.profile.size() > mozilla::gfx::kProfileNameListMaxLen) { + VRB_ERROR("controller profile size is over than kProfileNameListMaxLen."); + } + memcpy(&immersiveController.profiles, controller.profile.data(), mozilla::gfx::kProfileNameListMaxLen); + immersiveController.selectActionStartFrameId = controller.selectActionStartFrameId; + immersiveController.selectActionStopFrameId = controller.selectActionStopFrameId; + immersiveController.squeezeActionStartFrameId = controller.squeezeActionStartFrameId; + immersiveController.squeezeActionStopFrameId = controller.squeezeActionStopFrameId; } m.system.sensorState.timestamp = aTimestamp; diff --git a/app/src/main/cpp/ExternalVR.h b/app/src/main/cpp/ExternalVR.h index 079df2df6..d099d9398 100644 --- a/app/src/main/cpp/ExternalVR.h +++ b/app/src/main/cpp/ExternalVR.h @@ -63,6 +63,7 @@ class ExternalVR : public ImmersiveDisplay { void SetHapticState(ControllerContainerPtr aControllerContainer) const; void StopPresenting(); void SetSourceBrowser(VRBrowserType aBrowser); + uint64_t GetFrameId() const; ExternalVR(); ~ExternalVR() = default; protected: diff --git a/app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp b/app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp index a2ee3f6b5..6ddc105e3 100644 --- a/app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp +++ b/app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp @@ -955,12 +955,14 @@ struct DeviceDelegateOculusVR::State { controllerName, beamTransform); controller->SetButtonCount(controllerState.index, 6); controller->SetHapticCount(controllerState.index, 1); + controller->SetProfile(controllerState.index, "oculus-touch-v2"); } else { // Oculus Go only has one kind of controller model. controller->CreateController(controllerState.index, 0, "Oculus Go Controller"); controller->SetButtonCount(controllerState.index, 2); // Oculus Go has no haptic feedback. controller->SetHapticCount(controllerState.index, 0); + controller->SetProfile(controllerState.index, "oculus-go"); } controllerState.created = true; } @@ -1069,6 +1071,16 @@ struct DeviceDelegateOculusVR::State { // This is always false in Oculus Browser. const bool thumbRest = false; controller->SetButtonState(controllerState.index, ControllerDelegate::BUTTON_OTHERS, 5, thumbRest, thumbRest); + + if (gripPressed) { + if (renderMode == device::RenderMode::Immersive) { + controller->SetSqueezeActionStart(controllerState.index); + } else { + controller->SetSqueezeActionStop(controllerState.index); + } + } else { + controller->SetSqueezeActionStop(controllerState.index); + } } else { triggerPressed = (controllerState.inputState.Buttons & ovrButton_A) != 0; triggerTouched = triggerPressed; @@ -1098,6 +1110,17 @@ struct DeviceDelegateOculusVR::State { controller->SetButtonState(controllerState.index, ControllerDelegate::BUTTON_TOUCHPAD, 0, trackpadPressed, trackpadTouched); controller->SetAxes(controllerState.index, axes, kNumAxes); + + if (triggerPressed) { + if (renderMode == device::RenderMode::Immersive) { + controller->SetSelectActionStart(controllerState.index); + } + else { + controller->SetSelectActionStop(controllerState.index); + } + } else { + controller->SetSelectActionStop(controllerState.index); + } if (controller->GetHapticCount(controllerState.index)) { UpdateHaptics(controllerState); }