mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 12:46:12 +00:00
d/steamvr_lh: use provided properties for device descriptions
This allows more easily showing the names of any future HMDs. Also some cleanup of unused things. Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2207>
This commit is contained in:
parent
b6bc7bba1e
commit
f935fa943f
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <math.h>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -18,7 +17,6 @@
|
||||||
#include "math/m_space.h"
|
#include "math/m_space.h"
|
||||||
#include "device.hpp"
|
#include "device.hpp"
|
||||||
#include "interfaces/context.hpp"
|
#include "interfaces/context.hpp"
|
||||||
#include "os/os_time.h"
|
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
#include "util/u_device.h"
|
#include "util/u_device.h"
|
||||||
#include "util/u_hand_simulation.h"
|
#include "util/u_hand_simulation.h"
|
||||||
|
@ -35,27 +33,18 @@
|
||||||
#define DEV_INFO(...) U_LOG_IFL_I(ctx->log_level, __VA_ARGS__)
|
#define DEV_INFO(...) U_LOG_IFL_I(ctx->log_level, __VA_ARGS__)
|
||||||
#define DEV_DEBUG(...) U_LOG_IFL_D(ctx->log_level, __VA_ARGS__)
|
#define DEV_DEBUG(...) U_LOG_IFL_D(ctx->log_level, __VA_ARGS__)
|
||||||
|
|
||||||
#define DEG_TO_RAD(DEG) (DEG * M_PI / 180.)
|
|
||||||
|
|
||||||
DEBUG_GET_ONCE_BOOL_OPTION(lh_emulate_hand, "LH_EMULATE_HAND", true)
|
DEBUG_GET_ONCE_BOOL_OPTION(lh_emulate_hand, "LH_EMULATE_HAND", true)
|
||||||
|
|
||||||
// Each device will have its own input class.
|
// Each device will have its own input class.
|
||||||
struct InputClass
|
struct InputClass
|
||||||
{
|
{
|
||||||
xrt_device_name name;
|
xrt_device_name name;
|
||||||
std::string description;
|
|
||||||
const std::vector<xrt_input_name> poses;
|
const std::vector<xrt_input_name> poses;
|
||||||
const std::unordered_map<std::string_view, xrt_input_name> non_poses;
|
const std::unordered_map<std::string_view, xrt_input_name> non_poses;
|
||||||
const std::unordered_map<std::string_view, IndexFinger> finger_curls;
|
const std::unordered_map<std::string_view, IndexFinger> finger_curls;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const std::unordered_map<std::string_view, InputClass> hmd_classes{
|
|
||||||
{"vive", InputClass{XRT_DEVICE_GENERIC_HMD, "Vive HMD", {XRT_INPUT_GENERIC_HEAD_POSE}, {}, {}}},
|
|
||||||
{"indexhmd", InputClass{XRT_DEVICE_GENERIC_HMD, "Index HMD", {XRT_INPUT_GENERIC_HEAD_POSE}, {}, {}}},
|
|
||||||
{"vive_pro", InputClass{XRT_DEVICE_GENERIC_HMD, "Vive Pro HMD", {XRT_INPUT_GENERIC_HEAD_POSE}, {}, {}}},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Adding support for a new controller is a simple as adding it here.
|
// Adding support for a new controller is a simple as adding it here.
|
||||||
// The key for the map needs to be the name of input profile as indicated by the lighthouse driver.
|
// The key for the map needs to be the name of input profile as indicated by the lighthouse driver.
|
||||||
const std::unordered_map<std::string_view, InputClass> controller_classes{
|
const std::unordered_map<std::string_view, InputClass> controller_classes{
|
||||||
|
@ -63,7 +52,6 @@ const std::unordered_map<std::string_view, InputClass> controller_classes{
|
||||||
"vive_controller",
|
"vive_controller",
|
||||||
InputClass{
|
InputClass{
|
||||||
XRT_DEVICE_VIVE_WAND,
|
XRT_DEVICE_VIVE_WAND,
|
||||||
"Vive Wand",
|
|
||||||
{
|
{
|
||||||
XRT_INPUT_VIVE_GRIP_POSE,
|
XRT_INPUT_VIVE_GRIP_POSE,
|
||||||
XRT_INPUT_VIVE_AIM_POSE,
|
XRT_INPUT_VIVE_AIM_POSE,
|
||||||
|
@ -87,7 +75,6 @@ const std::unordered_map<std::string_view, InputClass> controller_classes{
|
||||||
"index_controller",
|
"index_controller",
|
||||||
InputClass{
|
InputClass{
|
||||||
XRT_DEVICE_INDEX_CONTROLLER,
|
XRT_DEVICE_INDEX_CONTROLLER,
|
||||||
"Valve Index Controller",
|
|
||||||
{
|
{
|
||||||
XRT_INPUT_INDEX_GRIP_POSE,
|
XRT_INPUT_INDEX_GRIP_POSE,
|
||||||
XRT_INPUT_INDEX_AIM_POSE,
|
XRT_INPUT_INDEX_AIM_POSE,
|
||||||
|
@ -123,7 +110,6 @@ const std::unordered_map<std::string_view, InputClass> controller_classes{
|
||||||
"vive_tracker",
|
"vive_tracker",
|
||||||
InputClass{
|
InputClass{
|
||||||
XRT_DEVICE_VIVE_TRACKER,
|
XRT_DEVICE_VIVE_TRACKER,
|
||||||
"HTC Vive Tracker",
|
|
||||||
{
|
{
|
||||||
XRT_INPUT_GENERIC_TRACKER_POSE,
|
XRT_INPUT_GENERIC_TRACKER_POSE,
|
||||||
},
|
},
|
||||||
|
@ -143,7 +129,6 @@ const std::unordered_map<std::string_view, InputClass> controller_classes{
|
||||||
"tundra_tracker",
|
"tundra_tracker",
|
||||||
InputClass{
|
InputClass{
|
||||||
XRT_DEVICE_VIVE_TRACKER,
|
XRT_DEVICE_VIVE_TRACKER,
|
||||||
"Tundra Tracker",
|
|
||||||
{
|
{
|
||||||
XRT_INPUT_GENERIC_TRACKER_POSE,
|
XRT_INPUT_GENERIC_TRACKER_POSE,
|
||||||
},
|
},
|
||||||
|
@ -186,6 +171,10 @@ HmdDevice::HmdDevice(const DeviceBuilder &builder) : Device(builder)
|
||||||
this->container_handle = 0;
|
this->container_handle = 0;
|
||||||
this->stage_supported = true;
|
this->stage_supported = true;
|
||||||
|
|
||||||
|
inputs_vec = {xrt_input{true, 0, XRT_INPUT_GENERIC_HEAD_POSE, {}}};
|
||||||
|
this->inputs = inputs_vec.data();
|
||||||
|
this->input_count = inputs_vec.size();
|
||||||
|
|
||||||
#define SETUP_MEMBER_FUNC(name) this->xrt_device::name = &device_bouncer<HmdDevice, &HmdDevice::name>
|
#define SETUP_MEMBER_FUNC(name) this->xrt_device::name = &device_bouncer<HmdDevice, &HmdDevice::name>
|
||||||
SETUP_MEMBER_FUNC(get_view_poses);
|
SETUP_MEMBER_FUNC(get_view_poses);
|
||||||
SETUP_MEMBER_FUNC(compute_distortion);
|
SETUP_MEMBER_FUNC(compute_distortion);
|
||||||
|
@ -241,8 +230,11 @@ ControllerDevice::set_hand_tracking_hand(xrt_input_name name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: No operations that would force inputs_vec or finger_inputs_vec to reallocate (such as insertion)
|
||||||
|
// should be done after this function is called, otherwise the pointers in inputs_map/finger_inputs_map
|
||||||
|
// would be invalidated.
|
||||||
void
|
void
|
||||||
Device::set_input_class(const InputClass *input_class)
|
ControllerDevice::set_input_class(const InputClass *input_class)
|
||||||
{
|
{
|
||||||
// this should only be called once
|
// this should only be called once
|
||||||
assert(inputs_vec.empty());
|
assert(inputs_vec.empty());
|
||||||
|
@ -258,28 +250,20 @@ Device::set_input_class(const InputClass *input_class)
|
||||||
inputs_vec.push_back({true, 0, input, {}});
|
inputs_vec.push_back({true, 0, input, {}});
|
||||||
inputs_map.insert({path, &inputs_vec.back()});
|
inputs_map.insert({path, &inputs_vec.back()});
|
||||||
}
|
}
|
||||||
this->inputs = inputs_vec.data();
|
|
||||||
this->input_count = inputs_vec.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ControllerDevice::set_input_class(const InputClass *input_class)
|
|
||||||
{
|
|
||||||
Device::set_input_class(input_class);
|
|
||||||
if (!debug_get_bool_option_lh_emulate_hand()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
has_index_hand_tracking = !input_class->finger_curls.empty();
|
has_index_hand_tracking = !input_class->finger_curls.empty();
|
||||||
if (!has_index_hand_tracking) {
|
if (debug_get_bool_option_lh_emulate_hand() && has_index_hand_tracking) {
|
||||||
return;
|
finger_inputs_vec.reserve(input_class->finger_curls.size());
|
||||||
|
for (const auto &[path, finger] : input_class->finger_curls) {
|
||||||
|
assert(finger_inputs_vec.capacity() >= finger_inputs_vec.size() + 1);
|
||||||
|
finger_inputs_vec.push_back({0, finger, 0.f});
|
||||||
|
finger_inputs_map.insert({path, &finger_inputs_vec.back()});
|
||||||
|
}
|
||||||
|
assert(inputs_vec.capacity() >= inputs_vec.size() + 1);
|
||||||
|
inputs_vec.push_back({true, 0, XRT_INPUT_GENERIC_HAND_TRACKING_LEFT, {}});
|
||||||
|
inputs_map.insert({std::string_view("HAND"), &inputs_vec.back()});
|
||||||
}
|
}
|
||||||
finger_inputs_vec.reserve(input_class->finger_curls.size());
|
|
||||||
for (const auto &[path, finger] : input_class->finger_curls) {
|
|
||||||
finger_inputs_vec.push_back({0, finger, 0.f});
|
|
||||||
finger_inputs_map.insert({path, &finger_inputs_vec.back()});
|
|
||||||
}
|
|
||||||
inputs_vec.push_back({true, 0, XRT_INPUT_GENERIC_HAND_TRACKING_LEFT, {}});
|
|
||||||
inputs_map.insert({std::string_view("HAND"), &inputs_vec.back()});
|
|
||||||
this->inputs = inputs_vec.data();
|
this->inputs = inputs_vec.data();
|
||||||
this->input_count = inputs_vec.size();
|
this->input_count = inputs_vec.size();
|
||||||
}
|
}
|
||||||
|
@ -756,6 +740,33 @@ parse_profile(std::string_view path)
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
void
|
||||||
|
Device::handle_property_write(const vr::PropertyWrite_t &prop)
|
||||||
|
{
|
||||||
|
switch (prop.prop) {
|
||||||
|
case vr::Prop_ManufacturerName_String: {
|
||||||
|
this->manufacturer = std::string(static_cast<char *>(prop.pvBuffer), prop.unBufferSize);
|
||||||
|
if (!this->model.empty()) {
|
||||||
|
std::snprintf(this->str, std::size(this->str), "%s %s", this->manufacturer.c_str(),
|
||||||
|
this->model.c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case vr::Prop_ModelNumber_String: {
|
||||||
|
this->model = std::string(static_cast<char *>(prop.pvBuffer), prop.unBufferSize);
|
||||||
|
if (!this->manufacturer.empty()) {
|
||||||
|
std::snprintf(this->str, std::size(this->str), "%s %s", this->manufacturer.c_str(),
|
||||||
|
this->model.c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
DEV_DEBUG("Unhandled property: %i", prop.prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HmdDevice::handle_property_write(const vr::PropertyWrite_t &prop)
|
HmdDevice::handle_property_write(const vr::PropertyWrite_t &prop)
|
||||||
{
|
{
|
||||||
|
@ -766,19 +777,6 @@ HmdDevice::handle_property_write(const vr::PropertyWrite_t &prop)
|
||||||
set_nominal_frame_interval((1.f / freq) * 1e9f);
|
set_nominal_frame_interval((1.f / freq) * 1e9f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case vr::Prop_InputProfilePath_String: {
|
|
||||||
std::string_view profile =
|
|
||||||
parse_profile(std::string_view(static_cast<char *>(prop.pvBuffer), prop.unBufferSize));
|
|
||||||
auto input_class = hmd_classes.find(profile);
|
|
||||||
if (input_class == hmd_classes.end()) {
|
|
||||||
DEV_ERR("Could not find input class for hmd profile %s", std::string(profile).c_str());
|
|
||||||
} else {
|
|
||||||
std::strcpy(this->str, input_class->second.description.c_str());
|
|
||||||
this->name = input_class->second.name;
|
|
||||||
set_input_class(&input_class->second);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case vr::Prop_UserIpdMeters_Float: {
|
case vr::Prop_UserIpdMeters_Float: {
|
||||||
if (*static_cast<float *>(prop.pvBuffer) != 0) {
|
if (*static_cast<float *>(prop.pvBuffer) != 0) {
|
||||||
ipd = *static_cast<float *>(prop.pvBuffer);
|
ipd = *static_cast<float *>(prop.pvBuffer);
|
||||||
|
@ -789,7 +787,10 @@ HmdDevice::handle_property_write(const vr::PropertyWrite_t &prop)
|
||||||
vsync_to_photon_ns = *static_cast<float *>(prop.pvBuffer) * 1e9f;
|
vsync_to_photon_ns = *static_cast<float *>(prop.pvBuffer) * 1e9f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: DEV_DEBUG("Unassigned HMD property: %i", prop.prop); break;
|
default: {
|
||||||
|
Device::handle_property_write(prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,7 +805,6 @@ ControllerDevice::handle_property_write(const vr::PropertyWrite_t &prop)
|
||||||
if (input_class == controller_classes.end()) {
|
if (input_class == controller_classes.end()) {
|
||||||
DEV_ERR("Could not find input class for controller profile %s", std::string(profile).c_str());
|
DEV_ERR("Could not find input class for controller profile %s", std::string(profile).c_str());
|
||||||
} else {
|
} else {
|
||||||
std::strcpy(this->str, input_class->second.description.c_str());
|
|
||||||
this->name = input_class->second.name;
|
this->name = input_class->second.name;
|
||||||
set_input_class(&input_class->second);
|
set_input_class(&input_class->second);
|
||||||
}
|
}
|
||||||
|
@ -877,6 +877,9 @@ ControllerDevice::handle_property_write(const vr::PropertyWrite_t &prop)
|
||||||
DEV_DEBUG("Battery: %s: %f", name, bat);
|
DEV_DEBUG("Battery: %s: %f", name, bat);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: DEV_DEBUG("Unassigned controller property: %i", prop.prop); break;
|
default: {
|
||||||
|
Device::handle_property_write(prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,14 +72,12 @@ protected:
|
||||||
std::vector<xrt_input> inputs_vec;
|
std::vector<xrt_input> inputs_vec;
|
||||||
inline static xrt_pose chaperone = XRT_POSE_IDENTITY;
|
inline static xrt_pose chaperone = XRT_POSE_IDENTITY;
|
||||||
const InputClass *input_class;
|
const InputClass *input_class;
|
||||||
|
std::string manufacturer;
|
||||||
|
std::string model;
|
||||||
float vsync_to_photon_ns{0.f};
|
float vsync_to_photon_ns{0.f};
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
handle_property_write(const vr::PropertyWrite_t &prop) = 0;
|
handle_property_write(const vr::PropertyWrite_t &prop);
|
||||||
|
|
||||||
void
|
|
||||||
set_input_class(const InputClass *input_class);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vr::ITrackedDeviceServerDriver *driver;
|
vr::ITrackedDeviceServerDriver *driver;
|
||||||
|
@ -147,10 +145,6 @@ private:
|
||||||
|
|
||||||
class ControllerDevice : public Device
|
class ControllerDevice : public Device
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
void
|
|
||||||
set_input_class(const InputClass *input_class);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ControllerDevice(vr::PropertyContainerHandle_t container_handle, const DeviceBuilder &builder);
|
ControllerDevice(vr::PropertyContainerHandle_t container_handle, const DeviceBuilder &builder);
|
||||||
|
|
||||||
|
@ -178,6 +172,10 @@ public:
|
||||||
void
|
void
|
||||||
update_hand_tracking(struct xrt_hand_joint_set *out);
|
update_hand_tracking(struct xrt_hand_joint_set *out);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void
|
||||||
|
set_input_class(const InputClass *input_class);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vr::VRInputComponentHandle_t haptic_handle{0};
|
vr::VRInputComponentHandle_t haptic_handle{0};
|
||||||
std::unique_ptr<xrt_output> output{nullptr};
|
std::unique_ptr<xrt_output> output{nullptr};
|
||||||
|
|
Loading…
Reference in a new issue