Commit e5ad8bea authored by ningxin.hu's avatar ningxin.hu Committed by Commit bot

Added support for OpenVR controllers

BUG=712987

Review-Url: https://codereview.chromium.org/2825203004
Cr-Commit-Position: refs/heads/master@{#466890}
parent 9a16f5fe
...@@ -26,6 +26,7 @@ enum GamepadSource { ...@@ -26,6 +26,7 @@ enum GamepadSource {
GAMEPAD_SOURCE_MAC_GC, GAMEPAD_SOURCE_MAC_GC,
GAMEPAD_SOURCE_MAC_HID, GAMEPAD_SOURCE_MAC_HID,
GAMEPAD_SOURCE_MAC_XBOX, GAMEPAD_SOURCE_MAC_XBOX,
GAMEPAD_SOURCE_OPENVR,
GAMEPAD_SOURCE_TEST, GAMEPAD_SOURCE_TEST,
GAMEPAD_SOURCE_WIN_XINPUT, GAMEPAD_SOURCE_WIN_XINPUT,
GAMEPAD_SOURCE_WIN_RAW, GAMEPAD_SOURCE_WIN_RAW,
......
...@@ -88,12 +88,17 @@ component("vr") { ...@@ -88,12 +88,17 @@ component("vr") {
} }
if (enable_openvr) { if (enable_openvr) {
deps += [ "//third_party/openvr:openvr" ] deps += [
"//device/gamepad",
"//third_party/openvr:openvr",
]
sources += [ sources += [
"openvr/openvr_device.cc", "openvr/openvr_device.cc",
"openvr/openvr_device.h", "openvr/openvr_device.h",
"openvr/openvr_device_provider.cc", "openvr/openvr_device_provider.cc",
"openvr/openvr_device_provider.h", "openvr/openvr_device_provider.h",
"openvr/openvr_gamepad_data_fetcher.cc",
"openvr/openvr_gamepad_data_fetcher.h",
] ]
} }
} }
......
...@@ -76,17 +76,12 @@ std::vector<float> HmdMatrix34ToWebVRTransformMatrix( ...@@ -76,17 +76,12 @@ std::vector<float> HmdMatrix34ToWebVRTransformMatrix(
namespace device { namespace device {
OpenVRDevice::OpenVRDevice() {} OpenVRDevice::OpenVRDevice(vr::IVRSystem* vr) : vr_system_(vr) {}
OpenVRDevice::~OpenVRDevice() {} OpenVRDevice::~OpenVRDevice() {}
void OpenVRDevice::CreateVRDisplayInfo( void OpenVRDevice::CreateVRDisplayInfo(
const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) { const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) {
vr::EVRInitError init_error; if (!vr_system_) {
auto vr_system =
vr::VR_Init(&init_error, vr::EVRApplicationType::VRApplication_Scene);
if (init_error != vr::VRInitError_None) {
LOG(ERROR) << vr::VR_GetVRInitErrorAsEnglishDescription(init_error);
on_created.Run(nullptr); on_created.Run(nullptr);
return; return;
} }
...@@ -94,8 +89,8 @@ void OpenVRDevice::CreateVRDisplayInfo( ...@@ -94,8 +89,8 @@ void OpenVRDevice::CreateVRDisplayInfo(
mojom::VRDisplayInfoPtr device = mojom::VRDisplayInfo::New(); mojom::VRDisplayInfoPtr device = mojom::VRDisplayInfo::New();
device->index = id(); device->index = id();
device->displayName = device->displayName =
GetOpenVRString(vr_system, vr::Prop_ManufacturerName_String) + " " + GetOpenVRString(vr_system_, vr::Prop_ManufacturerName_String) + " " +
GetOpenVRString(vr_system, vr::Prop_ModelNumber_String); GetOpenVRString(vr_system_, vr::Prop_ModelNumber_String);
device->capabilities = mojom::VRDisplayCapabilities::New(); device->capabilities = mojom::VRDisplayCapabilities::New();
device->capabilities->hasPosition = true; device->capabilities->hasPosition = true;
device->capabilities->hasExternalDisplay = true; device->capabilities->hasExternalDisplay = true;
...@@ -106,11 +101,11 @@ void OpenVRDevice::CreateVRDisplayInfo( ...@@ -106,11 +101,11 @@ void OpenVRDevice::CreateVRDisplayInfo(
mojom::VREyeParametersPtr& left_eye = device->leftEye; mojom::VREyeParametersPtr& left_eye = device->leftEye;
mojom::VREyeParametersPtr& right_eye = device->rightEye; mojom::VREyeParametersPtr& right_eye = device->rightEye;
left_eye->fieldOfView = openVRFovToWebVRFov(vr_system, vr::Eye_Left); left_eye->fieldOfView = openVRFovToWebVRFov(vr_system_, vr::Eye_Left);
right_eye->fieldOfView = openVRFovToWebVRFov(vr_system, vr::Eye_Left); right_eye->fieldOfView = openVRFovToWebVRFov(vr_system_, vr::Eye_Left);
vr::TrackedPropertyError error = vr::TrackedProp_Success; vr::TrackedPropertyError error = vr::TrackedProp_Success;
float ipd = vr_system->GetFloatTrackedDeviceProperty( float ipd = vr_system_->GetFloatTrackedDeviceProperty(
vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_UserIpdMeters_Float, &error); vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_UserIpdMeters_Float, &error);
if (error != vr::TrackedProp_Success) if (error != vr::TrackedProp_Success)
...@@ -126,7 +121,7 @@ void OpenVRDevice::CreateVRDisplayInfo( ...@@ -126,7 +121,7 @@ void OpenVRDevice::CreateVRDisplayInfo(
right_eye->offset[2] = 0.0; right_eye->offset[2] = 0.0;
uint32_t width, height; uint32_t width, height;
vr_system->GetRecommendedRenderTargetSize(&width, &height); vr_system_->GetRecommendedRenderTargetSize(&width, &height);
left_eye->renderWidth = width; left_eye->renderWidth = width;
left_eye->renderHeight = height; left_eye->renderHeight = height;
right_eye->renderWidth = left_eye->renderWidth; right_eye->renderWidth = left_eye->renderWidth;
...@@ -134,7 +129,7 @@ void OpenVRDevice::CreateVRDisplayInfo( ...@@ -134,7 +129,7 @@ void OpenVRDevice::CreateVRDisplayInfo(
device->stageParameters = mojom::VRStageParameters::New(); device->stageParameters = mojom::VRStageParameters::New();
vr::HmdMatrix34_t mat = vr::HmdMatrix34_t mat =
vr_system->GetSeatedZeroPoseToStandingAbsoluteTrackingPose(); vr_system_->GetSeatedZeroPoseToStandingAbsoluteTrackingPose();
device->stageParameters->standingTransform = device->stageParameters->standingTransform =
HmdMatrix34ToWebVRTransformMatrix(mat); HmdMatrix34ToWebVRTransformMatrix(mat);
...@@ -147,7 +142,7 @@ void OpenVRDevice::CreateVRDisplayInfo( ...@@ -147,7 +142,7 @@ void OpenVRDevice::CreateVRDisplayInfo(
device->stageParameters->sizeZ = 0.0f; device->stageParameters->sizeZ = 0.0f;
} }
render_loop_ = std::make_unique<OpenVRRenderLoop>(vr_system); render_loop_ = std::make_unique<OpenVRRenderLoop>(vr_system_);
on_created.Run(std::move(device)); on_created.Run(std::move(device));
} }
......
...@@ -18,7 +18,7 @@ namespace device { ...@@ -18,7 +18,7 @@ namespace device {
class OpenVRDevice : public VRDevice { class OpenVRDevice : public VRDevice {
public: public:
OpenVRDevice(); OpenVRDevice(vr::IVRSystem* vr);
~OpenVRDevice() override; ~OpenVRDevice() override;
// VRDevice // VRDevice
...@@ -68,6 +68,8 @@ class OpenVRDevice : public VRDevice { ...@@ -68,6 +68,8 @@ class OpenVRDevice : public VRDevice {
mojom::VRSubmitFrameClientPtr submit_client_; mojom::VRSubmitFrameClientPtr submit_client_;
vr::IVRSystem* vr_system_;
DISALLOW_COPY_AND_ASSIGN(OpenVRDevice); DISALLOW_COPY_AND_ASSIGN(OpenVRDevice);
}; };
......
...@@ -3,22 +3,43 @@ ...@@ -3,22 +3,43 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "device/vr/openvr/openvr_device_provider.h" #include "device/vr/openvr/openvr_device_provider.h"
#include "device/gamepad/gamepad_data_fetcher_manager.h"
#include "device/vr/openvr/openvr_device.h" #include "device/vr/openvr/openvr_device.h"
#include "device/vr/openvr/openvr_gamepad_data_fetcher.h"
#include "third_party/openvr/src/headers/openvr.h" #include "third_party/openvr/src/headers/openvr.h"
namespace device { namespace device {
OpenVRDeviceProvider::OpenVRDeviceProvider() {} OpenVRDeviceProvider::OpenVRDeviceProvider()
: initialized_(false), vr_system_(nullptr) {}
OpenVRDeviceProvider::~OpenVRDeviceProvider() {} OpenVRDeviceProvider::~OpenVRDeviceProvider() {}
void OpenVRDeviceProvider::GetDevices(std::vector<VRDevice*>* devices) { void OpenVRDeviceProvider::GetDevices(std::vector<VRDevice*>* devices) {
if (vr::VR_IsRuntimeInstalled() && vr::VR_IsHmdPresent()) { if (initialized_) {
devices->push_back(new OpenVRDevice()); VRDevice* device = new OpenVRDevice(vr_system_);
devices->push_back(device);
GamepadDataFetcherManager::GetInstance()->AddFactory(
new OpenVRGamepadDataFetcher::Factory(device->id(), vr_system_));
} }
} }
void OpenVRDeviceProvider::Initialize() {} void OpenVRDeviceProvider::Initialize() {
if (!initialized_ && vr::VR_IsRuntimeInstalled() && vr::VR_IsHmdPresent()) {
vr::EVRInitError init_error = vr::VRInitError_None;
vr_system_ =
vr::VR_Init(&init_error, vr::EVRApplicationType::VRApplication_Scene);
if (init_error != vr::VRInitError_None) {
LOG(ERROR) << vr::VR_GetVRInitErrorAsEnglishDescription(init_error);
vr_system_ = nullptr;
return;
}
initialized_ = true;
}
}
void OpenVRDeviceProvider::SetListeningForActivate(bool listening) {} void OpenVRDeviceProvider::SetListeningForActivate(bool listening) {}
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
#include "device/vr/vr_device_provider.h" #include "device/vr/vr_device_provider.h"
#include "device/vr/vr_export.h" #include "device/vr/vr_export.h"
namespace vr {
class IVRSystem;
} // namespace vr
namespace device { namespace device {
class OpenVRDeviceProvider : public VRDeviceProvider { class OpenVRDeviceProvider : public VRDeviceProvider {
...@@ -25,6 +29,9 @@ class OpenVRDeviceProvider : public VRDeviceProvider { ...@@ -25,6 +29,9 @@ class OpenVRDeviceProvider : public VRDeviceProvider {
void SetListeningForActivate(bool listening) override; void SetListeningForActivate(bool listening) override;
private: private:
bool initialized_;
vr::IVRSystem* vr_system_;
DISALLOW_COPY_AND_ASSIGN(OpenVRDeviceProvider); DISALLOW_COPY_AND_ASSIGN(OpenVRDeviceProvider);
}; };
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/vr/openvr/openvr_gamepad_data_fetcher.h"
#include <memory>
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "device/gamepad/public/cpp/gamepads.h"
#include "third_party/openvr/src/headers/openvr.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/transform_util.h"
namespace device {
namespace {
void SetGamepadButton(Gamepad* pad,
const vr::VRControllerState_t& controller_state,
uint64_t supported_buttons,
vr::EVRButtonId button_id) {
uint64_t button_mask = vr::ButtonMaskFromId(button_id);
if ((supported_buttons & button_mask) != 0) {
bool button_pressed = (controller_state.ulButtonPressed & button_mask) != 0;
bool button_touched = (controller_state.ulButtonTouched & button_mask) != 0;
pad->buttons[pad->buttons_length].touched = button_touched;
pad->buttons[pad->buttons_length].pressed = button_pressed;
pad->buttons[pad->buttons_length].value = button_pressed ? 1.0 : 0.0;
pad->buttons_length++;
}
}
} // namespace
OpenVRGamepadDataFetcher::Factory::Factory(unsigned int display_id,
vr::IVRSystem* vr)
: display_id_(display_id), vr_system_(vr) {
DVLOG(1) << __FUNCTION__ << "=" << this;
}
OpenVRGamepadDataFetcher::Factory::~Factory() {
DVLOG(1) << __FUNCTION__ << "=" << this;
}
std::unique_ptr<GamepadDataFetcher>
OpenVRGamepadDataFetcher::Factory::CreateDataFetcher() {
return base::MakeUnique<OpenVRGamepadDataFetcher>(display_id_, vr_system_);
}
GamepadSource OpenVRGamepadDataFetcher::Factory::source() {
return GAMEPAD_SOURCE_OPENVR;
}
OpenVRGamepadDataFetcher::OpenVRGamepadDataFetcher(unsigned int display_id,
vr::IVRSystem* vr)
: display_id_(display_id), vr_system_(vr) {
DVLOG(1) << __FUNCTION__ << "=" << this;
}
OpenVRGamepadDataFetcher::~OpenVRGamepadDataFetcher() {
DVLOG(1) << __FUNCTION__ << "=" << this;
}
GamepadSource OpenVRGamepadDataFetcher::source() {
return GAMEPAD_SOURCE_OPENVR;
}
void OpenVRGamepadDataFetcher::OnAddedToProvider() {}
void OpenVRGamepadDataFetcher::GetGamepadData(bool devices_changed_hint) {
if (!vr_system_)
return;
vr::TrackedDevicePose_t tracked_devices_poses[vr::k_unMaxTrackedDeviceCount];
vr_system_->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseSeated, 0.0f,
tracked_devices_poses,
vr::k_unMaxTrackedDeviceCount);
for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i) {
if (vr_system_->GetTrackedDeviceClass(i) !=
vr::TrackedDeviceClass_Controller)
continue;
PadState* state = GetPadState(i);
if (!state)
continue;
Gamepad& pad = state->data;
vr::VRControllerState_t controller_state;
if (vr_system_->GetControllerState(i, &controller_state,
sizeof(controller_state))) {
pad.timestamp = controller_state.unPacketNum;
pad.connected = true;
pad.pose.not_null = true;
pad.pose.has_orientation = true;
pad.pose.has_position = true;
vr::TrackedPropertyError error = vr::TrackedProp_Success;
char attached_device_id[vr::k_unMaxPropertyStringSize];
vr_system_->GetStringTrackedDeviceProperty(
i, vr::Prop_AttachedDeviceId_String, attached_device_id,
vr::k_unMaxPropertyStringSize, &error);
if (error == vr::TrackedProp_Success) {
swprintf(pad.id, Gamepad::kIdLengthCap,
base::UTF8ToUTF16(attached_device_id).c_str());
} else {
swprintf(pad.id, Gamepad::kIdLengthCap, L"OpenVR Controller");
}
swprintf(pad.mapping, Gamepad::kMappingLengthCap, L"");
pad.display_id = display_id_;
vr::ETrackedControllerRole hand =
vr_system_->GetControllerRoleForTrackedDeviceIndex(i);
switch (hand) {
case vr::TrackedControllerRole_Invalid:
pad.hand = GamepadHand::kNone;
break;
case vr::TrackedControllerRole_LeftHand:
pad.hand = GamepadHand::kLeft;
break;
case vr::TrackedControllerRole_RightHand:
pad.hand = GamepadHand::kRight;
break;
}
uint64_t supported_buttons = vr_system_->GetUint64TrackedDeviceProperty(
i, vr::Prop_SupportedButtons_Uint64);
pad.buttons_length = 0;
pad.axes_length = 0;
for (int j = 0; j < vr::k_unControllerStateAxisCount; ++j) {
int32_t axis_type = vr_system_->GetInt32TrackedDeviceProperty(
i, static_cast<vr::TrackedDeviceProperty>(vr::Prop_Axis0Type_Int32 +
j));
switch (axis_type) {
case vr::k_eControllerAxis_Joystick:
case vr::k_eControllerAxis_TrackPad:
pad.axes[pad.axes_length++] = controller_state.rAxis[j].x;
pad.axes[pad.axes_length++] = controller_state.rAxis[j].y;
SetGamepadButton(
&pad, controller_state, supported_buttons,
static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j));
break;
case vr::k_eControllerAxis_Trigger:
pad.buttons[pad.buttons_length].value = controller_state.rAxis[j].x;
uint64_t button_mask = vr::ButtonMaskFromId(
static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j));
if ((supported_buttons & button_mask) != 0) {
pad.buttons[pad.buttons_length].pressed =
(controller_state.ulButtonPressed & button_mask) != 0;
}
pad.buttons_length++;
break;
}
}
SetGamepadButton(&pad, controller_state, supported_buttons,
vr::k_EButton_A);
SetGamepadButton(&pad, controller_state, supported_buttons,
vr::k_EButton_Grip);
SetGamepadButton(&pad, controller_state, supported_buttons,
vr::k_EButton_ApplicationMenu);
SetGamepadButton(&pad, controller_state, supported_buttons,
vr::k_EButton_DPad_Left);
SetGamepadButton(&pad, controller_state, supported_buttons,
vr::k_EButton_DPad_Up);
SetGamepadButton(&pad, controller_state, supported_buttons,
vr::k_EButton_DPad_Right);
SetGamepadButton(&pad, controller_state, supported_buttons,
vr::k_EButton_DPad_Down);
}
const vr::TrackedDevicePose_t& pose = tracked_devices_poses[i];
if (pose.bPoseIsValid) {
const vr::HmdMatrix34_t& mat = pose.mDeviceToAbsoluteTracking;
gfx::Transform transform(
mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3], mat.m[1][0],
mat.m[1][1], mat.m[1][2], mat.m[1][3], mat.m[2][0], mat.m[2][1],
mat.m[2][2], mat.m[2][3], 0, 0, 0, 1);
gfx::DecomposedTransform decomposed_transform;
gfx::DecomposeTransform(&decomposed_transform, transform);
pad.pose.orientation.not_null = true;
pad.pose.orientation.x = decomposed_transform.quaternion[0];
pad.pose.orientation.y = decomposed_transform.quaternion[1];
pad.pose.orientation.z = decomposed_transform.quaternion[2];
pad.pose.orientation.w = decomposed_transform.quaternion[3];
pad.pose.position.not_null = true;
pad.pose.position.x = decomposed_transform.translate[0];
pad.pose.position.y = decomposed_transform.translate[1];
pad.pose.position.z = decomposed_transform.translate[2];
pad.pose.angular_velocity.not_null = true;
pad.pose.angular_velocity.x = pose.vAngularVelocity.v[0];
pad.pose.angular_velocity.y = pose.vAngularVelocity.v[1];
pad.pose.angular_velocity.z = pose.vAngularVelocity.v[2];
pad.pose.linear_velocity.not_null = true;
pad.pose.linear_velocity.x = pose.vVelocity.v[0];
pad.pose.linear_velocity.y = pose.vVelocity.v[1];
pad.pose.linear_velocity.z = pose.vVelocity.v[2];
} else {
pad.pose.orientation.not_null = false;
pad.pose.position.not_null = false;
pad.pose.angular_velocity.not_null = false;
pad.pose.linear_velocity.not_null = false;
}
}
}
void OpenVRGamepadDataFetcher::PauseHint(bool paused) {}
} // namespace device
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_VR_OPENVR_GAMEPAD_DATA_FETCHER_H_
#define DEVICE_VR_OPENVR_GAMEPAD_DATA_FETCHER_H_
#include "device/gamepad/gamepad_data_fetcher.h"
namespace vr {
class IVRSystem;
} // namespace vr
namespace device {
class OpenVRGamepadDataFetcher : public GamepadDataFetcher {
public:
class Factory : public GamepadDataFetcherFactory {
public:
Factory(unsigned int display_id, vr::IVRSystem* vr);
~Factory() override;
std::unique_ptr<GamepadDataFetcher> CreateDataFetcher() override;
GamepadSource source() override;
private:
unsigned int display_id_;
vr::IVRSystem* vr_system_;
};
OpenVRGamepadDataFetcher(unsigned int display_id, vr::IVRSystem* vr);
~OpenVRGamepadDataFetcher() override;
GamepadSource source() override;
void GetGamepadData(bool devices_changed_hint) override;
void PauseHint(bool paused) override;
void OnAddedToProvider() override;
private:
unsigned int display_id_;
vr::IVRSystem* vr_system_;
DISALLOW_COPY_AND_ASSIGN(OpenVRGamepadDataFetcher);
};
} // namespace device
#endif // DEVICE_VR_OPENVR_GAMEPAD_DATA_FETCHER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment