ipc,u/space_overseer: space offset api

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2284>
This commit is contained in:
galister 2024-07-17 02:39:32 +09:00 committed by galister
parent f635ac290b
commit 067090ad7d
10 changed files with 633 additions and 12 deletions

View file

@ -168,7 +168,8 @@ u_pp_xrt_result(struct u_pp_delegate dg, xrt_result_t xret)
case XRT_ERROR_RECENTERING_NOT_SUPPORTED: DG("XRT_ERROR_RECENTERING_NOT_SUPPORTED"); return;
case XRT_ERROR_COMPOSITOR_NOT_SUPPORTED: DG("XRT_ERROR_COMPOSITOR_NOT_SUPPORTED"); return;
case XRT_ERROR_IPC_COMPOSITOR_NOT_CREATED: DG("XRT_ERROR_IPC_COMPOSITOR_NOT_CREATED"); return;
case XRT_ERROR_NOT_IMPLEMENTED: DG("XRT_ERROR_NOT_IMPLEMENTED"); return;
case XRT_ERROR_NOT_IMPLEMENTED: DG("XRT_ERROR_NOT_IMPLEMENTED"); return;
case XRT_ERROR_UNSUPPORTED_SPACE_TYPE: DG("XRT_ERROR_UNSUPPORTED_SPACE_TYPE"); return;
}
// clang-format on

View file

@ -89,6 +89,9 @@ struct u_space_overseer
//! Map from xdev to space, each entry holds a reference.
struct u_hashmap_int *xdev_map;
//! Map from xrt_tracking_origin to space, each entry holds a reference.
struct u_hashmap_int *xto_map;
//! Tracks usage of reference spaces.
struct xrt_reference ref_space_use[XRT_SPACE_REFERENCE_TYPE_COUNT];
@ -210,6 +213,27 @@ find_xdev_space_read_locked(struct u_space_overseer *uso, struct xrt_device *xde
return (struct u_space *)ptr;
}
static struct u_space *
find_xto_space_read_locked(struct u_space_overseer *uso, struct xrt_tracking_origin *xto)
{
void *ptr = NULL;
uint64_t key = (uint64_t)(intptr_t)xto;
u_hashmap_int_find(uso->xto_map, key, &ptr);
if (ptr == NULL) {
U_LOG_E("Looking for space belonging to unknown xrt_tracking_origin! '%s'", xto->name);
}
assert(ptr != NULL);
return (struct u_space *)ptr;
}
static bool
space_is_offset_compatible(struct u_space *us)
{
return us != NULL && (us->type == U_SPACE_TYPE_NULL || us->type == U_SPACE_TYPE_OFFSET);
}
/*!
* Updates the offset of a NULL or OFFSET space.
*/
@ -826,6 +850,152 @@ create_local_space(struct xrt_space_overseer *xso, struct xrt_space **out_space)
return create_offset_space(xso, xso->semantic.root, &xsr.pose, out_space);
}
static xrt_result_t
get_tracking_origin_offset(struct xrt_space_overseer *xso, struct xrt_tracking_origin *xto, struct xrt_pose *out_offset)
{
struct u_space_overseer *uso = u_space_overseer(xso);
xrt_result_t xret = XRT_SUCCESS;
pthread_rwlock_rdlock(&uso->lock);
struct u_space *us = find_xto_space_read_locked(uso, xto);
if (!space_is_offset_compatible(us)) {
xret = XRT_ERROR_UNSUPPORTED_SPACE_TYPE;
goto unlock;
}
get_offset_or_ident_read_locked(us, out_offset);
unlock:
pthread_rwlock_unlock(&uso->lock);
return xret;
}
static xrt_result_t
set_tracking_origin_offset(struct xrt_space_overseer *xso,
struct xrt_tracking_origin *xto,
const struct xrt_pose *offset)
{
struct u_space_overseer *uso = u_space_overseer(xso);
xrt_result_t xret = XRT_SUCCESS;
pthread_rwlock_rdlock(&uso->lock);
struct u_space *us = find_xto_space_read_locked(uso, xto);
if (!space_is_offset_compatible(us)) {
xret = XRT_ERROR_UNSUPPORTED_SPACE_TYPE;
goto unlock;
}
update_offset_write_locked(us, offset);
unlock:
pthread_rwlock_unlock(&uso->lock);
return xret;
}
static xrt_result_t
get_reference_space_offset(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
struct xrt_pose *out_offset)
{
struct u_space_overseer *uso = u_space_overseer(xso);
xrt_result_t xret = XRT_SUCCESS;
pthread_rwlock_rdlock(&uso->lock);
struct u_space *us = get_semantic_space(uso, type);
if (!space_is_offset_compatible(us)) {
xret = XRT_ERROR_UNSUPPORTED_SPACE_TYPE;
goto unlock;
}
get_offset_or_ident_read_locked(us, out_offset);
unlock:
pthread_rwlock_unlock(&uso->lock);
return xret;
}
static xrt_result_t
set_reference_space_offset(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
const struct xrt_pose *offset)
{
if (type == XRT_SPACE_REFERENCE_TYPE_LOCAL_FLOOR) {
// LOCAL_FLOOR is calculated from LOCAL and STAGE
return XRT_ERROR_UNSUPPORTED_SPACE_TYPE;
}
struct u_space_overseer *uso = u_space_overseer(xso);
if (uso->can_do_local_spaces_recenter) {
return XRT_ERROR_RECENTERING_NOT_SUPPORTED;
}
xrt_result_t xret = XRT_SUCCESS;
pthread_rwlock_wrlock(&uso->lock);
struct u_space *us = get_semantic_space(uso, type);
if (!space_is_offset_compatible(us)) {
xret = XRT_ERROR_UNSUPPORTED_SPACE_TYPE;
goto unlock;
}
// can_do_local_spaces_recenter ensures that local_floor can be offset
struct u_space *ufloor = u_space(xso->semantic.local_floor);
struct xrt_pose floor;
get_offset_or_ident_read_locked(ufloor, &floor);
if (type == XRT_SPACE_REFERENCE_TYPE_STAGE) {
floor.position.y = offset->position.y;
} else if (type == XRT_SPACE_REFERENCE_TYPE_LOCAL) {
floor.orientation = offset->orientation;
floor.position.x = offset->position.x;
floor.position.z = offset->position.z;
}
update_offset_write_locked(us, offset);
update_offset_write_locked(ufloor, &floor);
// Push the events.
union xrt_session_event xse = XRT_STRUCT_INIT;
// Basics
xse.ref_change.event_type = XRT_SESSION_EVENT_REFERENCE_SPACE_CHANGE_PENDING;
xse.ref_change.pose_valid = false;
xse.ref_change.pose_in_previous_space = (struct xrt_pose)XRT_POSE_IDENTITY;
xse.ref_change.timestamp_ns = os_monotonic_get_ns();
if (type == XRT_SPACE_REFERENCE_TYPE_STAGE) {
xse.ref_change.ref_type = XRT_SPACE_REFERENCE_TYPE_STAGE;
xret = xrt_session_event_sink_push(uso->broadcast, &xse);
if (xret != XRT_SUCCESS) {
U_LOG_E("Failed to push event STAGE!");
}
} else if (type == XRT_SPACE_REFERENCE_TYPE_LOCAL) {
xse.ref_change.ref_type = XRT_SPACE_REFERENCE_TYPE_LOCAL;
xret = xrt_session_event_sink_push(uso->broadcast, &xse);
if (xret != XRT_SUCCESS) {
U_LOG_E("Failed to push event LOCAL!");
}
} else {
// did not change STAGE or LOCAL -> LOCAL_FLOOR also did not change
goto unlock;
}
xse.ref_change.ref_type = XRT_SPACE_REFERENCE_TYPE_LOCAL_FLOOR;
xret = xrt_session_event_sink_push(uso->broadcast, &xse);
if (xret != XRT_SUCCESS) {
U_LOG_E("Failed to push event LOCAL_FLOOR!");
}
unlock:
pthread_rwlock_unlock(&uso->lock);
return xret;
}
static void
destroy(struct xrt_space_overseer *xso)
{
@ -842,6 +1012,9 @@ destroy(struct xrt_space_overseer *xso)
u_hashmap_int_clear_and_call_for_each(uso->xdev_map, hashmap_unreference_space_items, uso);
u_hashmap_int_destroy(&uso->xdev_map);
u_hashmap_int_clear_and_call_for_each(uso->xto_map, hashmap_unreference_space_items, uso);
u_hashmap_int_destroy(&uso->xto_map);
for (int id = 0; id < XRT_MAX_CLIENT_SPACES; id++) {
struct xrt_space **xslocal_ptr = (struct xrt_space **)&xso->localspace[id];
xrt_space_reference(xslocal_ptr, NULL);
@ -872,6 +1045,10 @@ u_space_overseer_create(struct xrt_session_event_sink *broadcast)
uso->base.ref_space_inc = ref_space_inc;
uso->base.ref_space_dec = ref_space_dec;
uso->base.recenter_local_spaces = recenter_local_spaces;
uso->base.get_tracking_origin_offset = get_tracking_origin_offset;
uso->base.set_tracking_origin_offset = set_tracking_origin_offset;
uso->base.get_reference_space_offset = get_reference_space_offset;
uso->base.set_reference_space_offset = set_reference_space_offset;
uso->base.destroy = destroy;
uso->broadcast = broadcast;
@ -883,6 +1060,9 @@ u_space_overseer_create(struct xrt_session_event_sink *broadcast)
ret = u_hashmap_int_create(&uso->xdev_map);
assert(ret == 0);
ret = u_hashmap_int_create(&uso->xto_map);
assert(ret == 0);
create_and_set_root_space(uso);
return uso;
@ -898,10 +1078,6 @@ u_space_overseer_legacy_setup(struct u_space_overseer *uso,
{
struct xrt_space *root = uso->base.semantic.root; // Convenience
struct u_hashmap_int *torig_map = NULL;
u_hashmap_int_create(&torig_map);
for (uint32_t i = 0; i < xdev_count; i++) {
struct xrt_device *xdev = xdevs[i];
struct xrt_tracking_origin *torig = xdev->tracking_origin;
@ -909,22 +1085,18 @@ u_space_overseer_legacy_setup(struct u_space_overseer *uso,
struct xrt_space *xs = NULL;
void *ptr = NULL;
u_hashmap_int_find(torig_map, key, &ptr);
u_hashmap_int_find(uso->xto_map, key, &ptr);
if (ptr != NULL) {
xs = (struct xrt_space *)ptr;
} else {
u_space_overseer_create_offset_space(uso, root, &torig->initial_offset, &xs);
u_hashmap_int_insert(torig_map, key, xs);
u_hashmap_int_insert(uso->xto_map, key, xs);
}
u_space_overseer_link_space_to_device(uso, xs, xdev);
}
// Each item has a exrta reference make sure to clear before destroying.
u_hashmap_int_clear_and_call_for_each(torig_map, hashmap_unreference_space_items, uso);
u_hashmap_int_destroy(&torig_map);
// If these are set something is probably wrong, but just in case unset them.
assert(uso->base.semantic.view == NULL);
assert(uso->base.semantic.stage == NULL);

View file

@ -184,4 +184,9 @@ typedef enum xrt_result
* The interface function called is not implemented by its interface.
*/
XRT_ERROR_NOT_IMPLEMENTED = -29,
/*!
* The supplied space type is not supported for this operation.
*/
XRT_ERROR_UNSUPPORTED_SPACE_TYPE = -30,
} xrt_result_t;

View file

@ -17,6 +17,7 @@ extern "C" {
#define XRT_MAX_CLIENT_SPACES 128
struct xrt_device;
struct xrt_tracking_origin;
/*!
* A space very similar to a OpenXR XrSpace but not a full one-to-one mapping,
@ -239,6 +240,56 @@ struct xrt_space_overseer
*/
xrt_result_t (*recenter_local_spaces)(struct xrt_space_overseer *xso);
/*!
* Read the offset from a tracking origin, not all
* implementations of @ref xrt_space_overseer may support this.
* Outputs are only valid if XRT_SUCCESS is returned.
*
* @param[in] xso The space overseer.
* @param[in] xto The tracking origin.
* @param[out] out_offset Pointer to an xrt_pose to write the offset to
*/
xrt_result_t (*get_tracking_origin_offset)(struct xrt_space_overseer *xso,
struct xrt_tracking_origin *xto,
struct xrt_pose *out_offset);
/*!
* Apply an offset to a tracking origin, not all
* implementations of @ref xrt_space_overseer may support this.
*
* @param[in] xso The space overseer.
* @param[in] xto The tracking origin.
* @param[in] offset The offset to apply.
*/
xrt_result_t (*set_tracking_origin_offset)(struct xrt_space_overseer *xso,
struct xrt_tracking_origin *xto,
const struct xrt_pose *offset);
/*!
* Read the offset from the given reference space, not all
* implementations of @ref xrt_space_overseer may support this.
* Outputs are only valid if XRT_SUCCESS is returned.
*
* @param[in] xso The space overseer.
* @param[in] type The reference space.
* @param[out] out_offset Pointer to write the offset to.
*/
xrt_result_t (*get_reference_space_offset)(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
struct xrt_pose *out_offset);
/*!
* Apply an offset to the given reference space, not all
* implementations of @ref xrt_space_overseer may support this.
*
* @param[in] xso The space overseer.
* @param[in] type The reference space.
* @param[in] offset The offset to apply.
*/
xrt_result_t (*set_reference_space_offset)(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
const struct xrt_pose *offset);
/*!
* Create a localspace.
*
@ -384,6 +435,66 @@ xrt_space_overseer_recenter_local_spaces(struct xrt_space_overseer *xso)
return xso->recenter_local_spaces(xso);
}
/*!
* @copydoc xrt_space_overseer::get_tracking_origin_offset
*
* Helper for calling through the function pointer.
*
* @public @memberof xrt_space_overseer
*/
static inline xrt_result_t
xrt_space_overseer_get_tracking_origin_offset(struct xrt_space_overseer *xso,
struct xrt_tracking_origin *torig,
struct xrt_pose *out_offset)
{
return xso->get_tracking_origin_offset(xso, torig, out_offset);
}
/*!
* @copydoc xrt_space_overseer::set_tracking_origin_offset
*
* Helper for calling through the function pointer.
*
* @public @memberof xrt_space_overseer
*/
static inline xrt_result_t
xrt_space_overseer_set_tracking_origin_offset(struct xrt_space_overseer *xso,
struct xrt_tracking_origin *torig,
const struct xrt_pose *offset)
{
return xso->set_tracking_origin_offset(xso, torig, offset);
}
/*!
* @copydoc xrt_space_overseer::get_reference_space_offset
*
* Helper for calling through the function pointer.
*
* @public @memberof xrt_space_overseer
*/
static inline xrt_result_t
xrt_space_overseer_get_reference_space_offset(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
struct xrt_pose *out_offset)
{
return xso->get_reference_space_offset(xso, type, out_offset);
}
/*!
* @copydoc xrt_space_overseer::set_reference_space_offset
*
* Helper for calling through the function pointer.
*
* @public @memberof xrt_space_overseer
*/
static inline xrt_result_t
xrt_space_overseer_set_reference_space_offset(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
const struct xrt_pose *offset)
{
return xso->set_reference_space_offset(xso, type, offset);
}
/*!
* @copydoc xrt_space_overseer::create_localspace_space
*

View file

@ -282,6 +282,38 @@ recenter_local_spaces(struct xrt_space_overseer *xso)
return ipc_call_space_recenter_local_spaces(icspo->ipc_c);
}
static xrt_result_t
get_tracking_origin_offset(struct xrt_space_overseer *xso, struct xrt_tracking_origin *xto, struct xrt_pose *out_offset)
{
return XRT_ERROR_NOT_IMPLEMENTED;
}
static xrt_result_t
set_tracking_origin_offset(struct xrt_space_overseer *xso,
struct xrt_tracking_origin *xto,
const struct xrt_pose *offset)
{
return XRT_ERROR_NOT_IMPLEMENTED;
}
static xrt_result_t
get_reference_space_offset(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
struct xrt_pose *out_offset)
{
struct ipc_client_space_overseer *icspo = ipc_client_space_overseer(xso);
return ipc_call_space_get_reference_space_offset(icspo->ipc_c, type, out_offset);
}
static xrt_result_t
set_reference_space_offset(struct xrt_space_overseer *xso,
enum xrt_reference_space_type type,
const struct xrt_pose *offset)
{
struct ipc_client_space_overseer *icspo = ipc_client_space_overseer(xso);
return ipc_call_space_set_reference_space_offset(icspo->ipc_c, type, offset);
}
static void
destroy(struct xrt_space_overseer *xso)
{
@ -334,6 +366,10 @@ ipc_client_space_overseer_create(struct ipc_connection *ipc_c)
icspo->base.ref_space_inc = ref_space_inc;
icspo->base.ref_space_dec = ref_space_dec;
icspo->base.recenter_local_spaces = recenter_local_spaces;
icspo->base.get_tracking_origin_offset = get_tracking_origin_offset;
icspo->base.set_tracking_origin_offset = set_tracking_origin_offset;
icspo->base.get_reference_space_offset = get_reference_space_offset;
icspo->base.set_reference_space_offset = set_reference_space_offset;
icspo->base.destroy = destroy;
icspo->ipc_c = ipc_c;

View file

@ -48,6 +48,25 @@ validate_device_id(volatile struct ipc_client_state *ics, int64_t device_id, str
return XRT_SUCCESS;
}
static xrt_result_t
validate_origin_id(volatile struct ipc_client_state *ics, int64_t origin_id, struct xrt_tracking_origin **out_xtrack)
{
if (origin_id >= XRT_SYSTEM_MAX_DEVICES) {
IPC_ERROR(ics->server, "Invalid origin ID (origin_id >= XRT_SYSTEM_MAX_DEVICES)!");
return XRT_ERROR_IPC_FAILURE;
}
struct xrt_tracking_origin *xtrack = ics->server->xtracks[origin_id];
if (xtrack == NULL) {
IPC_ERROR(ics->server, "Invalid origin ID (xtrack is NULL)!");
return XRT_ERROR_IPC_FAILURE;
}
*out_xtrack = xtrack;
return XRT_SUCCESS;
}
static xrt_result_t
validate_swapchain_state(volatile struct ipc_client_state *ics, uint32_t *out_index)
{
@ -775,6 +794,52 @@ ipc_handle_space_recenter_local_spaces(volatile struct ipc_client_state *ics)
return xrt_space_overseer_recenter_local_spaces(xso);
}
xrt_result_t
ipc_handle_space_get_tracking_origin_offset(volatile struct ipc_client_state *ics,
uint32_t origin_id,
struct xrt_pose *out_offset)
{
struct xrt_space_overseer *xso = ics->server->xso;
struct xrt_tracking_origin *xto;
xrt_result_t xret = validate_origin_id(ics, origin_id, &xto);
if (xret != XRT_SUCCESS) {
return xret;
}
return xrt_space_overseer_get_tracking_origin_offset(xso, xto, out_offset);
}
xrt_result_t
ipc_handle_space_set_tracking_origin_offset(volatile struct ipc_client_state *ics,
uint32_t origin_id,
const struct xrt_pose *offset)
{
struct xrt_space_overseer *xso = ics->server->xso;
struct xrt_tracking_origin *xto;
xrt_result_t xret = validate_origin_id(ics, origin_id, &xto);
if (xret != XRT_SUCCESS) {
return xret;
}
return xrt_space_overseer_set_tracking_origin_offset(xso, xto, offset);
}
xrt_result_t
ipc_handle_space_get_reference_space_offset(volatile struct ipc_client_state *ics,
enum xrt_reference_space_type type,
struct xrt_pose *out_offset)
{
struct xrt_space_overseer *xso = ics->server->xso;
return xrt_space_overseer_get_reference_space_offset(xso, type, out_offset);
}
xrt_result_t
ipc_handle_space_set_reference_space_offset(volatile struct ipc_client_state *ics,
enum xrt_reference_space_type type,
const struct xrt_pose *offset)
{
struct xrt_space_overseer *xso = ics->server->xso;
return xrt_space_overseer_set_reference_space_offset(xso, type, offset);
}
xrt_result_t
ipc_handle_compositor_get_info(volatile struct ipc_client_state *ics, struct xrt_compositor_info *out_info)
{

View file

@ -174,6 +174,38 @@
"space_recenter_local_spaces": {
},
"space_get_tracking_origin_offset": {
"in": [
{"name": "origin_id", "type": "uint32_t"}
],
"out": [
{"name": "offset", "type": "struct xrt_pose"}
]
},
"space_set_tracking_origin_offset": {
"in": [
{"name": "origin_id", "type": "uint32_t"},
{"name": "offset", "type": "struct xrt_pose"}
]
},
"space_get_reference_space_offset": {
"in": [
{"name": "type", "type": "enum xrt_reference_space_type"}
],
"out": [
{"name": "offset", "type": "struct xrt_pose"}
]
},
"space_set_reference_space_offset": {
"in": [
{"name": "type", "type": "enum xrt_reference_space_type"},
{"name": "offset", "type": "struct xrt_pose"}
]
},
"compositor_get_info": {
"out": [
{"name": "info", "type": "struct xrt_compositor_info"}

View file

@ -14,3 +14,9 @@ EXPORTS
mnd_root_get_device_info
mnd_root_get_device_from_role
mnd_root_recenter_local_spaces
mnd_root_get_reference_space_offset
mnd_root_set_reference_space_offset
mnd_root_get_tracking_origin_offset
mnd_root_set_tracking_origin_offset
mnd_root_get_tracking_origin_count
mnd_root_get_tracking_origin_name

View file

@ -10,6 +10,7 @@
#include "monado.h"
#include "xrt/xrt_defines.h"
#include "xrt/xrt_results.h"
#include "util/u_misc.h"
@ -463,3 +464,85 @@ mnd_root_recenter_local_spaces(mnd_root_t *root)
default: PE("Internal error, shouldn't get here"); return MND_ERROR_OPERATION_FAILED;
}
}
mnd_result_t
mnd_root_get_reference_space_offset(mnd_root_t *root, mnd_reference_space_type_t type, mnd_pose_t *out_offset)
{
xrt_result_t xret = ipc_call_space_get_reference_space_offset(&root->ipc_c, (enum xrt_reference_space_type)type,
(struct xrt_pose *)out_offset);
switch (xret) {
case XRT_SUCCESS: return MND_SUCCESS;
case XRT_ERROR_UNSUPPORTED_SPACE_TYPE: return MND_ERROR_INVALID_OPERATION;
case XRT_ERROR_IPC_FAILURE: PE("Connection error!"); return MND_ERROR_OPERATION_FAILED;
default: PE("Internal error, shouldn't get here"); return MND_ERROR_OPERATION_FAILED;
}
}
mnd_result_t
mnd_root_set_reference_space_offset(mnd_root_t *root, mnd_reference_space_type_t type, const mnd_pose_t *offset)
{
xrt_result_t xret = ipc_call_space_set_reference_space_offset(&root->ipc_c, (enum xrt_reference_space_type)type,
(struct xrt_pose *)offset);
switch (xret) {
case XRT_SUCCESS: return MND_SUCCESS;
case XRT_ERROR_UNSUPPORTED_SPACE_TYPE: return MND_ERROR_INVALID_OPERATION;
case XRT_ERROR_RECENTERING_NOT_SUPPORTED: return MND_ERROR_RECENTERING_NOT_SUPPORTED;
case XRT_ERROR_IPC_FAILURE: PE("Connection error!"); return MND_ERROR_OPERATION_FAILED;
default: PE("Internal error, shouldn't get here"); return MND_ERROR_OPERATION_FAILED;
}
}
mnd_result_t
mnd_root_get_tracking_origin_offset(mnd_root_t *root, uint32_t origin_id, mnd_pose_t *out_offset)
{
xrt_result_t xret =
ipc_call_space_get_tracking_origin_offset(&root->ipc_c, origin_id, (struct xrt_pose *)out_offset);
switch (xret) {
case XRT_SUCCESS: return MND_SUCCESS;
case XRT_ERROR_UNSUPPORTED_SPACE_TYPE: return MND_ERROR_INVALID_OPERATION;
case XRT_ERROR_IPC_FAILURE: PE("Connection error!"); return MND_ERROR_OPERATION_FAILED;
default: PE("Internal error, shouldn't get here"); return MND_ERROR_OPERATION_FAILED;
}
}
mnd_result_t
mnd_root_set_tracking_origin_offset(mnd_root_t *root, uint32_t origin_id, const mnd_pose_t *offset)
{
xrt_result_t xret =
ipc_call_space_set_tracking_origin_offset(&root->ipc_c, origin_id, (struct xrt_pose *)offset);
switch (xret) {
case XRT_SUCCESS: return MND_SUCCESS;
case XRT_ERROR_UNSUPPORTED_SPACE_TYPE: return MND_ERROR_INVALID_OPERATION;
case XRT_ERROR_IPC_FAILURE: PE("Connection error!"); return MND_ERROR_OPERATION_FAILED;
default: PE("Internal error, shouldn't get here"); return MND_ERROR_OPERATION_FAILED;
}
}
mnd_result_t
mnd_root_get_tracking_origin_count(mnd_root_t *root, uint32_t *out_track_count)
{
CHECK_NOT_NULL(root);
CHECK_NOT_NULL(out_track_count);
*out_track_count = root->ipc_c.ism->itrack_count;
return MND_SUCCESS;
}
mnd_result_t
mnd_root_get_tracking_origin_name(mnd_root_t *root, uint32_t origin_id, const char **out_string)
{
CHECK_NOT_NULL(root);
CHECK_NOT_NULL(out_string);
if (origin_id >= root->ipc_c.ism->itrack_count) {
PE("Invalid itrack index (%u)", origin_id);
return MND_ERROR_INVALID_VALUE;
}
const struct ipc_shared_tracking_origin *ipcsto = &root->ipc_c.ism->itracks[origin_id];
*out_string = ipcsto->name;
return MND_SUCCESS;
}

View file

@ -25,7 +25,7 @@ extern "C" {
//! Major version of the API.
#define MND_API_VERSION_MAJOR 1
//! Minor version of the API.
#define MND_API_VERSION_MINOR 2
#define MND_API_VERSION_MINOR 3
//! Patch version of the API.
#define MND_API_VERSION_PATCH 0
@ -44,6 +44,8 @@ typedef enum mnd_result
MND_ERROR_RECENTERING_NOT_SUPPORTED = -5,
//! Supported in version 1.2 and above.
MND_ERROR_INVALID_PROPERTY = -6,
//! Supported in version 1.3 and above.
MND_ERROR_INVALID_OPERATION = -7,
} mnd_result_t;
/*!
@ -77,6 +79,32 @@ typedef enum mnd_property
*/
typedef struct mnd_root mnd_root_t;
/*!
* A pose composed of a position and orientation.
*/
typedef struct mnd_pose
{
struct
{
float x, y, z, w;
} orientation;
struct
{
float x, y, z;
} position;
} mnd_pose_t;
/*!
* Types of reference space.
*/
typedef enum mnd_reference_space_type
{
MND_SPACE_REFERENCE_TYPE_VIEW,
MND_SPACE_REFERENCE_TYPE_LOCAL,
MND_SPACE_REFERENCE_TYPE_LOCAL_FLOOR,
MND_SPACE_REFERENCE_TYPE_STAGE,
MND_SPACE_REFERENCE_TYPE_UNBOUNDED,
} mnd_reference_space_type_t;
/*
*
@ -349,6 +377,88 @@ mnd_root_get_device_from_role(mnd_root_t *root, const char *role_name, int32_t *
mnd_result_t
mnd_root_recenter_local_spaces(mnd_root_t *root);
/*!
* Get the current offset value of the specified reference space.
*
* Supported in version 1.3 and above.
*
* @param root The libmonado state.
* @param type The reference space.
* @param offset A pointer to where the offset should be written.
*
* @return MND_SUCCESS on success
*/
mnd_result_t
mnd_root_get_reference_space_offset(mnd_root_t *root, mnd_reference_space_type_t type, mnd_pose_t *out_offset);
/*!
* Apply an offset to the specified reference space.
*
* Supported in version 1.3 and above.
*
* @param root The libmonado state.
* @param type The reference space.
* @param offset A pointer to valid xrt_pose.
*
* @return MND_SUCCESS on success
*/
mnd_result_t
mnd_root_set_reference_space_offset(mnd_root_t *root, mnd_reference_space_type_t type, const mnd_pose_t *offset);
/*!
* Read the current offset of a tracking origin.
*
* Supported in version 1.3 and above.
*
* @param root The libmonado state.
* @param origin_id The ID of the tracking origin.
* @param offset A pointer to where the offset should be written.
*
* @return MND_SUCCESS on success
*/
mnd_result_t
mnd_root_get_tracking_origin_offset(mnd_root_t *root, uint32_t origin_id, mnd_pose_t *out_offset);
/*!
* Apply an offset to the specified tracking origin.
*
* Supported in version 1.3 and above.
*
* @param root The libmonado state.
* @param origin_id The ID of the tracking origin.
* @param offset A pointer to valid xrt_pose.
*
* @return MND_SUCCESS on success
*/
mnd_result_t
mnd_root_set_tracking_origin_offset(mnd_root_t *root, uint32_t origin_id, const mnd_pose_t *offset);
/*!
* Retrieve the number of tracking origins available.
*
* Supported in version 1.3 and above.
*
* @param root The libmonado state.
* @param out_track_count Pointer to where the count should be written.
*
* @return MND_SUCCESS on success
*/
mnd_result_t
mnd_root_get_tracking_origin_count(mnd_root_t *root, uint32_t *out_track_count);
/*!
* Retrieve the name of the indicated tracking origin.
*
* Supported in version 1.3 and above.
*
* @param root The libmonado state.
* @param origin_id The ID of a tracking origin.
* @param out_string The pointer to write the name's pointer to.
*
* @return MND_SUCCESS on success
*/
mnd_result_t
mnd_root_get_tracking_origin_name(mnd_root_t *root, uint32_t origin_id, const char **out_string);
#ifdef __cplusplus
}