mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
st/oxr: Rework composition of head relation for xrLocateViews
This commit is contained in:
parent
9b656cde77
commit
9cd3b47f94
|
@ -649,7 +649,8 @@ XrResult
|
|||
oxr_session_get_view_relation_at(struct oxr_logger *,
|
||||
struct oxr_session *sess,
|
||||
XrTime at_time,
|
||||
struct xrt_space_relation *out_relation);
|
||||
struct xrt_space_relation *out_relation,
|
||||
struct xrt_device **out_xdev);
|
||||
|
||||
XrResult
|
||||
oxr_session_locate_views(struct oxr_logger *log,
|
||||
|
@ -710,11 +711,20 @@ oxr_space_locate(
|
|||
XrResult
|
||||
oxr_space_ref_relation(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
XrReferenceSpaceType space,
|
||||
XrReferenceSpaceType baseSpc,
|
||||
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
|
||||
initial_head_relation_valid(struct oxr_session *sess);
|
||||
|
||||
|
|
|
@ -262,11 +262,16 @@ oxr_session_poll(struct oxr_logger *log, struct oxr_session *sess)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the view relation in global space. Even though @out_xdev is returned, the tracking origin offset is already
|
||||
* applied.
|
||||
*/
|
||||
XrResult
|
||||
oxr_session_get_view_relation_at(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
XrTime at_time,
|
||||
struct xrt_space_relation *out_relation)
|
||||
struct xrt_space_relation *out_relation,
|
||||
struct xrt_device **out_xdev)
|
||||
{
|
||||
// @todo This function needs to be massively expanded to support all
|
||||
// use cases this drive. The main use of this function is to get
|
||||
|
@ -285,6 +290,8 @@ oxr_session_get_view_relation_at(struct oxr_logger *log,
|
|||
oxr_xdev_get_relation_chain(log, sess->sys->inst, xdev, XRT_INPUT_GENERIC_HEAD_POSE, at_time, &xrc);
|
||||
m_relation_chain_resolve(&xrc, out_relation);
|
||||
|
||||
*out_xdev = xdev;
|
||||
|
||||
return oxr_session_success_result(sess);
|
||||
}
|
||||
|
||||
|
@ -378,7 +385,7 @@ oxr_session_locate_views(struct oxr_logger *log,
|
|||
|
||||
const uint64_t xdisplay_time =
|
||||
time_state_ts_to_monotonic_ns(sess->sys->inst->timekeeping, viewLocateInfo->displayTime);
|
||||
//! @todo Head relation currently not used.
|
||||
|
||||
struct xrt_space_relation head_relation = XRT_SPACE_RELATION_ZERO;
|
||||
struct xrt_fov fovs[2] = {0};
|
||||
struct xrt_pose poses[2] = {0};
|
||||
|
@ -392,26 +399,16 @@ oxr_session_locate_views(struct oxr_logger *log,
|
|||
fovs, //
|
||||
poses);
|
||||
|
||||
// head_relation is in xdev space. Bring it into global space by applying tracking origin offset.
|
||||
struct xrt_relation_chain xrc = {0};
|
||||
m_relation_chain_push_relation(&xrc, &head_relation);
|
||||
m_relation_chain_push_pose_if_not_identity(&xrc, &xdev->tracking_origin->offset);
|
||||
m_relation_chain_resolve(&xrc, &head_relation);
|
||||
|
||||
/*
|
||||
* Get the pure_relation if needed.
|
||||
*/
|
||||
|
||||
// Get the viewLocateInfo->space to view space relation.
|
||||
struct xrt_space_relation pure_relation;
|
||||
|
||||
/*!
|
||||
* @todo Introduce oxr_space_ref_relation_with_relation that takes
|
||||
* relation and transforms it into the correct relationship.
|
||||
*/
|
||||
// If we are going from stage space use the head pose.
|
||||
oxr_space_ref_relation( //
|
||||
log, //
|
||||
sess, //
|
||||
XR_REFERENCE_SPACE_TYPE_VIEW, //
|
||||
baseSpc->type, //
|
||||
viewLocateInfo->displayTime, //
|
||||
&pure_relation); //
|
||||
// transform head_relation into base_space
|
||||
struct xrt_space_relation base_spc_head_relation;
|
||||
oxr_view_relation_ref_relation(log, sess, &head_relation, xdev, baseSpc, viewLocateInfo->displayTime,
|
||||
&base_spc_head_relation);
|
||||
|
||||
// @todo the fov information that we get from xdev->hmd->views[i].fov is
|
||||
// not properly filled out in oh_device.c, fix before wasting time
|
||||
|
@ -432,8 +429,8 @@ oxr_session_locate_views(struct oxr_logger *log,
|
|||
struct xrt_space_relation result = {0};
|
||||
struct xrt_relation_chain xrc = {0};
|
||||
m_relation_chain_push_pose_if_not_identity(&xrc, &view_pose);
|
||||
m_relation_chain_push_relation(&xrc, &pure_relation);
|
||||
m_relation_chain_push_pose_if_not_identity(&xrc, &baseSpc->pose);
|
||||
m_relation_chain_push_relation(&xrc, &base_spc_head_relation);
|
||||
m_relation_chain_push_inverted_pose_if_not_identity(&xrc, &baseSpc->pose);
|
||||
m_relation_chain_resolve(&xrc, &result);
|
||||
union {
|
||||
struct xrt_pose xrt;
|
||||
|
@ -908,17 +905,17 @@ oxr_session_hand_joints(struct oxr_logger *log,
|
|||
/*! @todo: testing, relating to view space unsupported
|
||||
* in other parts of monado */
|
||||
|
||||
struct xrt_device *head_xdev = GET_XDEV_BY_ROLE(sess->sys, head);
|
||||
struct xrt_device *view_xdev = NULL;
|
||||
|
||||
struct xrt_space_relation view_relation;
|
||||
oxr_session_get_view_relation_at(log, sess, at_time, &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,
|
||||
&head_xdev->tracking_origin->offset);
|
||||
&view_xdev->tracking_origin->offset);
|
||||
|
||||
} else if (!baseSpc->is_reference) {
|
||||
// action space
|
||||
|
|
|
@ -165,6 +165,90 @@ global_to_local_space(struct oxr_session *sess, struct xrt_space_relation *rel)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Transform @view_relation given in global space into baseSpc without the app given offset pose for 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_locale_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.
|
||||
|
@ -172,71 +256,25 @@ global_to_local_space(struct oxr_session *sess, struct xrt_space_relation *rel)
|
|||
XrResult
|
||||
oxr_space_ref_relation(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
XrReferenceSpaceType space,
|
||||
XrReferenceSpaceType baseSpc,
|
||||
struct oxr_space *space,
|
||||
struct oxr_space *baseSpc,
|
||||
XrTime time,
|
||||
struct xrt_space_relation *out_relation)
|
||||
{
|
||||
m_space_relation_ident(out_relation);
|
||||
|
||||
|
||||
if (space == baseSpc) {
|
||||
// m_space_relation_ident() sets to identity.
|
||||
} else if (space == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
||||
oxr_session_get_view_relation_at(log, sess, time, out_relation);
|
||||
|
||||
if (!ensure_initial_head_relation(log, sess, out_relation)) {
|
||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
if (baseSpc == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
||||
// device poses are already in stage = "global" space
|
||||
} else if (baseSpc == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
||||
global_to_local_space(sess, out_relation);
|
||||
} else if (baseSpc == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
||||
|
||||
} else {
|
||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
} else if (baseSpc == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
||||
oxr_session_get_view_relation_at(log, sess, time, out_relation);
|
||||
|
||||
if (!ensure_initial_head_relation(log, sess, out_relation)) {
|
||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
if (space == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
||||
// device poses are already in stage = "global" space
|
||||
} else if (space == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
||||
global_to_local_space(sess, out_relation);
|
||||
} else if (space == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
||||
|
||||
} else {
|
||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
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 == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
||||
if (baseSpc == 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;
|
||||
}
|
||||
} else if (space == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
||||
if (baseSpc == 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;
|
||||
}
|
||||
} 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_locale_ref_relation(log, sess, baseSpc, time, out_relation);
|
||||
} else {
|
||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||
return XR_SUCCESS;
|
||||
|
@ -257,8 +295,8 @@ remove_angular_and_linear_stuff(struct xrt_space_relation *out_relation)
|
|||
}
|
||||
|
||||
/*!
|
||||
* This returns only the relation between two spaces without any of the app
|
||||
* given relations applied, assumes that only one is a action space.
|
||||
* 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,
|
||||
|
@ -327,7 +365,7 @@ oxr_space_action_relation(struct oxr_logger *log,
|
|||
|
||||
/*!
|
||||
* This returns only the relation between two directly-associated spaces without
|
||||
* any of the app given relations applied.
|
||||
* the app given offset pose for baseSpc applied.
|
||||
*/
|
||||
static XrResult
|
||||
get_pure_space_relation(struct oxr_logger *log,
|
||||
|
@ -339,7 +377,7 @@ get_pure_space_relation(struct oxr_logger *log,
|
|||
struct oxr_session *sess = spc->sess;
|
||||
|
||||
if (spc->is_reference && baseSpc->is_reference) {
|
||||
return oxr_space_ref_relation(log, sess, spc->type, baseSpc->type, time, out_relation);
|
||||
return oxr_space_ref_relation(log, sess, spc, baseSpc, time, out_relation);
|
||||
}
|
||||
/// @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) {
|
||||
|
|
Loading…
Reference in a new issue