Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
WebXR gamepad module support. (#2521)
Browse files Browse the repository at this point in the history
* Making OculusVR support WebXR gamepad.

* Making WaveVR support WebXR gamepad.

* Making PicoVR support WebXR gamepad.

* Add squeeze btn state for app usage.

* Bump GV to 77.0.20200418094905.

* Fix Pico G2 standing matrix

* Fixes 3DOF controller positionEmulated.

* Apply elbow transform for Pico G2 immersive mode

* Prevent select and squeeze actions to be triggered when clicking on the WebXR interstitial

* Bump GV to 77.0.20200422093542

Co-authored-by: Imanol Fernandez <[email protected]>
  • Loading branch information
daoshengmu and MortimerGoro authored Apr 22, 2020
1 parent d3f3c9b commit cdc8f1e
Show file tree
Hide file tree
Showing 15 changed files with 454 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public static void vrPrefsWorkAround(Context aContext, Bundle aExtras) {
try (FileOutputStream out = new FileOutputStream(prefFileName)) {
out.write("pref(\"dom.vr.enabled\", true);\n".getBytes());
out.write("pref(\"dom.vr.external.enabled\", true);\n".getBytes());
out.write("pref(\"dom.vr.webxr.enabled\", true);\n".getBytes());
out.write("pref(\"webgl.enable-surface-texture\", true);\n".getBytes());
// Enable MultiView draft extension
out.write("pref(\"webgl.enable-draft-extensions\", true);\n".getBytes());
Expand Down
9 changes: 8 additions & 1 deletion app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ BrowserWorld::State::CheckBackButton() {
VRBrowser::HandleBack();
webXRInterstialState = WebXRInterstialState::HIDDEN;
} else if (webXRInterstialState == WebXRInterstialState::ALLOW_DISMISS
&& controller.lastButtonState == 0 && controller.buttonState) {
&& controller.lastButtonState && controller.buttonState == 0) {
VRBrowser::OnDismissWebXRInterstitial();
webXRInterstialState = WebXRInterstialState::HIDDEN;
}
Expand Down Expand Up @@ -582,6 +582,10 @@ BrowserWorld::State::ClearWebXRControllerData() {
};
controller.immersiveTouchedState = 0;
controller.immersivePressedState = 0;
controller.selectActionStartFrameId = 0;
controller.selectActionStopFrameId = 0;
controller.squeezeActionStartFrameId = 0;
controller.squeezeActionStopFrameId = 0;
for (int i = 0; i < controller.numAxes; ++i) {
controller.immersiveAxes[i] = 0;
}
Expand Down Expand Up @@ -949,6 +953,9 @@ BrowserWorld::StartFrame() {
m.context->Update();
m.externalVR->PullBrowserState();
m.externalVR->SetHapticState(m.controllers);

const uint64_t frameId = m.externalVR->GetFrameId();
m.controllers->SetFrameId(frameId);
m.CheckExitImmersive();

if (m.splashAnimation) {
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/cpp/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Controller::operator=(const Controller& aController) {
pointer = aController.pointer;
transformMatrix = aController.transformMatrix;
beamTransformMatrix = aController.beamTransformMatrix;
immersiveBeamTransform = aController.immersiveBeamTransform;
immersiveName = aController.immersiveName;
immersivePressedState = aController.immersivePressedState;
immersiveTouchedState = aController.immersiveTouchedState;
Expand All @@ -65,6 +66,13 @@ Controller::operator=(const Controller& aController) {
leftHanded = aController.leftHanded;
inDeadZone = aController.inDeadZone;
lastHoverEvent = aController.lastHoverEvent;
profile = aController.profile;
type = aController.type;
targetRayMode = aController.targetRayMode;
selectActionStartFrameId = aController.selectActionStartFrameId;
selectActionStopFrameId = aController.selectActionStopFrameId;
squeezeActionStartFrameId = aController.squeezeActionStartFrameId;
squeezeActionStopFrameId = aController.squeezeActionStopFrameId;
return *this;
}

Expand All @@ -88,6 +96,7 @@ Controller::Reset() {
pointer = nullptr;
transformMatrix = Matrix::Identity();
beamTransformMatrix = Matrix::Identity();
immersiveBeamTransform = Matrix::Identity();
immersiveName.clear();
immersivePressedState = 0;
immersiveTouchedState = 0;
Expand All @@ -102,6 +111,12 @@ Controller::Reset() {
leftHanded = false;
inDeadZone = true;
lastHoverEvent = 0.0;
type = device::UnknownType;
targetRayMode = device::TargetRayMode::TrackedPointer;
selectActionStartFrameId = 0;
selectActionStopFrameId = 0;
squeezeActionStartFrameId = 0;
squeezeActionStopFrameId = 0;
}

vrb::Vector Controller::StartPoint() const {
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/cpp/Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace crow {
class Pointer;
typedef std::shared_ptr<Pointer> PointerPtr;

static const int kControllerMaxButtonCount = 6;
static const int kControllerMaxButtonCount = 7;
static const int kControllerMaxAxes = 6;

struct Controller {
Expand Down Expand Up @@ -44,6 +44,7 @@ struct Controller {
PointerPtr pointer;
vrb::Matrix transformMatrix;
vrb::Matrix beamTransformMatrix;
vrb::Matrix immersiveBeamTransform;
std::string immersiveName;
uint64_t immersivePressedState;
uint64_t immersiveTouchedState;
Expand All @@ -52,6 +53,8 @@ struct Controller {
float immersiveAxes[kControllerMaxAxes];
uint32_t numAxes;
uint32_t numHaptics;
device::DeviceType type;
device::TargetRayMode targetRayMode;
float inputFrameID;
float pulseDuration;
float pulseIntensity;
Expand All @@ -61,6 +64,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;

Expand Down
90 changes: 90 additions & 0 deletions app/src/main/cpp/ControllerContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ struct ControllerContainer::State {
bool visible = false;
vrb::Color pointerColor;
int gazeIndex = -1;
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) {
Expand Down Expand Up @@ -194,6 +198,7 @@ ControllerContainer::CreateController(const int32_t aControllerIndex, const int3
controller.index = aControllerIndex;
controller.immersiveName = aImmersiveName;
controller.beamTransformMatrix = aBeamTransform;
controller.immersiveBeamTransform = aBeamTransform;
if (aModelIndex < 0) {
return;
}
Expand Down Expand Up @@ -234,6 +239,15 @@ ControllerContainer::CreateController(const int32_t aControllerIndex, const int3
m.updatePointerColor(controller);
}

void
ControllerContainer::SetImmersiveBeamTransform(const int32_t aControllerIndex,
const vrb::Matrix& aImmersiveBeamTransform) {
if (!m.Contains(aControllerIndex)) {
return;
}
m.list[aControllerIndex].immersiveBeamTransform = aImmersiveBeamTransform;
}

void
ControllerContainer::SetFocused(const int32_t aControllerIndex) {
if (!m.Contains(aControllerIndex)) {
Expand Down Expand Up @@ -287,6 +301,24 @@ ControllerContainer::SetVisible(const int32_t aControllerIndex, const bool aVisi
}
}

void
ControllerContainer::SetControllerType(const int32_t aControllerIndex, device::DeviceType aType) {
if (!m.Contains(aControllerIndex)) {
return;
}
Controller& controller = m.list[aControllerIndex];
controller.type = aType;
}

void
ControllerContainer::SetTargetRayMode(const int32_t aControllerIndex, device::TargetRayMode aMode) {
if (!m.Contains(aControllerIndex)) {
return;
}
Controller& controller = m.list[aControllerIndex];
controller.targetRayMode = aMode;
}

void
ControllerContainer::SetTransform(const int32_t aControllerIndex, const vrb::Matrix& aTransform) {
if (!m.Contains(aControllerIndex)) {
Expand Down Expand Up @@ -399,6 +431,54 @@ ControllerContainer::GetHapticFeedback(const int32_t aControllerIndex, uint64_t
aPulseIntensity = m.list[aControllerIndex].pulseIntensity;
}

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)) {
Expand Down Expand Up @@ -466,6 +546,16 @@ void ControllerContainer::SetGazeModeIndex(const int32_t aControllerIndex) {
m.gazeIndex = aControllerIndex;
}

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);
}
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/cpp/ControllerContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ class ControllerContainer : public crow::ControllerDelegate {
uint32_t GetControllerCount() override;
void CreateController(const int32_t aControllerIndex, const int32_t aModelIndex, const std::string& aImmersiveName) override;
void CreateController(const int32_t aControllerIndex, const int32_t aModelIndex, const std::string& aImmersiveName, const vrb::Matrix& aBeamTransform) override;
void SetImmersiveBeamTransform(const int32_t aControllerIndex, const vrb::Matrix& aImmersiveBeamTransform) override;
void SetFocused(const int32_t aControllerIndex) override;
void DestroyController(const int32_t aControllerIndex) override;
void SetCapabilityFlags(const int32_t aControllerIndex, const device::CapabilityFlags aFlags) override;
void SetEnabled(const int32_t aControllerIndex, const bool aEnabled) override;
void SetVisible(const int32_t aControllerIndex, const bool aVisible) override;
void SetControllerType(const int32_t aControllerIndex, device::DeviceType aType) override;
void SetTargetRayMode(const int32_t aControllerIndex, device::TargetRayMode aMode) override;
void SetTransform(const int32_t aControllerIndex, const vrb::Matrix& aTransform) override;
void SetButtonCount(const int32_t aControllerIndex, const uint32_t aNumButtons) override;
void SetButtonState(const int32_t aControllerIndex, const Button aWhichButton, const int32_t aImmersiveIndex, const bool aPressed, const bool aTouched, const float aImmersiveTrigger = -1.0f) override;
Expand All @@ -48,13 +51,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 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 SetGazeModeIndex(const int32_t aControllerIndex) override;
void SetFrameId(const uint64_t aFrameId);
protected:
struct State;
ControllerContainer(State& aState, vrb::CreationContextPtr& aContext);
Expand Down
23 changes: 16 additions & 7 deletions app/src/main/cpp/ControllerDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "GestureDelegate.h"

#include <memory>
#include <string>

namespace crow {

Expand All @@ -22,23 +23,27 @@ class ControllerDelegate {
public:
enum Button {
BUTTON_TRIGGER = 1u << 0u,
BUTTON_TOUCHPAD = 1u << 1u,
BUTTON_APP = 1u << 2u,
BUTTON_A = 1u << 3u,
BUTTON_B = 1u << 4u,
BUTTON_X = 1u << 5u,
BUTTON_Y = 1u << 6u,
BUTTON_OTHERS = 1u << 7u, // Other buttons only for the immersive mode.
BUTTON_SQUEEZE = 1u << 1u,
BUTTON_TOUCHPAD = 1u << 2u,
BUTTON_APP = 1u << 3u,
BUTTON_A = 1u << 4u,
BUTTON_B = 1u << 5u,
BUTTON_X = 1u << 6u,
BUTTON_Y = 1u << 7u,
BUTTON_OTHERS = 1u << 8u, // Other buttons only for the immersive mode.
};

virtual void CreateController(const int32_t aControllerIndex, const int32_t aModelIndex, const std::string& aImmersiveName) = 0;
virtual void CreateController(const int32_t aControllerIndex, const int32_t aModelIndex, const std::string& aImmersiveName, const vrb::Matrix& aBeamTransform) = 0;
virtual void SetImmersiveBeamTransform(const int32_t aControllerIndex, const vrb::Matrix& aImmersiveBeamTransform) = 0;
virtual void SetFocused(const int32_t aControllerIndex) = 0;
virtual void DestroyController(const int32_t aControllerIndex) = 0;
virtual uint32_t GetControllerCount() = 0;
virtual void SetCapabilityFlags(const int32_t aControllerIndex, const device::CapabilityFlags aFlags) = 0;
virtual void SetEnabled(const int32_t aControllerIndex, const bool aEnabled) = 0;
virtual void SetVisible(const int32_t aControllerIndex, const bool aVisible) = 0;
virtual void SetControllerType(const int32_t aControllerIndex, device::DeviceType aType) = 0;
virtual void SetTargetRayMode(const int32_t aControllerIndex, device::TargetRayMode aMode) = 0;
virtual void SetTransform(const int32_t aControllerIndex, const vrb::Matrix& aTransform) = 0;
virtual void SetButtonCount(const int32_t aControllerIndex, const uint32_t aNumButtons) = 0;
virtual void SetButtonState(const int32_t aControllerIndex, const Button aWhichButton, const int32_t aImmersiveIndex, const bool aPressed, const bool aTouched, const float aImmersiveTrigger = -1.0f) = 0;
Expand All @@ -47,6 +52,10 @@ 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 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;
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/cpp/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const CapabilityFlags PositionEmulated = 1u << 9u;
const CapabilityFlags InlineSession = 1u << 10u;
const CapabilityFlags ImmersiveVRSession = 1u << 11u;
const CapabilityFlags ImmersiveARSession = 1u << 12u;
const CapabilityFlags GripSpacePosition = 1u << 13u;
enum class Eye { Left, Right };
enum class RenderMode { StandAlone, Immersive };
enum class CPULevel { Normal = 0, High };
Expand All @@ -32,6 +33,31 @@ typedef int32_t DeviceType;
const DeviceType UnknownType = 0;
const DeviceType OculusGo = 1;
const DeviceType OculusQuest = 2;
const DeviceType ViveFocus = 3;
const DeviceType ViveFocusPlus = 4;
const DeviceType PicoGaze = 5;
const DeviceType PicoNeo2 = 6;
const DeviceType PicoG2 = 7;

enum class TargetRayMode : uint8_t { Gaze, TrackedPointer, Screen };

// Placeholder buttons for WebXR
// https://www.w3.org/TR/webxr-gamepads-module-1/#xr-standard-gamepad-mapping
const uint8_t kImmersiveButtonTrigger = 0;
const uint8_t kImmersiveButtonSqueeze = 1;
const uint8_t kImmersiveButtonTouchpad = 2;
const uint8_t kImmersiveButtonThumbstick = 3;
const uint8_t kImmersiveButtonA = 4;
const uint8_t kImmersiveButtonB = 5;
const uint8_t kImmersiveButtonThumbrest = 6;

// Placeholder axes for WebXR
// https://www.w3.org/TR/webxr-gamepads-module-1/#xr-standard-gamepad-mapping
const uint8_t kImmersiveAxisTouchpadX = 0;
const uint8_t kImmersiveAxisTouchpadY = 1;
const uint8_t kImmersiveAxisThumbstickX = 2;
const uint8_t kImmersiveAxisThumbstickY = 3;

struct EyeRect {
float mX, mY;
float mWidth, mHeight;
Expand Down
Loading

0 comments on commit cdc8f1e

Please sign in to comment.