diff options
Diffstat (limited to 'tracker-steamvr/steamvr.cpp')
-rw-r--r-- | tracker-steamvr/steamvr.cpp | 133 |
1 files changed, 73 insertions, 60 deletions
diff --git a/tracker-steamvr/steamvr.cpp b/tracker-steamvr/steamvr.cpp index 32cb6ed1..05b5ed35 100644 --- a/tracker-steamvr/steamvr.cpp +++ b/tracker-steamvr/steamvr.cpp @@ -20,10 +20,8 @@ #include "api/plugin-api.hpp" -#include <cstdlib> #include <cmath> -#include <type_traits> -#include <algorithm> +#include <cstdlib> #include <QMessageBox> #include <QDebug> @@ -31,17 +29,16 @@ QMutex device_list::mtx(QMutex::Recursive); template<typename F> -auto with_vr_lock(F&& fun) -> decltype(fun(vr_t(), error_t())) +auto with_vr_lock(F&& fun) -> decltype(fun(vr_t(), vr_error_t())) { QMutexLocker l(&device_list::mtx); - error_t e; vr_t v; - std::tie(v, e) = device_list::vr_init(); + auto [v, e] = device_list::vr_init(); return fun(v, e); } void device_list::fill_device_specs(QList<device_spec>& list) { - with_vr_lock([&](vr_t v, error_t) + with_vr_lock([&](vr_t v, vr_error_t) { list.clear(); @@ -60,13 +57,13 @@ void device_list::fill_device_specs(QList<device_spec>& list) { if (v->GetTrackedDeviceClass(k) == vr::ETrackedDeviceClass::TrackedDeviceClass_Invalid) { - qDebug() << "no device with index"; + qDebug() << "steamvr: no device with index"; continue; } if (!device_states[k].bDeviceIsConnected) { - qDebug() << "device not connected but proceeding"; + qDebug() << "steamvr: device not connected but proceeding"; continue; } @@ -92,12 +89,17 @@ void device_list::fill_device_specs(QList<device_spec>& list) switch (v->GetTrackedDeviceClass(k)) { - case vr::ETrackedDeviceClass::TrackedDeviceClass_HMD: + using enum vr::ETrackedDeviceClass; + case TrackedDeviceClass_HMD: dev.type = "HMD"; break; - case vr::ETrackedDeviceClass::TrackedDeviceClass_Controller: + case TrackedDeviceClass_Controller: dev.type = "Controller"; break; - case vr::ETrackedDeviceClass::TrackedDeviceClass_TrackingReference: - dev.type = "Tracker"; break; + case TrackedDeviceClass_TrackingReference: + dev.type = "Tracking reference"; break; + case TrackedDeviceClass_DisplayRedirect: + dev.type = "Display redirect"; break; + case TrackedDeviceClass_GenericTracker: + dev.type = "Generic"; break; default: dev.type = "Unknown"; break; } @@ -126,10 +128,10 @@ void device_list::refresh_device_list() device_list::maybe_pose device_list::get_pose(int k) { - if (k < 0 || !(k < max_devices)) + if (!(unsigned(k) < max_devices)) return maybe_pose(false, pose_t{}); - return with_vr_lock([k](vr_t v, error_t) + return with_vr_lock([k](vr_t v, vr_error_t) { static pose_t poses[max_devices] {}; // vr_lock removes reentrancy @@ -139,14 +141,14 @@ device_list::maybe_pose device_list::get_pose(int k) const pose_t& pose = poses[k]; if (pose.bPoseIsValid && pose.bDeviceIsConnected) - return maybe_pose(true, poses[k]); + return maybe_pose{ true, poses[k] }; else - once_only(qDebug() << "steamvr:" + eval_once(qDebug() << "steamvr:" << "no valid pose from device" << k << "valid" << pose.bPoseIsValid << "connected" << pose.bDeviceIsConnected); - return maybe_pose(false, pose_t{}); + return maybe_pose{ false, {} }; }); } @@ -158,40 +160,43 @@ tt device_list::vr_init() tt device_list::vr_init_() { - error_t error = error_t::VRInitError_Unknown; + vr_error_t error = vr_error_t::VRInitError_Unknown; vr_t v = vr::VR_Init(&error, vr::EVRApplicationType::VRApplication_Other); if (v) std::atexit(vr::VR_Shutdown); else - qDebug() << "steamvr: init failure" << error << device_list::strerror(error); + qDebug() << "steamvr: init failure" << error << device_list::error_string(error); - return tt(v, error); + return { v, error }; } -QString device_list::strerror(error_t err) +QString device_list::error_string(vr_error_t err) { - const char* str(vr::VR_GetVRInitErrorAsSymbol(err)); - return QString(str ? str : "No description"); -} + const char* str = vr::VR_GetVRInitErrorAsSymbol(err); + const char* desc = vr::VR_GetVRInitErrorAsEnglishDescription(err); -steamvr::steamvr() : device_index(-1) -{ -} + if (!desc) + desc = "No description"; -steamvr::~steamvr() -{ + if (str) + return QStringLiteral("%1: %2").arg(str, desc); + else + return { "Unknown error" }; } +steamvr::steamvr() = default; +steamvr::~steamvr() = default; + module_status steamvr::start_tracker(QFrame*) { - return with_vr_lock([this](vr_t v, error_t e) + return with_vr_lock([this](vr_t v, vr_error_t e) { QString err; if (!v) { - err = device_list::strerror(e); + err = device_list::error_string(e); return error(err); } @@ -203,42 +208,47 @@ module_status steamvr::start_tracker(QFrame*) if (sz == 0) err = tr("No HMD connected"); - device_index = -1; - for (const device_spec& spec : specs) { if (serial == "" || serial == spec.to_string()) { - device_index = int(spec.k); + device_index = spec.k; break; } } - if (device_index == -1 && err.isEmpty()) + if (device_index == UINT_MAX && err.isEmpty()) err = tr("Can't find device with that serial"); if (err.isEmpty()) - return status_ok(); - else - return error(err); + { + if (auto* c = vr::VRCompositor(); c != nullptr) + { + c->SetTrackingSpace(origin::TrackingUniverseSeated); + return status_ok(); + } + else + return error("vr::VRCompositor == NULL"); + } + + return error(err); }); } void steamvr::data(double* data) { - if (device_index != -1) + if (device_index != UINT_MAX) { - pose_t pose; bool ok; - std::tie(ok, pose) = device_list::get_pose(device_index); + auto [ok, pose] = device_list::get_pose(device_index); if (ok) { constexpr int c = 10; const auto& result = pose.mDeviceToAbsoluteTracking; - data[TX] = -result.m[0][3] * c; - data[TY] = result.m[1][3] * c; - data[TZ] = result.m[2][3] * c; + data[TX] = (double)(-result.m[0][3] * c); + data[TY] = (double)(result.m[1][3] * c); + data[TZ] = (double)(result.m[2][3] * c); matrix_to_euler(data[Yaw], data[Pitch], data[Roll], result); @@ -250,18 +260,25 @@ void steamvr::data(double* data) bool steamvr::center() { - return with_vr_lock([&](vr_t v, error_t) + return with_vr_lock([&](vr_t v, vr_error_t) { if (v) { if (v->GetTrackedDeviceClass(device_index) == vr::ETrackedDeviceClass::TrackedDeviceClass_HMD) { - // Reset yaw and position - v->ResetSeatedZeroPose(); - - // Use chaperone universe real world up instead of opentrack's initial pose centering - // Note: Controllers will be centered based on initial headset position. - return true; + auto* c = vr::VRChaperone(); + if (!c) + { + eval_once(qDebug() << "steamvr: vr::VRChaperone == NULL"); + return false; + } + else + { + c->ResetZeroPose(origin::TrackingUniverseSeated); + // Use chaperone universe real world up instead of opentrack's initial pose centering + // Note: Controllers will be centered based on initial headset position. + return true; + } } else // with controllers, resetting the seated pose does nothing @@ -273,15 +290,11 @@ bool steamvr::center() void steamvr::matrix_to_euler(double& yaw, double& pitch, double& roll, const vr::HmdMatrix34_t& result) { - using std::atan2; - using std::sqrt; - using std::asin; - using d = double; - yaw = atan2(d(result.m[2][0]), d(result.m[0][0])); - pitch = atan2(-d(result.m[1][2]), d(result.m[1][1])); - roll = asin(d(result.m[1][0])); + yaw = std::atan2(d(result.m[2][0]), d(result.m[0][0])); + pitch = std::atan2(-d(result.m[1][2]), d(result.m[1][1])); + roll = std::asin(d(result.m[1][0])); } steamvr_dialog::steamvr_dialog() @@ -321,7 +334,7 @@ void steamvr_dialog::doCancel() QString device_spec::to_string() const { - return QStringLiteral("<%1> %2 [%3]").arg(type).arg(model).arg(serial); + return QStringLiteral("<%1> %2 [%3]").arg(type, model, serial); } OPENTRACK_DECLARE_TRACKER(steamvr, steamvr_dialog, steamvr_metadata) |