From 22a314482645477b04e68222620d596ccfe13d77 Mon Sep 17 00:00:00 2001 From: Korcan Hussein Date: Wed, 2 Jul 2025 11:58:48 +0100 Subject: [PATCH] xrt: new hand-tracking input type XRT_INPUT_HT_CONFORMING Part-of: --- doc/example_configs/config_v0.schema.json | 2 + src/xrt/auxiliary/bindings/bindings.py | 2 + src/xrt/auxiliary/util/u_system_helpers.h | 24 +++++++- src/xrt/auxiliary/vive/vive_poses.c | 4 +- src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp | 49 ++++++++++++++- src/xrt/drivers/remote/r_device.c | 6 +- src/xrt/drivers/steamvr_lh/device.cpp | 6 +- src/xrt/drivers/survive/survive_driver.c | 6 +- src/xrt/drivers/vive/vive_controller.c | 6 +- src/xrt/include/xrt/xrt_defines.h | 18 +++--- src/xrt/state_trackers/oxr/oxr_api_session.c | 16 ++++- .../steamvr_drv/ovrd_driver.cpp | 60 ++++++++++++++----- 12 files changed, 155 insertions(+), 44 deletions(-) diff --git a/doc/example_configs/config_v0.schema.json b/doc/example_configs/config_v0.schema.json index 2453abc60..fb33a80cc 100644 --- a/doc/example_configs/config_v0.schema.json +++ b/doc/example_configs/config_v0.schema.json @@ -165,6 +165,8 @@ "XRT_INPUT_HAND_GRIP_POSE", "XRT_INPUT_HT_UNOBSTRUCTED_RIGHT", "XRT_INPUT_HT_UNOBSTRUCTED_LEFT", + "XRT_INPUT_HT_CONFORMING_LEFT", + "XRT_INPUT_HT_CONFORMING_RIGHT", "XRT_INPUT_GENERIC_TRACKER_POSE", "XRT_INPUT_PSMV_GRIP_POSE", "XRT_INPUT_GO_AIM_POSE", diff --git a/src/xrt/auxiliary/bindings/bindings.py b/src/xrt/auxiliary/bindings/bindings.py index 1c5ee7182..690132160 100755 --- a/src/xrt/auxiliary/bindings/bindings.py +++ b/src/xrt/auxiliary/bindings/bindings.py @@ -826,6 +826,8 @@ def generate_bindings_c(file, b): inputs.add("XRT_INPUT_GENERIC_HEAD_DETECT") inputs.add("XRT_INPUT_HT_UNOBSTRUCTED_LEFT") inputs.add("XRT_INPUT_HT_UNOBSTRUCTED_RIGHT") + inputs.add("XRT_INPUT_HT_CONFORMING_LEFT") + inputs.add("XRT_INPUT_HT_CONFORMING_RIGHT") inputs.add("XRT_INPUT_GENERIC_TRACKER_POSE") f.write('const char *\n') diff --git a/src/xrt/auxiliary/util/u_system_helpers.h b/src/xrt/auxiliary/util/u_system_helpers.h index 9df1de5d2..c66c6fd56 100644 --- a/src/xrt/auxiliary/util/u_system_helpers.h +++ b/src/xrt/auxiliary/util/u_system_helpers.h @@ -193,7 +193,17 @@ u_system_devices_get_ht_device(struct xrt_system_devices *xsysd, enum xrt_input_ static inline struct xrt_device * u_system_devices_get_ht_device_left(struct xrt_system_devices *xsysd) { - return u_system_devices_get_ht_device(xsysd, XRT_INPUT_HT_UNOBSTRUCTED_LEFT); + const enum xrt_input_name ht_input_names[2] = { + XRT_INPUT_HT_UNOBSTRUCTED_LEFT, + XRT_INPUT_HT_CONFORMING_LEFT, + }; + for (uint32_t i = 0; i < ARRAY_SIZE(ht_input_names); ++i) { + struct xrt_device *xdev = u_system_devices_get_ht_device(xsysd, ht_input_names[i]); + if (xdev != NULL) { + return xdev; + } + } + return NULL; } /*! @@ -205,7 +215,17 @@ u_system_devices_get_ht_device_left(struct xrt_system_devices *xsysd) static inline struct xrt_device * u_system_devices_get_ht_device_right(struct xrt_system_devices *xsysd) { - return u_system_devices_get_ht_device(xsysd, XRT_INPUT_HT_UNOBSTRUCTED_RIGHT); + const enum xrt_input_name ht_input_names[2] = { + XRT_INPUT_HT_UNOBSTRUCTED_RIGHT, + XRT_INPUT_HT_CONFORMING_RIGHT, + }; + for (uint32_t i = 0; i < ARRAY_SIZE(ht_input_names); ++i) { + struct xrt_device *xdev = u_system_devices_get_ht_device(xsysd, ht_input_names[i]); + if (xdev != NULL) { + return xdev; + } + } + return NULL; } diff --git a/src/xrt/auxiliary/vive/vive_poses.c b/src/xrt/auxiliary/vive/vive_poses.c index 987d9da51..ef60bbe53 100644 --- a/src/xrt/auxiliary/vive/vive_poses.c +++ b/src/xrt/auxiliary/vive/vive_poses.c @@ -138,10 +138,10 @@ vive_poses_get_index_offset_pose(const enum xrt_input_name input_name, struct xrt_pose *out_offset_pose) { switch (input_name) { - case XRT_INPUT_HT_UNOBSTRUCTED_RIGHT: + case XRT_INPUT_HT_CONFORMING_LEFT: vive_poses_get_index_hand_offset_pose(XRT_HAND_RIGHT, out_offset_pose); return; - case XRT_INPUT_HT_UNOBSTRUCTED_LEFT: + case XRT_INPUT_HT_CONFORMING_RIGHT: vive_poses_get_index_hand_offset_pose(XRT_HAND_LEFT, out_offset_pose); return; default: break; // Go to code below. diff --git a/src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp b/src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp index 716cd6e2a..64eec189b 100644 --- a/src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp +++ b/src/xrt/drivers/ht_ctrl_emu/ht_ctrl_emu.cpp @@ -106,6 +106,44 @@ wct_to_quat(float waggle, float curl, float twist) return out; } +static inline bool +find_best_ht_input_names(const struct xrt_device *ht_device, enum xrt_input_name ht_input_names[2]) +{ + assert(ht_device && ht_device->inputs); + + if (!ht_device->supported.hand_tracking) + return false; + + constexpr const enum xrt_input_name XRT_NULL_INPUT_NAME = (enum xrt_input_name)0; + + ht_input_names[0] = ht_input_names[1] = XRT_NULL_INPUT_NAME; + + for (uint32_t i = 0; i < ht_device->input_count; ++i) { + if (ht_device->inputs[i].name == XRT_INPUT_HT_UNOBSTRUCTED_LEFT) { + ht_input_names[0] = XRT_INPUT_HT_UNOBSTRUCTED_LEFT; + } + + if (ht_device->inputs[i].name == XRT_INPUT_HT_UNOBSTRUCTED_RIGHT) { + ht_input_names[1] = XRT_INPUT_HT_UNOBSTRUCTED_RIGHT; + } + } + + for (uint32_t i = 0; i < ht_device->input_count; ++i) { + if (ht_input_names[0] == XRT_NULL_INPUT_NAME && + ht_device->inputs[i].name == XRT_INPUT_HT_CONFORMING_LEFT) { + ht_input_names[0] = XRT_INPUT_HT_CONFORMING_LEFT; + } + + if (ht_input_names[1] == XRT_NULL_INPUT_NAME && + ht_device->inputs[i].name == XRT_INPUT_HT_CONFORMING_RIGHT) { + ht_input_names[1] = XRT_INPUT_HT_CONFORMING_RIGHT; + } + } + + return ht_input_names[0] != XRT_NULL_INPUT_NAME && // + ht_input_names[1] != XRT_NULL_INPUT_NAME; +} + static inline struct cemu_device * cemu_device(struct xrt_device *xdev) { @@ -417,6 +455,12 @@ cemu_device_update_inputs(struct xrt_device *xdev) extern "C" int cemu_devices_create(struct xrt_device *head, struct xrt_device *hands, struct xrt_device **out_xdevs) { + enum xrt_input_name ht_input_names[2]; + if (!find_best_ht_input_names(hands, ht_input_names)) { + U_LOG_E("\"hands\" parameter is not a hand-tracking device or does have expected inputs."); + return 0; + } + enum u_device_alloc_flags flags = U_DEVICE_ALLOC_NO_FLAGS; struct cemu_device *cemud[2]; @@ -442,8 +486,7 @@ cemu_devices_create(struct xrt_device *head, struct xrt_device *hands, struct xr cemud[i]->base.supported.position_tracking = true; - cemud[i]->base.inputs[CEMU_INDEX_HAND_TRACKING].name = - i ? XRT_INPUT_HT_UNOBSTRUCTED_RIGHT : XRT_INPUT_HT_UNOBSTRUCTED_LEFT; + cemud[i]->base.inputs[CEMU_INDEX_HAND_TRACKING].name = ht_input_names[i]; cemud[i]->base.inputs[CEMU_INDEX_SELECT].name = XRT_INPUT_SIMPLE_SELECT_CLICK; cemud[i]->base.inputs[CEMU_INDEX_MENU].name = XRT_INPUT_SIMPLE_MENU_CLICK; cemud[i]->base.inputs[CEMU_INDEX_GRIP].name = XRT_INPUT_SIMPLE_GRIP_POSE; @@ -469,7 +512,7 @@ cemu_devices_create(struct xrt_device *head, struct xrt_device *hands, struct xr CEMU_WARN(cemud[i], "serial truncated: %s", cemud[i]->base.str); } - cemud[i]->ht_input_name = i ? XRT_INPUT_HT_UNOBSTRUCTED_RIGHT : XRT_INPUT_HT_UNOBSTRUCTED_LEFT; + cemud[i]->ht_input_name = ht_input_names[i]; cemud[i]->hand_index = i; system->out_hand[i] = cemud[i]; diff --git a/src/xrt/drivers/remote/r_device.c b/src/xrt/drivers/remote/r_device.c index 72a0a2cbf..8ad1f3690 100644 --- a/src/xrt/drivers/remote/r_device.c +++ b/src/xrt/drivers/remote/r_device.c @@ -147,7 +147,7 @@ r_device_get_hand_tracking(struct xrt_device *xdev, struct r_device *rd = r_device(xdev); struct r_hub *r = rd->r; - if (name != XRT_INPUT_HT_UNOBSTRUCTED_LEFT && name != XRT_INPUT_HT_UNOBSTRUCTED_RIGHT) { + if (name != XRT_INPUT_HT_CONFORMING_LEFT && name != XRT_INPUT_HT_CONFORMING_RIGHT) { U_LOG_XDEV_UNSUPPORTED_INPUT(&rd->base, u_log_get_global_level(), name); return XRT_ERROR_INPUT_UNSUPPORTED; } @@ -236,9 +236,9 @@ r_device_create(struct r_hub *r, bool is_left) rd->base.inputs[17].name = XRT_INPUT_INDEX_GRIP_POSE; rd->base.inputs[18].name = XRT_INPUT_INDEX_AIM_POSE; if (is_left) { - rd->base.inputs[19].name = XRT_INPUT_HT_UNOBSTRUCTED_LEFT; + rd->base.inputs[19].name = XRT_INPUT_HT_CONFORMING_LEFT; } else { - rd->base.inputs[19].name = XRT_INPUT_HT_UNOBSTRUCTED_RIGHT; + rd->base.inputs[19].name = XRT_INPUT_HT_CONFORMING_RIGHT; } rd->base.inputs[20].name = XRT_INPUT_GENERIC_PALM_POSE; diff --git a/src/xrt/drivers/steamvr_lh/device.cpp b/src/xrt/drivers/steamvr_lh/device.cpp index 52fc8f069..ceffc3857 100644 --- a/src/xrt/drivers/steamvr_lh/device.cpp +++ b/src/xrt/drivers/steamvr_lh/device.cpp @@ -261,7 +261,7 @@ ControllerDevice::set_input_class(const InputClass *input_class) 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_HT_UNOBSTRUCTED_LEFT, {}}); + inputs_vec.push_back({true, 0, XRT_INPUT_HT_CONFORMING_LEFT, {}}); inputs_map.insert({std::string_view("HAND"), &inputs_vec.back()}); } @@ -875,12 +875,12 @@ ControllerDevice::handle_property_write(const vr::PropertyWrite_t &prop) } case vr::TrackedControllerRole_RightHand: { this->device_type = XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER; - set_hand_tracking_hand(XRT_INPUT_HT_UNOBSTRUCTED_RIGHT); + set_hand_tracking_hand(XRT_INPUT_HT_CONFORMING_RIGHT); break; } case vr::TrackedControllerRole_LeftHand: { this->device_type = XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER; - set_hand_tracking_hand(XRT_INPUT_HT_UNOBSTRUCTED_LEFT); + set_hand_tracking_hand(XRT_INPUT_HT_CONFORMING_LEFT); break; } case vr::TrackedControllerRole_OptOut: { diff --git a/src/xrt/drivers/survive/survive_driver.c b/src/xrt/drivers/survive/survive_driver.c index a9fc5a554..62791e764 100644 --- a/src/xrt/drivers/survive/survive_driver.c +++ b/src/xrt/drivers/survive/survive_driver.c @@ -468,7 +468,7 @@ survive_controller_get_hand_tracking(struct xrt_device *xdev, { struct survive_device *survive = (struct survive_device *)xdev; - if (name != XRT_INPUT_HT_UNOBSTRUCTED_LEFT && name != XRT_INPUT_HT_UNOBSTRUCTED_RIGHT) { + if (name != XRT_INPUT_HT_CONFORMING_LEFT && name != XRT_INPUT_HT_CONFORMING_RIGHT) { U_LOG_XDEV_UNSUPPORTED_INPUT(&survive->base, survive->sys->log_level, name); return XRT_ERROR_INPUT_UNSUPPORTED; } @@ -1136,11 +1136,11 @@ _create_controller_device(struct survive_system *sys, if (variant == CONTROLLER_INDEX_LEFT) { survive->base.device_type = XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER; - survive->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_UNOBSTRUCTED_LEFT; + survive->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_CONFORMING_LEFT; snprintf(survive->base.str, XRT_DEVICE_NAME_LEN, "Valve Index Left Controller (libsurvive)"); } else if (variant == CONTROLLER_INDEX_RIGHT) { survive->base.device_type = XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER; - survive->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_UNOBSTRUCTED_RIGHT; + survive->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_CONFORMING_RIGHT; snprintf(survive->base.str, XRT_DEVICE_NAME_LEN, "Valve Index Right Controller (libsurvive)"); } diff --git a/src/xrt/drivers/vive/vive_controller.c b/src/xrt/drivers/vive/vive_controller.c index 050c6da08..b4fc52015 100644 --- a/src/xrt/drivers/vive/vive_controller.c +++ b/src/xrt/drivers/vive/vive_controller.c @@ -375,7 +375,7 @@ vive_controller_get_hand_tracking(struct xrt_device *xdev, struct vive_controller_device *d = vive_controller_device(xdev); - if (name != XRT_INPUT_HT_UNOBSTRUCTED_LEFT && name != XRT_INPUT_HT_UNOBSTRUCTED_RIGHT) { + if (name != XRT_INPUT_HT_CONFORMING_LEFT && name != XRT_INPUT_HT_CONFORMING_LEFT) { U_LOG_XDEV_UNSUPPORTED_INPUT(&d->base, d->log_level, name); return XRT_ERROR_INPUT_UNSUPPORTED; } @@ -1181,11 +1181,11 @@ vive_controller_create(struct os_hid_device *controller_hid, enum watchman_gen w if (d->config.variant == CONTROLLER_INDEX_LEFT) { d->base.device_type = XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER; - d->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_UNOBSTRUCTED_LEFT; + d->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_CONFORMING_LEFT; snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Valve Index Left Controller (vive)"); } else if (d->config.variant == CONTROLLER_INDEX_RIGHT) { d->base.device_type = XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER; - d->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_UNOBSTRUCTED_RIGHT; + d->base.inputs[VIVE_CONTROLLER_HAND_TRACKING].name = XRT_INPUT_HT_CONFORMING_RIGHT; snprintf(d->base.str, XRT_DEVICE_NAME_LEN, "Valve Index Right Controller (vive)"); } } else if (d->config.variant == CONTROLLER_TRACKER_GEN1) { diff --git a/src/xrt/include/xrt/xrt_defines.h b/src/xrt/include/xrt/xrt_defines.h index 6984e3d3c..b94570541 100644 --- a/src/xrt/include/xrt/xrt_defines.h +++ b/src/xrt/include/xrt/xrt_defines.h @@ -881,18 +881,20 @@ enum xrt_input_type _(XRT_INPUT_GENERIC_HEAD_POSE , XRT_INPUT_NAME(0x0000, POSE)) \ _(XRT_INPUT_GENERIC_HEAD_DETECT , XRT_INPUT_NAME(0x0001, BOOLEAN)) \ _(XRT_INPUT_HT_UNOBSTRUCTED_LEFT , XRT_INPUT_NAME(0x0002, HAND_TRACKING)) \ - _(XRT_INPUT_HT_UNOBSTRUCTED_RIGHT , XRT_INPUT_NAME(0x0004, HAND_TRACKING)) \ - _(XRT_INPUT_GENERIC_TRACKER_POSE , XRT_INPUT_NAME(0x0005, POSE)) \ + _(XRT_INPUT_HT_UNOBSTRUCTED_RIGHT , XRT_INPUT_NAME(0x0003, HAND_TRACKING)) \ + _(XRT_INPUT_HT_CONFORMING_LEFT , XRT_INPUT_NAME(0x0004, HAND_TRACKING)) \ + _(XRT_INPUT_HT_CONFORMING_RIGHT , XRT_INPUT_NAME(0x0005, HAND_TRACKING)) \ + _(XRT_INPUT_GENERIC_TRACKER_POSE , XRT_INPUT_NAME(0x0006, POSE)) \ /** XR_EXT_palm_pose */ \ - _(XRT_INPUT_GENERIC_PALM_POSE , XRT_INPUT_NAME(0x0006, POSE)) \ + _(XRT_INPUT_GENERIC_PALM_POSE , XRT_INPUT_NAME(0x0007, POSE)) \ \ /** XR_EXT_eye_gaze_interaction */ \ - _(XRT_INPUT_GENERIC_EYE_GAZE_POSE , XRT_INPUT_NAME(0x0007, POSE)) \ + _(XRT_INPUT_GENERIC_EYE_GAZE_POSE , XRT_INPUT_NAME(0x0008, POSE)) \ /** Standard non-view reference spaces */ \ - _(XRT_INPUT_GENERIC_LOCAL_SPACE_POSE , XRT_INPUT_NAME(0x0008, POSE)) \ - _(XRT_INPUT_GENERIC_LOCAL_FLOOR_SPACE_POSE , XRT_INPUT_NAME(0x0009, POSE)) \ - _(XRT_INPUT_GENERIC_STAGE_SPACE_POSE , XRT_INPUT_NAME(0x000A, POSE)) \ - _(XRT_INPUT_GENERIC_UNBOUNDED_SPACE_POSE , XRT_INPUT_NAME(0x000B, POSE)) \ + _(XRT_INPUT_GENERIC_LOCAL_SPACE_POSE , XRT_INPUT_NAME(0x0009, POSE)) \ + _(XRT_INPUT_GENERIC_LOCAL_FLOOR_SPACE_POSE , XRT_INPUT_NAME(0x000A, POSE)) \ + _(XRT_INPUT_GENERIC_STAGE_SPACE_POSE , XRT_INPUT_NAME(0x000B, POSE)) \ + _(XRT_INPUT_GENERIC_UNBOUNDED_SPACE_POSE , XRT_INPUT_NAME(0x000C, POSE)) \ \ _(XRT_INPUT_SIMPLE_SELECT_CLICK , XRT_INPUT_NAME(0x0010, BOOLEAN)) \ _(XRT_INPUT_SIMPLE_MENU_CLICK , XRT_INPUT_NAME(0x0011, BOOLEAN)) \ diff --git a/src/xrt/state_trackers/oxr/oxr_api_session.c b/src/xrt/state_trackers/oxr/oxr_api_session.c index 3f75d27ad..c58963747 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_session.c +++ b/src/xrt/state_trackers/oxr/oxr_api_session.c @@ -442,7 +442,7 @@ oxr_hand_tracker_create(struct oxr_logger *log, // Find the correct input on the device. if (xdev != NULL && xdev->supported.hand_tracking) { for (uint32_t j = 0; j < xdev->input_count; j++) { - struct xrt_input *input = &xdev->inputs[j]; + const struct xrt_input *input = &xdev->inputs[j]; if ((input->name == XRT_INPUT_HT_UNOBSTRUCTED_LEFT && createInfo->hand == XR_HAND_LEFT_EXT) || (input->name == XRT_INPUT_HT_UNOBSTRUCTED_RIGHT && createInfo->hand == XR_HAND_RIGHT_EXT)) { @@ -451,6 +451,20 @@ oxr_hand_tracker_create(struct oxr_logger *log, break; } } + if (hand_tracker->xdev == NULL) { + for (uint32_t j = 0; j < xdev->input_count; j++) { + const struct xrt_input *input = &xdev->inputs[j]; + + if ((input->name == XRT_INPUT_HT_CONFORMING_LEFT && + createInfo->hand == XR_HAND_LEFT_EXT) || + (input->name == XRT_INPUT_HT_CONFORMING_RIGHT && + createInfo->hand == XR_HAND_RIGHT_EXT)) { + hand_tracker->xdev = xdev; + hand_tracker->input_name = input->name; + break; + } + } + } } // Consistency checking. diff --git a/src/xrt/state_trackers/steamvr_drv/ovrd_driver.cpp b/src/xrt/state_trackers/steamvr_drv/ovrd_driver.cpp index 4127ed1f2..4207d0b00 100644 --- a/src/xrt/state_trackers/steamvr_drv/ovrd_driver.cpp +++ b/src/xrt/state_trackers/steamvr_drv/ovrd_driver.cpp @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include "math/m_api.h" @@ -966,30 +968,56 @@ public: } if (m_xdev->supported.hand_tracking && m_skeletal_input_control.control_handle) { - vr::VRBoneTransform_t bone_transforms[OPENVR_BONE_COUNT]; - - timepoint_ns now_ns = os_monotonic_get_ns(); - struct xrt_hand_joint_set out_joint_set_value; - int64_t out_timestamp_ns; - - m_xdev->get_hand_tracking(m_xdev, - m_hand == XRT_HAND_LEFT ? XRT_INPUT_HT_UNOBSTRUCTED_LEFT - : XRT_INPUT_HT_UNOBSTRUCTED_RIGHT, - now_ns, &out_joint_set_value, &out_timestamp_ns); + constexpr const std::size_t sk_comp_size = 2; + + using ht_input_name_list = std::array; + constexpr const std::array ht_input_name_map = { + ht_input_name_list{ + XRT_INPUT_HT_UNOBSTRUCTED_LEFT, + XRT_INPUT_HT_CONFORMING_LEFT, + }, + ht_input_name_list{ + XRT_INPUT_HT_UNOBSTRUCTED_RIGHT, + XRT_INPUT_HT_CONFORMING_RIGHT, + }, + }; + using bone_transform_list = std::array; + using bone_transforms_list = std::vector; + + bone_transforms_list bone_transforms; + bone_transforms.reserve(sk_comp_size); + const auto &ht_input_names = ht_input_name_map[m_hand]; + const timepoint_ns now_ns = os_monotonic_get_ns(); + + for (size_t i = 0; i < ht_input_names.size(); ++i) { + int64_t out_timestamp_ns; + struct xrt_hand_joint_set joint_set_value = {}; + if (m_xdev->get_hand_tracking(m_xdev, ht_input_names[i], now_ns, &joint_set_value, + &out_timestamp_ns) != XRT_SUCCESS) { + continue; + } + auto &bts = bone_transforms.emplace_back(); + hand_joint_set_to_bone_transform(joint_set_value, bts.data(), m_hand); + // hand_joint_set_to_bone_transforms(out_joint_set_value, bone_transforms); + } - hand_joint_set_to_bone_transform(out_joint_set_value, bone_transforms, m_hand); - // hand_joint_set_to_bone_transforms(out_joint_set_value, bone_transforms); + if (bone_transforms.empty()) + return; + if (bone_transforms.size() < sk_comp_size) { + bone_transforms.push_back(bone_transforms.back()); + } + assert(bone_transforms.size() >= sk_comp_size); vr::EVRInputError err = vr::VRDriverInput()->UpdateSkeletonComponent( m_skeletal_input_control.control_handle, vr::VRSkeletalMotionRange_WithoutController, - bone_transforms, OPENVR_BONE_COUNT); + bone_transforms[0].data(), OPENVR_BONE_COUNT); if (err != vr::VRInputError_None) { ovrd_log("error updating skeleton: %i ", err); } - err = vr::VRDriverInput()->UpdateSkeletonComponent(m_skeletal_input_control.control_handle, - vr::VRSkeletalMotionRange_WithController, - bone_transforms, OPENVR_BONE_COUNT); + err = vr::VRDriverInput()->UpdateSkeletonComponent( + m_skeletal_input_control.control_handle, vr::VRSkeletalMotionRange_WithController, + bone_transforms[1].data(), OPENVR_BONE_COUNT); if (err != vr::VRInputError_None) { ovrd_log("error updating skeleton: %i ", err); } -- 2.51.2