mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-04 06:06:17 +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 *,
|
oxr_session_get_view_relation_at(struct oxr_logger *,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
XrTime at_time,
|
XrTime at_time,
|
||||||
struct xrt_space_relation *out_relation);
|
struct xrt_space_relation *out_relation,
|
||||||
|
struct xrt_device **out_xdev);
|
||||||
|
|
||||||
XrResult
|
XrResult
|
||||||
oxr_session_locate_views(struct oxr_logger *log,
|
oxr_session_locate_views(struct oxr_logger *log,
|
||||||
|
@ -710,8 +711,17 @@ oxr_space_locate(
|
||||||
XrResult
|
XrResult
|
||||||
oxr_space_ref_relation(struct oxr_logger *log,
|
oxr_space_ref_relation(struct oxr_logger *log,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
XrReferenceSpaceType space,
|
struct oxr_space *space,
|
||||||
XrReferenceSpaceType baseSpc,
|
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,
|
XrTime time,
|
||||||
struct xrt_space_relation *out_relation);
|
struct xrt_space_relation *out_relation);
|
||||||
|
|
||||||
|
|
|
@ -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
|
XrResult
|
||||||
oxr_session_get_view_relation_at(struct oxr_logger *log,
|
oxr_session_get_view_relation_at(struct oxr_logger *log,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
XrTime at_time,
|
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
|
// @todo This function needs to be massively expanded to support all
|
||||||
// use cases this drive. The main use of this function is to get
|
// 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);
|
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);
|
m_relation_chain_resolve(&xrc, out_relation);
|
||||||
|
|
||||||
|
*out_xdev = xdev;
|
||||||
|
|
||||||
return oxr_session_success_result(sess);
|
return oxr_session_success_result(sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +385,7 @@ oxr_session_locate_views(struct oxr_logger *log,
|
||||||
|
|
||||||
const uint64_t xdisplay_time =
|
const uint64_t xdisplay_time =
|
||||||
time_state_ts_to_monotonic_ns(sess->sys->inst->timekeeping, viewLocateInfo->displayTime);
|
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_space_relation head_relation = XRT_SPACE_RELATION_ZERO;
|
||||||
struct xrt_fov fovs[2] = {0};
|
struct xrt_fov fovs[2] = {0};
|
||||||
struct xrt_pose poses[2] = {0};
|
struct xrt_pose poses[2] = {0};
|
||||||
|
@ -392,26 +399,16 @@ 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_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);
|
||||||
|
|
||||||
/*
|
// transform head_relation into base_space
|
||||||
* Get the pure_relation if needed.
|
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);
|
||||||
// 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); //
|
|
||||||
|
|
||||||
// @todo the fov information that we get from xdev->hmd->views[i].fov is
|
// @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
|
// 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_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, &pure_relation);
|
m_relation_chain_push_relation(&xrc, &base_spc_head_relation);
|
||||||
m_relation_chain_push_pose_if_not_identity(&xrc, &baseSpc->pose);
|
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;
|
||||||
|
@ -908,17 +905,17 @@ oxr_session_hand_joints(struct oxr_logger *log,
|
||||||
/*! @todo: testing, relating to view space unsupported
|
/*! @todo: testing, relating to view space unsupported
|
||||||
* in other parts of monado */
|
* 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;
|
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_relation(&chain, &value.hand_pose);
|
||||||
m_relation_chain_push_pose_if_not_identity(&chain, tracking_origin_offset);
|
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_relation(&chain, &view_relation);
|
||||||
m_relation_chain_push_inverted_pose_if_not_identity(&chain,
|
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) {
|
} else if (!baseSpc->is_reference) {
|
||||||
// action space
|
// action space
|
||||||
|
|
|
@ -166,77 +166,115 @@ global_to_local_space(struct oxr_session *sess, struct xrt_space_relation *rel)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This returns only the relation between two spaces without any of the app
|
* Transform @view_relation given in global space into baseSpc without the app given offset pose for baseSpc
|
||||||
* given relations applied, assumes that both spaces are reference spaces.
|
* applied.
|
||||||
*/
|
*/
|
||||||
XrResult
|
XrResult
|
||||||
oxr_space_ref_relation(struct oxr_logger *log,
|
oxr_view_relation_ref_relation(struct oxr_logger *log,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
XrReferenceSpaceType space,
|
struct xrt_space_relation *view_relation,
|
||||||
XrReferenceSpaceType baseSpc,
|
struct xrt_device *view_xdev,
|
||||||
|
struct oxr_space *baseSpc,
|
||||||
XrTime time,
|
XrTime time,
|
||||||
struct xrt_space_relation *out_relation)
|
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);
|
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 {
|
} else {
|
||||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
OXR_WARN_ONCE(log, "unsupported base reference space in space_ref_relation");
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||||
return XR_SUCCESS;
|
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;
|
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 {
|
static XrResult
|
||||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
oxr_view_ref_relation(struct oxr_logger *log,
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
struct oxr_session *sess,
|
||||||
return XR_SUCCESS;
|
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);
|
||||||
}
|
}
|
||||||
math_pose_invert(&out_relation->pose, &out_relation->pose);
|
|
||||||
|
|
||||||
} else if (space == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
static XrResult
|
||||||
if (baseSpc == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
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);
|
math_pose_invert(&sess->initial_head_relation.pose, &out_relation->pose);
|
||||||
} else {
|
} else {
|
||||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||||
return XR_SUCCESS;
|
return XR_SUCCESS;
|
||||||
}
|
}
|
||||||
} else if (space == XR_REFERENCE_SPACE_TYPE_LOCAL) {
|
return XR_SUCCESS;
|
||||||
if (baseSpc == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
}
|
||||||
|
|
||||||
|
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;
|
out_relation->pose = sess->initial_head_relation.pose;
|
||||||
} else {
|
} else {
|
||||||
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
OXR_WARN_ONCE(log, "unsupported base space in space_ref_relation");
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||||
return XR_SUCCESS;
|
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_locale_ref_relation(log, sess, baseSpc, time, out_relation);
|
||||||
} else {
|
} else {
|
||||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||||
return XR_SUCCESS;
|
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
|
* This returns only the relation between two space without the app given offset pose for baseSpc applied,
|
||||||
* given relations applied, assumes that only one is a action space.
|
* assumes that only one is a action space.
|
||||||
*/
|
*/
|
||||||
static XrResult
|
static XrResult
|
||||||
oxr_space_action_relation(struct oxr_logger *log,
|
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
|
* 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
|
static XrResult
|
||||||
get_pure_space_relation(struct oxr_logger *log,
|
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;
|
struct oxr_session *sess = spc->sess;
|
||||||
|
|
||||||
if (spc->is_reference && baseSpc->is_reference) {
|
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)
|
/// @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) {
|
if (!spc->is_reference && !baseSpc->is_reference) {
|
||||||
|
|
Loading…
Reference in a new issue