Skip to content

Commit

Permalink
Oculus VR multiple controllers support (#886)
Browse files Browse the repository at this point in the history
* Add new controller models to the asset folder.

* Adjust VRLayer projection matrix as Oculus samples.

* Add controller capability flag for 6DOF.

* Support multiple controllers in Oculus.

* Add Oculus Touch controller btn mapping for immersive web.
  • Loading branch information
daoshengmu authored and MortimerGoro committed Jan 18, 2019
1 parent 6e5bb72 commit 0afae0d
Show file tree
Hide file tree
Showing 16 changed files with 16,284 additions and 112 deletions.
1 change: 1 addition & 0 deletions app/src/googlevr/cpp/DeviceDelegateGoogleVR.cpp
Expand Up @@ -280,6 +280,7 @@ struct DeviceDelegateGoogleVR::State {
controller.enabled = true;
controllerDelegate->SetEnabled(index, true);
controllerDelegate->SetVisible(index, true);
controllerDelegate->SetCapabilityFlags(index, device::Orientation);
}

recentered = recentered || gvr_controller_state_get_recentered(controllerState);
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/cpp/Controller.h
Expand Up @@ -7,6 +7,7 @@
#define VRBROWSER_CONTROLLER_H

#include "ControllerDelegate.h"
#include "Device.h"
#include "vrb/Forward.h"
#include "vrb/Matrix.h"

Expand All @@ -15,7 +16,7 @@ namespace crow {
class Pointer;
typedef std::shared_ptr<Pointer> PointerPtr;

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

struct Controller {
Expand Down Expand Up @@ -47,6 +48,7 @@ struct Controller {
bool leftHanded;
bool inDeadZone;
double lastHoverEvent;
device::CapabilityFlags deviceCapabilities;

Controller();
Controller(const Controller& aController);
Expand Down
22 changes: 20 additions & 2 deletions app/src/main/cpp/ControllerContainer.cpp
Expand Up @@ -3,6 +3,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <assert.h>
#include "ControllerContainer.h"
#include "Controller.h"
#include "Pointer.h"
Expand Down Expand Up @@ -60,13 +61,11 @@ ControllerContainer::Create(vrb::CreationContextPtr& aContext, const vrb::GroupP
return result;
}


TogglePtr
ControllerContainer::GetRoot() const {
return m.root;
}


void
ControllerContainer::LoadControllerModel(const int32_t aModelIndex, const ModelLoaderAndroidPtr& aLoader, const std::string& aFileName) {
m.SetUpModelsGroup(aModelIndex);
Expand Down Expand Up @@ -161,6 +160,10 @@ ControllerContainer::GetControllers() const {
}

// crow::ControllerDelegate interface
uint32_t
ControllerContainer::GetControllerCount() {
return m.list.size();
}

void
ControllerContainer::CreateController(const int32_t aControllerIndex, const int32_t aModelIndex, const std::string& aImmersiveName) {
Expand Down Expand Up @@ -200,6 +203,15 @@ ControllerContainer::DestroyController(const int32_t aControllerIndex) {
}
}

void
ControllerContainer::SetCapabilityFlags(const int32_t aControllerIndex, const device::CapabilityFlags aFlags) {
if (!m.Contains(aControllerIndex)) {
return;
}

m.list[aControllerIndex].deviceCapabilities = aFlags;
}

void
ControllerContainer::SetEnabled(const int32_t aControllerIndex, const bool aEnabled) {
if (!m.Contains(aControllerIndex)) {
Expand Down Expand Up @@ -247,6 +259,9 @@ ControllerContainer::SetButtonCount(const int32_t aControllerIndex, const uint32

void
ControllerContainer::SetButtonState(const int32_t aControllerIndex, const Button aWhichButton, const int32_t aImmersiveIndex, const bool aPressed, const bool aTouched, const float aImmersiveTrigger) {
assert(kControllerMaxButtonCount > aImmersiveIndex
&& "Button index must < kControllerMaxButtonCount.");

if (!m.Contains(aControllerIndex)) {
return;
}
Expand Down Expand Up @@ -282,6 +297,9 @@ ControllerContainer::SetButtonState(const int32_t aControllerIndex, const Button

void
ControllerContainer::SetAxes(const int32_t aControllerIndex, const float* aData, const uint32_t aLength) {
assert(kControllerMaxAxes >= aLength
&& "Axis length must <= kControllerMaxAxes.");

if (!m.Contains(aControllerIndex)) {
return;
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/cpp/ControllerContainer.h
Expand Up @@ -32,8 +32,10 @@ class ControllerContainer : public crow::ControllerDelegate {
std::vector<Controller>& GetControllers();
const std::vector<Controller>& GetControllers() const;
// crow::ControllerDelegate interface
uint32_t GetControllerCount() override;
void CreateController(const int32_t aControllerIndex, const int32_t aModelIndex, const std::string& aImmersiveName) 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 SetTransform(const int32_t aControllerIndex, const vrb::Matrix& aTransform) override;
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/cpp/ControllerDelegate.h
Expand Up @@ -8,6 +8,7 @@

#include "vrb/MacroUtils.h"
#include "vrb/Forward.h"
#include "Device.h"
#include "GestureDelegate.h"

#include <memory>
Expand All @@ -22,11 +23,14 @@ class ControllerDelegate {
enum Button {
BUTTON_TRIGGER = 1 << 0,
BUTTON_TOUCHPAD = 1 << 1,
BUTTON_APP = 1 << 2,
BUTTON_APP = 1 << 2,
BUTTON_OTHERS = 1 << 3, // 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 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 SetTransform(const int32_t aControllerIndex, const vrb::Matrix& aTransform) = 0;
Expand Down
40 changes: 35 additions & 5 deletions app/src/main/cpp/ExternalVR.cpp
Expand Up @@ -314,6 +314,25 @@ ExternalVR::IsPresenting() const {
return m.IsPresenting();
}

uint16_t
ExternalVR::GetControllerCapabilityFlags(device::CapabilityFlags aFlags) {
uint16_t result = 0;
if (device::Position & aFlags) {
result |= static_cast<uint16_t>(mozilla::gfx::ControllerCapabilityFlags::Cap_Position);
}
if (device::Orientation & aFlags) {
result |= static_cast<uint16_t>(mozilla::gfx::ControllerCapabilityFlags::Cap_Orientation);
}
if (device::AngularAcceleration & aFlags) {
result |= static_cast<uint16_t>(mozilla::gfx::ControllerCapabilityFlags::Cap_AngularAcceleration);
}
if (device::LinearAcceleration & aFlags) {
result |= static_cast<uint16_t>(mozilla::gfx::ControllerCapabilityFlags::Cap_LinearAcceleration);
}

return result;
}

ExternalVR::VRState
ExternalVR::GetVRState() const {
if (!IsPresenting()) {
Expand Down Expand Up @@ -367,11 +386,22 @@ ExternalVR::PushFramePoses(const vrb::Matrix& aHeadTransform, const std::vector<
}
immersiveController.hand = controller.leftHanded ? mozilla::gfx::ControllerHand::Left : mozilla::gfx::ControllerHand::Right;

immersiveController.flags = mozilla::gfx::ControllerCapabilityFlags::Cap_Orientation;
immersiveController.isOrientationValid = true;
vrb::Quaternion quaternion(controller.transformMatrix);
quaternion = quaternion.Inverse();
memcpy(&(immersiveController.pose.orientation), quaternion.Data(), sizeof(immersiveController.pose.orientation));
const uint16_t flags = GetControllerCapabilityFlags(controller.deviceCapabilities);
immersiveController.flags = static_cast<mozilla::gfx::ControllerCapabilityFlags>(flags);

if (flags & static_cast<uint16_t>(mozilla::gfx::ControllerCapabilityFlags::Cap_Orientation)) {
immersiveController.isOrientationValid = true;

vrb::Quaternion quaternion(controller.transformMatrix);
quaternion = quaternion.Inverse();
memcpy(&(immersiveController.pose.orientation), quaternion.Data(), sizeof(immersiveController.pose.orientation));
}
if (flags & static_cast<uint16_t>(mozilla::gfx::ControllerCapabilityFlags::Cap_Position)) {
immersiveController.isPositionValid = true;

vrb::Vector position(controller.transformMatrix.GetTranslation());
memcpy(&(immersiveController.pose.position), position.Data(), sizeof(immersiveController.pose.position));
}
}

PushSystemState();
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/cpp/ExternalVR.h
Expand Up @@ -56,6 +56,8 @@ class ExternalVR : public ImmersiveDisplay {
struct State;
ExternalVR();
private:
uint16_t GetControllerCapabilityFlags(device::CapabilityFlags aFlags);

State& m;
VRB_NO_DEFAULTS(ExternalVR)
};
Expand Down
13 changes: 13 additions & 0 deletions app/src/oculusvr/assets/vr_controller_oculusquest_left.mtl
@@ -0,0 +1,13 @@
# Blender MTL File: 'None'
# Material Count: 1

newmtl controllerMTL
Ns 94.117647
Ka 1.000000 1.000000 1.000000
Kd 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd vr_controller_oculusquest_tex.ktx

0 comments on commit 0afae0d

Please sign in to comment.