Bug 1558952 - Vive cosmos controller binding for OpenVR. r=kip

Differential Revision: https://phabricator.services.mozilla.com/D35209

--HG--
rename : gfx/vr/service/binding/OpenVRKnucklesBinding.h => gfx/vr/service/binding/OpenVRCosmosBinding.h
extra : moz-landing-system : lando
This commit is contained in:
Daosheng Mu 2019-06-26 18:26:16 +00:00
parent bfd623a7dd
commit a2e31cbc26
6 changed files with 300 additions and 12 deletions

View File

@ -56,6 +56,7 @@ enum class OpenVRControllerType : uint16_t {
Vive,
WMR,
Knuckles,
Cosmos,
NumOpenVRControllerTypes
};

View File

@ -25,6 +25,7 @@
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/dom/GamepadBinding.h"
#include "binding/OpenVRCosmosBinding.h"
#include "binding/OpenVRKnucklesBinding.h"
#include "binding/OpenVRViveBinding.h"
#if defined(XP_WIN) // Windows Mixed Reality is only available in Windows.
@ -100,6 +101,7 @@ class ControllerManifestFile {
// We wanna keep these temporary files existing
// until Firefox is closed instead of following OpenVRSession's lifetime.
StaticRefPtr<ControllerManifestFile> sCosmosBindingFile;
StaticRefPtr<ControllerManifestFile> sKnucklesBindingFile;
StaticRefPtr<ControllerManifestFile> sViveBindingFile;
#if defined(XP_WIN)
@ -324,6 +326,7 @@ bool OpenVRSession::SetupContollerActions() {
nsCString viveManifest;
nsCString WMRManifest;
nsCString knucklesManifest;
nsCString cosmosManifest;
// Getting / Generating manifest file paths.
if (StaticPrefs::VRProcessEnabled()) {
@ -367,7 +370,6 @@ bool OpenVRSession::SetupContollerActions() {
}
}
#endif
if (vrParent->GetOpenVRControllerManifestPath(
OpenVRControllerType::Knuckles, &output)) {
knucklesManifest = output;
@ -383,6 +385,21 @@ bool OpenVRSession::SetupContollerActions() {
knucklesBindingFile.close();
}
}
if (vrParent->GetOpenVRControllerManifestPath(
OpenVRControllerType::Cosmos, &output)) {
cosmosManifest = output;
}
if (!cosmosManifest.Length() || !FileIsExisting(cosmosManifest)) {
if (!GenerateTempFileName(cosmosManifest)) {
return false;
}
OpenVRCosmosBinding cosmosBinding;
std::ofstream cosmosBindingFile(cosmosManifest.BeginReading());
if (cosmosBindingFile.is_open()) {
cosmosBindingFile << cosmosBinding.binding;
cosmosBindingFile.close();
}
}
} else {
// Without using VR process
if (!sControllerActionFile) {
@ -435,6 +452,26 @@ bool OpenVRSession::SetupContollerActions() {
}
knucklesManifest = sKnucklesBindingFile->GetFileName();
if (!sCosmosBindingFile) {
sCosmosBindingFile = ControllerManifestFile::CreateManifest();
NS_DispatchToMainThread(NS_NewRunnableFunction(
"ClearOnShutdown ControllerManifestFile",
[]() { ClearOnShutdown(&sCosmosBindingFile); }));
}
if (!sCosmosBindingFile->IsExisting()) {
nsCString cosmosBindingPath;
if (!GenerateTempFileName(cosmosBindingPath)) {
return false;
}
sCosmosBindingFile->SetFileName(cosmosBindingPath.BeginReading());
OpenVRCosmosBinding cosmosBinding;
std::ofstream cosmosBindingFile(sCosmosBindingFile->GetFileName());
if (cosmosBindingFile.is_open()) {
cosmosBindingFile << cosmosBinding.binding;
cosmosBindingFile.close();
}
}
cosmosManifest = sCosmosBindingFile->GetFileName();
#if defined(XP_WIN)
if (!sWMRBindingFile) {
sWMRBindingFile = ControllerManifestFile::CreateManifest();
@ -508,6 +545,8 @@ bool OpenVRSession::SetupContollerActions() {
"/actions/firefox/in/LHand_finger_ring_value", "vector1");
leftContollerInfo.mActionFingerPinky_Value = ControllerAction(
"/actions/firefox/in/LHand_finger_pinky_value", "vector1");
leftContollerInfo.mActionBumper_Pressed =
ControllerAction("/actions/firefox/in/LHand_bumper_pressed", "boolean");
ControllerInfo rightContollerInfo;
rightContollerInfo.mActionPose =
@ -556,6 +595,8 @@ bool OpenVRSession::SetupContollerActions() {
"/actions/firefox/in/RHand_finger_ring_value", "vector1");
rightContollerInfo.mActionFingerPinky_Value = ControllerAction(
"/actions/firefox/in/RHand_finger_pinky_value", "vector1");
rightContollerInfo.mActionBumper_Pressed =
ControllerAction("/actions/firefox/in/RHand_bumper_pressed", "boolean");
mControllerHand[OpenVRHand::Left] = leftContollerInfo;
mControllerHand[OpenVRHand::Right] = rightContollerInfo;
@ -580,6 +621,10 @@ bool OpenVRSession::SetupContollerActions() {
actionWriter.StringProperty("controller_type", "knuckles");
actionWriter.StringProperty("binding_url", knucklesManifest.BeginReading());
actionWriter.EndObject();
actionWriter.StartObjectElement();
actionWriter.StringProperty("controller_type", "vive_cosmos_controller");
actionWriter.StringProperty("binding_url", cosmosManifest.BeginReading());
actionWriter.EndObject();
#if defined(XP_WIN)
actionWriter.StartObjectElement();
actionWriter.StringProperty("controller_type", "holographic_controller");
@ -747,6 +792,13 @@ bool OpenVRSession::SetupContollerActions() {
"type", controller.mActionFingerPinky_Value.type.BeginReading());
actionWriter.EndObject();
actionWriter.StartObjectElement();
actionWriter.StringProperty(
"name", controller.mActionBumper_Pressed.name.BeginReading());
actionWriter.StringProperty(
"type", controller.mActionBumper_Pressed.type.BeginReading());
actionWriter.EndObject();
actionWriter.StartObjectElement();
actionWriter.StringProperty("name",
controller.mActionHaptic.name.BeginReading());
@ -772,7 +824,8 @@ bool OpenVRSession::SetupContollerActions() {
if (StaticPrefs::VRProcessEnabled()) {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"SendOpenVRControllerActionPathToParent",
[controllerAction, viveManifest, WMRManifest, knucklesManifest]() {
[controllerAction, viveManifest, WMRManifest, knucklesManifest,
cosmosManifest]() {
VRParent* vrParent = VRProcessChild::GetVRParent();
Unused << vrParent->SendOpenVRControllerActionPathToParent(
controllerAction);
@ -782,6 +835,8 @@ bool OpenVRSession::SetupContollerActions() {
OpenVRControllerType::WMR, WMRManifest);
Unused << vrParent->SendOpenVRControllerManifestPathToParent(
OpenVRControllerType::Knuckles, knucklesManifest);
Unused << vrParent->SendOpenVRControllerManifestPathToParent(
OpenVRControllerType::Cosmos, cosmosManifest);
}));
} else {
sControllerActionFile->SetFileName(controllerAction.BeginReading());
@ -1136,6 +1191,9 @@ void OpenVRSession::EnumerateControllers(VRSystemState& aState) {
mControllerHand[handIndex]
.mActionFingerPinky_Value.name.BeginReading(),
&mControllerHand[handIndex].mActionFingerPinky_Value.handle);
vr::VRInput()->GetActionHandle(
mControllerHand[handIndex].mActionBumper_Pressed.name.BeginReading(),
&mControllerHand[handIndex].mActionBumper_Pressed.handle);
nsCString deviceId;
GetControllerDeviceId(deviceType, originInfo.trackedDeviceIndex,
@ -1352,7 +1410,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionTrackpad_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionTrackpad_Touched.handle,
@ -1395,7 +1452,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionGrip_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionGrip_Touched.handle,
@ -1427,7 +1483,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionMenu_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionMenu_Touched.handle,
@ -1459,7 +1514,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionSystem_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionSystem_Touched.handle,
@ -1506,6 +1560,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
}
++buttonIdx;
}
// Button 5: B
if (mControllerHand[stateIndex].mActionB_Pressed.handle &&
vr::VRInput()->GetDigitalActionData(
@ -1521,7 +1576,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionB_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionB_Touched.handle, &actionData,
@ -1537,6 +1591,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
}
++buttonIdx;
}
// Axis 2 3: Thumbstick
// Button 6: Thumbstick
if (mControllerHand[stateIndex].mActionThumbstick_Analog.handle &&
@ -1550,7 +1605,6 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
controllerState.axisValue[axisIdx] = analogData.y * yAxisInvert;
++axisIdx;
}
if (mControllerHand[stateIndex].mActionThumbstick_Pressed.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionThumbstick_Pressed.handle,
@ -1558,13 +1612,13 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None &&
actionData.bActive) {
bPressed = actionData.bState;
mask = (1ULL << buttonIdx);
controllerState.triggerValue[buttonIdx] = bPressed ? 1.0 : 0.0f;
if (bPressed) {
controllerState.buttonPressed |= mask;
} else {
controllerState.buttonPressed &= ~mask;
}
if (mControllerHand[stateIndex].mActionThumbstick_Touched.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionThumbstick_Touched.handle,
@ -1580,6 +1634,25 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
}
++buttonIdx;
}
// Button 7: Bumper (Cosmos only)
if (mControllerHand[stateIndex].mActionBumper_Pressed.handle &&
vr::VRInput()->GetDigitalActionData(
mControllerHand[stateIndex].mActionBumper_Pressed.handle, &actionData,
sizeof(actionData),
vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None &&
actionData.bActive) {
bPressed = actionData.bState;
mask = (1ULL << buttonIdx);
controllerState.triggerValue[buttonIdx] = bPressed ? 1.0 : 0.0f;
if (bPressed) {
controllerState.buttonPressed |= mask;
} else {
controllerState.buttonPressed &= ~mask;
}
++buttonIdx;
}
// Button 7: Finger index
if (mControllerHand[stateIndex].mActionFingerIndex_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1590,6 +1663,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
UpdateTrigger(controllerState, buttonIdx, analogData.x, triggerThreshold);
++buttonIdx;
}
// Button 8: Finger middle
if (mControllerHand[stateIndex].mActionFingerMiddle_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1600,6 +1674,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
UpdateTrigger(controllerState, buttonIdx, analogData.x, triggerThreshold);
++buttonIdx;
}
// Button 9: Finger ring
if (mControllerHand[stateIndex].mActionFingerRing_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1610,6 +1685,7 @@ void OpenVRSession::UpdateControllerButtons(VRSystemState& aState) {
UpdateTrigger(controllerState, buttonIdx, analogData.x, triggerThreshold);
++buttonIdx;
}
// Button 10: Finger pinky
if (mControllerHand[stateIndex].mActionFingerPinky_Value.handle &&
vr::VRInput()->GetAnalogActionData(
@ -1903,6 +1979,9 @@ void OpenVRSession::GetControllerDeviceId(
if (deviceId.Find("knuckles") != kNotFound) {
aId.AssignLiteral("OpenVR Knuckles");
isFound = true;
} else if (deviceId.Find("vive_cosmos_controller") != kNotFound) {
aId.AssignLiteral("OpenVR Cosmos");
isFound = true;
}
requiredBufferLen = mVRSystem->GetStringTrackedDeviceProperty(
aDeviceIndex, ::vr::Prop_SerialNumber_String, charBuf, 128, &err);

View File

@ -62,20 +62,25 @@ struct ControllerInfo {
ControllerAction mActionSystem_Pressed;
ControllerAction mActionSystem_Touched;
// --- Knuckles
// --- Knuckles & Cosmos
ControllerAction mActionA_Pressed;
ControllerAction mActionA_Touched;
ControllerAction mActionB_Pressed;
ControllerAction mActionB_Touched;
// --- Knuckles, Cosmos, and WMR
ControllerAction mActionThumbstick_Analog;
ControllerAction mActionThumbstick_Pressed;
ControllerAction mActionThumbstick_Touched;
// --- Knuckles
ControllerAction mActionFingerIndex_Value;
ControllerAction mActionFingerMiddle_Value;
ControllerAction mActionFingerRing_Value;
ControllerAction mActionFingerPinky_Value;
// --- Cosmos
ControllerAction mActionBumper_Pressed;
};
class OpenVRSession : public VRSession {

View File

@ -0,0 +1,204 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef GFX_VR_BLINDING_OPENVRCOSMOSBINDING_H
#define GFX_VR_BLINDING_OPENVRCOSMOSBINDING_H
namespace mozilla {
namespace gfx {
struct OpenVRCosmosBinding {
const char* binding =
// clang-format off
"{\n"
" \"version\" : \"0.1\", \n"
" \"controller_type\" : \"vive_cosmos_controller\", \n"
" \"description\" : \"Bindings for Firefox OpenVR for the Vive Cosmos controller\", \n"
" \"name\" : \"Firefox bindings for Vive Cosmos Controller\", \n"
" \"bindings\" : { \n"
" \"/actions/firefox\" : { \n"
" \"poses\" : [ \n"
" { \n"
" \"output\" : \"/actions/firefox/in/LHand_pose\", \n"
" \"path\" : \"/user/hand/left/pose/raw\" \n"
" },\n"
" { \n"
" \"output\" : \"/actions/firefox/in/RHand_pose\", \n"
" \"path\" : \"/user/hand/right/pose/raw\" \n"
" }\n"
" ],\n"
" \"haptics\" : [ \n"
" {\n"
" \"output\" : \"/actions/firefox/out/LHand_haptic\", \n"
" \"path\" : \"/user/hand/left/output/haptic\" \n"
" },\n"
" { \n"
" \"output\" : \"/actions/firefox/out/RHand_haptic\", \n"
" \"path\" : \"/user/hand/right/output/haptic\" \n"
" }\n"
" ],\n"
" \"sources\" : [ \n"
" {\n"
" \"inputs\" : { \n"
" \"pull\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_trigger_value\" \n"
" } \n"
" },\n"
" \"mode\" : \"trigger\", \n"
" \"path\" : \"/user/hand/left/input/trigger\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"pull\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_trigger_value\" \n"
" } \n"
" },\n"
" \"mode\" : \"trigger\", \n"
" \"path\" : \"/user/hand/right/input/trigger\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_grip_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_grip_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/paddle_heavy\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_grip_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_grip_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/paddle_heavy\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_system_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_system_touched\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/system\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_system_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_system_touched\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/system\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_a_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/a\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_a_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/a\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_b_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/b\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_b_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/b\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"position\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_thumbstick_analog\" \n"
" }, \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_thumbstick_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_thumbstick_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"joystick\", \n"
" \"path\" : \"/user/hand/left/input/joystick\" \n"
" },\n"
" {\n"
" \"inputs\" : { \n"
" \"position\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_thumbstick_analog\" \n"
" }, \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_thumbstick_pressed\" \n"
" }, \n"
" \"touch\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_thumbstick_touched\" \n"
" } \n"
" }, \n"
" \"mode\" : \"joystick\", \n"
" \"path\" : \"/user/hand/right/input/joystick\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_bumper_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/left/input/bumper\" \n"
" }, \n"
" {\n"
" \"inputs\" : { \n"
" \"click\" : { \n"
" \"output\" : \"/actions/firefox/in/RHand_bumper_pressed\" \n"
" } \n"
" },\n"
" \"mode\" : \"button\", \n"
" \"path\" : \"/user/hand/right/input/bumper\" \n"
" } \n"
" ]\n"
" }\n"
" }\n"
"}";
// clang-format on
};
} // namespace gfx
} // namespace mozilla
#endif // GFX_VR_BLINDING_OPENVRCOSMOSBINDING_H

View File

@ -233,7 +233,7 @@ struct OpenVRKnucklesBinding {
" \"mode\" : \"trigger\", \n"
" \"path\" : \"/user/hand/right/input/finger/index\" \n"
" }, \n"
" {\n"
" {\n"
" \"inputs\" : { \n"
" \"pull\" : { \n"
" \"output\" : \"/actions/firefox/in/LHand_finger_middle_value\" \n"

View File

@ -11,7 +11,6 @@ namespace mozilla {
namespace gfx {
struct OpenVRWMRBinding {
// OpenVRWMRBinding();
const char* binding =
// clang-format off
"{\n"