summaryrefslogtreecommitdiffhomepage
path: root/tracker-steamvr/steamvr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tracker-steamvr/steamvr.cpp')
-rw-r--r--tracker-steamvr/steamvr.cpp133
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)