The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Shawn Wallace and committed by
Christoph Haag
f935fa94 b6bc7bba

+61 -60
+54 -51
src/xrt/drivers/steamvr_lh/device.cpp
··· 9 9 10 10 #include <functional> 11 11 #include <cstring> 12 - #include <math.h> 13 12 #include <thread> 14 13 #include <algorithm> 15 14 ··· 18 17 #include "math/m_space.h" 19 18 #include "device.hpp" 20 19 #include "interfaces/context.hpp" 21 - #include "os/os_time.h" 22 20 #include "util/u_debug.h" 23 21 #include "util/u_device.h" 24 22 #include "util/u_hand_simulation.h" ··· 34 32 #define DEV_WARN(...) U_LOG_IFL_W(ctx->log_level, __VA_ARGS__) 35 33 #define DEV_INFO(...) U_LOG_IFL_I(ctx->log_level, __VA_ARGS__) 36 34 #define DEV_DEBUG(...) U_LOG_IFL_D(ctx->log_level, __VA_ARGS__) 37 - 38 - #define DEG_TO_RAD(DEG) (DEG * M_PI / 180.) 39 35 40 36 DEBUG_GET_ONCE_BOOL_OPTION(lh_emulate_hand, "LH_EMULATE_HAND", true) 41 37 ··· 43 39 struct InputClass 44 40 { 45 41 xrt_device_name name; 46 - std::string description; 47 42 const std::vector<xrt_input_name> poses; 48 43 const std::unordered_map<std::string_view, xrt_input_name> non_poses; 49 44 const std::unordered_map<std::string_view, IndexFinger> finger_curls; 50 45 }; 51 46 52 47 namespace { 53 - const std::unordered_map<std::string_view, InputClass> hmd_classes{ 54 - {"vive", InputClass{XRT_DEVICE_GENERIC_HMD, "Vive HMD", {XRT_INPUT_GENERIC_HEAD_POSE}, {}, {}}}, 55 - {"indexhmd", InputClass{XRT_DEVICE_GENERIC_HMD, "Index HMD", {XRT_INPUT_GENERIC_HEAD_POSE}, {}, {}}}, 56 - {"vive_pro", InputClass{XRT_DEVICE_GENERIC_HMD, "Vive Pro HMD", {XRT_INPUT_GENERIC_HEAD_POSE}, {}, {}}}, 57 - }; 58 - 59 48 // Adding support for a new controller is a simple as adding it here. 60 49 // The key for the map needs to be the name of input profile as indicated by the lighthouse driver. 61 50 const std::unordered_map<std::string_view, InputClass> controller_classes{ ··· 63 52 "vive_controller", 64 53 InputClass{ 65 54 XRT_DEVICE_VIVE_WAND, 66 - "Vive Wand", 67 55 { 68 56 XRT_INPUT_VIVE_GRIP_POSE, 69 57 XRT_INPUT_VIVE_AIM_POSE, ··· 87 75 "index_controller", 88 76 InputClass{ 89 77 XRT_DEVICE_INDEX_CONTROLLER, 90 - "Valve Index Controller", 91 78 { 92 79 XRT_INPUT_INDEX_GRIP_POSE, 93 80 XRT_INPUT_INDEX_AIM_POSE, ··· 123 110 "vive_tracker", 124 111 InputClass{ 125 112 XRT_DEVICE_VIVE_TRACKER, 126 - "HTC Vive Tracker", 127 113 { 128 114 XRT_INPUT_GENERIC_TRACKER_POSE, 129 115 }, ··· 143 129 "tundra_tracker", 144 130 InputClass{ 145 131 XRT_DEVICE_VIVE_TRACKER, 146 - "Tundra Tracker", 147 132 { 148 133 XRT_INPUT_GENERIC_TRACKER_POSE, 149 134 }, ··· 185 170 this->device_type = XRT_DEVICE_TYPE_HMD; 186 171 this->container_handle = 0; 187 172 this->stage_supported = true; 173 + 174 + inputs_vec = {xrt_input{true, 0, XRT_INPUT_GENERIC_HEAD_POSE, {}}}; 175 + this->inputs = inputs_vec.data(); 176 + this->input_count = inputs_vec.size(); 188 177 189 178 #define SETUP_MEMBER_FUNC(name) this->xrt_device::name = &device_bouncer<HmdDevice, &HmdDevice::name> 190 179 SETUP_MEMBER_FUNC(get_view_poses); ··· 241 230 } 242 231 } 243 232 233 + // NOTE: No operations that would force inputs_vec or finger_inputs_vec to reallocate (such as insertion) 234 + // should be done after this function is called, otherwise the pointers in inputs_map/finger_inputs_map 235 + // would be invalidated. 244 236 void 245 - Device::set_input_class(const InputClass *input_class) 237 + ControllerDevice::set_input_class(const InputClass *input_class) 246 238 { 247 239 // this should only be called once 248 240 assert(inputs_vec.empty()); ··· 258 250 inputs_vec.push_back({true, 0, input, {}}); 259 251 inputs_map.insert({path, &inputs_vec.back()}); 260 252 } 261 - this->inputs = inputs_vec.data(); 262 - this->input_count = inputs_vec.size(); 263 - } 264 253 265 - void 266 - ControllerDevice::set_input_class(const InputClass *input_class) 267 - { 268 - Device::set_input_class(input_class); 269 - if (!debug_get_bool_option_lh_emulate_hand()) { 270 - return; 271 - } 272 254 has_index_hand_tracking = !input_class->finger_curls.empty(); 273 - if (!has_index_hand_tracking) { 274 - return; 255 + if (debug_get_bool_option_lh_emulate_hand() && has_index_hand_tracking) { 256 + finger_inputs_vec.reserve(input_class->finger_curls.size()); 257 + for (const auto &[path, finger] : input_class->finger_curls) { 258 + assert(finger_inputs_vec.capacity() >= finger_inputs_vec.size() + 1); 259 + finger_inputs_vec.push_back({0, finger, 0.f}); 260 + finger_inputs_map.insert({path, &finger_inputs_vec.back()}); 261 + } 262 + assert(inputs_vec.capacity() >= inputs_vec.size() + 1); 263 + inputs_vec.push_back({true, 0, XRT_INPUT_GENERIC_HAND_TRACKING_LEFT, {}}); 264 + inputs_map.insert({std::string_view("HAND"), &inputs_vec.back()}); 275 265 } 276 - finger_inputs_vec.reserve(input_class->finger_curls.size()); 277 - for (const auto &[path, finger] : input_class->finger_curls) { 278 - finger_inputs_vec.push_back({0, finger, 0.f}); 279 - finger_inputs_map.insert({path, &finger_inputs_vec.back()}); 280 - } 281 - inputs_vec.push_back({true, 0, XRT_INPUT_GENERIC_HAND_TRACKING_LEFT, {}}); 282 - inputs_map.insert({std::string_view("HAND"), &inputs_vec.back()}); 266 + 283 267 this->inputs = inputs_vec.data(); 284 268 this->input_count = inputs_vec.size(); 285 269 } ··· 757 741 } // namespace 758 742 759 743 void 744 + Device::handle_property_write(const vr::PropertyWrite_t &prop) 745 + { 746 + switch (prop.prop) { 747 + case vr::Prop_ManufacturerName_String: { 748 + this->manufacturer = std::string(static_cast<char *>(prop.pvBuffer), prop.unBufferSize); 749 + if (!this->model.empty()) { 750 + std::snprintf(this->str, std::size(this->str), "%s %s", this->manufacturer.c_str(), 751 + this->model.c_str()); 752 + } 753 + break; 754 + } 755 + case vr::Prop_ModelNumber_String: { 756 + this->model = std::string(static_cast<char *>(prop.pvBuffer), prop.unBufferSize); 757 + if (!this->manufacturer.empty()) { 758 + std::snprintf(this->str, std::size(this->str), "%s %s", this->manufacturer.c_str(), 759 + this->model.c_str()); 760 + } 761 + break; 762 + } 763 + default: { 764 + DEV_DEBUG("Unhandled property: %i", prop.prop); 765 + break; 766 + } 767 + } 768 + } 769 + 770 + void 760 771 HmdDevice::handle_property_write(const vr::PropertyWrite_t &prop) 761 772 { 762 773 switch (prop.prop) { ··· 766 777 set_nominal_frame_interval((1.f / freq) * 1e9f); 767 778 break; 768 779 } 769 - case vr::Prop_InputProfilePath_String: { 770 - std::string_view profile = 771 - parse_profile(std::string_view(static_cast<char *>(prop.pvBuffer), prop.unBufferSize)); 772 - auto input_class = hmd_classes.find(profile); 773 - if (input_class == hmd_classes.end()) { 774 - DEV_ERR("Could not find input class for hmd profile %s", std::string(profile).c_str()); 775 - } else { 776 - std::strcpy(this->str, input_class->second.description.c_str()); 777 - this->name = input_class->second.name; 778 - set_input_class(&input_class->second); 779 - } 780 - break; 781 - } 782 780 case vr::Prop_UserIpdMeters_Float: { 783 781 if (*static_cast<float *>(prop.pvBuffer) != 0) { 784 782 ipd = *static_cast<float *>(prop.pvBuffer); ··· 789 787 vsync_to_photon_ns = *static_cast<float *>(prop.pvBuffer) * 1e9f; 790 788 break; 791 789 } 792 - default: DEV_DEBUG("Unassigned HMD property: %i", prop.prop); break; 790 + default: { 791 + Device::handle_property_write(prop); 792 + break; 793 + } 793 794 } 794 795 } 795 796 ··· 804 805 if (input_class == controller_classes.end()) { 805 806 DEV_ERR("Could not find input class for controller profile %s", std::string(profile).c_str()); 806 807 } else { 807 - std::strcpy(this->str, input_class->second.description.c_str()); 808 808 this->name = input_class->second.name; 809 809 set_input_class(&input_class->second); 810 810 } ··· 877 877 DEV_DEBUG("Battery: %s: %f", name, bat); 878 878 break; 879 879 } 880 - default: DEV_DEBUG("Unassigned controller property: %i", prop.prop); break; 880 + default: { 881 + Device::handle_property_write(prop); 882 + break; 883 + } 881 884 } 882 885 }
+7 -9
src/xrt/drivers/steamvr_lh/device.hpp
··· 72 72 std::vector<xrt_input> inputs_vec; 73 73 inline static xrt_pose chaperone = XRT_POSE_IDENTITY; 74 74 const InputClass *input_class; 75 - 75 + std::string manufacturer; 76 + std::string model; 76 77 float vsync_to_photon_ns{0.f}; 77 78 78 79 virtual void 79 - handle_property_write(const vr::PropertyWrite_t &prop) = 0; 80 - 81 - void 82 - set_input_class(const InputClass *input_class); 80 + handle_property_write(const vr::PropertyWrite_t &prop); 83 81 84 82 private: 85 83 vr::ITrackedDeviceServerDriver *driver; ··· 147 145 148 146 class ControllerDevice : public Device 149 147 { 150 - protected: 151 - void 152 - set_input_class(const InputClass *input_class); 153 - 154 148 public: 155 149 ControllerDevice(vr::PropertyContainerHandle_t container_handle, const DeviceBuilder &builder); 156 150 ··· 177 171 178 172 void 179 173 update_hand_tracking(struct xrt_hand_joint_set *out); 174 + 175 + protected: 176 + void 177 + set_input_class(const InputClass *input_class); 180 178 181 179 private: 182 180 vr::VRInputComponentHandle_t haptic_handle{0};