mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
st/oxr: rework spaces
This commit is contained in:
parent
f633680506
commit
ed0bd9c244
|
@ -708,35 +708,77 @@ oxr_space_reference_create(struct oxr_logger *log,
|
||||||
const XrReferenceSpaceCreateInfo *createInfo,
|
const XrReferenceSpaceCreateInfo *createInfo,
|
||||||
struct oxr_space **out_space);
|
struct oxr_space **out_space);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Transforms a relation given in pure global space into the oxr_space @p spc.
|
||||||
|
* If @p apply_space_pose is true, the pose offset of @p spc will be included in @p out_relation.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
oxr_space_pure_relation_in_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_space_relation *relation,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
bool apply_space_pose,
|
||||||
|
struct xrt_space_relation *out_relation);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Transforms a pose given in pure global space into a relation in the oxr_space @p spc.
|
||||||
|
* If @p apply_space_pose is true, the pose offset of @p spc will be included in @p out_relation.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
oxr_space_pure_pose_in_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_pose *pose,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
bool apply_space_pose,
|
||||||
|
struct xrt_space_relation *out_relation);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Transforms a relation in an given oxr_space @p spc into pure global space, taking the pose offset of @p spc into
|
||||||
|
* account.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
oxr_space_pure_relation_from_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_space_relation *relation,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
struct xrt_space_relation *out_relation);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Transforms a posen in a given oxr_space @p spc into a relation in "pure" global space, taking the pose offset of @p
|
||||||
|
* spc into account.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
oxr_space_pure_pose_from_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_pose *pose,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
struct xrt_space_relation *out_relation);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns the pure relation in global space of an oxr_space, meaning the tracking_origin offsets are already applied
|
||||||
|
* and sets @p out_xdev to the device the space is associated with.
|
||||||
|
*
|
||||||
|
* @todo: This function currently assumes all reference spaces are associated with the HMD.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
oxr_space_get_pure_relation(struct oxr_logger *log,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_space_relation *out_relation,
|
||||||
|
struct xrt_device **out_xdev);
|
||||||
|
|
||||||
XrResult
|
XrResult
|
||||||
oxr_space_locate(
|
oxr_space_locate(
|
||||||
struct oxr_logger *log, struct oxr_space *spc, struct oxr_space *baseSpc, XrTime time, XrSpaceLocation *location);
|
struct oxr_logger *log, struct oxr_space *spc, struct oxr_space *baseSpc, XrTime time, XrSpaceLocation *location);
|
||||||
|
|
||||||
XrResult
|
|
||||||
oxr_space_ref_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct oxr_space *space,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime time,
|
|
||||||
struct xrt_space_relation *out_relation);
|
|
||||||
|
|
||||||
XrResult
|
|
||||||
oxr_view_relation_ref_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct xrt_space_relation *view_relation,
|
|
||||||
struct xrt_device *view_xdev,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime time,
|
|
||||||
struct xrt_space_relation *out_relation);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
initial_head_relation_valid(struct oxr_session *sess);
|
is_local_space_set_up(struct oxr_session *sess);
|
||||||
|
|
||||||
XrSpaceLocationFlags
|
XrSpaceLocationFlags
|
||||||
xrt_to_xr_space_location_flags(enum xrt_space_relation_flags relation_flags);
|
xrt_to_xr_space_location_flags(enum xrt_space_relation_flags relation_flags);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
global_to_local_space(struct oxr_session *sess, struct xrt_space_relation *rel);
|
global_to_local_space(struct oxr_logger *log, struct oxr_session *sess, XrTime time, struct xrt_space_relation *rel);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -1376,7 +1418,7 @@ struct oxr_session
|
||||||
|
|
||||||
/*! initial relation of head in "global" space.
|
/*! initial relation of head in "global" space.
|
||||||
* Used as reference for local space. */
|
* Used as reference for local space. */
|
||||||
struct xrt_space_relation initial_head_relation;
|
struct xrt_space_relation local_space_pure_relation;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -399,16 +399,18 @@ oxr_session_locate_views(struct oxr_logger *log,
|
||||||
fovs, //
|
fovs, //
|
||||||
poses);
|
poses);
|
||||||
|
|
||||||
// head_relation is in xdev space. Bring it into global space by applying tracking origin offset.
|
|
||||||
|
struct xrt_space_relation pure_head_relation;
|
||||||
|
|
||||||
|
// head_relation is in xdev space. Bring it into pure global space by applying tracking origin offset.
|
||||||
struct xrt_relation_chain xrc = {0};
|
struct xrt_relation_chain xrc = {0};
|
||||||
m_relation_chain_push_relation(&xrc, &head_relation);
|
m_relation_chain_push_relation(&xrc, &head_relation);
|
||||||
m_relation_chain_push_pose_if_not_identity(&xrc, &xdev->tracking_origin->offset);
|
m_relation_chain_push_pose_if_not_identity(&xrc, &xdev->tracking_origin->offset);
|
||||||
m_relation_chain_resolve(&xrc, &head_relation);
|
m_relation_chain_resolve(&xrc, &pure_head_relation);
|
||||||
|
|
||||||
// transform head_relation into base_space
|
struct xrt_space_relation head_relation_in_base_space;
|
||||||
struct xrt_space_relation base_spc_head_relation;
|
oxr_space_pure_relation_in_space(log, viewLocateInfo->displayTime, &pure_head_relation, baseSpc, true,
|
||||||
oxr_view_relation_ref_relation(log, sess, &head_relation, xdev, baseSpc, viewLocateInfo->displayTime,
|
&head_relation_in_base_space);
|
||||||
&base_spc_head_relation);
|
|
||||||
|
|
||||||
// Clear here and filled in loop.
|
// Clear here and filled in loop.
|
||||||
viewState->viewStateFlags = 0;
|
viewState->viewStateFlags = 0;
|
||||||
|
@ -424,8 +426,7 @@ oxr_session_locate_views(struct oxr_logger *log,
|
||||||
struct xrt_space_relation result = {0};
|
struct xrt_space_relation result = {0};
|
||||||
struct xrt_relation_chain xrc = {0};
|
struct xrt_relation_chain xrc = {0};
|
||||||
m_relation_chain_push_pose_if_not_identity(&xrc, &view_pose);
|
m_relation_chain_push_pose_if_not_identity(&xrc, &view_pose);
|
||||||
m_relation_chain_push_relation(&xrc, &base_spc_head_relation);
|
m_relation_chain_push_relation(&xrc, &head_relation_in_base_space);
|
||||||
m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &baseSpc->pose);
|
|
||||||
m_relation_chain_resolve(&xrc, &result);
|
m_relation_chain_resolve(&xrc, &result);
|
||||||
union {
|
union {
|
||||||
struct xrt_pose xrt;
|
struct xrt_pose xrt;
|
||||||
|
@ -865,13 +866,21 @@ oxr_session_hand_joints(struct oxr_logger *log,
|
||||||
struct xrt_device *xdev = hand_tracker->xdev;
|
struct xrt_device *xdev = hand_tracker->xdev;
|
||||||
enum xrt_input_name name = hand_tracker->input_name;
|
enum xrt_input_name name = hand_tracker->input_name;
|
||||||
|
|
||||||
struct xrt_pose *tracking_origin_offset = &xdev->tracking_origin->offset;
|
|
||||||
|
|
||||||
XrTime at_time = locateInfo->time;
|
XrTime at_time = locateInfo->time;
|
||||||
struct xrt_hand_joint_set value;
|
struct xrt_hand_joint_set value;
|
||||||
|
|
||||||
oxr_xdev_get_hand_tracking_at(log, sess->sys->inst, xdev, name, at_time, &value);
|
oxr_xdev_get_hand_tracking_at(log, sess->sys->inst, xdev, name, at_time, &value);
|
||||||
|
|
||||||
|
struct xrt_space_relation pure_hand_relation = value.hand_pose;
|
||||||
|
struct xrt_relation_chain xrc = {0};
|
||||||
|
m_relation_chain_push_relation(&xrc, &pure_hand_relation);
|
||||||
|
m_relation_chain_push_pose_if_not_identity(&xrc, &xdev->tracking_origin->offset);
|
||||||
|
m_relation_chain_resolve(&xrc, &pure_hand_relation);
|
||||||
|
|
||||||
|
struct xrt_space_relation hand_pose_in_base_space;
|
||||||
|
oxr_space_pure_relation_in_space(log, at_time, &pure_hand_relation, baseSpc, true, &hand_pose_in_base_space);
|
||||||
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < locations->jointCount; i++) {
|
for (uint32_t i = 0; i < locations->jointCount; i++) {
|
||||||
locations->jointLocations[i].locationFlags =
|
locations->jointLocations[i].locationFlags =
|
||||||
xrt_to_xr_space_location_flags(value.values.hand_joint_set_default[i].relation.relation_flags);
|
xrt_to_xr_space_location_flags(value.values.hand_joint_set_default[i].relation.relation_flags);
|
||||||
|
@ -882,72 +891,9 @@ oxr_session_hand_joints(struct oxr_logger *log,
|
||||||
struct xrt_space_relation result;
|
struct xrt_space_relation result;
|
||||||
struct xrt_relation_chain chain = {0};
|
struct xrt_relation_chain chain = {0};
|
||||||
m_relation_chain_push_relation(&chain, &r);
|
m_relation_chain_push_relation(&chain, &r);
|
||||||
|
m_relation_chain_push_relation(&chain, &hand_pose_in_base_space);
|
||||||
|
|
||||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
|
||||||
|
|
||||||
m_relation_chain_push_relation(&chain, &value.hand_pose);
|
|
||||||
m_relation_chain_push_pose_if_not_identity(&chain, tracking_origin_offset);
|
|
||||||
|
|
||||||
} else if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
|
||||||
|
|
||||||
// for local space, first do stage space and transform
|
|
||||||
// result to local @todo: improve local space
|
|
||||||
m_relation_chain_push_relation(&chain, &value.hand_pose);
|
|
||||||
m_relation_chain_push_pose_if_not_identity(&chain, tracking_origin_offset);
|
|
||||||
|
|
||||||
} else if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
|
||||||
/*! @todo: testing, relating to view space unsupported
|
|
||||||
* in other parts of monado */
|
|
||||||
|
|
||||||
struct xrt_device *view_xdev = NULL;
|
|
||||||
|
|
||||||
struct xrt_space_relation view_relation;
|
|
||||||
oxr_session_get_view_relation_at(log, sess, at_time, &view_relation, &view_xdev);
|
|
||||||
|
|
||||||
m_relation_chain_push_relation(&chain, &value.hand_pose);
|
|
||||||
m_relation_chain_push_pose_if_not_identity(&chain, tracking_origin_offset);
|
|
||||||
|
|
||||||
m_relation_chain_push_inverted_relation(&chain, &view_relation);
|
|
||||||
m_relation_chain_push_inverted_pose_if_not_identity(&chain,
|
|
||||||
&view_xdev->tracking_origin->offset);
|
|
||||||
|
|
||||||
} else if (!baseSpc->is_reference) {
|
|
||||||
// action space
|
|
||||||
|
|
||||||
struct oxr_action_input *input = NULL;
|
|
||||||
oxr_action_get_pose_input(log, sess, baseSpc->act_key, &baseSpc->subaction_paths, &input);
|
|
||||||
|
|
||||||
// If the input isn't active.
|
|
||||||
if (input == NULL) {
|
|
||||||
locations->isActive = false;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct xrt_space_relation act_space_relation;
|
|
||||||
|
|
||||||
oxr_xdev_get_space_relation(log, sess->sys->inst, input->xdev, input->input->name, at_time,
|
|
||||||
&act_space_relation);
|
|
||||||
|
|
||||||
|
|
||||||
m_relation_chain_push_relation(&chain, &value.hand_pose);
|
|
||||||
m_relation_chain_push_pose_if_not_identity(&chain, tracking_origin_offset);
|
|
||||||
|
|
||||||
m_relation_chain_push_inverted_relation(&chain, &act_space_relation);
|
|
||||||
m_relation_chain_push_inverted_pose_if_not_identity(&chain,
|
|
||||||
&input->xdev->tracking_origin->offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_relation_chain_push_inverted_pose_if_not_identity(&chain, &baseSpc->pose);
|
|
||||||
m_relation_chain_resolve(&chain, &result);
|
m_relation_chain_resolve(&chain, &result);
|
||||||
|
|
||||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
|
||||||
if (!global_to_local_space(sess, &result)) {
|
|
||||||
locations->isActive = false;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xrt_to_xr_pose(&result.pose, &locations->jointLocations[i].pose);
|
xrt_to_xr_pose(&result.pose, &locations->jointLocations[i].pose);
|
||||||
|
|
||||||
if (vel) {
|
if (vel) {
|
||||||
|
|
|
@ -804,55 +804,9 @@ handle_space(struct oxr_logger *log,
|
||||||
math_quat_normalize(&pose.orientation);
|
math_quat_normalize(&pose.orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spc->is_reference && spc->type == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
struct xrt_space_relation rel;
|
||||||
// The space might have a pose, transform that in as well.
|
oxr_space_pure_pose_from_space(log, timestamp, &pose, spc, &rel);
|
||||||
math_pose_transform(&spc->pose, &pose, &pose);
|
*out_pose = rel.pose;
|
||||||
} else if (spc->is_reference) {
|
|
||||||
// The space might have a pose, transform that in as well.
|
|
||||||
math_pose_transform(&spc->pose, &pose, &pose);
|
|
||||||
|
|
||||||
// Remove the tracking system origin offset.
|
|
||||||
math_pose_transform(inv_offset, &pose, &pose);
|
|
||||||
|
|
||||||
if (spc->type == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
|
||||||
if (!initial_head_relation_valid(sess)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
math_pose_transform(&sess->initial_head_relation.pose, &pose, &pose);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//! @todo Action space handling not very complete
|
|
||||||
|
|
||||||
struct oxr_action_input *input = NULL;
|
|
||||||
|
|
||||||
oxr_action_get_pose_input(log, sess, spc->act_key, &spc->subaction_paths, &input);
|
|
||||||
|
|
||||||
// If the input isn't active.
|
|
||||||
if (input == NULL) {
|
|
||||||
//! @todo just don't render the quad here?
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct xrt_space_relation out_relation;
|
|
||||||
|
|
||||||
oxr_xdev_get_space_relation(log, sess->sys->inst, input->xdev, input->input->name, timestamp,
|
|
||||||
&out_relation);
|
|
||||||
|
|
||||||
struct xrt_pose device_pose = out_relation.pose;
|
|
||||||
|
|
||||||
// The space might have a pose, transform that in as well.
|
|
||||||
math_pose_transform(&spc->pose, &device_pose, &device_pose);
|
|
||||||
|
|
||||||
math_pose_transform(&device_pose, &pose, &pose);
|
|
||||||
|
|
||||||
// Remove the tracking system origin offset.
|
|
||||||
math_pose_transform(inv_offset, &pose, &pose);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
*out_pose = pose;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -948,7 +902,6 @@ submit_projection_layer(struct oxr_session *sess,
|
||||||
fill_in_sub_image(scs[0], &proj->views[0].subImage, &data.stereo.l.sub);
|
fill_in_sub_image(scs[0], &proj->views[0].subImage, &data.stereo.l.sub);
|
||||||
fill_in_sub_image(scs[1], &proj->views[1].subImage, &data.stereo.r.sub);
|
fill_in_sub_image(scs[1], &proj->views[1].subImage, &data.stereo.r.sub);
|
||||||
|
|
||||||
|
|
||||||
#ifdef XRT_FEATURE_OPENXR_LAYER_DEPTH
|
#ifdef XRT_FEATURE_OPENXR_LAYER_DEPTH
|
||||||
const XrCompositionLayerDepthInfoKHR *d_l = OXR_GET_INPUT_FROM_CHAIN(
|
const XrCompositionLayerDepthInfoKHR *d_l = OXR_GET_INPUT_FROM_CHAIN(
|
||||||
&proj->views[0], XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR, XrCompositionLayerDepthInfoKHR);
|
&proj->views[0], XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR, XrCompositionLayerDepthInfoKHR);
|
||||||
|
|
|
@ -123,21 +123,30 @@ get_ref_space_type_short_str(struct oxr_space *spc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_pose(struct oxr_session *sess, const char *prefix, struct xrt_pose *pose);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ensure_initial_head_relation(struct oxr_logger *log, struct oxr_session *sess, struct xrt_space_relation *head_relation)
|
set_up_local_space(struct oxr_logger *log, struct oxr_session *sess, XrTime time)
|
||||||
{
|
{
|
||||||
if ((head_relation->relation_flags & XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT) == 0) {
|
struct xrt_device *head_xdev = GET_XDEV_BY_ROLE(sess->sys, head);
|
||||||
|
struct xrt_space_relation head_relation;
|
||||||
|
oxr_xdev_get_space_relation(log, sess->sys->inst, head_xdev, XRT_INPUT_GENERIC_HEAD_POSE, time, &head_relation);
|
||||||
|
|
||||||
|
if ((head_relation.relation_flags & XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT) == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initial_head_relation_valid(sess)) {
|
if (!is_local_space_set_up(sess)) {
|
||||||
sess->initial_head_relation = *head_relation;
|
sess->local_space_pure_relation = head_relation;
|
||||||
|
|
||||||
// take only head rotation around y axis
|
// take only head rotation around y axis
|
||||||
// https://stackoverflow.com/a/5783030
|
// https://stackoverflow.com/a/5783030
|
||||||
sess->initial_head_relation.pose.orientation.x = 0;
|
sess->local_space_pure_relation.pose.orientation.x = 0;
|
||||||
sess->initial_head_relation.pose.orientation.z = 0;
|
sess->local_space_pure_relation.pose.orientation.z = 0;
|
||||||
math_quat_normalize(&sess->initial_head_relation.pose.orientation);
|
math_quat_normalize(&sess->local_space_pure_relation.pose.orientation);
|
||||||
|
|
||||||
|
print_pose(sess, "local space updated", &head_relation.pose);
|
||||||
|
|
||||||
//! @todo: Handle relation velocities if necessary
|
//! @todo: Handle relation velocities if necessary
|
||||||
}
|
}
|
||||||
|
@ -145,224 +154,173 @@ ensure_initial_head_relation(struct oxr_logger *log, struct oxr_session *sess, s
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
initial_head_relation_valid(struct oxr_session *sess)
|
is_local_space_set_up(struct oxr_session *sess)
|
||||||
{
|
{
|
||||||
return sess->initial_head_relation.relation_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT;
|
return (sess->local_space_pure_relation.relation_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns the pure relation in global space of an oxr_space, meaning the tracking_origin offsets are already applied.
|
||||||
|
*
|
||||||
|
* @todo: Until a proper reference space system is implemented, the xdev assigned to the head role should be used as @p
|
||||||
|
* ref_xdev for consistency.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
oxr_space_ref_get_pure_relation(struct oxr_logger *log,
|
||||||
|
struct oxr_session *sess,
|
||||||
|
XrReferenceSpaceType ref_type,
|
||||||
|
struct xrt_device *ref_xdev,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_space_relation *out_relation)
|
||||||
|
{
|
||||||
|
switch (ref_type) {
|
||||||
|
case XR_REFERENCE_SPACE_TYPE_LOCAL: {
|
||||||
|
if (!is_local_space_set_up(sess)) {
|
||||||
|
if (!set_up_local_space(log, sess, time)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_relation = sess->local_space_pure_relation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case XR_REFERENCE_SPACE_TYPE_STAGE: {
|
||||||
|
//! @todo: stage space origin assumed to be the same as HMD xdev space origin for now.
|
||||||
|
m_space_relation_ident(out_relation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case XR_REFERENCE_SPACE_TYPE_VIEW: {
|
||||||
|
oxr_xdev_get_space_relation(log, sess->sys->inst, ref_xdev, XRT_INPUT_GENERIC_HEAD_POSE, time,
|
||||||
|
out_relation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT:
|
||||||
|
case XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO:
|
||||||
|
// not implemented
|
||||||
|
return false;
|
||||||
|
case XR_REFERENCE_SPACE_TYPE_MAX_ENUM: return false; ;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
global_to_local_space(struct oxr_session *sess, struct xrt_space_relation *rel)
|
oxr_space_pure_relation_in_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_space_relation *relation,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
bool apply_space_pose,
|
||||||
|
struct xrt_space_relation *out_relation)
|
||||||
{
|
{
|
||||||
if (!initial_head_relation_valid(sess)) {
|
struct xrt_space_relation pure_space_relation;
|
||||||
|
struct xrt_device *xdev;
|
||||||
|
oxr_space_get_pure_relation(log, spc, time, &pure_space_relation, &xdev);
|
||||||
|
|
||||||
|
struct xrt_relation_chain xrc = {0};
|
||||||
|
|
||||||
|
m_relation_chain_push_relation(&xrc, relation);
|
||||||
|
m_relation_chain_push_inverted_relation(&xrc, &pure_space_relation);
|
||||||
|
|
||||||
|
if (apply_space_pose) {
|
||||||
|
m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &spc->pose);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_relation_chain_resolve(&xrc, out_relation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
oxr_space_pure_pose_in_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_pose *pose,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
bool apply_space_pose,
|
||||||
|
struct xrt_space_relation *out_relation)
|
||||||
|
{
|
||||||
|
struct xrt_space_relation rel;
|
||||||
|
m_space_relation_from_pose(pose, &rel);
|
||||||
|
return oxr_space_pure_relation_in_space(log, time, &rel, spc, apply_space_pose, out_relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
oxr_space_pure_relation_from_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_space_relation *relation,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
struct xrt_space_relation *out_relation)
|
||||||
|
{
|
||||||
|
struct xrt_space_relation pure_space_relation;
|
||||||
|
struct xrt_device *xdev;
|
||||||
|
oxr_space_get_pure_relation(log, spc, time, &pure_space_relation, &xdev);
|
||||||
|
|
||||||
|
struct xrt_relation_chain xrc = {0};
|
||||||
|
m_relation_chain_push_relation(&xrc, &pure_space_relation);
|
||||||
|
m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &spc->pose);
|
||||||
|
m_relation_chain_push_relation(&xrc, relation);
|
||||||
|
m_relation_chain_resolve(&xrc, out_relation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
oxr_space_pure_pose_from_space(struct oxr_logger *log,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_pose *pose,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
struct xrt_space_relation *out_relation)
|
||||||
|
{
|
||||||
|
struct xrt_space_relation rel;
|
||||||
|
m_space_relation_from_pose(pose, &rel);
|
||||||
|
return oxr_space_pure_relation_from_space(log, time, &rel, spc, out_relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
oxr_space_get_pure_relation(struct oxr_logger *log,
|
||||||
|
struct oxr_space *spc,
|
||||||
|
XrTime time,
|
||||||
|
struct xrt_space_relation *out_relation,
|
||||||
|
struct xrt_device **out_xdev)
|
||||||
|
{
|
||||||
|
if (spc->is_reference) {
|
||||||
|
struct xrt_device *head_xdev = GET_XDEV_BY_ROLE(spc->sess->sys, head);
|
||||||
|
*out_xdev = head_xdev;
|
||||||
|
return oxr_space_ref_get_pure_relation(log, spc->sess, spc->type, head_xdev, time, out_relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct oxr_action_input *input = NULL;
|
||||||
|
oxr_action_get_pose_input(log, spc->sess, spc->act_key, &spc->subaction_paths, &input);
|
||||||
|
|
||||||
|
// If the input isn't active.
|
||||||
|
if (input == NULL) {
|
||||||
|
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_xdev = input->xdev;
|
||||||
|
oxr_xdev_get_space_relation(log, spc->sess->sys->inst, input->xdev, input->input->name, time, out_relation);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
global_to_local_space(struct oxr_logger *log, struct oxr_session *sess, XrTime time, struct xrt_space_relation *rel)
|
||||||
|
{
|
||||||
|
if (!is_local_space_set_up(sess)) {
|
||||||
|
if (!set_up_local_space(log, sess, time)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct xrt_relation_chain xrc = {0};
|
struct xrt_relation_chain xrc = {0};
|
||||||
m_relation_chain_push_relation(&xrc, rel);
|
m_relation_chain_push_relation(&xrc, rel);
|
||||||
m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &sess->initial_head_relation.pose);
|
m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &sess->local_space_pure_relation.pose);
|
||||||
m_relation_chain_resolve(&xrc, rel);
|
m_relation_chain_resolve(&xrc, rel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* Transform @p view_relation given in global space into @p baseSpc without the app-given offset pose for @p baseSpc
|
|
||||||
* applied.
|
|
||||||
*/
|
|
||||||
XrResult
|
|
||||||
oxr_view_relation_ref_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct xrt_space_relation *view_relation,
|
|
||||||
struct xrt_device *view_xdev,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime time,
|
|
||||||
struct xrt_space_relation *out_relation)
|
|
||||||
{
|
|
||||||
*out_relation = *view_relation;
|
|
||||||
|
|
||||||
//! @todo: find a central place to set up local space
|
|
||||||
if (!ensure_initial_head_relation(log, sess, out_relation)) {
|
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
|
||||||
// device poses are already in stage = "global" space
|
|
||||||
} else if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
|
||||||
global_to_local_space(sess, out_relation);
|
|
||||||
} else if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
|
||||||
// view relation in view space should be identity
|
|
||||||
m_space_relation_ident(out_relation);
|
|
||||||
} else {
|
|
||||||
OXR_WARN_ONCE(log, "unsupported base reference space in space_ref_relation");
|
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static XrResult
|
|
||||||
oxr_view_ref_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime time,
|
|
||||||
struct xrt_space_relation *out_relation)
|
|
||||||
{
|
|
||||||
struct xrt_device *view_xdev = NULL;
|
|
||||||
struct xrt_space_relation view_relation;
|
|
||||||
oxr_session_get_view_relation_at(log, sess, time, &view_relation, &view_xdev);
|
|
||||||
return oxr_view_relation_ref_relation(log, sess, &view_relation, view_xdev, baseSpc, time, out_relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
static XrResult
|
|
||||||
oxr_stage_ref_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime time,
|
|
||||||
struct xrt_space_relation *out_relation)
|
|
||||||
{
|
|
||||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
|
||||||
math_pose_invert(&sess->initial_head_relation.pose, &out_relation->pose);
|
|
||||||
} else {
|
|
||||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static XrResult
|
|
||||||
oxr_local_ref_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime time,
|
|
||||||
struct xrt_space_relation *out_relation)
|
|
||||||
{
|
|
||||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
|
||||||
out_relation->pose = sess->initial_head_relation.pose;
|
|
||||||
} else {
|
|
||||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* This returns only the relation between two spaces without any of the app
|
|
||||||
* given relations applied, assumes that both spaces are reference spaces.
|
|
||||||
*/
|
|
||||||
XrResult
|
|
||||||
oxr_space_ref_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct oxr_space *space,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime time,
|
|
||||||
struct xrt_space_relation *out_relation)
|
|
||||||
{
|
|
||||||
m_space_relation_ident(out_relation);
|
|
||||||
|
|
||||||
if (space->type == baseSpc->type) {
|
|
||||||
// m_space_relation_ident() already set this to identity.
|
|
||||||
} else if (space->type == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
|
||||||
oxr_view_ref_relation(log, sess, baseSpc, time, out_relation);
|
|
||||||
} else if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
|
||||||
oxr_view_ref_relation(log, sess, space, time, out_relation);
|
|
||||||
//! @todo invert complete relation
|
|
||||||
math_pose_invert(&out_relation->pose, &out_relation->pose);
|
|
||||||
} else if (space->type == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
|
||||||
oxr_stage_ref_relation(log, sess, baseSpc, time, out_relation);
|
|
||||||
} else if (space->type == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
|
||||||
oxr_local_ref_relation(log, sess, baseSpc, time, out_relation);
|
|
||||||
} else {
|
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
remove_angular_and_linear_stuff(struct xrt_space_relation *out_relation)
|
|
||||||
{
|
|
||||||
const enum xrt_space_relation_flags flags =
|
|
||||||
XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT | XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT;
|
|
||||||
|
|
||||||
out_relation->relation_flags &= ~flags;
|
|
||||||
out_relation->linear_velocity = (struct xrt_vec3){0, 0, 0};
|
|
||||||
out_relation->angular_velocity = (struct xrt_vec3){0, 0, 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* This returns only the relation between two space without the app given offset pose for baseSpc applied,
|
|
||||||
* assumes that only one is a action space.
|
|
||||||
*/
|
|
||||||
static XrResult
|
|
||||||
oxr_space_action_relation(struct oxr_logger *log,
|
|
||||||
struct oxr_session *sess,
|
|
||||||
struct oxr_space *spc,
|
|
||||||
struct oxr_space *baseSpc,
|
|
||||||
XrTime at_time,
|
|
||||||
struct xrt_space_relation *out_relation)
|
|
||||||
{
|
|
||||||
struct oxr_action_input *input = NULL;
|
|
||||||
struct oxr_space *act_spc, *ref_spc = NULL;
|
|
||||||
bool invert = false;
|
|
||||||
|
|
||||||
// Find the action space
|
|
||||||
if (baseSpc->is_reference) {
|
|
||||||
// Note spc, is assumed to be the action space.
|
|
||||||
act_spc = spc;
|
|
||||||
ref_spc = baseSpc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the action space.
|
|
||||||
if (spc->is_reference) {
|
|
||||||
// Note baseSpc, is assumed to be the action space.
|
|
||||||
act_spc = baseSpc;
|
|
||||||
ref_spc = spc;
|
|
||||||
invert = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal error check.
|
|
||||||
if (act_spc == NULL || act_spc->is_reference || ref_spc == NULL || !ref_spc->is_reference) {
|
|
||||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "This is bad!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset so no relation is returned.
|
|
||||||
m_space_relation_ident(out_relation);
|
|
||||||
|
|
||||||
//! @todo Can not relate to the view space right now.
|
|
||||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
|
||||||
//! @todo Error code?
|
|
||||||
OXR_WARN_ONCE(log, "relating to view space unsupported");
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
oxr_action_get_pose_input(log, sess, act_spc->act_key, &act_spc->subaction_paths, &input);
|
|
||||||
|
|
||||||
// If the input isn't active.
|
|
||||||
if (input == NULL) {
|
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
oxr_xdev_get_space_relation(log, sess->sys->inst, input->xdev, input->input->name, at_time, out_relation);
|
|
||||||
|
|
||||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
|
||||||
global_to_local_space(sess, out_relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invert) {
|
|
||||||
math_pose_invert(&out_relation->pose, &out_relation->pose);
|
|
||||||
// Remove this since we can't (for now) invert the derivatives.
|
|
||||||
remove_angular_and_linear_stuff(out_relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This returns only the relation between two directly-associated spaces without
|
* This returns only the relation between two directly-associated spaces without
|
||||||
* the app given offset pose for baseSpc applied.
|
* the app given offset pose for baseSpc applied.
|
||||||
|
@ -374,26 +332,19 @@ get_pure_space_relation(struct oxr_logger *log,
|
||||||
XrTime time,
|
XrTime time,
|
||||||
struct xrt_space_relation *out_relation)
|
struct xrt_space_relation *out_relation)
|
||||||
{
|
{
|
||||||
struct oxr_session *sess = spc->sess;
|
struct xrt_space_relation space_pure_relation;
|
||||||
|
struct xrt_device *space_xdev;
|
||||||
|
oxr_space_get_pure_relation(log, spc, time, &space_pure_relation, &space_xdev);
|
||||||
|
|
||||||
if (spc->is_reference && baseSpc->is_reference) {
|
struct xrt_space_relation base_space_pure_relation;
|
||||||
return oxr_space_ref_relation(log, sess, spc, baseSpc, time, out_relation);
|
struct xrt_device *base_space_xdev;
|
||||||
}
|
oxr_space_get_pure_relation(log, baseSpc, time, &base_space_pure_relation, &base_space_xdev);
|
||||||
/// @todo Deal with action to action by keeping a true_space that we can always go via. (poor mans space graph)
|
|
||||||
if (!spc->is_reference && !baseSpc->is_reference) {
|
struct xrt_relation_chain xrc = {0};
|
||||||
// WARNING order not thought through here!
|
m_relation_chain_push_relation(&xrc, &space_pure_relation);
|
||||||
// struct xrt_pose pose1;
|
m_relation_chain_push_inverted_relation(&xrc, &base_space_pure_relation);
|
||||||
// struct xrt_pose pose2;
|
m_relation_chain_resolve(&xrc, out_relation);
|
||||||
// get_pure_space_relation(log, session->true_space, baseSpc,
|
|
||||||
// time, &pose1);
|
|
||||||
// get_pure_space_relation(log, space, session->true_space,
|
|
||||||
// time, &pose2);
|
|
||||||
// math_pose_relate_2(&pose1, &pose2, out_pose);
|
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
|
||||||
return XR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
oxr_space_action_relation(log, sess, spc, baseSpc, time, out_relation);
|
|
||||||
return XR_SUCCESS;
|
return XR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,8 +419,6 @@ oxr_space_locate(
|
||||||
print_space("baseSpace", baseSpc);
|
print_space("baseSpace", baseSpc);
|
||||||
|
|
||||||
// Get the pure space relation.
|
// Get the pure space relation.
|
||||||
//! @todo for longer paths in "space graph" than one edge, this will be
|
|
||||||
//! a loop.
|
|
||||||
struct xrt_space_relation pure;
|
struct xrt_space_relation pure;
|
||||||
XrResult ret = get_pure_space_relation(log, spc, baseSpc, time, &pure);
|
XrResult ret = get_pure_space_relation(log, spc, baseSpc, time, &pure);
|
||||||
if (ret != XR_SUCCESS) {
|
if (ret != XR_SUCCESS) {
|
||||||
|
|
Loading…
Reference in a new issue