mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
Merge pull request #387 from ctrlaltdavid/feature/openvr-linux
Build OpenVR plugin on Linux
This commit is contained in:
commit
cf2beb6c96
9 changed files with 218 additions and 78 deletions
4
BUILD.md
4
BUILD.md
|
@ -21,8 +21,8 @@
|
|||
These dependencies need not be installed manually. They are automatically downloaded on the platforms where they are required.
|
||||
- [Bullet Physics Engine](https://github.com/bulletphysics/bullet3/releases): 2.83
|
||||
- [glm](https://glm.g-truc.net/0.9.8/index.html): 0.9.8
|
||||
- [Oculus SDK](https://developer.oculus.com/downloads/): 1.11 (Win32) / 0.5 (Mac)
|
||||
- [OpenVR](https://github.com/ValveSoftware/openvr): 1.11.11 (Win32 only)
|
||||
- [Oculus SDK](https://developer.oculus.com/downloads/): 1.11 (Windows) / 0.5 (Mac)
|
||||
- [OpenVR](https://github.com/ValveSoftware/openvr): 1.11.11 (Windows, Linux)
|
||||
- [Polyvox](http://www.volumesoffun.com/): 0.2.1
|
||||
- [QuaZip](https://sourceforge.net/projects/quazip/files/quazip/): 0.7.3
|
||||
- [SDL2](https://www.libsdl.org/download-2.0.php): 2.0.3
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Source: hifi-client-deps
|
||||
Version: 0.1
|
||||
Description: Collected dependencies for High Fidelity applications
|
||||
Build-Depends: hifi-deps, aristo (windows), glslang, liblo (windows), nlohmann-json, openvr (windows), quazip (!android), sdl2 (!android), spirv-cross (!android), spirv-tools (!android), sranipal (windows), vulkanmemoryallocator
|
||||
Build-Depends: hifi-deps, aristo (windows), glslang, liblo (windows), nlohmann-json, openvr (linux|windows), quazip (!android), sdl2 (!android), spirv-cross (!android), spirv-tools (!android), sranipal (windows), vulkanmemoryallocator
|
||||
|
|
|
@ -11,15 +11,23 @@ vcpkg_from_github(
|
|||
set(VCPKG_LIBRARY_LINKAGE dynamic)
|
||||
|
||||
if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
|
||||
set(ARCH_PATH "win64")
|
||||
if(WIN32)
|
||||
set(ARCH_PATH "win64")
|
||||
else()
|
||||
set(ARCH_PATH "linux64")
|
||||
endif()
|
||||
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86")
|
||||
set(ARCH_PATH "win32")
|
||||
if(WIN32)
|
||||
set(ARCH_PATH "win32")
|
||||
else()
|
||||
set(ARCH_PATH "linux32")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Package only supports x64 and x86 windows.")
|
||||
message(FATAL_ERROR "Package only supports x64 and x86 Windows and Linux.")
|
||||
endif()
|
||||
|
||||
if(VCPKG_CMAKE_SYSTEM_NAME)
|
||||
message(FATAL_ERROR "Package only supports windows desktop.")
|
||||
if(VCPKG_CMAKE_SYSTEM_NAME AND NOT (VCPKG_CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
||||
message(FATAL_ERROR "Package only supports Windows or Linux desktop.")
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY
|
||||
|
@ -28,18 +36,35 @@ file(MAKE_DIRECTORY
|
|||
${CURRENT_PACKAGES_DIR}/debug/lib
|
||||
${CURRENT_PACKAGES_DIR}/debug/bin
|
||||
)
|
||||
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/openvr_api.lib DESTINATION ${CURRENT_PACKAGES_DIR}/lib)
|
||||
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/openvr_api.lib DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib)
|
||||
file(COPY
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.dll
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.pdb
|
||||
DESTINATION ${CURRENT_PACKAGES_DIR}/bin
|
||||
)
|
||||
file(COPY
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.dll
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.pdb
|
||||
DESTINATION ${CURRENT_PACKAGES_DIR}/debug/bin
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/openvr_api.lib DESTINATION ${CURRENT_PACKAGES_DIR}/lib)
|
||||
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/openvr_api.lib DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib)
|
||||
file(COPY
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.dll
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.pdb
|
||||
DESTINATION ${CURRENT_PACKAGES_DIR}/bin
|
||||
)
|
||||
file(COPY
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.dll
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.pdb
|
||||
DESTINATION ${CURRENT_PACKAGES_DIR}/debug/bin
|
||||
)
|
||||
else()
|
||||
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/libopenvr_api.so DESTINATION ${CURRENT_PACKAGES_DIR}/lib)
|
||||
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/libopenvr_api.so DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib)
|
||||
file(COPY
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/libopenvr_api.so
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/libopenvr_api.so.dbg
|
||||
DESTINATION ${CURRENT_PACKAGES_DIR}/bin
|
||||
)
|
||||
file(COPY
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/libopenvr_api.so
|
||||
${SOURCE_PATH}/bin/${ARCH_PATH}/libopenvr_api.so.dbg
|
||||
DESTINATION ${CURRENT_PACKAGES_DIR}/debug/bin
|
||||
)
|
||||
endif()
|
||||
|
||||
file(COPY ${SOURCE_PATH}/headers DESTINATION ${CURRENT_PACKAGES_DIR})
|
||||
file(RENAME ${CURRENT_PACKAGES_DIR}/headers ${CURRENT_PACKAGES_DIR}/include)
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#
|
||||
# Created by Bradley Austin Davis on 2015/11/18
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
# Copyright 2020 Vircadia contributors.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
if (WIN32 AND (NOT USE_GLES))
|
||||
if ((WIN32 OR UNIX AND NOT APPLE) AND NOT USE_GLES)
|
||||
set(TARGET_NAME openvr)
|
||||
setup_hifi_plugin(Gui Qml Multimedia)
|
||||
link_hifi_libraries(shared task gl qml networking controllers ui
|
||||
|
@ -15,7 +16,9 @@ if (WIN32 AND (NOT USE_GLES))
|
|||
include_hifi_library_headers(octree)
|
||||
|
||||
target_openvr()
|
||||
target_sranipal()
|
||||
target_aristo()
|
||||
target_link_libraries(${TARGET_NAME} Winmm.lib)
|
||||
if (WIN32)
|
||||
target_sranipal()
|
||||
target_aristo()
|
||||
target_link_libraries(${TARGET_NAME} Winmm.lib)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/05/12
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
// Copyright 2020 Vircadia contributors.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -739,6 +740,8 @@ int OpenVrDisplayPlugin::getRequiredThreadCount() const {
|
|||
|
||||
QString OpenVrDisplayPlugin::getPreferredAudioInDevice() const {
|
||||
QString device = getVrSettingString(vr::k_pch_audio_Section, vr::k_pch_audio_RecordingDeviceOverride_String);
|
||||
// FIXME: Address Linux.
|
||||
#ifdef Q_OS_WIN
|
||||
if (!device.isEmpty()) {
|
||||
static const WCHAR INIT = 0;
|
||||
size_t size = device.size() + 1;
|
||||
|
@ -748,11 +751,14 @@ QString OpenVrDisplayPlugin::getPreferredAudioInDevice() const {
|
|||
// FIXME: This may not be necessary if vr::k_pch_audio_RecordingDeviceOverride_StringName is used above.
|
||||
device = AudioClient::getWinDeviceName(deviceW.data());
|
||||
}
|
||||
#endif
|
||||
return device;
|
||||
}
|
||||
|
||||
QString OpenVrDisplayPlugin::getPreferredAudioOutDevice() const {
|
||||
QString device = getVrSettingString(vr::k_pch_audio_Section, vr::k_pch_audio_PlaybackDeviceOverride_String);
|
||||
// FIXME: Address Linux.
|
||||
#ifdef Q_OS_WIN
|
||||
if (!device.isEmpty()) {
|
||||
static const WCHAR INIT = 0;
|
||||
size_t size = device.size() + 1;
|
||||
|
@ -762,6 +768,7 @@ QString OpenVrDisplayPlugin::getPreferredAudioOutDevice() const {
|
|||
// FIXME: This may not be necessary if vr::k_pch_audio_PlaybackDeviceOverride_StringName is used above.
|
||||
device = AudioClient::getWinDeviceName(deviceW.data());
|
||||
}
|
||||
#endif
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/11/01
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
// Copyright 2020 Vircadia contributors.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -18,8 +19,6 @@
|
|||
#include <QtGui/QInputMethodEvent>
|
||||
#include <QtQuick/QQuickWindow>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <Windows.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <controllers/Pose.h>
|
||||
#include <NumericalConstants.h>
|
||||
|
@ -51,7 +50,7 @@ static const uint32_t RELEASE_OPENVR_HMD_DELAY_MS = 5000;
|
|||
|
||||
bool isOculusPresent() {
|
||||
bool result = false;
|
||||
#if defined(Q_OS_WIN32)
|
||||
#ifdef Q_OS_WIN
|
||||
HANDLE oculusServiceEvent = ::OpenEventW(SYNCHRONIZE, FALSE, L"OculusHMDConnected");
|
||||
// The existence of the service indicates a running Oculus runtime
|
||||
if (oculusServiceEvent) {
|
||||
|
@ -208,8 +207,10 @@ void finishOpenVrKeyboardInput() {
|
|||
updateFromOpenVrKeyboardInput();
|
||||
// Simulate an enter press on the top level window to trigger the action
|
||||
if (0 == (_currentHints & Qt::ImhMultiLine)) {
|
||||
qApp->sendEvent(offscreenUi->getWindow(), &QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::KeyboardModifiers(), QString("\n")));
|
||||
qApp->sendEvent(offscreenUi->getWindow(), &QKeyEvent(QEvent::KeyRelease, Qt::Key_Return, Qt::KeyboardModifiers()));
|
||||
auto keyPress = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::KeyboardModifiers(), QString("\n"));
|
||||
auto keyRelease = QKeyEvent(QEvent::KeyRelease, Qt::Key_Return, Qt::KeyboardModifiers());
|
||||
qApp->sendEvent(offscreenUi->getWindow(), &keyPress);
|
||||
qApp->sendEvent(offscreenUi->getWindow(), &keyRelease);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,11 +294,20 @@ void handleOpenVrEvents() {
|
|||
ulong promitySensorFlag = (1UL << ((int)vr::k_EButton_ProximitySensor));
|
||||
_headInHeadset = (controllerState.ulButtonPressed & promitySensorFlag) == promitySensorFlag;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if DEV_BUILD
|
||||
qDebug() << "OpenVR: Event " << activeHmd->GetEventTypeNameFromEnum((vr::EVREventType)event.eventType) << "(" << event.eventType << ")";
|
||||
//qDebug() << "OpenVR: Event " << activeHmd->GetEventTypeNameFromEnum((vr::EVREventType)event.eventType) << "(" << event.eventType << ")";
|
||||
// FIXME: Reinstate the line above and remove the following lines once the problem with excessive occurrences of
|
||||
// VREvent_ActionBindingReloaded events is fixed in SteamVR for Linux.
|
||||
// https://github.com/ValveSoftware/SteamVR-for-Linux/issues/307
|
||||
#ifdef Q_OS_LINUX
|
||||
if (event.eventType != vr::VREvent_ActionBindingReloaded) {
|
||||
qDebug() << "OpenVR: Event " << activeHmd->GetEventTypeNameFromEnum((vr::EVREventType)event.eventType) << "(" << event.eventType << ")";
|
||||
};
|
||||
#else
|
||||
qDebug() << "OpenVR: Event " << activeHmd->GetEventTypeNameFromEnum((vr::EVREventType)event.eventType) << "(" << event.eventType << ")";
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -407,9 +417,32 @@ void showMinSpecWarning() {
|
|||
qFatal("Unable to create overlay");
|
||||
}
|
||||
|
||||
// Needed here for PathUtils
|
||||
#ifdef Q_OS_LINUX
|
||||
QFile cmdlineFile("/proc/self/cmdline");
|
||||
if (!cmdlineFile.open(QIODevice::ReadOnly)) {
|
||||
qFatal("Unable to open /proc/self/cmdline");
|
||||
}
|
||||
|
||||
auto contents = cmdlineFile.readAll();
|
||||
auto arguments = contents.split('\0');
|
||||
arguments.pop_back(); // Last element is empty.
|
||||
cmdlineFile.close();
|
||||
|
||||
int __argc = arguments.count();
|
||||
char** __argv = new char* [__argc];
|
||||
for (int i = 0; i < __argc; i++) {
|
||||
__argv[i] = arguments[i].data();
|
||||
}
|
||||
#endif
|
||||
|
||||
QCoreApplication miniApp(__argc, __argv);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
QObject::connect(&miniApp, &QCoreApplication::destroyed, [=] {
|
||||
delete[] __argv;
|
||||
});
|
||||
#endif
|
||||
|
||||
vrSystem->ResetSeatedZeroPose();
|
||||
QString imagePath = PathUtils::resourcesPath() + "/images/steam-min-spec-failed.png";
|
||||
vrOverlay->SetOverlayFromFile(minSpecFailedOverlay, imagePath.toLocal8Bit().toStdString().c_str());
|
||||
|
@ -487,7 +520,12 @@ bool checkMinSpecImpl() {
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
#if defined(Q_OS_WIN32)
|
||||
__declspec(dllexport) int __stdcall CheckMinSpec() {
|
||||
#else
|
||||
__attribute__((visibility("default"))) int CheckMinSpec() {
|
||||
#endif
|
||||
return checkMinSpecImpl() ? 1 : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/06/12
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
// Copyright 2020 Vircadia contributors.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -76,7 +77,7 @@ struct PoseData {
|
|||
}
|
||||
|
||||
void update(const glm::mat4& resetMat) {
|
||||
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||
for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||
if (!vrPoses[i].bPoseIsValid) {
|
||||
continue;
|
||||
}
|
||||
|
@ -87,7 +88,7 @@ struct PoseData {
|
|||
}
|
||||
|
||||
void resetToInvalid() {
|
||||
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||
for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||
vrPoses[i].bPoseIsValid = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//
|
||||
// ViveControllerManager.cpp
|
||||
// input-plugins/src/input-plugins
|
||||
//
|
||||
// Created by Sam Gondelman on 6/29/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
// Copyright 2020 Vircadia contributors.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -19,10 +19,12 @@
|
|||
#pragma warning( disable : 4334 )
|
||||
#endif
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
#include <SRanipal.h>
|
||||
#include <SRanipal_Eye.h>
|
||||
#include <SRanipal_Enums.h>
|
||||
#include <interface_gesture.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning( pop )
|
||||
|
@ -49,7 +51,7 @@
|
|||
#include <plugins/DisplayPlugin.h>
|
||||
|
||||
#include <controllers/UserInputMapper.h>
|
||||
#include <Plugins/InputConfiguration.h>
|
||||
#include <plugins/InputConfiguration.h>
|
||||
#include <controllers/StandardControls.h>
|
||||
|
||||
#include "OpenVrDisplayPlugin.h"
|
||||
|
@ -60,13 +62,8 @@ vr::IVRSystem* acquireOpenVrSystem();
|
|||
void releaseOpenVrSystem();
|
||||
|
||||
static const QString OPENVR_LAYOUT = QString("OpenVrConfiguration.qml");
|
||||
static const char* CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
|
||||
const quint64 CALIBRATION_TIMELAPSE = 1 * USECS_PER_SECOND;
|
||||
|
||||
static const char* MENU_PARENT = "Avatar";
|
||||
static const char* MENU_NAME = "Vive Controllers";
|
||||
static const char* MENU_PATH = "Avatar" ">" "Vive Controllers";
|
||||
|
||||
static const int MIN_HEAD = 1;
|
||||
static const int MIN_PUCK_COUNT = 2;
|
||||
static const int MIN_FEET_AND_HIPS = 3;
|
||||
|
@ -79,6 +76,7 @@ static const int SECOND_FOOT = 1;
|
|||
static const int HIP = 2;
|
||||
static const int CHEST = 3;
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
enum ViveHandJointIndex {
|
||||
HAND = 0,
|
||||
THUMB_1,
|
||||
|
@ -104,6 +102,7 @@ enum ViveHandJointIndex {
|
|||
|
||||
Size
|
||||
};
|
||||
#endif
|
||||
|
||||
const char* ViveControllerManager::NAME { "OpenVR" };
|
||||
|
||||
|
@ -157,22 +156,7 @@ static QString deviceTrackingResultToString(vr::ETrackingResult trackingResult)
|
|||
return result;
|
||||
}
|
||||
|
||||
static glm::mat4 calculateResetMat() {
|
||||
auto chaperone = vr::VRChaperone();
|
||||
if (chaperone) {
|
||||
float const UI_RADIUS = 1.0f;
|
||||
float const UI_HEIGHT = 1.6f;
|
||||
float const UI_Z_OFFSET = 0.5;
|
||||
|
||||
float xSize, zSize;
|
||||
chaperone->GetPlayAreaSize(&xSize, &zSize);
|
||||
glm::vec3 uiPos(0.0f, UI_HEIGHT, UI_RADIUS - (0.5f * zSize) - UI_Z_OFFSET);
|
||||
|
||||
return glm::inverse(createMatFromQuatAndPos(glm::quat(), uiPos));
|
||||
}
|
||||
return glm::mat4();
|
||||
}
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
class ViveProEyeReadThread : public QThread {
|
||||
public:
|
||||
ViveProEyeReadThread() {
|
||||
|
@ -216,6 +200,7 @@ public:
|
|||
QMutex eyeDataMutex;
|
||||
EyeDataBuffer eyeDataBuffer;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static QString outOfRangeDataStrategyToString(ViveControllerManager::OutOfRangeDataStrategy strategy) {
|
||||
|
@ -328,7 +313,7 @@ bool areBothHandControllersActive(vr::IVRSystem*& system) {
|
|||
isHandControllerActive(system, vr::TrackedControllerRole_RightHand);
|
||||
}
|
||||
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
void ViveControllerManager::enableGestureDetection() {
|
||||
if (_viveCameraHandTracker) {
|
||||
return;
|
||||
|
@ -373,6 +358,7 @@ void ViveControllerManager::disableGestureDetection() {
|
|||
StopGestureDetection();
|
||||
_viveCameraHandTracker = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ViveControllerManager::activate() {
|
||||
InputPlugin::activate();
|
||||
|
@ -394,6 +380,7 @@ bool ViveControllerManager::activate() {
|
|||
userInputMapper->registerDevice(_inputDevice);
|
||||
_registeredWithInputMapper = true;
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
if (ViveSR::anipal::Eye::IsViveProEye()) {
|
||||
qDebug() << "Vive Pro eye-tracking detected";
|
||||
|
||||
|
@ -414,6 +401,7 @@ bool ViveControllerManager::activate() {
|
|||
_viveProEyeReadThread->start(QThread::HighPriority);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -436,12 +424,14 @@ void ViveControllerManager::deactivate() {
|
|||
userInputMapper->removeDevice(_inputDevice->_deviceID);
|
||||
_registeredWithInputMapper = false;
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
if (_viveProEyeReadThread) {
|
||||
_viveProEyeReadThread->quit = true;
|
||||
_viveProEyeReadThread->wait();
|
||||
_viveProEyeReadThread = nullptr;
|
||||
ViveSR::anipal::Release(ViveSR::anipal::Eye::ANIPAL_TYPE_EYE);
|
||||
}
|
||||
#endif
|
||||
|
||||
saveSettings();
|
||||
}
|
||||
|
@ -454,6 +444,7 @@ bool ViveControllerManager::isHeadControllerMounted() const {
|
|||
return activityLevel == vr::k_EDeviceActivityLevel_UserInteraction;
|
||||
}
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
void ViveControllerManager::invalidateEyeInputs() {
|
||||
_inputDevice->_poseStateMap[controller::LEFT_EYE].valid = false;
|
||||
_inputDevice->_poseStateMap[controller::RIGHT_EYE].valid = false;
|
||||
|
@ -461,7 +452,6 @@ void ViveControllerManager::invalidateEyeInputs() {
|
|||
_inputDevice->_axisStateMap[controller::EYEBLINK_R].valid = false;
|
||||
}
|
||||
|
||||
|
||||
void ViveControllerManager::updateEyeTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
if (!isHeadControllerMounted()) {
|
||||
invalidateEyeInputs();
|
||||
|
@ -763,6 +753,7 @@ void ViveControllerManager::updateCameraHandTracker(float deltaTime,
|
|||
}
|
||||
_lastHandTrackerFrameIndex = handTrackerFrameIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
|
@ -801,11 +792,14 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
|
|||
_registeredWithInputMapper = true;
|
||||
}
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
if (_viveProEye) {
|
||||
updateEyeTracker(deltaTime, inputCalibrationData);
|
||||
}
|
||||
|
||||
updateCameraHandTracker(deltaTime, inputCalibrationData);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void ViveControllerManager::loadSettings() {
|
||||
|
@ -879,7 +873,7 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
|
|||
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
||||
|
||||
// collect poses for all generic trackers
|
||||
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||
for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||
handleTrackedObject(i, inputCalibrationData);
|
||||
handleHmd(i, inputCalibrationData);
|
||||
}
|
||||
|
@ -954,8 +948,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
|||
bool overrideHead = headObject["override"].toBool();
|
||||
if (overrideHead) {
|
||||
_headConfig = HeadConfig::Puck;
|
||||
_headPuckYOffset = headObject["Y"].toDouble() * CM_TO_M;
|
||||
_headPuckZOffset = headObject["Z"].toDouble() * CM_TO_M;
|
||||
_headPuckYOffset = (float)headObject["Y"].toDouble() * CM_TO_M;
|
||||
_headPuckZOffset = (float)headObject["Z"].toDouble() * CM_TO_M;
|
||||
} else {
|
||||
_headConfig = HeadConfig::HMD;
|
||||
}
|
||||
|
@ -964,8 +958,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
|||
bool overrideHands = handsObject["override"].toBool();
|
||||
if (overrideHands) {
|
||||
_handConfig = HandConfig::Pucks;
|
||||
_handPuckYOffset = handsObject["Y"].toDouble() * CM_TO_M;
|
||||
_handPuckZOffset = handsObject["Z"].toDouble() * CM_TO_M;
|
||||
_handPuckYOffset = (float)handsObject["Y"].toDouble() * CM_TO_M;
|
||||
_handPuckZOffset = (float)handsObject["Z"].toDouble() * CM_TO_M;
|
||||
} else {
|
||||
_handConfig = HandConfig::HandController;
|
||||
}
|
||||
|
@ -999,8 +993,8 @@ QJsonObject ViveControllerManager::InputDevice::configurationSettings() {
|
|||
configurationSettings["HMDHead"] = (_headConfig == HeadConfig::HMD);
|
||||
configurationSettings["handController"] = (_handConfig == HandConfig::HandController);
|
||||
configurationSettings["puckCount"] = (int)_validTrackedObjects.size();
|
||||
configurationSettings["armCircumference"] = (double)_armCircumference * M_TO_CM;
|
||||
configurationSettings["shoulderWidth"] = (double)_shoulderWidth * M_TO_CM;
|
||||
configurationSettings["armCircumference"] = (double)(_armCircumference * M_TO_CM);
|
||||
configurationSettings["shoulderWidth"] = (double)(_shoulderWidth * M_TO_CM);
|
||||
configurationSettings["outOfRangeDataStrategy"] = outOfRangeDataStrategyToString(_outOfRangeDataStrategy);
|
||||
return configurationSettings;
|
||||
}
|
||||
|
@ -1217,8 +1211,6 @@ bool ViveControllerManager::InputDevice::configureHead(const glm::mat4& defaultT
|
|||
bool ViveControllerManager::InputDevice::configureBody(const glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration) {
|
||||
std::sort(_validTrackedObjects.begin(), _validTrackedObjects.end(), sortPucksYPosition);
|
||||
int puckCount = (int)_validTrackedObjects.size();
|
||||
glm::vec3 headXAxis = getReferenceHeadXAxis(defaultToReferenceMat, inputCalibration.defaultHeadMat);
|
||||
glm::vec3 headPosition = getReferenceHeadPosition(defaultToReferenceMat, inputCalibration.defaultHeadMat);
|
||||
if (_config == Config::None) {
|
||||
return true;
|
||||
} else if (_config == Config::Feet && puckCount >= MIN_PUCK_COUNT) {
|
||||
|
@ -1316,8 +1308,6 @@ controller::Pose ViveControllerManager::InputDevice::addOffsetToPuckPose(const c
|
|||
}
|
||||
|
||||
void ViveControllerManager::InputDevice::handleHmd(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex;
|
||||
|
||||
if (_system->IsTrackedDeviceConnected(deviceIndex) &&
|
||||
_system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_HMD &&
|
||||
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid) {
|
||||
|
@ -1491,11 +1481,11 @@ void ViveControllerManager::InputDevice::printDeviceTrackingResultChange(uint32_
|
|||
}
|
||||
|
||||
bool ViveControllerManager::InputDevice::checkForCalibrationEvent() {
|
||||
auto& endOfMap = _buttonPressedMap.end();
|
||||
auto& leftTrigger = _buttonPressedMap.find(controller::LT);
|
||||
auto& rightTrigger = _buttonPressedMap.find(controller::RT);
|
||||
auto& leftAppButton = _buttonPressedMap.find(LEFT_APP_MENU);
|
||||
auto& rightAppButton = _buttonPressedMap.find(RIGHT_APP_MENU);
|
||||
auto endOfMap = _buttonPressedMap.end();
|
||||
auto leftTrigger = _buttonPressedMap.find(controller::LT);
|
||||
auto rightTrigger = _buttonPressedMap.find(controller::RT);
|
||||
auto leftAppButton = _buttonPressedMap.find(LEFT_APP_MENU);
|
||||
auto rightAppButton = _buttonPressedMap.find(RIGHT_APP_MENU);
|
||||
return ((leftTrigger != endOfMap && leftAppButton != endOfMap) && (rightTrigger != endOfMap && rightAppButton != endOfMap));
|
||||
}
|
||||
|
||||
|
@ -1846,10 +1836,74 @@ void ViveControllerManager::InputDevice::setConfigFromString(const QString& valu
|
|||
* <tr><td><code>Hips</code></td><td>number</td><td>{@link Pose}</td><td>Hips pose.</td></tr>
|
||||
* <tr><td><code>Spine2</code></td><td>number</td><td>{@link Pose}</td><td>Spine2 pose.</td></tr>
|
||||
* <tr><td><code>Head</code></td><td>number</td><td>{@link Pose}</td><td>Head pose.</td></tr>
|
||||
* <tr><td><code>LeftEye</code></td><td>number</td><td>{@link Pose}</td><td>Left eye pose.</td></tr>
|
||||
* <tr><td><code>RightEye</code></td><td>number</td><td>{@link Pose}</td><td>Right eye pose.</td></tr>
|
||||
* <tr><td><code>EyeBlink_L</code></td><td>number</td><td>number</td><td>Left eyelid blink.</td></tr>
|
||||
* <tr><td><code>EyeBlink_R</code></td><td>number</td><td>number</td><td>Right eyelid blink.</td></tr>
|
||||
* <tr><td><code>LeftArm</code></td><td>number</td><td>{@link Pose}</td><td>Left arm pose.</td></tr>
|
||||
* <tr><td><code>RightArm</code></td><td>number</td><td>{@link Pose}</td><td>Right arm pose</td></tr>
|
||||
* <tr><td><code>LeftHand</code></td><td>number</td><td>{@link Pose}</td><td>Left hand pose.</td></tr>
|
||||
* <tr><td><code>LeftHandThumb1</code></td><td>number</td><td>{@link Pose}</td><td>Left thumb 1 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandThumb2</code></td><td>number</td><td>{@link Pose}</td><td>Left thumb 2 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandThumb3</code></td><td>number</td><td>{@link Pose}</td><td>Left thumb 3 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandThumb4</code></td><td>number</td><td>{@link Pose}</td><td>Left thumb 4 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandIndex1</code></td><td>number</td><td>{@link Pose}</td><td>Left index 1 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandIndex2</code></td><td>number</td><td>{@link Pose}</td><td>Left index 2 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandIndex3</code></td><td>number</td><td>{@link Pose}</td><td>Left index 3 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandIndex4</code></td><td>number</td><td>{@link Pose}</td><td>Left index 4 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandMiddle1</code></td><td>number</td><td>{@link Pose}</td><td>Left middle 1 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>LeftHandMiddle2</code></td><td>number</td><td>{@link Pose}</td><td>Left middle 2 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>LeftHandMiddle3</code></td><td>number</td><td>{@link Pose}</td><td>Left middle 3 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>LeftHandMiddle4</code></td><td>number</td><td>{@link Pose}</td><td>Left middle 4 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>LeftHandRing1</code></td><td>number</td><td>{@link Pose}</td><td>Left ring 1 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandRing2</code></td><td>number</td><td>{@link Pose}</td><td>Left ring 2 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandRing3</code></td><td>number</td><td>{@link Pose}</td><td>Left ring 3 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandRing4</code></td><td>number</td><td>{@link Pose}</td><td>Left ring 4 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandPinky1</code></td><td>number</td><td>{@link Pose}</td><td>Left pinky 1 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandPinky2</code></td><td>number</td><td>{@link Pose}</td><td>Left pinky 2 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandPinky3</code></td><td>number</td><td>{@link Pose}</td><td>Left pinky 3 finger joint pose.</td></tr>
|
||||
* <tr><td><code>LeftHandPinky4</code></td><td>number</td><td>{@link Pose}</td><td>Left pinky 4 finger joint pose.</td></tr>
|
||||
* <tr><td><code>RightHand</code></td><td>number</td><td>{@link Pose}</td><td>Right hand pose.</td></tr>
|
||||
* <tr><td><code>RightHandThumb1</code></td><td>number</td><td>{@link Pose}</td><td>Right thumb 1 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandThumb2</code></td><td>number</td><td>{@link Pose}</td><td>Right thumb 2 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandThumb3</code></td><td>number</td><td>{@link Pose}</td><td>Right thumb 3 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandThumb4</code></td><td>number</td><td>{@link Pose}</td><td>Right thumb 4 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandIndex1</code></td><td>number</td><td>{@link Pose}</td><td>Right index 1 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandIndex2</code></td><td>number</td><td>{@link Pose}</td><td>Right index 2 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandIndex3</code></td><td>number</td><td>{@link Pose}</td><td>Right index 3 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandIndex4</code></td><td>number</td><td>{@link Pose}</td><td>Right index 4 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandMiddle1</code></td><td>number</td><td>{@link Pose}</td><td>Right middle 1 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandMiddle2</code></td><td>number</td><td>{@link Pose}</td><td>Right middle 2 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandMiddle3</code></td><td>number</td><td>{@link Pose}</td><td>Right middle 3 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandMiddle4</code></td><td>number</td><td>{@link Pose}</td><td>Right middle 4 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandRing1</code></td><td>number</td><td>{@link Pose}</td><td>Right ring 1 finger joint pose.</td></tr>
|
||||
* <tr><td><code>RightHandRing2</code></td><td>number</td><td>{@link Pose}</td><td>Right ring 2 finger joint pose.</td></tr>
|
||||
* <tr><td><code>RightHandRing3</code></td><td>number</td><td>{@link Pose}</td><td>Right ring 3 finger joint pose.</td></tr>
|
||||
* <tr><td><code>RightHandRing4</code></td><td>number</td><td>{@link Pose}</td><td>Right ring 4 finger joint pose.</td></tr>
|
||||
* <tr><td><code>RightHandPinky1</code></td><td>number</td><td>{@link Pose}</td><td>Right pinky 1 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandPinky2</code></td><td>number</td><td>{@link Pose}</td><td>Right pinky 2 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandPinky3</code></td><td>number</td><td>{@link Pose}</td><td>Right pinky 3 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightHandPinky4</code></td><td>number</td><td>{@link Pose}</td><td>Right pinky 4 finger joint pose.
|
||||
* </td></tr>
|
||||
* <tr><td colspan="4"><strong>Trackers</strong></td></tr>
|
||||
* <tr><td><code>TrackedObject00</code></td><td>number</td><td>{@link Pose}</td><td>Tracker 0 pose.</td></tr>
|
||||
* <tr><td><code>TrackedObject01</code></td><td>number</td><td>{@link Pose}</td><td>Tracker 1 pose.</td></tr>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//
|
||||
// ViveControllerManager.h
|
||||
// input-plugins/src/input-plugins
|
||||
//
|
||||
// Created by Sam Gondelman on 6/29/15.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
// Copyright 2020 Vircadia contributors.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -25,12 +25,18 @@
|
|||
#include <plugins/InputPlugin.h>
|
||||
#include "OpenVrHelpers.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#define VIVE_PRO_EYE
|
||||
#endif
|
||||
|
||||
using PuckPosePair = std::pair<uint32_t, controller::Pose>;
|
||||
|
||||
namespace vr {
|
||||
class IVRSystem;
|
||||
}
|
||||
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
class ViveProEyeReadThread;
|
||||
|
||||
class EyeDataBuffer {
|
||||
|
@ -45,7 +51,7 @@ public:
|
|||
float leftEyeOpenness { 0.0f };
|
||||
float rightEyeOpenness { 0.0f };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class ViveControllerManager : public InputPlugin {
|
||||
|
@ -66,18 +72,22 @@ public:
|
|||
bool isHeadController() const override { return true; }
|
||||
bool isHeadControllerMounted() const;
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
void enableGestureDetection();
|
||||
void disableGestureDetection();
|
||||
#endif
|
||||
|
||||
bool activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
QString getDeviceName() { return QString::fromStdString(_inputDevice->_headsetName); }
|
||||
QString getDeviceName() override { return QString::fromStdString(_inputDevice->_headsetName); }
|
||||
|
||||
void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||
#ifdef VIVE_PRO_EYE
|
||||
void invalidateEyeInputs();
|
||||
void updateEyeTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData);
|
||||
void updateCameraHandTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData);
|
||||
#endif
|
||||
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||
|
||||
virtual void saveSettings() const override;
|
||||
|
@ -252,6 +262,7 @@ private:
|
|||
vr::IVRSystem* _system { nullptr };
|
||||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>(_system) };
|
||||
|
||||
#ifdef VIVE_PRO_EYE
|
||||
bool _viveProEye { false };
|
||||
std::shared_ptr<ViveProEyeReadThread> _viveProEyeReadThread;
|
||||
EyeDataBuffer _prevEyeData;
|
||||
|
@ -268,6 +279,7 @@ private:
|
|||
void trackFinger(int hand, int jointIndex1, int jointIndex2, int jointIndex3, int jointIndex4,
|
||||
controller::StandardPoseChannel joint1, controller::StandardPoseChannel joint2,
|
||||
controller::StandardPoseChannel joint3, controller::StandardPoseChannel joint4);
|
||||
#endif
|
||||
|
||||
static const char* NAME;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue