mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-30 19:11:24 +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.
|
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
|
- [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
|
- [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)
|
- [Oculus SDK](https://developer.oculus.com/downloads/): 1.11 (Windows) / 0.5 (Mac)
|
||||||
- [OpenVR](https://github.com/ValveSoftware/openvr): 1.11.11 (Win32 only)
|
- [OpenVR](https://github.com/ValveSoftware/openvr): 1.11.11 (Windows, Linux)
|
||||||
- [Polyvox](http://www.volumesoffun.com/): 0.2.1
|
- [Polyvox](http://www.volumesoffun.com/): 0.2.1
|
||||||
- [QuaZip](https://sourceforge.net/projects/quazip/files/quazip/): 0.7.3
|
- [QuaZip](https://sourceforge.net/projects/quazip/files/quazip/): 0.7.3
|
||||||
- [SDL2](https://www.libsdl.org/download-2.0.php): 2.0.3
|
- [SDL2](https://www.libsdl.org/download-2.0.php): 2.0.3
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Source: hifi-client-deps
|
Source: hifi-client-deps
|
||||||
Version: 0.1
|
Version: 0.1
|
||||||
Description: Collected dependencies for High Fidelity applications
|
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)
|
set(VCPKG_LIBRARY_LINKAGE dynamic)
|
||||||
|
|
||||||
if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
|
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")
|
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86")
|
||||||
set(ARCH_PATH "win32")
|
if(WIN32)
|
||||||
|
set(ARCH_PATH "win32")
|
||||||
|
else()
|
||||||
|
set(ARCH_PATH "linux32")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Package only supports x64 and x86 windows.")
|
message(FATAL_ERROR "Package only supports x64 and x86 Windows and Linux.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(VCPKG_CMAKE_SYSTEM_NAME)
|
if(VCPKG_CMAKE_SYSTEM_NAME AND NOT (VCPKG_CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
||||||
message(FATAL_ERROR "Package only supports windows desktop.")
|
message(FATAL_ERROR "Package only supports Windows or Linux desktop.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(MAKE_DIRECTORY
|
file(MAKE_DIRECTORY
|
||||||
|
@ -28,18 +36,35 @@ file(MAKE_DIRECTORY
|
||||||
${CURRENT_PACKAGES_DIR}/debug/lib
|
${CURRENT_PACKAGES_DIR}/debug/lib
|
||||||
${CURRENT_PACKAGES_DIR}/debug/bin
|
${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)
|
if(WIN32)
|
||||||
file(COPY
|
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/openvr_api.lib DESTINATION ${CURRENT_PACKAGES_DIR}/lib)
|
||||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.dll
|
file(COPY ${SOURCE_PATH}/lib/${ARCH_PATH}/openvr_api.lib DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib)
|
||||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.pdb
|
file(COPY
|
||||||
DESTINATION ${CURRENT_PACKAGES_DIR}/bin
|
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.dll
|
||||||
)
|
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.pdb
|
||||||
file(COPY
|
DESTINATION ${CURRENT_PACKAGES_DIR}/bin
|
||||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.dll
|
)
|
||||||
${SOURCE_PATH}/bin/${ARCH_PATH}/openvr_api.pdb
|
file(COPY
|
||||||
DESTINATION ${CURRENT_PACKAGES_DIR}/debug/bin
|
${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(COPY ${SOURCE_PATH}/headers DESTINATION ${CURRENT_PACKAGES_DIR})
|
||||||
file(RENAME ${CURRENT_PACKAGES_DIR}/headers ${CURRENT_PACKAGES_DIR}/include)
|
file(RENAME ${CURRENT_PACKAGES_DIR}/headers ${CURRENT_PACKAGES_DIR}/include)
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#
|
#
|
||||||
# Created by Bradley Austin Davis on 2015/11/18
|
# Created by Bradley Austin Davis on 2015/11/18
|
||||||
# Copyright 2015 High Fidelity, Inc.
|
# Copyright 2015 High Fidelity, Inc.
|
||||||
|
# Copyright 2020 Vircadia contributors.
|
||||||
#
|
#
|
||||||
# Distributed under the Apache License, Version 2.0.
|
# Distributed under the Apache License, Version 2.0.
|
||||||
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
|
# 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)
|
set(TARGET_NAME openvr)
|
||||||
setup_hifi_plugin(Gui Qml Multimedia)
|
setup_hifi_plugin(Gui Qml Multimedia)
|
||||||
link_hifi_libraries(shared task gl qml networking controllers ui
|
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)
|
include_hifi_library_headers(octree)
|
||||||
|
|
||||||
target_openvr()
|
target_openvr()
|
||||||
target_sranipal()
|
if (WIN32)
|
||||||
target_aristo()
|
target_sranipal()
|
||||||
target_link_libraries(${TARGET_NAME} Winmm.lib)
|
target_aristo()
|
||||||
|
target_link_libraries(${TARGET_NAME} Winmm.lib)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Created by Bradley Austin Davis on 2015/05/12
|
// Created by Bradley Austin Davis on 2015/05/12
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
// Copyright 2020 Vircadia contributors.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// 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 OpenVrDisplayPlugin::getPreferredAudioInDevice() const {
|
||||||
QString device = getVrSettingString(vr::k_pch_audio_Section, vr::k_pch_audio_RecordingDeviceOverride_String);
|
QString device = getVrSettingString(vr::k_pch_audio_Section, vr::k_pch_audio_RecordingDeviceOverride_String);
|
||||||
|
// FIXME: Address Linux.
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
if (!device.isEmpty()) {
|
if (!device.isEmpty()) {
|
||||||
static const WCHAR INIT = 0;
|
static const WCHAR INIT = 0;
|
||||||
size_t size = device.size() + 1;
|
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.
|
// FIXME: This may not be necessary if vr::k_pch_audio_RecordingDeviceOverride_StringName is used above.
|
||||||
device = AudioClient::getWinDeviceName(deviceW.data());
|
device = AudioClient::getWinDeviceName(deviceW.data());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVrDisplayPlugin::getPreferredAudioOutDevice() const {
|
QString OpenVrDisplayPlugin::getPreferredAudioOutDevice() const {
|
||||||
QString device = getVrSettingString(vr::k_pch_audio_Section, vr::k_pch_audio_PlaybackDeviceOverride_String);
|
QString device = getVrSettingString(vr::k_pch_audio_Section, vr::k_pch_audio_PlaybackDeviceOverride_String);
|
||||||
|
// FIXME: Address Linux.
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
if (!device.isEmpty()) {
|
if (!device.isEmpty()) {
|
||||||
static const WCHAR INIT = 0;
|
static const WCHAR INIT = 0;
|
||||||
size_t size = device.size() + 1;
|
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.
|
// FIXME: This may not be necessary if vr::k_pch_audio_PlaybackDeviceOverride_StringName is used above.
|
||||||
device = AudioClient::getWinDeviceName(deviceW.data());
|
device = AudioClient::getWinDeviceName(deviceW.data());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Created by Bradley Austin Davis on 2015/11/01
|
// Created by Bradley Austin Davis on 2015/11/01
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
// Copyright 2020 Vircadia contributors.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
@ -18,8 +19,6 @@
|
||||||
#include <QtGui/QInputMethodEvent>
|
#include <QtGui/QInputMethodEvent>
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
#include <PathUtils.h>
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <OffscreenUi.h>
|
#include <OffscreenUi.h>
|
||||||
#include <controllers/Pose.h>
|
#include <controllers/Pose.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
@ -51,7 +50,7 @@ static const uint32_t RELEASE_OPENVR_HMD_DELAY_MS = 5000;
|
||||||
|
|
||||||
bool isOculusPresent() {
|
bool isOculusPresent() {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
#if defined(Q_OS_WIN32)
|
#ifdef Q_OS_WIN
|
||||||
HANDLE oculusServiceEvent = ::OpenEventW(SYNCHRONIZE, FALSE, L"OculusHMDConnected");
|
HANDLE oculusServiceEvent = ::OpenEventW(SYNCHRONIZE, FALSE, L"OculusHMDConnected");
|
||||||
// The existence of the service indicates a running Oculus runtime
|
// The existence of the service indicates a running Oculus runtime
|
||||||
if (oculusServiceEvent) {
|
if (oculusServiceEvent) {
|
||||||
|
@ -208,8 +207,10 @@ void finishOpenVrKeyboardInput() {
|
||||||
updateFromOpenVrKeyboardInput();
|
updateFromOpenVrKeyboardInput();
|
||||||
// Simulate an enter press on the top level window to trigger the action
|
// Simulate an enter press on the top level window to trigger the action
|
||||||
if (0 == (_currentHints & Qt::ImhMultiLine)) {
|
if (0 == (_currentHints & Qt::ImhMultiLine)) {
|
||||||
qApp->sendEvent(offscreenUi->getWindow(), &QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::KeyboardModifiers(), QString("\n")));
|
auto keyPress = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::KeyboardModifiers(), QString("\n"));
|
||||||
qApp->sendEvent(offscreenUi->getWindow(), &QKeyEvent(QEvent::KeyRelease, Qt::Key_Return, Qt::KeyboardModifiers()));
|
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));
|
ulong promitySensorFlag = (1UL << ((int)vr::k_EButton_ProximitySensor));
|
||||||
_headInHeadset = (controllerState.ulButtonPressed & promitySensorFlag) == promitySensorFlag;
|
_headInHeadset = (controllerState.ulButtonPressed & promitySensorFlag) == promitySensorFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEV_BUILD
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,9 +417,32 @@ void showMinSpecWarning() {
|
||||||
qFatal("Unable to create overlay");
|
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);
|
QCoreApplication miniApp(__argc, __argv);
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
QObject::connect(&miniApp, &QCoreApplication::destroyed, [=] {
|
||||||
|
delete[] __argv;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
vrSystem->ResetSeatedZeroPose();
|
vrSystem->ResetSeatedZeroPose();
|
||||||
QString imagePath = PathUtils::resourcesPath() + "/images/steam-min-spec-failed.png";
|
QString imagePath = PathUtils::resourcesPath() + "/images/steam-min-spec-failed.png";
|
||||||
vrOverlay->SetOverlayFromFile(minSpecFailedOverlay, imagePath.toLocal8Bit().toStdString().c_str());
|
vrOverlay->SetOverlayFromFile(minSpecFailedOverlay, imagePath.toLocal8Bit().toStdString().c_str());
|
||||||
|
@ -487,7 +520,12 @@ bool checkMinSpecImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#if defined(Q_OS_WIN32)
|
||||||
__declspec(dllexport) int __stdcall CheckMinSpec() {
|
__declspec(dllexport) int __stdcall CheckMinSpec() {
|
||||||
|
#else
|
||||||
|
__attribute__((visibility("default"))) int CheckMinSpec() {
|
||||||
|
#endif
|
||||||
return checkMinSpecImpl() ? 1 : 0;
|
return checkMinSpecImpl() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
// Created by Bradley Austin Davis on 2015/06/12
|
// Created by Bradley Austin Davis on 2015/06/12
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
// Copyright 2020 Vircadia contributors.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// 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) {
|
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) {
|
if (!vrPoses[i].bPoseIsValid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +88,7 @@ struct PoseData {
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetToInvalid() {
|
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;
|
vrPoses[i].bPoseIsValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//
|
//
|
||||||
// ViveControllerManager.cpp
|
// ViveControllerManager.cpp
|
||||||
// input-plugins/src/input-plugins
|
|
||||||
//
|
//
|
||||||
// Created by Sam Gondelman on 6/29/15.
|
// Created by Sam Gondelman on 6/29/15.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
// Copyright 2020 Vircadia contributors.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
@ -19,10 +19,12 @@
|
||||||
#pragma warning( disable : 4334 )
|
#pragma warning( disable : 4334 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
#include <SRanipal.h>
|
#include <SRanipal.h>
|
||||||
#include <SRanipal_Eye.h>
|
#include <SRanipal_Eye.h>
|
||||||
#include <SRanipal_Enums.h>
|
#include <SRanipal_Enums.h>
|
||||||
#include <interface_gesture.hpp>
|
#include <interface_gesture.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma warning( pop )
|
#pragma warning( pop )
|
||||||
|
@ -49,7 +51,7 @@
|
||||||
#include <plugins/DisplayPlugin.h>
|
#include <plugins/DisplayPlugin.h>
|
||||||
|
|
||||||
#include <controllers/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
#include <Plugins/InputConfiguration.h>
|
#include <plugins/InputConfiguration.h>
|
||||||
#include <controllers/StandardControls.h>
|
#include <controllers/StandardControls.h>
|
||||||
|
|
||||||
#include "OpenVrDisplayPlugin.h"
|
#include "OpenVrDisplayPlugin.h"
|
||||||
|
@ -60,13 +62,8 @@ vr::IVRSystem* acquireOpenVrSystem();
|
||||||
void releaseOpenVrSystem();
|
void releaseOpenVrSystem();
|
||||||
|
|
||||||
static const QString OPENVR_LAYOUT = QString("OpenVrConfiguration.qml");
|
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;
|
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_HEAD = 1;
|
||||||
static const int MIN_PUCK_COUNT = 2;
|
static const int MIN_PUCK_COUNT = 2;
|
||||||
static const int MIN_FEET_AND_HIPS = 3;
|
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 HIP = 2;
|
||||||
static const int CHEST = 3;
|
static const int CHEST = 3;
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
enum ViveHandJointIndex {
|
enum ViveHandJointIndex {
|
||||||
HAND = 0,
|
HAND = 0,
|
||||||
THUMB_1,
|
THUMB_1,
|
||||||
|
@ -104,6 +102,7 @@ enum ViveHandJointIndex {
|
||||||
|
|
||||||
Size
|
Size
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
const char* ViveControllerManager::NAME { "OpenVR" };
|
const char* ViveControllerManager::NAME { "OpenVR" };
|
||||||
|
|
||||||
|
@ -157,22 +156,7 @@ static QString deviceTrackingResultToString(vr::ETrackingResult trackingResult)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static glm::mat4 calculateResetMat() {
|
#ifdef VIVE_PRO_EYE
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViveProEyeReadThread : public QThread {
|
class ViveProEyeReadThread : public QThread {
|
||||||
public:
|
public:
|
||||||
ViveProEyeReadThread() {
|
ViveProEyeReadThread() {
|
||||||
|
@ -216,6 +200,7 @@ public:
|
||||||
QMutex eyeDataMutex;
|
QMutex eyeDataMutex;
|
||||||
EyeDataBuffer eyeDataBuffer;
|
EyeDataBuffer eyeDataBuffer;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static QString outOfRangeDataStrategyToString(ViveControllerManager::OutOfRangeDataStrategy strategy) {
|
static QString outOfRangeDataStrategyToString(ViveControllerManager::OutOfRangeDataStrategy strategy) {
|
||||||
|
@ -328,7 +313,7 @@ bool areBothHandControllersActive(vr::IVRSystem*& system) {
|
||||||
isHandControllerActive(system, vr::TrackedControllerRole_RightHand);
|
isHandControllerActive(system, vr::TrackedControllerRole_RightHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
void ViveControllerManager::enableGestureDetection() {
|
void ViveControllerManager::enableGestureDetection() {
|
||||||
if (_viveCameraHandTracker) {
|
if (_viveCameraHandTracker) {
|
||||||
return;
|
return;
|
||||||
|
@ -373,6 +358,7 @@ void ViveControllerManager::disableGestureDetection() {
|
||||||
StopGestureDetection();
|
StopGestureDetection();
|
||||||
_viveCameraHandTracker = false;
|
_viveCameraHandTracker = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool ViveControllerManager::activate() {
|
bool ViveControllerManager::activate() {
|
||||||
InputPlugin::activate();
|
InputPlugin::activate();
|
||||||
|
@ -394,6 +380,7 @@ bool ViveControllerManager::activate() {
|
||||||
userInputMapper->registerDevice(_inputDevice);
|
userInputMapper->registerDevice(_inputDevice);
|
||||||
_registeredWithInputMapper = true;
|
_registeredWithInputMapper = true;
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
if (ViveSR::anipal::Eye::IsViveProEye()) {
|
if (ViveSR::anipal::Eye::IsViveProEye()) {
|
||||||
qDebug() << "Vive Pro eye-tracking detected";
|
qDebug() << "Vive Pro eye-tracking detected";
|
||||||
|
|
||||||
|
@ -414,6 +401,7 @@ bool ViveControllerManager::activate() {
|
||||||
_viveProEyeReadThread->start(QThread::HighPriority);
|
_viveProEyeReadThread->start(QThread::HighPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -436,12 +424,14 @@ void ViveControllerManager::deactivate() {
|
||||||
userInputMapper->removeDevice(_inputDevice->_deviceID);
|
userInputMapper->removeDevice(_inputDevice->_deviceID);
|
||||||
_registeredWithInputMapper = false;
|
_registeredWithInputMapper = false;
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
if (_viveProEyeReadThread) {
|
if (_viveProEyeReadThread) {
|
||||||
_viveProEyeReadThread->quit = true;
|
_viveProEyeReadThread->quit = true;
|
||||||
_viveProEyeReadThread->wait();
|
_viveProEyeReadThread->wait();
|
||||||
_viveProEyeReadThread = nullptr;
|
_viveProEyeReadThread = nullptr;
|
||||||
ViveSR::anipal::Release(ViveSR::anipal::Eye::ANIPAL_TYPE_EYE);
|
ViveSR::anipal::Release(ViveSR::anipal::Eye::ANIPAL_TYPE_EYE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
@ -454,6 +444,7 @@ bool ViveControllerManager::isHeadControllerMounted() const {
|
||||||
return activityLevel == vr::k_EDeviceActivityLevel_UserInteraction;
|
return activityLevel == vr::k_EDeviceActivityLevel_UserInteraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
void ViveControllerManager::invalidateEyeInputs() {
|
void ViveControllerManager::invalidateEyeInputs() {
|
||||||
_inputDevice->_poseStateMap[controller::LEFT_EYE].valid = false;
|
_inputDevice->_poseStateMap[controller::LEFT_EYE].valid = false;
|
||||||
_inputDevice->_poseStateMap[controller::RIGHT_EYE].valid = false;
|
_inputDevice->_poseStateMap[controller::RIGHT_EYE].valid = false;
|
||||||
|
@ -461,7 +452,6 @@ void ViveControllerManager::invalidateEyeInputs() {
|
||||||
_inputDevice->_axisStateMap[controller::EYEBLINK_R].valid = false;
|
_inputDevice->_axisStateMap[controller::EYEBLINK_R].valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ViveControllerManager::updateEyeTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
void ViveControllerManager::updateEyeTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
if (!isHeadControllerMounted()) {
|
if (!isHeadControllerMounted()) {
|
||||||
invalidateEyeInputs();
|
invalidateEyeInputs();
|
||||||
|
@ -763,6 +753,7 @@ void ViveControllerManager::updateCameraHandTracker(float deltaTime,
|
||||||
}
|
}
|
||||||
_lastHandTrackerFrameIndex = handTrackerFrameIndex;
|
_lastHandTrackerFrameIndex = handTrackerFrameIndex;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
|
@ -801,11 +792,14 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
|
||||||
_registeredWithInputMapper = true;
|
_registeredWithInputMapper = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
if (_viveProEye) {
|
if (_viveProEye) {
|
||||||
updateEyeTracker(deltaTime, inputCalibrationData);
|
updateEyeTracker(deltaTime, inputCalibrationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCameraHandTracker(deltaTime, inputCalibrationData);
|
updateCameraHandTracker(deltaTime, inputCalibrationData);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::loadSettings() {
|
void ViveControllerManager::loadSettings() {
|
||||||
|
@ -879,7 +873,7 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
|
||||||
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
||||||
|
|
||||||
// collect poses for all generic trackers
|
// 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);
|
handleTrackedObject(i, inputCalibrationData);
|
||||||
handleHmd(i, inputCalibrationData);
|
handleHmd(i, inputCalibrationData);
|
||||||
}
|
}
|
||||||
|
@ -954,8 +948,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
bool overrideHead = headObject["override"].toBool();
|
bool overrideHead = headObject["override"].toBool();
|
||||||
if (overrideHead) {
|
if (overrideHead) {
|
||||||
_headConfig = HeadConfig::Puck;
|
_headConfig = HeadConfig::Puck;
|
||||||
_headPuckYOffset = headObject["Y"].toDouble() * CM_TO_M;
|
_headPuckYOffset = (float)headObject["Y"].toDouble() * CM_TO_M;
|
||||||
_headPuckZOffset = headObject["Z"].toDouble() * CM_TO_M;
|
_headPuckZOffset = (float)headObject["Z"].toDouble() * CM_TO_M;
|
||||||
} else {
|
} else {
|
||||||
_headConfig = HeadConfig::HMD;
|
_headConfig = HeadConfig::HMD;
|
||||||
}
|
}
|
||||||
|
@ -964,8 +958,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
bool overrideHands = handsObject["override"].toBool();
|
bool overrideHands = handsObject["override"].toBool();
|
||||||
if (overrideHands) {
|
if (overrideHands) {
|
||||||
_handConfig = HandConfig::Pucks;
|
_handConfig = HandConfig::Pucks;
|
||||||
_handPuckYOffset = handsObject["Y"].toDouble() * CM_TO_M;
|
_handPuckYOffset = (float)handsObject["Y"].toDouble() * CM_TO_M;
|
||||||
_handPuckZOffset = handsObject["Z"].toDouble() * CM_TO_M;
|
_handPuckZOffset = (float)handsObject["Z"].toDouble() * CM_TO_M;
|
||||||
} else {
|
} else {
|
||||||
_handConfig = HandConfig::HandController;
|
_handConfig = HandConfig::HandController;
|
||||||
}
|
}
|
||||||
|
@ -999,8 +993,8 @@ QJsonObject ViveControllerManager::InputDevice::configurationSettings() {
|
||||||
configurationSettings["HMDHead"] = (_headConfig == HeadConfig::HMD);
|
configurationSettings["HMDHead"] = (_headConfig == HeadConfig::HMD);
|
||||||
configurationSettings["handController"] = (_handConfig == HandConfig::HandController);
|
configurationSettings["handController"] = (_handConfig == HandConfig::HandController);
|
||||||
configurationSettings["puckCount"] = (int)_validTrackedObjects.size();
|
configurationSettings["puckCount"] = (int)_validTrackedObjects.size();
|
||||||
configurationSettings["armCircumference"] = (double)_armCircumference * M_TO_CM;
|
configurationSettings["armCircumference"] = (double)(_armCircumference * M_TO_CM);
|
||||||
configurationSettings["shoulderWidth"] = (double)_shoulderWidth * M_TO_CM;
|
configurationSettings["shoulderWidth"] = (double)(_shoulderWidth * M_TO_CM);
|
||||||
configurationSettings["outOfRangeDataStrategy"] = outOfRangeDataStrategyToString(_outOfRangeDataStrategy);
|
configurationSettings["outOfRangeDataStrategy"] = outOfRangeDataStrategyToString(_outOfRangeDataStrategy);
|
||||||
return configurationSettings;
|
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) {
|
bool ViveControllerManager::InputDevice::configureBody(const glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration) {
|
||||||
std::sort(_validTrackedObjects.begin(), _validTrackedObjects.end(), sortPucksYPosition);
|
std::sort(_validTrackedObjects.begin(), _validTrackedObjects.end(), sortPucksYPosition);
|
||||||
int puckCount = (int)_validTrackedObjects.size();
|
int puckCount = (int)_validTrackedObjects.size();
|
||||||
glm::vec3 headXAxis = getReferenceHeadXAxis(defaultToReferenceMat, inputCalibration.defaultHeadMat);
|
|
||||||
glm::vec3 headPosition = getReferenceHeadPosition(defaultToReferenceMat, inputCalibration.defaultHeadMat);
|
|
||||||
if (_config == Config::None) {
|
if (_config == Config::None) {
|
||||||
return true;
|
return true;
|
||||||
} else if (_config == Config::Feet && puckCount >= MIN_PUCK_COUNT) {
|
} 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) {
|
void ViveControllerManager::InputDevice::handleHmd(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex;
|
|
||||||
|
|
||||||
if (_system->IsTrackedDeviceConnected(deviceIndex) &&
|
if (_system->IsTrackedDeviceConnected(deviceIndex) &&
|
||||||
_system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_HMD &&
|
_system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_HMD &&
|
||||||
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid) {
|
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid) {
|
||||||
|
@ -1491,11 +1481,11 @@ void ViveControllerManager::InputDevice::printDeviceTrackingResultChange(uint32_
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViveControllerManager::InputDevice::checkForCalibrationEvent() {
|
bool ViveControllerManager::InputDevice::checkForCalibrationEvent() {
|
||||||
auto& endOfMap = _buttonPressedMap.end();
|
auto endOfMap = _buttonPressedMap.end();
|
||||||
auto& leftTrigger = _buttonPressedMap.find(controller::LT);
|
auto leftTrigger = _buttonPressedMap.find(controller::LT);
|
||||||
auto& rightTrigger = _buttonPressedMap.find(controller::RT);
|
auto rightTrigger = _buttonPressedMap.find(controller::RT);
|
||||||
auto& leftAppButton = _buttonPressedMap.find(LEFT_APP_MENU);
|
auto leftAppButton = _buttonPressedMap.find(LEFT_APP_MENU);
|
||||||
auto& rightAppButton = _buttonPressedMap.find(RIGHT_APP_MENU);
|
auto rightAppButton = _buttonPressedMap.find(RIGHT_APP_MENU);
|
||||||
return ((leftTrigger != endOfMap && leftAppButton != endOfMap) && (rightTrigger != endOfMap && rightAppButton != endOfMap));
|
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>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>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>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>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>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>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>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 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>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>
|
* <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
|
// ViveControllerManager.h
|
||||||
// input-plugins/src/input-plugins
|
|
||||||
//
|
//
|
||||||
// Created by Sam Gondelman on 6/29/15.
|
// Created by Sam Gondelman on 6/29/15.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
// Copyright 2020 Vircadia contributors.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
@ -25,12 +25,18 @@
|
||||||
#include <plugins/InputPlugin.h>
|
#include <plugins/InputPlugin.h>
|
||||||
#include "OpenVrHelpers.h"
|
#include "OpenVrHelpers.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#define VIVE_PRO_EYE
|
||||||
|
#endif
|
||||||
|
|
||||||
using PuckPosePair = std::pair<uint32_t, controller::Pose>;
|
using PuckPosePair = std::pair<uint32_t, controller::Pose>;
|
||||||
|
|
||||||
namespace vr {
|
namespace vr {
|
||||||
class IVRSystem;
|
class IVRSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
class ViveProEyeReadThread;
|
class ViveProEyeReadThread;
|
||||||
|
|
||||||
class EyeDataBuffer {
|
class EyeDataBuffer {
|
||||||
|
@ -45,7 +51,7 @@ public:
|
||||||
float leftEyeOpenness { 0.0f };
|
float leftEyeOpenness { 0.0f };
|
||||||
float rightEyeOpenness { 0.0f };
|
float rightEyeOpenness { 0.0f };
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class ViveControllerManager : public InputPlugin {
|
class ViveControllerManager : public InputPlugin {
|
||||||
|
@ -66,18 +72,22 @@ public:
|
||||||
bool isHeadController() const override { return true; }
|
bool isHeadController() const override { return true; }
|
||||||
bool isHeadControllerMounted() const;
|
bool isHeadControllerMounted() const;
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
void enableGestureDetection();
|
void enableGestureDetection();
|
||||||
void disableGestureDetection();
|
void disableGestureDetection();
|
||||||
|
#endif
|
||||||
|
|
||||||
bool activate() override;
|
bool activate() override;
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
|
|
||||||
QString getDeviceName() { return QString::fromStdString(_inputDevice->_headsetName); }
|
QString getDeviceName() override { return QString::fromStdString(_inputDevice->_headsetName); }
|
||||||
|
|
||||||
void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
void invalidateEyeInputs();
|
void invalidateEyeInputs();
|
||||||
void updateEyeTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData);
|
void updateEyeTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData);
|
||||||
void updateCameraHandTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData);
|
void updateCameraHandTracker(float deltaTime, const controller::InputCalibrationData& inputCalibrationData);
|
||||||
|
#endif
|
||||||
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
virtual void saveSettings() const override;
|
virtual void saveSettings() const override;
|
||||||
|
@ -252,6 +262,7 @@ private:
|
||||||
vr::IVRSystem* _system { nullptr };
|
vr::IVRSystem* _system { nullptr };
|
||||||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>(_system) };
|
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>(_system) };
|
||||||
|
|
||||||
|
#ifdef VIVE_PRO_EYE
|
||||||
bool _viveProEye { false };
|
bool _viveProEye { false };
|
||||||
std::shared_ptr<ViveProEyeReadThread> _viveProEyeReadThread;
|
std::shared_ptr<ViveProEyeReadThread> _viveProEyeReadThread;
|
||||||
EyeDataBuffer _prevEyeData;
|
EyeDataBuffer _prevEyeData;
|
||||||
|
@ -268,6 +279,7 @@ private:
|
||||||
void trackFinger(int hand, int jointIndex1, int jointIndex2, int jointIndex3, int jointIndex4,
|
void trackFinger(int hand, int jointIndex1, int jointIndex2, int jointIndex3, int jointIndex4,
|
||||||
controller::StandardPoseChannel joint1, controller::StandardPoseChannel joint2,
|
controller::StandardPoseChannel joint1, controller::StandardPoseChannel joint2,
|
||||||
controller::StandardPoseChannel joint3, controller::StandardPoseChannel joint4);
|
controller::StandardPoseChannel joint3, controller::StandardPoseChannel joint4);
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* NAME;
|
static const char* NAME;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue