diff --git a/src/xrt/drivers/opengloves/encoding/alpha_encoding.cpp b/src/xrt/drivers/opengloves/encoding/alpha_encoding.cpp index e830fae32..ce8d851a8 100644 --- a/src/xrt/drivers/opengloves/encoding/alpha_encoding.cpp +++ b/src/xrt/drivers/opengloves/encoding/alpha_encoding.cpp @@ -140,6 +140,14 @@ static const std::map<std::string, int> opengloves_alpha_encoding_key_string{ {"", OPENGLOVES_ALPHA_ENCODING_MAX} // Junk key }; +static const std::map<int, std::string> opengloves_alpha_encoding_output_key_string{ + {OPENGLOVES_ALPHA_ENCODING_FinThumb, "A"}, // thumb force feedback + {OPENGLOVES_ALPHA_ENCODING_FinIndex, "B"}, // index force feedback + {OPENGLOVES_ALPHA_ENCODING_FinMiddle, "C"}, // middle force feedback + {OPENGLOVES_ALPHA_ENCODING_FinRing, "D"}, // ring force feedback + {OPENGLOVES_ALPHA_ENCODING_FinPinky, "E"}, // pinky force feedback +}; + static std::map<int, std::string> opengloves_alpha_encoding_parse_to_map(const std::string &str) { @@ -247,4 +255,20 @@ opengloves_alpha_encoding_decode(const char *data, struct opengloves_input *out) out->gestures.grab.activated = input_map.find(OPENGLOVES_ALPHA_ENCODING_GesGrab) != input_map.end(); out->gestures.pinch.activated = input_map.find(OPENGLOVES_ALPHA_ENCODING_GesPinch) != input_map.end(); out->buttons.menu.pressed = input_map.find(OPENGLOVES_ALPHA_ENCODING_BtnMenu) != input_map.end(); -} \ No newline at end of file +} + +void +opengloves_alpha_encoding_encode(const struct opengloves_output *output, char *out_buff) +{ + sprintf(out_buff, "%s%d%s%d%s%d%s%d%s%d\n", + opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinThumb).c_str(), + (int)(output->force_feedback.thumb * 1000), + opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinIndex).c_str(), + (int)(output->force_feedback.index * 1000), + opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinMiddle).c_str(), + (int)(output->force_feedback.middle * 1000), + opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinRing).c_str(), + (int)(output->force_feedback.ring * 1000), + opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinPinky).c_str(), + (int)(output->force_feedback.little * 1000)); +} diff --git a/src/xrt/drivers/opengloves/encoding/alpha_encoding.h b/src/xrt/drivers/opengloves/encoding/alpha_encoding.h index 1ca7a1dd8..29b05f114 100644 --- a/src/xrt/drivers/opengloves/encoding/alpha_encoding.h +++ b/src/xrt/drivers/opengloves/encoding/alpha_encoding.h @@ -17,6 +17,8 @@ extern "C" { void opengloves_alpha_encoding_decode(const char *data, struct opengloves_input *out_kv); +void +opengloves_alpha_encoding_encode(const struct opengloves_output *output, char *out_buff); #ifdef __cplusplus } #endif diff --git a/src/xrt/drivers/opengloves/encoding/encoding.h b/src/xrt/drivers/opengloves/encoding/encoding.h index 7775ee411..5713b6ec4 100644 --- a/src/xrt/drivers/opengloves/encoding/encoding.h +++ b/src/xrt/drivers/opengloves/encoding/encoding.h @@ -66,6 +66,20 @@ struct opengloves_input struct opengloves_input_gestures gestures; }; +struct opengloves_output_force_feedback +{ + float thumb; + float index; + float middle; + float ring; + float little; +}; + +struct opengloves_output +{ + struct opengloves_output_force_feedback force_feedback; +}; + #ifdef __cplusplus } #endif diff --git a/src/xrt/drivers/opengloves/opengloves_device.c b/src/xrt/drivers/opengloves/opengloves_device.c index 6b69be333..920c0297a 100644 --- a/src/xrt/drivers/opengloves/opengloves_device.c +++ b/src/xrt/drivers/opengloves/opengloves_device.c @@ -159,6 +159,45 @@ opengloves_device_update_inputs(struct xrt_device *xdev) os_mutex_unlock(&od->lock); } +static void +opengloves_ffb_location_convert(const struct xrt_output_force_feedback *xrt_ffb, + struct opengloves_output_force_feedback *out_ffb) +{ + switch (xrt_ffb->location) { + case XRT_FORCE_FEEDBACK_LOCATION_LEFT_THUMB: out_ffb->thumb = xrt_ffb->value; break; + case XRT_FORCE_FEEDBACK_LOCATION_LEFT_INDEX: out_ffb->index = xrt_ffb->value; break; + case XRT_FORCE_FEEDBACK_LOCATION_LEFT_MIDDLE: out_ffb->middle = xrt_ffb->value; break; + case XRT_FORCE_FEEDBACK_LOCATION_LEFT_RING: out_ffb->ring = xrt_ffb->value; break; + case XRT_FORCE_FEEDBACK_LOCATION_LEFT_PINKY: out_ffb->little = xrt_ffb->value; break; + } +} + +static void +opengloves_device_set_output(struct xrt_device *xdev, enum xrt_output_name name, const union xrt_output_value *value) +{ + struct opengloves_device *od = opengloves_device(xdev); + + switch (name) { + case XRT_OUTPUT_NAME_FORCE_FEEDBACK_LEFT: + case XRT_OUTPUT_NAME_FORCE_FEEDBACK_RIGHT: { + struct opengloves_output out; + + int location_count = value->force_feedback.force_feedback_location_count; + const struct xrt_output_force_feedback *ffb = value->force_feedback.force_feedback; + + for (int i = 0; i < location_count; i++) { + opengloves_ffb_location_convert(ffb + i, &out.force_feedback); + } + + char buff[64]; + opengloves_alpha_encoding_encode(&out, buff); + + opengloves_communication_device_write(od->ocd, buff, strlen(buff)); + } + default: break; + } +} + static void opengloves_device_destroy(struct xrt_device *xdev) { @@ -235,7 +274,8 @@ struct xrt_device * opengloves_device_create(struct opengloves_communication_device *ocd, enum xrt_hand hand) { enum u_device_alloc_flags flags = (enum u_device_alloc_flags)(U_DEVICE_ALLOC_TRACKING_NONE); - struct opengloves_device *od = U_DEVICE_ALLOCATE(struct opengloves_device, flags, 8, 0); + + struct opengloves_device *od = U_DEVICE_ALLOCATE(struct opengloves_device, flags, 8, 1); od->base.name = XRT_DEVICE_HAND_TRACKER; od->base.device_type = XRT_DEVICE_TYPE_HAND_TRACKER; @@ -251,6 +291,7 @@ opengloves_device_create(struct opengloves_communication_device *ocd, enum xrt_h od->hand == XRT_HAND_LEFT ? XRT_INPUT_GENERIC_HAND_TRACKING_LEFT : XRT_INPUT_GENERIC_HAND_TRACKING_RIGHT; od->base.hand_tracking_supported = true; + od->base.force_feedback_supported = true; // inputs od->base.update_inputs = opengloves_device_update_inputs; @@ -266,6 +307,11 @@ opengloves_device_create(struct opengloves_communication_device *ocd, enum xrt_h od->base.inputs[OPENGLOVES_INDEX_JOYSTICK_MAIN].name = XRT_INPUT_INDEX_THUMBSTICK; od->base.inputs[OPENGLOVES_INDEX_JOYSTICK_MAIN_CLICK].name = XRT_INPUT_INDEX_THUMBSTICK_CLICK; + // outputs + od->base.outputs[0].name = + od->hand == XRT_HAND_LEFT ? XRT_OUTPUT_NAME_FORCE_FEEDBACK_LEFT : XRT_OUTPUT_NAME_FORCE_FEEDBACK_RIGHT; + od->base.set_output = opengloves_device_set_output; + // startup thread int ret = os_thread_helper_init(&od->oth); if (ret != 0) {