The open source OpenXR runtime

st/oxr: Use xrt_space

+276 -432
-10
src/xrt/state_trackers/oxr/oxr_instance.c
··· 49 49 DEBUG_GET_ONCE_BOOL_OPTION(debug_bindings, "OXR_DEBUG_BINDINGS", false) 50 50 DEBUG_GET_ONCE_BOOL_OPTION(lifecycle_verbose, "OXR_LIFECYCLE_VERBOSE", false) 51 51 52 - DEBUG_GET_ONCE_FLOAT_OPTION(tracking_origin_offset_x, "OXR_TRACKING_ORIGIN_OFFSET_X", 0.0f) 53 - DEBUG_GET_ONCE_FLOAT_OPTION(tracking_origin_offset_y, "OXR_TRACKING_ORIGIN_OFFSET_Y", 0.0f) 54 - DEBUG_GET_ONCE_FLOAT_OPTION(tracking_origin_offset_z, "OXR_TRACKING_ORIGIN_OFFSET_Z", 0.0f) 55 52 56 53 static XrResult 57 54 oxr_instance_destroy(struct oxr_logger *log, struct oxr_handle_base *hb) ··· 301 298 oxr_instance_destroy(log, &inst->handle); 302 299 return ret; 303 300 } 304 - 305 - struct xrt_vec3 global_tracking_origin_offset = {debug_get_float_option_tracking_origin_offset_x(), 306 - debug_get_float_option_tracking_origin_offset_y(), 307 - debug_get_float_option_tracking_origin_offset_z()}; 308 - 309 - u_builder_setup_tracking_origins(dev, GET_XDEV_BY_ROLE(sys, left), GET_XDEV_BY_ROLE(sys, right), 310 - &global_tracking_origin_offset); 311 301 312 302 // Sets the enabled extensions, this is where we should do any extra validation. 313 303 inst->extensions = *extensions;
+26 -79
src/xrt/state_trackers/oxr/oxr_objects.h
··· 764 764 const XrReferenceSpaceCreateInfo *createInfo, 765 765 struct oxr_space **out_space); 766 766 767 - /*! 768 - * Transforms a relation given in pure global space into the oxr_space @p spc. 769 - * If @p apply_space_pose is true, the pose offset of @p spc will be included in @p out_relation. 770 - */ 771 - XRT_CHECK_RESULT bool 772 - oxr_space_pure_relation_in_space(struct oxr_logger *log, 773 - XrTime time, 774 - struct xrt_space_relation *relation, 775 - struct oxr_space *spc, 776 - bool apply_space_pose, 777 - struct xrt_space_relation *out_relation); 767 + XrResult 768 + oxr_space_locate( 769 + struct oxr_logger *log, struct oxr_space *spc, struct oxr_space *baseSpc, XrTime time, XrSpaceLocation *location); 778 770 779 771 /*! 780 - * Transforms a pose given in pure global space into a relation in the oxr_space @p spc. 781 - * If @p apply_space_pose is true, the pose offset of @p spc will be included in @p out_relation. 782 - */ 783 - XRT_CHECK_RESULT bool 784 - oxr_space_pure_pose_in_space(struct oxr_logger *log, 785 - XrTime time, 786 - struct xrt_pose *pose, 787 - struct oxr_space *spc, 788 - bool apply_space_pose, 789 - struct xrt_space_relation *out_relation); 790 - 791 - /*! 792 - * Transforms a relation in an given oxr_space @p spc into pure global space, taking the pose offset of @p spc into 793 - * account. 794 - */ 795 - XRT_CHECK_RESULT bool 796 - oxr_space_pure_relation_from_space(struct oxr_logger *log, 797 - XrTime time, 798 - struct xrt_space_relation *relation, 799 - struct oxr_space *spc, 800 - struct xrt_space_relation *out_relation); 801 - 802 - /*! 803 - * Transforms a posen in a given oxr_space @p spc into a relation in "pure" global space, taking the pose offset of @p 804 - * spc into account. 805 - */ 806 - XRT_CHECK_RESULT bool 807 - oxr_space_pure_pose_from_space(struct oxr_logger *log, 808 - XrTime time, 809 - struct xrt_pose *pose, 810 - struct oxr_space *spc, 811 - struct xrt_space_relation *out_relation); 812 - 813 - /*! 814 - * Returns the pure relation in global space of an oxr_space, meaning the tracking_origin offsets are already applied 815 - * and sets @p out_xdev to the device the space is associated with. 772 + * Locate the @ref xrt_device in the given base space, useful for implementing 773 + * hand tracking location look ups and the like. 774 + * 775 + * @param log Logging struct. 776 + * @param xdev Device to locate in the base space. 777 + * @param baseSpc Base space where the device is to be located. 778 + * @param[in] time Time in OpenXR domain. 779 + * @param[out] out_relation Returns T_base_xdev, aka xdev in base space. 816 780 * 817 - * @todo: This function currently assumes all reference spaces are associated with the HMD. 781 + * @return Any errors, XR_SUCCESS, pose might not be valid on XR_SUCCESS. 818 782 */ 819 - XRT_CHECK_RESULT bool 820 - oxr_space_get_pure_relation(struct oxr_logger *log, 821 - struct oxr_space *spc, 822 - XrTime time, 823 - struct xrt_space_relation *out_relation); 824 - 825 - XrResult 826 - oxr_space_locate( 827 - struct oxr_logger *log, struct oxr_space *spc, struct oxr_space *baseSpc, XrTime time, XrSpaceLocation *location); 828 - 829 - XRT_CHECK_RESULT bool 830 - is_local_space_set_up(struct oxr_session *sess); 831 - 832 - XRT_CHECK_RESULT bool 833 - global_to_local_space(struct oxr_logger *log, struct oxr_session *sess, XrTime time, struct xrt_space_relation *rel); 783 + XRT_CHECK_RESULT XrResult 784 + oxr_space_locate_device(struct oxr_logger *log, 785 + struct xrt_device *xdev, 786 + struct oxr_space *baseSpc, 787 + XrTime time, 788 + struct xrt_space_relation *out_relation); 834 789 835 790 836 791 /* ··· 996 951 bool 997 952 oxr_xdev_find_output(struct xrt_device *xdev, enum xrt_output_name name, struct xrt_output **out_output); 998 953 999 - void 1000 - oxr_xdev_get_relation_chain(struct oxr_logger *log, 1001 - struct oxr_instance *inst, 1002 - struct xrt_device *xdev, 1003 - enum xrt_input_name name, 1004 - XrTime at_time, 1005 - struct xrt_relation_chain *xrc); 1006 - 1007 - void 1008 - oxr_xdev_get_space_relation(struct oxr_logger *log, 1009 - struct oxr_instance *inst, 1010 - struct xrt_device *xdev, 1011 - enum xrt_input_name name, 1012 - XrTime at_time, 1013 - struct xrt_space_relation *out_relation); 1014 - 1015 954 /*! 1016 955 * Returns the hand tracking value of the named input from the device. 1017 956 * Does NOT apply tracking origin offset to each joint. ··· 1023 962 enum xrt_input_name name, 1024 963 XrTime at_time, 1025 964 struct xrt_hand_joint_set *out_value); 965 + 1026 966 1027 967 /* 1028 968 * ··· 1995 1935 1996 1936 //! Which sub action path is this? 1997 1937 struct oxr_subaction_paths subaction_paths; 1938 + 1939 + struct 1940 + { 1941 + struct xrt_space *xs; 1942 + struct xrt_device *xdev; 1943 + enum xrt_input_name name; 1944 + } action; 1998 1945 }; 1999 1946 2000 1947 /*!
+45 -41
src/xrt/state_trackers/oxr/oxr_session.c
··· 343 343 const uint64_t xdisplay_time = 344 344 time_state_ts_to_monotonic_ns(sess->sys->inst->timekeeping, viewLocateInfo->displayTime); 345 345 346 - struct xrt_space_relation head_relation = XRT_SPACE_RELATION_ZERO; 346 + // The head pose as in the xdev's space, aka XRT_INPUT_GENERIC_HEAD_POSE. 347 + struct xrt_space_relation T_xdev_head = XRT_SPACE_RELATION_ZERO; 347 348 struct xrt_fov fovs[2] = {0}; 348 349 struct xrt_pose poses[2] = {0}; 349 350 ··· 352 353 &default_eye_relation, // 353 354 xdisplay_time, // 354 355 2, // 355 - &head_relation, // 356 + &T_xdev_head, // 356 357 fovs, // 357 358 poses); 358 359 359 - 360 - struct xrt_space_relation pure_head_relation; 361 - 362 - // head_relation is in xdev space. Bring it into pure global space by applying tracking origin offset. 363 - struct xrt_relation_chain xrc = {0}; 364 - m_relation_chain_push_relation(&xrc, &head_relation); 365 - m_relation_chain_push_pose_if_not_identity(&xrc, &xdev->tracking_origin->offset); 366 - m_relation_chain_resolve(&xrc, &pure_head_relation); 367 - 368 - // Clear here and filled in loop. 369 - viewState->viewStateFlags = 0; 370 - 371 - struct xrt_space_relation head_relation_in_base_space; 372 - if (!oxr_space_pure_relation_in_space(log, viewLocateInfo->displayTime, &pure_head_relation, baseSpc, true, 373 - &head_relation_in_base_space)) { 374 - for (uint32_t i = 0; i < view_count; i++) { 375 - OXR_XRT_POSE_TO_XRPOSEF(XRT_POSE_IDENTITY, views[i].pose); 376 - } 377 - 360 + // The xdev pose in the base space. 361 + struct xrt_space_relation T_base_xdev = XRT_SPACE_RELATION_ZERO; 362 + XrResult ret = oxr_space_locate_device( // 363 + log, // 364 + xdev, // 365 + baseSpc, // 366 + viewLocateInfo->displayTime, // 367 + &T_base_xdev); // 368 + if (ret != XR_SUCCESS || T_base_xdev.relation_flags == 0) { 378 369 if (print) { 379 370 oxr_slog(&slog, "\n\tReturning invalid poses"); 380 371 oxr_log_slog(log, &slog); 381 372 } else { 382 373 oxr_slog_cancel(&slog); 383 374 } 384 - 385 - return XR_SUCCESS; 375 + return ret; 386 376 } 387 377 378 + struct xrt_space_relation T_base_head; 379 + struct xrt_relation_chain xrc = {0}; 380 + m_relation_chain_push_relation(&xrc, &T_xdev_head); 381 + m_relation_chain_push_relation(&xrc, &T_base_xdev); 382 + m_relation_chain_resolve(&xrc, &T_base_head); 383 + 388 384 if (print) { 389 385 for (uint32_t i = 0; i < view_count; i++) { 390 386 char tmp[32]; ··· 392 388 oxr_pp_fov_indented_as_object(&slog, &fovs[i], tmp); 393 389 oxr_pp_pose_indented_as_object(&slog, &poses[i], tmp); 394 390 } 395 - oxr_pp_relation_indented(&slog, &head_relation, "xdev.head_relation"); 396 - oxr_pp_relation_indented(&slog, &head_relation_in_base_space, "head_relation_in_base_space"); 391 + oxr_pp_relation_indented(&slog, &T_xdev_head, "T_xdev_head"); 392 + oxr_pp_relation_indented(&slog, &T_base_xdev, "T_base_xdev"); 397 393 } 398 394 399 395 for (uint32_t i = 0; i < view_count; i++) { ··· 407 403 struct xrt_space_relation result = {0}; 408 404 struct xrt_relation_chain xrc = {0}; 409 405 m_relation_chain_push_pose_if_not_identity(&xrc, &view_pose); 410 - m_relation_chain_push_relation(&xrc, &head_relation_in_base_space); 406 + m_relation_chain_push_relation(&xrc, &T_base_head); 411 407 m_relation_chain_resolve(&xrc, &result); 412 408 OXR_XRT_POSE_TO_XRPOSEF(result.pose, views[i].pose); 413 409 ··· 942 938 943 939 oxr_xdev_get_hand_tracking_at(log, sess->sys->inst, xdev, name, at_time, &value); 944 940 945 - struct xrt_space_relation pure_hand_relation = value.hand_pose; 946 - struct xrt_relation_chain xrc = {0}; 947 - m_relation_chain_push_relation(&xrc, &pure_hand_relation); 948 - m_relation_chain_push_pose_if_not_identity(&xrc, &xdev->tracking_origin->offset); 949 - m_relation_chain_resolve(&xrc, &pure_hand_relation); 941 + // The hand pose is returned in the xdev's space. 942 + struct xrt_space_relation T_xdev_hand = value.hand_pose; 950 943 951 - struct xrt_space_relation hand_pose_in_base_space; 952 - bool has_hand_pose_in_base_sapce = oxr_space_pure_relation_in_space( // 953 - log, // 954 - at_time, // 955 - &pure_hand_relation, // 956 - baseSpc, // 957 - true, // 958 - &hand_pose_in_base_space); // 944 + // Get the xdev's pose in the base space. 945 + struct xrt_space_relation T_base_xdev = XRT_SPACE_RELATION_ZERO; 946 + 947 + XrResult ret = oxr_space_locate_device(log, xdev, baseSpc, at_time, &T_base_xdev); 948 + if (ret != XR_SUCCESS) { 949 + // Error printed logged oxr_space_locate_device 950 + return ret; 951 + } 952 + if (T_base_xdev.relation_flags == 0) { 953 + locations->isActive = false; 954 + return XR_SUCCESS; 955 + } 956 + 957 + // Get the hands pose in the base space. 958 + struct xrt_space_relation T_base_hand; 959 + struct xrt_relation_chain xrc = {0}; 960 + m_relation_chain_push_relation(&xrc, &T_xdev_hand); 961 + m_relation_chain_push_relation(&xrc, &T_base_xdev); 962 + m_relation_chain_resolve(&xrc, &T_base_hand); 959 963 960 964 // Can we not relate to this space or did we not get values? 961 - if (!has_hand_pose_in_base_sapce || !value.is_active) { 965 + if (T_base_hand.relation_flags == 0 || !value.is_active) { 962 966 locations->isActive = false; 963 967 964 968 // Loop over all joints and zero flags. ··· 986 990 struct xrt_space_relation result; 987 991 struct xrt_relation_chain chain = {0}; 988 992 m_relation_chain_push_relation(&chain, &r); 989 - m_relation_chain_push_relation(&chain, &hand_pose_in_base_space); 993 + m_relation_chain_push_relation(&chain, &T_base_hand); 990 994 m_relation_chain_resolve(&chain, &result); 991 995 992 996 xrt_to_xr_pose(&result.pose, &locations->jointLocations[i].pose);
+21 -15
src/xrt/state_trackers/oxr/oxr_session_frame_end.c
··· 858 858 uint64_t timestamp, 859 859 struct xrt_pose *out_pose) 860 860 { 861 - struct xrt_pose pose = *pose_ptr; 861 + // Aka T_offset_layer 862 + struct xrt_pose T_space_layer = *pose_ptr; 862 863 863 - // The pose might be valid for OpenXR, but not good enough for math. 864 - if (!math_quat_validate(&pose.orientation)) { 865 - math_quat_normalize(&pose.orientation); 864 + // The T_space_layer might be valid for OpenXR, but not good enough for math. 865 + if (!math_quat_validate(&T_space_layer.orientation)) { 866 + math_quat_normalize(&T_space_layer.orientation); 866 867 } 867 868 868 869 /* ··· 871 872 if (spc->space_type == OXR_SPACE_TYPE_REFERENCE_VIEW) { 872 873 struct xrt_space_relation rel; 873 874 struct xrt_relation_chain xrc = {0}; 874 - m_relation_chain_push_pose(&xrc, &pose); 875 - m_relation_chain_push_pose_if_not_identity(&xrc, &spc->pose); 875 + m_relation_chain_push_pose(&xrc, &T_space_layer); // T_offset_layer 876 + m_relation_chain_push_pose_if_not_identity(&xrc, &spc->pose); // T_space_offset 876 877 m_relation_chain_resolve(&xrc, &rel); 877 878 *out_pose = rel.pose; 878 879 return true; 879 880 } 880 881 881 - struct xrt_space_relation rel; 882 - if (!oxr_space_pure_pose_from_space(log, timestamp, &pose, spc, &rel)) { 882 + // The compositor doesn't know about spaces, so we want the space in the xdev's "space". 883 + struct xrt_device *head_xdev = GET_XDEV_BY_ROLE(sess->sys, head); 884 + struct xrt_space_relation T_space_xdev = XRT_SPACE_RELATION_ZERO; 885 + 886 + XrResult ret = oxr_space_locate_device(log, head_xdev, spc, timestamp, &T_space_xdev); 887 + if (ret != XR_SUCCESS) { 883 888 return false; 884 889 } 885 - 890 + if (T_space_xdev.relation_flags == 0) { 891 + return false; 892 + } 886 893 887 - // The compositor doesn't know about tracking origins, transform into the "raw" HMD tracking space. 888 - struct xrt_device *head_xdev = GET_XDEV_BY_ROLE(sess->sys, head); 894 + struct xrt_space_relation T_xdev_layer; 889 895 struct xrt_relation_chain xrc = {0}; 890 - m_relation_chain_push_relation(&xrc, &rel); 891 - m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &head_xdev->tracking_origin->offset); 892 - m_relation_chain_resolve(&xrc, &rel); 896 + m_relation_chain_push_pose_if_not_identity(&xrc, &T_space_layer); 897 + m_relation_chain_push_inverted_relation(&xrc, &T_space_xdev); // T_xdev_space 898 + m_relation_chain_resolve(&xrc, &T_xdev_layer); 893 899 894 - *out_pose = rel.pose; 900 + *out_pose = T_xdev_layer.pose; 895 901 896 902 return true; 897 903 }
+184 -255
src/xrt/state_trackers/oxr/oxr_space.c
··· 8 8 */ 9 9 10 10 11 - #include <stdio.h> 12 - #include <stdlib.h> 13 - #include <string.h> 11 + #include "xrt/xrt_space.h" 14 12 15 13 #include "math/m_api.h" 16 14 #include "math/m_space.h" 15 + 17 16 #include "util/u_debug.h" 18 17 #include "util/u_misc.h" 19 18 ··· 25 24 #include "oxr_pretty_print.h" 26 25 #include "oxr_conversions.h" 27 26 27 + #include <stdio.h> 28 + #include <stdlib.h> 29 + #include <string.h> 28 30 29 - const struct xrt_pose origin = XRT_POSE_IDENTITY; 31 + 32 + /* 33 + * 34 + * Helper functions. 35 + * 36 + */ 30 37 31 38 static XrResult 32 39 check_reference_space_type(struct oxr_logger *log, XrReferenceSpaceType type) ··· 48 55 } 49 56 } 50 57 58 + 59 + /* 60 + * 61 + * To xrt_space functions. 62 + * 63 + */ 64 + 65 + static XrResult 66 + get_xrt_space_action(struct oxr_logger *log, struct oxr_space *spc, struct xrt_space **out_xspace) 67 + { 68 + 69 + struct oxr_action_input *input = NULL; 70 + 71 + XrResult ret = oxr_action_get_pose_input(spc->sess, spc->act_key, &spc->subaction_paths, &input); 72 + if (ret != XR_SUCCESS) { 73 + return ret; 74 + } 75 + 76 + // Clear the cache. 77 + if (input == NULL) { 78 + xrt_space_reference(&spc->action.xs, NULL); 79 + spc->action.name = 0; 80 + spc->action.xdev = NULL; 81 + return XR_SUCCESS; 82 + } 83 + 84 + struct xrt_device *xdev = input->xdev; 85 + enum xrt_input_name name = input->input->name; 86 + 87 + assert(xdev != NULL); 88 + assert(name != 0); 89 + 90 + if (xdev != spc->action.xdev || name != spc->action.name) { 91 + xrt_space_reference(&spc->action.xs, NULL); 92 + 93 + xrt_result_t xret = xrt_space_overseer_create_pose_space( // 94 + spc->sess->sys->xso, // 95 + xdev, // 96 + name, // 97 + &spc->action.xs); // 98 + if (xret != XRT_SUCCESS) { 99 + oxr_warn(log, "Failed to create pose space"); 100 + } else { 101 + spc->action.xdev = xdev; 102 + spc->action.name = name; 103 + } 104 + } 105 + 106 + *out_xspace = spc->action.xs; 107 + 108 + return XR_SUCCESS; 109 + } 110 + 111 + static XrResult 112 + get_xrt_space(struct oxr_logger *log, struct oxr_space *spc, struct xrt_space **out_xspace) 113 + { 114 + assert(out_xspace != NULL); 115 + assert(*out_xspace == NULL); 116 + 117 + struct xrt_space *xspace = NULL; 118 + switch (spc->space_type) { 119 + case OXR_SPACE_TYPE_ACTION: return get_xrt_space_action(log, spc, out_xspace); 120 + case OXR_SPACE_TYPE_REFERENCE_VIEW: xspace = spc->sess->sys->xso->semantic.view; break; 121 + case OXR_SPACE_TYPE_REFERENCE_LOCAL: xspace = spc->sess->sys->xso->semantic.local; break; 122 + case OXR_SPACE_TYPE_REFERENCE_STAGE: xspace = spc->sess->sys->xso->semantic.stage; break; 123 + case OXR_SPACE_TYPE_REFERENCE_UNBOUNDED_MSFT: xspace = spc->sess->sys->xso->semantic.unbounded; break; 124 + case OXR_SPACE_TYPE_REFERENCE_COMBINED_EYE_VARJO: xspace = NULL; break; 125 + } 126 + 127 + if (xspace == NULL) { 128 + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Reference space without internal semantic space!"); 129 + } 130 + 131 + *out_xspace = xspace; 132 + 133 + return XR_SUCCESS; 134 + } 135 + 136 + 137 + /* 138 + * 139 + * Space creation and destroy functions. 140 + * 141 + */ 142 + 51 143 static XrResult 52 144 oxr_space_destroy(struct oxr_logger *log, struct oxr_handle_base *hb) 53 145 { 54 146 struct oxr_space *spc = (struct oxr_space *)hb; 147 + 148 + xrt_space_reference(&spc->action.xs, NULL); 149 + spc->action.xdev = NULL; 150 + spc->action.name = 0; 151 + 55 152 free(spc); 153 + 56 154 return XR_SUCCESS; 57 155 } 58 156 ··· 110 208 return XR_SUCCESS; 111 209 } 112 210 113 - static void 114 - print_pose(struct oxr_session *sess, const char *prefix, struct xrt_pose *pose); 115 211 116 - static bool 117 - set_up_local_space(struct oxr_logger *log, struct oxr_session *sess, XrTime time) 118 - { 119 - struct xrt_device *head_xdev = GET_XDEV_BY_ROLE(sess->sys, head); 120 - struct xrt_space_relation head_relation; 121 - oxr_xdev_get_space_relation(log, sess->sys->inst, head_xdev, XRT_INPUT_GENERIC_HEAD_POSE, time, &head_relation); 122 - 123 - if ((head_relation.relation_flags & XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT) == 0) { 124 - return false; 125 - } 126 - 127 - if (!is_local_space_set_up(sess)) { 128 - sess->local_space_pure_relation = head_relation; 129 - 130 - // take only head rotation around y axis 131 - // https://stackoverflow.com/a/5783030 132 - sess->local_space_pure_relation.pose.orientation.x = 0; 133 - sess->local_space_pure_relation.pose.orientation.z = 0; 134 - math_quat_normalize(&sess->local_space_pure_relation.pose.orientation); 135 - 136 - print_pose(sess, "local space updated", &head_relation.pose); 137 - 138 - //! @todo: Handle relation velocities if necessary 139 - } 140 - return true; 141 - } 142 - 143 - XRT_CHECK_RESULT bool 144 - is_local_space_set_up(struct oxr_session *sess) 145 - { 146 - return (sess->local_space_pure_relation.relation_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0; 147 - } 148 - 149 - 150 - /*! 151 - * Returns the pure relation in global space of an oxr_space, meaning the tracking_origin offsets are already applied. 212 + /* 213 + * 214 + * OpenXR API functions. 152 215 * 153 - * @todo: Until a proper reference space system is implemented, the xdev assigned to the head role should be used as @p 154 - * ref_xdev for consistency. 155 216 */ 156 - XRT_CHECK_RESULT static bool 157 - oxr_space_ref_get_pure_relation(struct oxr_logger *log, 158 - struct oxr_session *sess, 159 - enum oxr_space_type space_type, 160 - struct xrt_device *ref_xdev, 161 - XrTime time, 162 - struct xrt_space_relation *out_relation) 163 - { 164 - switch (space_type) { 165 - case OXR_SPACE_TYPE_REFERENCE_LOCAL: { 166 - if (!is_local_space_set_up(sess)) { 167 - if (!set_up_local_space(log, sess, time)) { 168 - return false; 169 - } 170 - } 171 217 172 - *out_relation = sess->local_space_pure_relation; 173 - return true; 174 - } 175 - case OXR_SPACE_TYPE_REFERENCE_STAGE: { 176 - //! @todo: stage space origin assumed to be the same as HMD xdev space origin for now. 177 - m_space_relation_ident(out_relation); 178 - return true; 179 - } 180 - case OXR_SPACE_TYPE_REFERENCE_VIEW: { 181 - oxr_xdev_get_space_relation(log, sess->sys->inst, ref_xdev, XRT_INPUT_GENERIC_HEAD_POSE, time, 182 - out_relation); 183 - return true; 184 - } 185 - 186 - case OXR_SPACE_TYPE_REFERENCE_UNBOUNDED_MSFT: 187 - case OXR_SPACE_TYPE_REFERENCE_COMBINED_EYE_VARJO: 188 - // not implemented 189 - return oxr_error(log, false, "Reference Space type %d not implemented!", space_type); 190 - case OXR_SPACE_TYPE_ACTION: return oxr_error(log, false, "Space is not a reference space!"); 191 - } 192 - return true; 193 - } 194 - 195 - XRT_CHECK_RESULT bool 196 - oxr_space_pure_relation_in_space(struct oxr_logger *log, 197 - XrTime time, 198 - struct xrt_space_relation *relation, 199 - struct oxr_space *spc, 200 - bool apply_space_pose, 201 - struct xrt_space_relation *out_relation) 218 + XrResult 219 + oxr_space_locate( 220 + struct oxr_logger *log, struct oxr_space *spc, struct oxr_space *baseSpc, XrTime time, XrSpaceLocation *location) 202 221 { 203 - struct xrt_space_relation pure_space_relation; 204 - if (!oxr_space_get_pure_relation(log, spc, time, &pure_space_relation)) { 205 - return false; 222 + struct oxr_sink_logger slog = {0}; 223 + struct oxr_system *sys = spc->sess->sys; 224 + bool print = sys->inst->debug_spaces; 225 + if (print) { 226 + oxr_pp_space_indented(&slog, spc, "space"); 227 + oxr_pp_space_indented(&slog, baseSpc, "baseSpace"); 206 228 } 207 229 208 - struct xrt_relation_chain xrc = {0}; 230 + // Used in a lot of places. 231 + XrSpaceVelocity *vel = OXR_GET_OUTPUT_FROM_CHAIN(location->next, XR_TYPE_SPACE_VELOCITY, XrSpaceVelocity); 209 232 210 - m_relation_chain_push_relation(&xrc, relation); 211 - m_relation_chain_push_inverted_relation(&xrc, &pure_space_relation); 212 233 213 - if (apply_space_pose) { 214 - m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &spc->pose); 215 - } 234 + /* 235 + * Seek knowledge about the spaces from the space overseer. 236 + */ 216 237 217 - m_relation_chain_resolve(&xrc, out_relation); 218 - return true; 219 - } 238 + struct xrt_space *xtarget = NULL; 239 + struct xrt_space *xbase = NULL; 240 + XrResult ret; 220 241 221 - XRT_CHECK_RESULT bool 222 - oxr_space_pure_pose_in_space(struct oxr_logger *log, 223 - XrTime time, 224 - struct xrt_pose *pose, 225 - struct oxr_space *spc, 226 - bool apply_space_pose, 227 - struct xrt_space_relation *out_relation) 228 - { 229 - struct xrt_space_relation rel; 230 - m_space_relation_from_pose(pose, &rel); 231 - return oxr_space_pure_relation_in_space(log, time, &rel, spc, apply_space_pose, out_relation); 232 - } 233 - 234 - XRT_CHECK_RESULT bool 235 - oxr_space_pure_relation_from_space(struct oxr_logger *log, 236 - XrTime time, 237 - struct xrt_space_relation *relation, 238 - struct oxr_space *spc, 239 - struct xrt_space_relation *out_relation) 240 - { 241 - struct xrt_space_relation pure_space_relation; 242 - if (!oxr_space_get_pure_relation(log, spc, time, &pure_space_relation)) { 243 - return false; 244 - } 245 - 246 - struct xrt_relation_chain xrc = {0}; 247 - m_relation_chain_push_relation(&xrc, relation); 248 - m_relation_chain_push_pose_if_not_identity(&xrc, &spc->pose); 249 - m_relation_chain_push_relation(&xrc, &pure_space_relation); 250 - m_relation_chain_resolve(&xrc, out_relation); 251 - return true; 252 - } 253 - 254 - XRT_CHECK_RESULT bool 255 - oxr_space_pure_pose_from_space(struct oxr_logger *log, 256 - XrTime time, 257 - struct xrt_pose *pose, 258 - struct oxr_space *spc, 259 - struct xrt_space_relation *out_relation) 260 - { 261 - struct xrt_space_relation rel; 262 - m_space_relation_from_pose(pose, &rel); 263 - return oxr_space_pure_relation_from_space(log, time, &rel, spc, out_relation); 264 - } 265 - 266 - XRT_CHECK_RESULT bool 267 - oxr_space_get_pure_relation(struct oxr_logger *log, 268 - struct oxr_space *spc, 269 - XrTime time, 270 - struct xrt_space_relation *out_relation) 271 - { 272 - if (oxr_space_type_is_reference(spc->space_type)) { 273 - struct xrt_device *head_xdev = GET_XDEV_BY_ROLE(spc->sess->sys, head); 274 - return oxr_space_ref_get_pure_relation(log, spc->sess, spc->space_type, head_xdev, time, out_relation); 242 + ret = get_xrt_space(log, spc, &xtarget); 243 + // Make sure not to overwrite error return 244 + if (ret == XR_SUCCESS) { 245 + ret = get_xrt_space(log, baseSpc, &xbase); 275 246 } 276 - if (spc->space_type == OXR_SPACE_TYPE_ACTION) { 277 - struct oxr_action_input *input = NULL; 278 - oxr_action_get_pose_input(spc->sess, spc->act_key, &spc->subaction_paths, &input); 279 247 280 - // If the input isn't active. 281 - if (input == NULL) { 282 - out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE; 283 - return false; 284 - } 248 + // Only fill this out if the above succeeded. 249 + struct xrt_space_relation result = XRT_SPACE_RELATION_ZERO; 250 + if (xtarget != NULL && xbase != NULL) { 251 + // Convert at_time to monotonic and give to device. 252 + uint64_t at_timestamp_ns = time_state_ts_to_monotonic_ns(sys->inst->timekeeping, time); 285 253 286 - oxr_xdev_get_space_relation(log, spc->sess->sys->inst, input->xdev, input->input->name, time, 287 - out_relation); 288 - 289 - return true; 254 + // Ask the space overseer to locate the spaces. 255 + xrt_space_overseer_locate_space( // 256 + sys->xso, // 257 + xbase, // 258 + &baseSpc->pose, // 259 + at_timestamp_ns, // 260 + xtarget, // 261 + &spc->pose, // 262 + &result); // 290 263 } 291 264 292 - return oxr_error(log, false, "Unknown space type"); 293 - } 294 265 295 - XRT_CHECK_RESULT bool 296 - global_to_local_space(struct oxr_logger *log, struct oxr_session *sess, XrTime time, struct xrt_space_relation *rel) 297 - { 298 - if (!is_local_space_set_up(sess)) { 299 - if (!set_up_local_space(log, sess, time)) { 300 - return false; 301 - } 302 - } 266 + /* 267 + * Validate results 268 + */ 303 269 304 - struct xrt_relation_chain xrc = {0}; 305 - m_relation_chain_push_relation(&xrc, rel); 306 - m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &sess->local_space_pure_relation.pose); 307 - m_relation_chain_resolve(&xrc, rel); 308 - 309 - return true; 310 - } 311 - 312 - /*! 313 - * This returns only the relation between two directly-associated spaces without 314 - * the app given offset pose for baseSpc applied. 315 - */ 316 - XRT_CHECK_RESULT static bool 317 - get_pure_space_relation(struct oxr_logger *log, 318 - struct oxr_space *spc, 319 - struct oxr_space *baseSpc, 320 - XrTime time, 321 - struct xrt_space_relation *out_relation) 322 - { 323 - struct xrt_space_relation space_pure_relation; 324 - if (!oxr_space_get_pure_relation(log, spc, time, &space_pure_relation)) { 325 - return false; 326 - } 327 - 328 - struct xrt_space_relation base_space_pure_relation; 329 - if (!oxr_space_get_pure_relation(log, baseSpc, time, &base_space_pure_relation)) { 330 - return false; 331 - } 332 - 333 - struct xrt_relation_chain xrc = {0}; 334 - m_relation_chain_push_relation(&xrc, &space_pure_relation); 335 - m_relation_chain_push_inverted_relation(&xrc, &base_space_pure_relation); 336 - m_relation_chain_resolve(&xrc, out_relation); 337 - 338 - return true; 339 - } 340 - 341 - static void 342 - print_pose(struct oxr_session *sess, const char *prefix, struct xrt_pose *pose) 343 - { 344 - if (!sess->sys->inst->debug_spaces) { 345 - return; 346 - } 347 - 348 - struct xrt_vec3 *p = &pose->position; 349 - struct xrt_quat *q = &pose->orientation; 350 - 351 - U_LOG_D("%s (%f, %f, %f) (%f, %f, %f, %f)", prefix, p->x, p->y, p->z, q->x, q->y, q->z, q->w); 352 - } 353 - 354 - XrResult 355 - oxr_space_locate( 356 - struct oxr_logger *log, struct oxr_space *spc, struct oxr_space *baseSpc, XrTime time, XrSpaceLocation *location) 357 - { 358 - struct oxr_sink_logger slog = {0}; 359 - bool print = spc->sess->sys->inst->debug_spaces; 360 - if (print) { 361 - oxr_pp_space_indented(&slog, spc, "space"); 362 - oxr_pp_space_indented(&slog, baseSpc, "baseSpace"); 363 - } 364 - 365 - // Used in a lot of places. 366 - XrSpaceVelocity *vel = OXR_GET_OUTPUT_FROM_CHAIN(location->next, XR_TYPE_SPACE_VELOCITY, XrSpaceVelocity); 367 - 368 - // Get the pure space relation. 369 - struct xrt_space_relation pure; 370 - bool has_pure_relation = get_pure_space_relation(log, spc, baseSpc, time, &pure); 371 - if (!has_pure_relation) { 270 + if (result.relation_flags == 0) { 372 271 location->locationFlags = 0; 373 272 374 273 OXR_XRT_POSE_TO_XRPOSEF(XRT_POSE_IDENTITY, location->pose); ··· 386 285 oxr_slog_cancel(&slog); 387 286 } 388 287 389 - return XR_SUCCESS; 288 + return ret; // Return any error. 390 289 } 391 290 392 291 393 292 /* 394 293 * Combine and copy 395 294 */ 396 - 397 - // Combine space and base space poses with pure relation 398 - struct xrt_space_relation result; 399 - struct xrt_relation_chain xrc = {0}; 400 - m_relation_chain_push_pose_if_not_identity(&xrc, &spc->pose); 401 - m_relation_chain_push_relation(&xrc, &pure); 402 - m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &baseSpc->pose); 403 - m_relation_chain_resolve(&xrc, &result); 404 295 405 296 OXR_XRT_POSE_TO_XRPOSEF(result.pose, location->pose); 406 297 location->locationFlags = xrt_to_xr_space_location_flags(result.relation_flags); ··· 432 323 */ 433 324 434 325 if (print) { 435 - oxr_pp_pose_indented_as_object(&slog, (struct xrt_pose *)&pure.pose, "pure"); 436 326 oxr_pp_relation_indented(&slog, &result, "relation"); 437 327 oxr_log_slog(log, &slog); 438 328 } else { ··· 441 331 442 332 return oxr_session_success_result(spc->sess); 443 333 } 334 + 335 + 336 + /* 337 + * 338 + * 'Exported' functions. 339 + * 340 + */ 341 + 342 + XrResult 343 + oxr_space_locate_device(struct oxr_logger *log, 344 + struct xrt_device *xdev, 345 + struct oxr_space *baseSpc, 346 + XrTime time, 347 + struct xrt_space_relation *out_relation) 348 + { 349 + struct oxr_system *sys = baseSpc->sess->sys; 350 + 351 + struct xrt_space *xbase = NULL; 352 + XrResult ret; 353 + 354 + ret = get_xrt_space(log, baseSpc, &xbase); 355 + if (xbase == NULL) { 356 + return ret; 357 + } 358 + 359 + // Convert at_time to monotonic and give to device. 360 + uint64_t at_timestamp_ns = time_state_ts_to_monotonic_ns(sys->inst->timekeeping, time); 361 + 362 + // Ask the space overseer to locate the spaces. 363 + xrt_space_overseer_locate_device( // 364 + sys->xso, // 365 + xbase, // 366 + &baseSpc->pose, // 367 + at_timestamp_ns, // 368 + xdev, // 369 + out_relation); // 370 + 371 + return ret; 372 + }
-32
src/xrt/state_trackers/oxr/oxr_xdev.c
··· 79 79 } 80 80 81 81 void 82 - oxr_xdev_get_relation_chain(struct oxr_logger *log, 83 - struct oxr_instance *inst, 84 - struct xrt_device *xdev, 85 - enum xrt_input_name name, 86 - XrTime at_time, 87 - struct xrt_relation_chain *xrc) 88 - { 89 - // Convert at_time to monotonic and give to device. 90 - uint64_t at_timestamp_ns = time_state_ts_to_monotonic_ns(inst->timekeeping, at_time); 91 - 92 - struct xrt_space_relation *rel = m_relation_chain_reserve(xrc); 93 - 94 - xrt_device_get_tracked_pose(xdev, name, at_timestamp_ns, rel); 95 - 96 - // Add in the offset from the tracking system. 97 - m_relation_chain_push_pose(xrc, &xdev->tracking_origin->offset); 98 - } 99 - 100 - void 101 82 oxr_xdev_get_hand_tracking_at(struct oxr_logger *log, 102 83 struct oxr_instance *inst, 103 84 struct xrt_device *xdev, ··· 117 98 118 99 *out_value = value; 119 100 } 120 - 121 - void 122 - oxr_xdev_get_space_relation(struct oxr_logger *log, 123 - struct oxr_instance *inst, 124 - struct xrt_device *xdev, 125 - enum xrt_input_name name, 126 - XrTime at_time, 127 - struct xrt_space_relation *out_relation) 128 - { 129 - struct xrt_relation_chain xrc = {0}; 130 - oxr_xdev_get_relation_chain(log, inst, xdev, name, at_time, &xrc); 131 - m_relation_chain_resolve(&xrc, out_relation); 132 - }