mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 18:46:18 +00:00
st/oxr: Basic foundation for input and output
This commits lays the foundation for actions in Monado (input and output). There are lots of things missing and non-conformant in there. But once in more people then just me can test it out and work on it.
This commit is contained in:
parent
b71e143eaa
commit
e745a28374
|
@ -39,6 +39,7 @@ set(OXR_SOURCE_FILES
|
|||
oxr_two_call.h
|
||||
oxr_verify.cpp
|
||||
oxr_vulkan.c
|
||||
oxr_xdev.c
|
||||
)
|
||||
|
||||
# Use OBJECT to not create a archive, since it just gets in the way.
|
||||
|
|
|
@ -41,12 +41,14 @@ oxr_xrSyncActionData(XrSession session,
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < countActionSets; i++) {
|
||||
struct oxr_action_set* act_set;
|
||||
struct oxr_action_set* act_set = NULL;
|
||||
OXR_VERIFY_ARG_TYPE_AND_NULL(&log, (&actionSets[i]),
|
||||
XR_TYPE_ACTIVE_ACTION_SET);
|
||||
OXR_VERIFY_ACTIONSET_NOT_NULL(&log, actionSets[i].actionSet,
|
||||
act_set);
|
||||
//! @todo verify path.
|
||||
|
||||
oxr_verify_subaction_path_sync(&log, sess->sys->inst,
|
||||
actionSets[i].subactionPath, i);
|
||||
}
|
||||
|
||||
return oxr_action_sync_data(&log, sess, countActionSets, actionSets);
|
||||
|
@ -187,6 +189,15 @@ oxr_xrCreateAction(XrActionSet actionSet,
|
|||
OXR_VERIFY_ARG_LOCALIZED_NAME(&log, createInfo->localizedActionName);
|
||||
OXR_VERIFY_ARG_NOT_NULL(&log, action);
|
||||
|
||||
struct oxr_instance* inst = act_set->sess->sys->inst;
|
||||
|
||||
ret = oxr_verify_subaction_paths_create(
|
||||
&log, inst, createInfo->countSubactionPaths,
|
||||
createInfo->subactionPaths, "createInfo->subactionPaths");
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = oxr_action_create(&log, act_set, createInfo, &act);
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -213,16 +224,39 @@ oxr_xrGetActionStateBoolean(XrAction action,
|
|||
const XrPath* subactionPaths,
|
||||
XrActionStateBoolean* data)
|
||||
{
|
||||
XrPath subactionPath = XR_NULL_PATH;
|
||||
struct oxr_sub_paths sub_paths = {0};
|
||||
struct oxr_action* act;
|
||||
struct oxr_logger log;
|
||||
XrResult ret;
|
||||
OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act,
|
||||
"xrGetActionStateBoolean");
|
||||
OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_BOOLEAN);
|
||||
OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths);
|
||||
//! @todo verify paths
|
||||
|
||||
return oxr_action_get_boolean(&log, act, countSubactionPaths,
|
||||
subactionPaths, data);
|
||||
if (act->action_type != XR_INPUT_ACTION_TYPE_BOOLEAN) {
|
||||
return oxr_error(&log, XR_ERROR_ACTION_TYPE_MISMATCH,
|
||||
" not created with pose type");
|
||||
}
|
||||
|
||||
// Trust me.
|
||||
if (countSubactionPaths > 1) {
|
||||
return oxr_error(&log, XR_ERROR_PATH_INVALID,
|
||||
" can not handle more then one subactionPath");
|
||||
}
|
||||
|
||||
if (countSubactionPaths == 1) {
|
||||
subactionPath = subactionPaths[0];
|
||||
}
|
||||
|
||||
ret = oxr_verify_subaction_path_get(&log, act->act_set->sess->sys->inst,
|
||||
subactionPath, &act->sub_paths,
|
||||
&sub_paths, "subactionPaths[0]");
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return oxr_action_get_boolean(&log, act, sub_paths, data);
|
||||
}
|
||||
|
||||
XrResult
|
||||
|
@ -231,16 +265,39 @@ oxr_xrGetActionStateVector1f(XrAction action,
|
|||
const XrPath* subactionPaths,
|
||||
XrActionStateVector1f* data)
|
||||
{
|
||||
XrPath subactionPath = XR_NULL_PATH;
|
||||
struct oxr_sub_paths sub_paths = {0};
|
||||
struct oxr_action* act;
|
||||
struct oxr_logger log;
|
||||
XrResult ret;
|
||||
OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act,
|
||||
"xrGetActionStateVector1f");
|
||||
OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_VECTOR1F);
|
||||
OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths);
|
||||
//! @todo verify paths
|
||||
|
||||
return oxr_action_get_vector1f(&log, act, countSubactionPaths,
|
||||
subactionPaths, data);
|
||||
if (act->action_type != XR_INPUT_ACTION_TYPE_VECTOR1F) {
|
||||
return oxr_error(&log, XR_ERROR_ACTION_TYPE_MISMATCH,
|
||||
" not created with float type");
|
||||
}
|
||||
|
||||
// Trust me.
|
||||
if (countSubactionPaths > 1) {
|
||||
return oxr_error(&log, XR_ERROR_PATH_INVALID,
|
||||
" can not handle more then one subactionPath");
|
||||
}
|
||||
|
||||
if (countSubactionPaths == 1) {
|
||||
subactionPath = subactionPaths[0];
|
||||
}
|
||||
|
||||
ret = oxr_verify_subaction_path_get(&log, act->act_set->sess->sys->inst,
|
||||
subactionPath, &act->sub_paths,
|
||||
&sub_paths, "subactionPaths[0]");
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return oxr_action_get_vector1f(&log, act, sub_paths, data);
|
||||
}
|
||||
|
||||
XrResult
|
||||
|
@ -249,16 +306,39 @@ oxr_xrGetActionStateVector2f(XrAction action,
|
|||
const XrPath* subactionPaths,
|
||||
XrActionStateVector2f* data)
|
||||
{
|
||||
XrPath subactionPath = XR_NULL_PATH;
|
||||
struct oxr_sub_paths sub_paths = {0};
|
||||
struct oxr_action* act;
|
||||
struct oxr_logger log;
|
||||
XrResult ret;
|
||||
OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act,
|
||||
"xrGetActionStateVector2f");
|
||||
OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_VECTOR2F);
|
||||
OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths);
|
||||
//! @todo verify paths
|
||||
|
||||
return oxr_action_get_vector2f(&log, act, countSubactionPaths,
|
||||
subactionPaths, data);
|
||||
if (act->action_type != XR_INPUT_ACTION_TYPE_VECTOR2F) {
|
||||
return oxr_error(&log, XR_ERROR_ACTION_TYPE_MISMATCH,
|
||||
" not created with float[2] type");
|
||||
}
|
||||
|
||||
// Trust me.
|
||||
if (countSubactionPaths > 1) {
|
||||
return oxr_error(&log, XR_ERROR_PATH_INVALID,
|
||||
" can not handle more then one subactionPath");
|
||||
}
|
||||
|
||||
if (countSubactionPaths == 1) {
|
||||
subactionPath = subactionPaths[0];
|
||||
}
|
||||
|
||||
ret = oxr_verify_subaction_path_get(&log, act->act_set->sess->sys->inst,
|
||||
subactionPath, &act->sub_paths,
|
||||
&sub_paths, "subactionPaths[0]");
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return oxr_action_get_vector2f(&log, act, sub_paths, data);
|
||||
}
|
||||
|
||||
XrResult
|
||||
|
@ -266,14 +346,27 @@ oxr_xrGetActionStatePose(XrAction action,
|
|||
XrPath subactionPath,
|
||||
XrActionStatePose* data)
|
||||
{
|
||||
struct oxr_sub_paths sub_paths = {0};
|
||||
struct oxr_action* act;
|
||||
struct oxr_logger log;
|
||||
XrResult ret;
|
||||
OXR_VERIFY_ACTION_AND_INIT_LOG(&log, action, act,
|
||||
"xrGetActionStatePose");
|
||||
OXR_VERIFY_ARG_TYPE_AND_NULL(&log, data, XR_TYPE_ACTION_STATE_POSE);
|
||||
//! @todo verify path
|
||||
|
||||
return oxr_action_get_pose(&log, act, subactionPath, data);
|
||||
if (act->action_type != XR_INPUT_ACTION_TYPE_POSE) {
|
||||
return oxr_error(&log, XR_ERROR_ACTION_TYPE_MISMATCH,
|
||||
" not created with pose type");
|
||||
}
|
||||
|
||||
ret = oxr_verify_subaction_path_get(&log, act->act_set->sess->sys->inst,
|
||||
subactionPath, &act->sub_paths,
|
||||
&sub_paths, "subactionPath");
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return oxr_action_get_pose(&log, act, sub_paths, data);
|
||||
}
|
||||
|
||||
XrResult
|
||||
|
@ -311,6 +404,11 @@ oxr_xrApplyHapticFeedback(XrAction hapticAction,
|
|||
OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths);
|
||||
//! @todo verify paths
|
||||
|
||||
if (act->action_type != XR_OUTPUT_ACTION_TYPE_VIBRATION) {
|
||||
return oxr_error(&log, XR_ERROR_ACTION_TYPE_MISMATCH,
|
||||
" not created with output vibration type");
|
||||
}
|
||||
|
||||
return oxr_action_apply_haptic_feedback(&log, act, countSubactionPaths,
|
||||
subactionPaths, hapticEvent);
|
||||
}
|
||||
|
@ -327,6 +425,11 @@ oxr_xrStopHapticFeedback(XrAction hapticAction,
|
|||
OXR_VERIFY_SUBACTION_PATHS(&log, countSubactionPaths, subactionPaths);
|
||||
//! @todo verify paths
|
||||
|
||||
if (act->action_type != XR_OUTPUT_ACTION_TYPE_VIBRATION) {
|
||||
return oxr_error(&log, XR_ERROR_ACTION_TYPE_MISMATCH,
|
||||
" not created with output vibration type");
|
||||
}
|
||||
|
||||
return oxr_action_stop_haptic_feedback(&log, act, countSubactionPaths,
|
||||
subactionPaths);
|
||||
}
|
||||
|
|
|
@ -170,6 +170,36 @@ oxr_verify_localized_name(struct oxr_logger*,
|
|||
uint32_t array_size,
|
||||
const char* name);
|
||||
|
||||
/*!
|
||||
* Verify a set of subaction paths for action creation.
|
||||
*/
|
||||
XrResult
|
||||
oxr_verify_subaction_paths_create(struct oxr_logger* log,
|
||||
struct oxr_instance* inst,
|
||||
uint32_t countSubactionPaths,
|
||||
const XrPath* subactionPaths,
|
||||
const char* variable);
|
||||
|
||||
/*!
|
||||
* Verify a set of subaction paths for action sync.
|
||||
*/
|
||||
XrResult
|
||||
oxr_verify_subaction_path_sync(struct oxr_logger* log,
|
||||
struct oxr_instance* inst,
|
||||
XrPath path,
|
||||
uint32_t index);
|
||||
|
||||
/*!
|
||||
* Verify a set of subaction paths for action state get.
|
||||
*/
|
||||
XrResult
|
||||
oxr_verify_subaction_path_get(struct oxr_logger* log,
|
||||
struct oxr_instance* inst,
|
||||
XrPath path,
|
||||
const struct oxr_sub_paths* act_sub_paths,
|
||||
struct oxr_sub_paths* out_sub_paths,
|
||||
const char* variable);
|
||||
|
||||
XrResult
|
||||
oxr_verify_XrSessionCreateInfo(struct oxr_logger*,
|
||||
const struct oxr_instance*,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -34,12 +34,24 @@ radtodeg_for_display(float radians)
|
|||
return (int32_t)(radians * 180 * M_1_PI);
|
||||
}
|
||||
|
||||
static inline void
|
||||
xdev_destroy(struct xrt_device **xdev_ptr)
|
||||
{
|
||||
struct xrt_device *xdev = *xdev_ptr;
|
||||
|
||||
if (xdev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
xdev->destroy(xdev);
|
||||
*xdev_ptr = NULL;
|
||||
}
|
||||
|
||||
static XrResult
|
||||
oxr_instance_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
||||
{
|
||||
struct oxr_instance *inst = (struct oxr_instance *)hb;
|
||||
struct xrt_auto_prober *prober = inst->prober;
|
||||
struct xrt_device *dev = inst->system.device;
|
||||
struct xrt_prober *prober = inst->prober;
|
||||
|
||||
oxr_path_destroy_all(log, inst);
|
||||
|
||||
|
@ -47,14 +59,12 @@ oxr_instance_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
|||
u_hashset_destroy(&inst->path_store);
|
||||
}
|
||||
|
||||
if (dev != NULL) {
|
||||
dev->destroy(dev);
|
||||
inst->system.device = NULL;
|
||||
}
|
||||
xdev_destroy(&inst->system.head);
|
||||
xdev_destroy(&inst->system.left);
|
||||
xdev_destroy(&inst->system.right);
|
||||
|
||||
if (prober != NULL) {
|
||||
prober->destroy(prober);
|
||||
inst->prober = NULL;
|
||||
if (inst->prober != NULL) {
|
||||
prober->destroy(&inst->prober);
|
||||
}
|
||||
|
||||
time_state_destroy(inst->timekeeping);
|
||||
|
@ -65,13 +75,23 @@ oxr_instance_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
|||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
cache_path(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
const char *str,
|
||||
XrPath *out_path)
|
||||
{
|
||||
oxr_path_get_or_create(log, inst, str, strlen(str), out_path);
|
||||
}
|
||||
|
||||
XrResult
|
||||
oxr_instance_create(struct oxr_logger *log,
|
||||
const XrInstanceCreateInfo *createInfo,
|
||||
struct oxr_instance **out_instance)
|
||||
{
|
||||
struct oxr_instance *inst = NULL;
|
||||
int h_ret;
|
||||
struct xrt_device *xdevs[3] = {0};
|
||||
int h_ret, p_ret;
|
||||
|
||||
OXR_ALLOCATE_HANDLE_OR_RETURN(log, inst, OXR_XR_DEBUG_INSTANCE,
|
||||
oxr_instance_destroy, NULL);
|
||||
|
@ -83,10 +103,35 @@ oxr_instance_create(struct oxr_logger *log,
|
|||
"Failed to create hashset");
|
||||
}
|
||||
|
||||
inst->prober = xrt_auto_prober_create();
|
||||
// Cache certain often looked up paths.
|
||||
cache_path(log, inst, "/user", &inst->path_cache.user);
|
||||
cache_path(log, inst, "/user/hand/head", &inst->path_cache.head);
|
||||
cache_path(log, inst, "/user/hand/left", &inst->path_cache.left);
|
||||
cache_path(log, inst, "/user/hand/right", &inst->path_cache.right);
|
||||
cache_path(log, inst, "/user/hand/gamepad", &inst->path_cache.gamepad);
|
||||
|
||||
struct xrt_device *dev =
|
||||
inst->prober->lelo_dallas_autoprobe(inst->prober);
|
||||
p_ret = xrt_prober_create(&inst->prober);
|
||||
if (p_ret != 0) {
|
||||
inst->prober->destroy(&inst->prober);
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
||||
"Failed to create prober");
|
||||
}
|
||||
|
||||
p_ret = inst->prober->probe(inst->prober);
|
||||
if (p_ret != 0) {
|
||||
inst->prober->destroy(&inst->prober);
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
||||
"Failed to probe device(s)");
|
||||
}
|
||||
|
||||
p_ret = inst->prober->select(inst->prober, xdevs, 3);
|
||||
if (p_ret != 0) {
|
||||
inst->prober->destroy(&inst->prober);
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
||||
"Failed to select device");
|
||||
}
|
||||
|
||||
struct xrt_device *dev = xdevs[0];
|
||||
|
||||
const float left_override = debug_get_float_option_lfov_left();
|
||||
if (left_override != 0.0f) {
|
||||
|
@ -127,7 +172,8 @@ oxr_instance_create(struct oxr_logger *log,
|
|||
dev->hmd->views[1].fov.angle_down = down_override;
|
||||
}
|
||||
|
||||
oxr_system_fill_in(log, inst, 1, &inst->system, dev);
|
||||
oxr_system_fill_in(log, inst, 1, &inst->system, xdevs[0], xdevs[1],
|
||||
xdevs[2]);
|
||||
|
||||
inst->timekeeping = time_state_create();
|
||||
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "xrt/xrt_device.h"
|
||||
#include "xrt/xrt_tracking.h"
|
||||
#include "xrt/xrt_compositor.h"
|
||||
#include "xrt/xrt_vulkan_includes.h"
|
||||
#include "xrt/xrt_openxr_includes.h"
|
||||
#include "util/u_hashset.h"
|
||||
#include "util/u_hashmap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -48,6 +50,8 @@ extern "C" {
|
|||
#define OXR_XR_DEBUG_SWAPCHAIN (*(uint64_t *)"oxrswap\0")
|
||||
#define OXR_XR_DEBUG_ACTIONSET (*(uint64_t *)"oxraset\0")
|
||||
#define OXR_XR_DEBUG_MESSENGER (*(uint64_t *)"oxrmess\0")
|
||||
#define OXR_XR_DEBUG_SOURCESET (*(uint64_t *)"oxrsrcs\0")
|
||||
#define OXR_XR_DEBUG_SOURCE (*(uint64_t *)"oxrsrc_\0")
|
||||
// clang-format on
|
||||
|
||||
|
||||
|
@ -68,6 +72,11 @@ struct oxr_action_set;
|
|||
struct oxr_action;
|
||||
struct oxr_debug_messenger;
|
||||
struct oxr_handle_base;
|
||||
struct oxr_sub_paths;
|
||||
struct oxr_source;
|
||||
struct oxr_source_set;
|
||||
struct oxr_source_input;
|
||||
struct oxr_source_output;
|
||||
|
||||
#define XRT_MAX_HANDLE_CHILDREN 256
|
||||
|
||||
|
@ -212,6 +221,26 @@ oxr_path_destroy_all(struct oxr_logger *log, struct oxr_instance *inst);
|
|||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Helper function to classify sub_paths.
|
||||
*/
|
||||
void
|
||||
oxr_classify_sub_action_paths(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
uint32_t num_subaction_paths,
|
||||
const XrPath *subaction_paths,
|
||||
struct oxr_sub_paths *sub_paths);
|
||||
|
||||
/*!
|
||||
* Find the pose input for the set of sub_paths
|
||||
*/
|
||||
XrResult
|
||||
oxr_source_get_pose_input(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
uint32_t key,
|
||||
const struct oxr_sub_paths *sub_paths,
|
||||
struct oxr_source_input **out_input);
|
||||
|
||||
/*!
|
||||
* To go back to a OpenXR object.
|
||||
*/
|
||||
|
@ -274,28 +303,25 @@ oxr_action_get_input_source_localized_name(
|
|||
XrResult
|
||||
oxr_action_get_boolean(struct oxr_logger *log,
|
||||
struct oxr_action *act,
|
||||
uint32_t countSubactionPaths,
|
||||
const XrPath *subactionPaths,
|
||||
struct oxr_sub_paths sub_paths,
|
||||
XrActionStateBoolean *data);
|
||||
XrResult
|
||||
oxr_action_get_vector1f(struct oxr_logger *log,
|
||||
struct oxr_action *act,
|
||||
uint32_t countSubactionPaths,
|
||||
const XrPath *subactionPaths,
|
||||
struct oxr_sub_paths sub_paths,
|
||||
XrActionStateVector1f *data);
|
||||
|
||||
|
||||
XrResult
|
||||
oxr_action_get_vector2f(struct oxr_logger *log,
|
||||
struct oxr_action *act,
|
||||
uint32_t countSubactionPaths,
|
||||
const XrPath *subactionPaths,
|
||||
struct oxr_sub_paths sub_paths,
|
||||
XrActionStateVector2f *data);
|
||||
|
||||
XrResult
|
||||
oxr_action_get_pose(struct oxr_logger *log,
|
||||
struct oxr_action *act,
|
||||
XrPath subactionPath,
|
||||
struct oxr_sub_paths sub_paths,
|
||||
XrActionStatePose *data);
|
||||
|
||||
XrResult
|
||||
|
@ -495,7 +521,9 @@ oxr_system_fill_in(struct oxr_logger *log,
|
|||
struct oxr_instance *inst,
|
||||
XrSystemId systemId,
|
||||
struct oxr_system *sys,
|
||||
struct xrt_device *dev);
|
||||
struct xrt_device *head,
|
||||
struct xrt_device *left,
|
||||
struct xrt_device *right);
|
||||
|
||||
XrResult
|
||||
oxr_system_verify_id(struct oxr_logger *log,
|
||||
|
@ -563,6 +591,34 @@ oxr_event_push_XrEventDataSessionStateChanged(struct oxr_logger *log,
|
|||
XrTime time);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* oxr_xdev.c
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
oxr_xdev_update(struct xrt_device* xdev, struct time_state* timekeeping);
|
||||
|
||||
void
|
||||
oxr_xdev_find_input(struct xrt_device *xdev,
|
||||
enum xrt_input_name name,
|
||||
struct xrt_input **out_input);
|
||||
|
||||
void
|
||||
oxr_xdev_find_output(struct xrt_device *xdev,
|
||||
enum xrt_output_name name,
|
||||
struct xrt_output **out_output);
|
||||
|
||||
void
|
||||
oxr_xdev_get_pose_at(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
struct xrt_device *xdev,
|
||||
enum xrt_input_name name,
|
||||
struct xrt_pose *pose,
|
||||
int64_t *timestamp);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* OpenGL, located in various files.
|
||||
|
@ -687,7 +743,11 @@ struct oxr_handle_base
|
|||
struct oxr_system
|
||||
{
|
||||
struct oxr_instance *inst;
|
||||
struct xrt_device *device;
|
||||
|
||||
struct xrt_device *head;
|
||||
struct xrt_device *left;
|
||||
struct xrt_device *right;
|
||||
|
||||
XrSystemId systemId;
|
||||
|
||||
XrFormFactor form_factor;
|
||||
|
@ -707,7 +767,7 @@ struct oxr_instance
|
|||
//! Common structure for things referred to by OpenXR handles.
|
||||
struct oxr_handle_base handle;
|
||||
|
||||
struct xrt_auto_prober *prober;
|
||||
struct xrt_prober *prober;
|
||||
|
||||
// Enabled extensions
|
||||
bool headless;
|
||||
|
@ -726,6 +786,16 @@ struct oxr_instance
|
|||
struct oxr_event *last_event;
|
||||
struct oxr_event *next_event;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
XrPath user;
|
||||
XrPath head;
|
||||
XrPath left;
|
||||
XrPath right;
|
||||
XrPath gamepad;
|
||||
} path_cache;
|
||||
|
||||
#ifdef XR_EXT_debug_utils
|
||||
//! Debug messengers
|
||||
struct oxr_debug_messenger *messengers[XRT_MAX_HANDLE_CHILDREN];
|
||||
|
@ -747,6 +817,9 @@ struct oxr_session
|
|||
XrSessionState state;
|
||||
bool frame_started;
|
||||
|
||||
struct u_hashmap_int *act_sets;
|
||||
struct u_hashmap_int *sources;
|
||||
|
||||
/*!
|
||||
* IPD, to be expanded to a proper 3D relation.
|
||||
*/
|
||||
|
@ -763,6 +836,122 @@ struct oxr_session
|
|||
struct oxr_swapchain **);
|
||||
};
|
||||
|
||||
/*!
|
||||
* To carry around a sementic selection of sub action paths.
|
||||
*/
|
||||
struct oxr_sub_paths
|
||||
{
|
||||
bool any;
|
||||
bool user;
|
||||
bool head;
|
||||
bool left;
|
||||
bool right;
|
||||
bool gamepad;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Session input source.
|
||||
*
|
||||
* @see oxr_action_set
|
||||
*/
|
||||
struct oxr_source_set
|
||||
{
|
||||
//! Common structure for things referred to by OpenXR handles.
|
||||
struct oxr_handle_base handle;
|
||||
|
||||
//! Which generation of the XrActionSet was this created from.
|
||||
uint32_t generation;
|
||||
};
|
||||
|
||||
/*!
|
||||
* The state of a action input source.
|
||||
*
|
||||
* @see oxr_source
|
||||
*/
|
||||
struct oxr_source_state
|
||||
{
|
||||
union {
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
} vec1;
|
||||
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
} vec2;
|
||||
|
||||
bool boolean;
|
||||
};
|
||||
|
||||
bool active;
|
||||
|
||||
// Was this changed.
|
||||
bool changed;
|
||||
|
||||
//! When was this last changed.
|
||||
XrTime timestamp;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A input source pair of a @ref xrt_input and a @ref xrt_device.
|
||||
*
|
||||
* @see xrt_device
|
||||
* @see xrt_input
|
||||
*/
|
||||
struct oxr_source_input
|
||||
{
|
||||
struct xrt_device *xdev;
|
||||
struct xrt_input *input;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A output source pair of a @ref xrt_output_name and a @ref xrt_device.
|
||||
*
|
||||
* @see xrt_device
|
||||
* @see xrt_output_name
|
||||
*/
|
||||
struct oxr_source_output
|
||||
{
|
||||
struct xrt_device *xdev;
|
||||
enum xrt_output_name name;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A set of inputs for a single sub action path.
|
||||
*
|
||||
* @see oxr_source
|
||||
*/
|
||||
struct oxr_source_cache
|
||||
{
|
||||
struct oxr_source_state current;
|
||||
|
||||
size_t num_inputs;
|
||||
struct oxr_source_input *inputs;
|
||||
|
||||
int64_t stop_output_time;
|
||||
size_t num_outputs;
|
||||
struct oxr_source_output *outputs;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Session input source.
|
||||
*
|
||||
* @see oxr_action
|
||||
*/
|
||||
struct oxr_source
|
||||
{
|
||||
//! Common structure for things referred to by OpenXR handles.
|
||||
struct oxr_handle_base handle;
|
||||
|
||||
struct oxr_source_cache user;
|
||||
struct oxr_source_cache head;
|
||||
struct oxr_source_cache left;
|
||||
struct oxr_source_cache right;
|
||||
struct oxr_source_cache gamepad;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Can be one of 3 references or a space that are bound to actions.
|
||||
*
|
||||
|
@ -782,8 +971,14 @@ struct oxr_space
|
|||
//! What kind of reference space is this, if any.
|
||||
XrReferenceSpaceType type;
|
||||
|
||||
//! Action key from which action this space was created from.
|
||||
uint32_t act_key;
|
||||
|
||||
//! Is this a reference space?
|
||||
bool is_reference;
|
||||
|
||||
//! Which sub action path is this?
|
||||
struct oxr_sub_paths sub_paths;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -839,6 +1034,15 @@ struct oxr_action_set
|
|||
|
||||
//! Onwer of this messenger.
|
||||
struct oxr_session *sess;
|
||||
|
||||
/*!
|
||||
* Every change that is done to a action set will increment this
|
||||
* counter and trigger a rebinding of inputs when syncing actions.
|
||||
*/
|
||||
uint32_t generation;
|
||||
|
||||
//! Unique key for the session hashmap.
|
||||
uint32_t key;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -853,6 +1057,18 @@ struct oxr_action
|
|||
|
||||
//! Onwer of this messenger.
|
||||
struct oxr_action_set *act_set;
|
||||
|
||||
//! Application supplied name of this action.
|
||||
char name[XR_MAX_ACTION_NAME_SIZE];
|
||||
|
||||
//! Unique key for the session hashmap.
|
||||
uint32_t key;
|
||||
|
||||
//! Type this action was created with.
|
||||
XrActionType action_type;
|
||||
|
||||
//! Which sub action paths that this action was created with.
|
||||
struct oxr_sub_paths sub_paths;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -129,6 +129,7 @@ oxr_session_end(struct oxr_logger *log, struct oxr_session *sess)
|
|||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
XrResult
|
||||
oxr_session_get_view_pose_at(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
|
@ -145,33 +146,39 @@ oxr_session_get_view_pose_at(struct oxr_logger *log,
|
|||
// @todo If using orientation tracking only implement a neck model to
|
||||
// get at least a slightly better position.
|
||||
|
||||
struct xrt_device *xdev = sess->sys->device;
|
||||
struct xrt_device *xdev = sess->sys->head;
|
||||
struct xrt_pose *offset = &xdev->tracking->offset;
|
||||
|
||||
struct xrt_space_relation relation;
|
||||
int64_t timestamp;
|
||||
xdev->get_tracked_pose(xdev, XRT_INPUT_GENERIC_HEAD_RELATION,
|
||||
sess->sys->inst->timekeeping, ×tamp,
|
||||
&relation);
|
||||
if ((relation.relation_flags &
|
||||
XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0) {
|
||||
|
||||
// Add in the offset from the tracking system.
|
||||
math_relation_accumulate_transform(offset, &relation);
|
||||
|
||||
// clang-format off
|
||||
bool valid_pos = (relation.relation_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) != 0;
|
||||
bool valid_ori = (relation.relation_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0;
|
||||
bool valid_vel = (relation.relation_flags & XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT) != 0;
|
||||
// clang-format on
|
||||
|
||||
if (valid_ori) {
|
||||
pose->orientation = relation.pose.orientation;
|
||||
} else {
|
||||
pose->orientation.x = 0;
|
||||
pose->orientation.y = 0;
|
||||
pose->orientation.z = 0;
|
||||
pose->orientation.w = 1;
|
||||
}
|
||||
if ((relation.relation_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) !=
|
||||
0) {
|
||||
pose->position = relation.pose.position;
|
||||
} else {
|
||||
// "nominal height" 1.6m
|
||||
pose->position.x = 0.0f;
|
||||
pose->position.y = 1.60f;
|
||||
pose->position.z = 0.0f;
|
||||
// If the orientation is not valid just use the offset.
|
||||
pose->orientation = offset->orientation;
|
||||
}
|
||||
|
||||
if ((relation.relation_flags &
|
||||
XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT) != 0) {
|
||||
if (valid_pos) {
|
||||
pose->position = relation.pose.position;
|
||||
} else {
|
||||
// If the position is not valid just use the offset.
|
||||
pose->position = offset->position;
|
||||
}
|
||||
|
||||
if (valid_vel) {
|
||||
//! @todo Forcing a fixed amount of prediction for now since
|
||||
//! devices don't tell us timestamps yet.
|
||||
int64_t ns_diff = at_time - timestamp;
|
||||
|
@ -187,8 +194,8 @@ oxr_session_get_view_pose_at(struct oxr_logger *log,
|
|||
math_quat_integrate_velocity(&pose->orientation,
|
||||
&relation.angular_velocity,
|
||||
interval, &predicted);
|
||||
if (debug_get_bool_option_views()) {
|
||||
|
||||
if (debug_get_bool_option_views()) {
|
||||
fprintf(stderr,
|
||||
"\toriginal quat = {%f, %f, %f, %f} "
|
||||
"(time requested: %li, Interval %li nsec, with "
|
||||
|
@ -197,6 +204,7 @@ oxr_session_get_view_pose_at(struct oxr_logger *log,
|
|||
pose->orientation.z, pose->orientation.w,
|
||||
at_time, ns_diff, interval);
|
||||
}
|
||||
|
||||
pose->orientation = predicted;
|
||||
}
|
||||
|
||||
|
@ -238,7 +246,7 @@ oxr_session_views(struct oxr_logger *log,
|
|||
uint32_t *viewCountOutput,
|
||||
XrView *views)
|
||||
{
|
||||
struct xrt_device *xdev = sess->sys->device;
|
||||
struct xrt_device *xdev = sess->sys->head;
|
||||
struct oxr_space *baseSpc = (struct oxr_space *)viewLocateInfo->space;
|
||||
uint32_t num_views = 2;
|
||||
|
||||
|
@ -276,9 +284,9 @@ oxr_session_views(struct oxr_logger *log,
|
|||
|
||||
struct xrt_pose pure = pure_relation.pose;
|
||||
|
||||
// @todo the fov information that we get from xdev->views[i].fov is not
|
||||
// properly filled out in oh_device.c, fix before wasting time on
|
||||
// debugging weird rendering when adding stuff here.
|
||||
// @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
|
||||
// on debugging weird rendering when adding stuff here.
|
||||
|
||||
for (uint32_t i = 0; i < num_views; i++) {
|
||||
//! @todo Do not hardcode IPD.
|
||||
|
@ -427,7 +435,7 @@ oxr_session_frame_end(struct oxr_logger *log,
|
|||
"unknown environment blend mode");
|
||||
}
|
||||
|
||||
if ((blend_mode & sess->sys->device->hmd->blend_mode) == 0) {
|
||||
if ((blend_mode & sess->sys->head->hmd->blend_mode) == 0) {
|
||||
return oxr_error(log,
|
||||
XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED,
|
||||
"(frameEndInfo->environmentBlendMode) "
|
||||
|
@ -582,6 +590,9 @@ oxr_session_create(struct oxr_logger *log,
|
|||
log, sess, XR_SESSION_STATE_READY, 0);
|
||||
sess->state = XR_SESSION_STATE_READY;
|
||||
|
||||
u_hashmap_int_create(&sess->act_sets);
|
||||
u_hashmap_int_create(&sess->sources);
|
||||
|
||||
*out_session = sess;
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -27,7 +27,7 @@ oxr_session_populate_gl_xlib(struct oxr_logger *log,
|
|||
struct oxr_session *sess)
|
||||
{
|
||||
struct xrt_compositor_gl *xcgl = xrt_gfx_provider_create_gl_xlib(
|
||||
sys->device, sys->inst->timekeeping, next->xDisplay, next->visualid,
|
||||
sys->head, sys->inst->timekeeping, next->xDisplay, next->visualid,
|
||||
next->glxFBConfig, next->glxDrawable, next->glxContext);
|
||||
|
||||
if (xcgl == NULL) {
|
||||
|
|
|
@ -30,7 +30,7 @@ oxr_session_populate_vk(struct oxr_logger *log,
|
|||
struct oxr_session *sess)
|
||||
{
|
||||
struct xrt_compositor_vk *xcvk = xrt_gfx_vk_provider_create(
|
||||
sys->device, sys->inst->timekeeping, next->instance,
|
||||
sys->head, sys->inst->timekeeping, next->instance,
|
||||
vkGetInstanceProcAddr, next->physicalDevice, next->device,
|
||||
next->queueFamilyIndex, next->queueIndex);
|
||||
|
||||
|
|
|
@ -58,6 +58,10 @@ oxr_space_action_create(struct oxr_logger *log,
|
|||
const XrActionSpaceCreateInfo *createInfo,
|
||||
struct oxr_space **out_space)
|
||||
{
|
||||
struct oxr_session *sess = act->act_set->sess;
|
||||
struct oxr_instance *inst = sess->sys->inst;
|
||||
struct oxr_sub_paths sub_paths = {0};
|
||||
|
||||
struct oxr_space *spc = NULL;
|
||||
OXR_ALLOCATE_HANDLE_OR_RETURN(log, spc, OXR_XR_DEBUG_SPACE,
|
||||
oxr_space_destroy, &act->handle);
|
||||
|
@ -65,8 +69,12 @@ oxr_space_action_create(struct oxr_logger *log,
|
|||
//! @todo implement more fully
|
||||
oxr_warn(log, " not fully implemented");
|
||||
|
||||
oxr_classify_sub_action_paths(log, inst, 1, &createInfo->subactionPath,
|
||||
&sub_paths);
|
||||
|
||||
spc->sess = act->act_set->sess;
|
||||
spc->is_reference = false;
|
||||
spc->sub_paths = sub_paths;
|
||||
memcpy(&spc->pose, &createInfo->poseInActionSpace, sizeof(spc->pose));
|
||||
|
||||
*out_space = spc;
|
||||
|
@ -112,7 +120,7 @@ static const char *
|
|||
get_ref_space_type_short_str(struct oxr_space *spc)
|
||||
{
|
||||
if (!spc->is_reference) {
|
||||
return "action?";
|
||||
return "action";
|
||||
}
|
||||
|
||||
switch (spc->type) {
|
||||
|
@ -181,6 +189,82 @@ oxr_space_ref_relation(struct oxr_logger *log,
|
|||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This returns only the relation between two spaces without any of the app
|
||||
* given relations applied, assumes that only one is a action space.
|
||||
*/
|
||||
XrResult
|
||||
oxr_space_action_relation(struct oxr_logger *log,
|
||||
struct oxr_session *sess,
|
||||
struct oxr_space *spc,
|
||||
struct oxr_space *baseSpc,
|
||||
XrTime time,
|
||||
struct xrt_space_relation *out_relation)
|
||||
{
|
||||
struct oxr_source_input *input = NULL;
|
||||
struct oxr_space *act_spc, *ref_spc = NULL;
|
||||
int64_t timestamp = 0;
|
||||
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.
|
||||
math_relation_reset(out_relation);
|
||||
|
||||
// We treat state and local space as the same.
|
||||
//! @todo Can not relate to the view space right now.
|
||||
if (baseSpc->type == XR_REFERENCE_SPACE_TYPE_VIEW) {
|
||||
//! @todo Error code?
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
oxr_source_get_pose_input(log, sess, act_spc->act_key,
|
||||
&act_spc->sub_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_pose_at(log, sess->sys->inst, input->xdev,
|
||||
input->input->name, &out_relation->pose,
|
||||
×tamp);
|
||||
|
||||
out_relation->relation_flags = (enum xrt_space_relation_flags)(
|
||||
XRT_SPACE_RELATION_POSITION_VALID_BIT |
|
||||
XRT_SPACE_RELATION_POSITION_TRACKED_BIT |
|
||||
XRT_SPACE_RELATION_ORIENTATION_VALID_BIT |
|
||||
XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT);
|
||||
|
||||
if (invert) {
|
||||
math_pose_invert(&out_relation->pose, &out_relation->pose);
|
||||
}
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This returns only the relation between two directly-associated spaces without
|
||||
* any of the app given relations applied.
|
||||
|
@ -211,8 +295,8 @@ get_pure_space_relation(struct oxr_logger *log,
|
|||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||
return XR_SUCCESS;
|
||||
} else {
|
||||
// @todo deal with action space poses.
|
||||
out_relation->relation_flags = XRT_SPACE_RELATION_BITMASK_NONE;
|
||||
oxr_space_action_relation(log, sess, spc, baseSpc, time,
|
||||
out_relation);
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,15 +93,38 @@ oxr_system_fill_in(struct oxr_logger *log,
|
|||
struct oxr_instance *inst,
|
||||
XrSystemId systemId,
|
||||
struct oxr_system *sys,
|
||||
struct xrt_device *xdev)
|
||||
struct xrt_device *head,
|
||||
struct xrt_device *left,
|
||||
struct xrt_device *right)
|
||||
{
|
||||
if (xdev == NULL) {
|
||||
if (head == NULL) {
|
||||
return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED,
|
||||
" failed to probe device");
|
||||
}
|
||||
|
||||
if (head->tracking->type == XRT_TRACKING_TYPE_NONE) {
|
||||
// "nominal height" 1.6m
|
||||
head->tracking->offset.position.x = 0.0f;
|
||||
head->tracking->offset.position.y = 1.6f;
|
||||
head->tracking->offset.position.z = 0.0f;
|
||||
}
|
||||
|
||||
if (left != NULL && left->tracking->type == XRT_TRACKING_TYPE_NONE) {
|
||||
left->tracking->offset.position.x = -0.2f;
|
||||
left->tracking->offset.position.y = 1.3f;
|
||||
left->tracking->offset.position.z = -0.5f;
|
||||
}
|
||||
|
||||
if (right != NULL && right->tracking->type == XRT_TRACKING_TYPE_NONE) {
|
||||
right->tracking->offset.position.x = 0.2f;
|
||||
right->tracking->offset.position.y = 1.3f;
|
||||
right->tracking->offset.position.z = -0.5f;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
sys->device = xdev;
|
||||
sys->head = head;
|
||||
sys->left = left;
|
||||
sys->right = right;
|
||||
sys->inst = inst;
|
||||
sys->systemId = systemId;
|
||||
sys->form_factor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
|
||||
|
@ -109,10 +132,11 @@ oxr_system_fill_in(struct oxr_logger *log,
|
|||
|
||||
double scale = debug_get_num_option_scale_percentage() / 100.0;
|
||||
|
||||
uint32_t w0 = (uint32_t)(xdev->hmd->views[0].display.w_pixels * scale);
|
||||
uint32_t h0 = (uint32_t)(xdev->hmd->views[0].display.w_pixels * scale);
|
||||
uint32_t w1 = (uint32_t)(xdev->hmd->views[1].display.w_pixels * scale);
|
||||
uint32_t h1 = (uint32_t)(xdev->hmd->views[1].display.w_pixels * scale);
|
||||
|
||||
uint32_t w0 = (uint32_t)(head->hmd->views[0].display.w_pixels * scale);
|
||||
uint32_t h0 = (uint32_t)(head->hmd->views[0].display.w_pixels * scale);
|
||||
uint32_t w1 = (uint32_t)(head->hmd->views[1].display.w_pixels * scale);
|
||||
uint32_t h1 = (uint32_t)(head->hmd->views[1].display.w_pixels * scale);
|
||||
|
||||
sys->views[0].recommendedImageRectWidth = w0;
|
||||
sys->views[0].maxImageRectWidth = w0;
|
||||
|
@ -130,13 +154,13 @@ oxr_system_fill_in(struct oxr_logger *log,
|
|||
// clang-format on
|
||||
|
||||
uint32_t i = 0;
|
||||
if (xdev->hmd->blend_mode & XRT_BLEND_MODE_OPAQUE) {
|
||||
if (head->hmd->blend_mode & XRT_BLEND_MODE_OPAQUE) {
|
||||
sys->blend_modes[i++] = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
|
||||
}
|
||||
if (xdev->hmd->blend_mode & XRT_BLEND_MODE_ADDITIVE) {
|
||||
if (head->hmd->blend_mode & XRT_BLEND_MODE_ADDITIVE) {
|
||||
sys->blend_modes[i++] = XR_ENVIRONMENT_BLEND_MODE_ADDITIVE;
|
||||
}
|
||||
if (xdev->hmd->blend_mode & XRT_BLEND_MODE_ALPHA_BLEND) {
|
||||
if (head->hmd->blend_mode & XRT_BLEND_MODE_ALPHA_BLEND) {
|
||||
sys->blend_modes[i++] = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND;
|
||||
}
|
||||
sys->num_blend_modes = i;
|
||||
|
@ -157,7 +181,7 @@ oxr_system_get_properties(struct oxr_logger *log,
|
|||
properties->graphicsProperties.maxViewCount = 2;
|
||||
|
||||
// Needed to silence the warnings.
|
||||
const char *name = sys->device->name;
|
||||
const char *name = sys->head->name;
|
||||
|
||||
snprintf(properties->systemName, XR_MAX_SYSTEM_NAME_SIZE, "Monado: %s",
|
||||
name);
|
||||
|
|
|
@ -264,6 +264,185 @@ oxr_verify_full_path(struct oxr_logger* log,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Subaction path functions.
|
||||
*
|
||||
*/
|
||||
|
||||
static XrResult
|
||||
subaction_path_no_dups(struct oxr_logger* log,
|
||||
struct oxr_instance* inst,
|
||||
struct oxr_sub_paths& sub_paths,
|
||||
XrPath path,
|
||||
const char* variable,
|
||||
uint32_t index)
|
||||
{
|
||||
bool duplicate = false;
|
||||
|
||||
if (path == XR_NULL_PATH) {
|
||||
return oxr_error(log, XR_ERROR_PATH_INVALID,
|
||||
"(%s[%u] == XR_NULL_PATH) not a "
|
||||
"valid subaction path.",
|
||||
variable, index);
|
||||
} else if (path == inst->path_cache.user) {
|
||||
if (sub_paths.user) {
|
||||
duplicate = true;
|
||||
} else {
|
||||
sub_paths.user = true;
|
||||
}
|
||||
} else if (path == inst->path_cache.head) {
|
||||
if (sub_paths.head) {
|
||||
duplicate = true;
|
||||
} else {
|
||||
sub_paths.head = true;
|
||||
}
|
||||
} else if (path == inst->path_cache.left) {
|
||||
if (sub_paths.left) {
|
||||
duplicate = true;
|
||||
} else {
|
||||
sub_paths.left = true;
|
||||
}
|
||||
} else if (path == inst->path_cache.right) {
|
||||
if (sub_paths.right) {
|
||||
duplicate = true;
|
||||
} else {
|
||||
sub_paths.right = true;
|
||||
}
|
||||
} else if (path == inst->path_cache.gamepad) {
|
||||
if (sub_paths.gamepad) {
|
||||
duplicate = true;
|
||||
} else {
|
||||
sub_paths.gamepad = true;
|
||||
}
|
||||
} else {
|
||||
const char* str = NULL;
|
||||
size_t length = 0;
|
||||
|
||||
oxr_path_get_string(log, inst, path, &str, &length);
|
||||
return oxr_error(log, XR_ERROR_PATH_INVALID,
|
||||
"(%s[%u] == '%s') path is not a "
|
||||
"valid subaction path.",
|
||||
variable, index, str);
|
||||
}
|
||||
|
||||
if (duplicate) {
|
||||
const char* str = NULL;
|
||||
size_t length = 0;
|
||||
|
||||
oxr_path_get_string(log, inst, path, &str, &length);
|
||||
|
||||
return oxr_error(log, XR_ERROR_PATH_INVALID,
|
||||
"(%s[%u] == '%s') duplicate paths", variable,
|
||||
index, str);
|
||||
}
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
extern "C" XrResult
|
||||
oxr_verify_subaction_paths_create(struct oxr_logger* log,
|
||||
struct oxr_instance* inst,
|
||||
uint32_t countSubactionPaths,
|
||||
const XrPath* subactionPaths,
|
||||
const char* variable)
|
||||
{
|
||||
struct oxr_sub_paths sub_paths = {};
|
||||
|
||||
for (uint32_t i = 0; i < countSubactionPaths; i++) {
|
||||
XrPath path = subactionPaths[i];
|
||||
|
||||
XrResult ret = subaction_path_no_dups(log, inst, sub_paths,
|
||||
path, variable, i);
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
extern "C" XrResult
|
||||
oxr_verify_subaction_path_sync(struct oxr_logger* log,
|
||||
struct oxr_instance* inst,
|
||||
XrPath path,
|
||||
uint32_t index)
|
||||
{
|
||||
if (path == XR_NULL_PATH || path == inst->path_cache.user ||
|
||||
path == inst->path_cache.head || path == inst->path_cache.left ||
|
||||
path == inst->path_cache.right ||
|
||||
path == inst->path_cache.gamepad) {
|
||||
return XR_SUCCESS;
|
||||
} else {
|
||||
const char* str = NULL;
|
||||
size_t length = 0;
|
||||
|
||||
oxr_path_get_string(log, inst, path, &str, &length);
|
||||
return oxr_error(log, XR_ERROR_PATH_INVALID,
|
||||
"(actionSets[%i].subactionPath == '%s') path "
|
||||
"is not a valid subaction path.",
|
||||
index, str);
|
||||
}
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
extern "C" XrResult
|
||||
oxr_verify_subaction_path_get(struct oxr_logger* log,
|
||||
struct oxr_instance* inst,
|
||||
XrPath path,
|
||||
const struct oxr_sub_paths* act_sub_paths,
|
||||
struct oxr_sub_paths* out_sub_paths,
|
||||
const char* variable)
|
||||
{
|
||||
struct oxr_sub_paths sub_paths = {};
|
||||
|
||||
if (path == XR_NULL_PATH) {
|
||||
sub_paths.any = true;
|
||||
} else if (path == inst->path_cache.user) {
|
||||
sub_paths.user = true;
|
||||
} else if (path == inst->path_cache.head) {
|
||||
sub_paths.head = true;
|
||||
} else if (path == inst->path_cache.left) {
|
||||
sub_paths.left = true;
|
||||
} else if (path == inst->path_cache.right) {
|
||||
sub_paths.right = true;
|
||||
} else if (path == inst->path_cache.gamepad) {
|
||||
sub_paths.gamepad = true;
|
||||
} else {
|
||||
const char* str = NULL;
|
||||
size_t length = 0;
|
||||
|
||||
oxr_path_get_string(log, inst, path, &str, &length);
|
||||
return oxr_error(log, XR_ERROR_PATH_INVALID,
|
||||
"(%s == '%s') path is not "
|
||||
"a valid subaction path.",
|
||||
variable, str);
|
||||
}
|
||||
|
||||
if ((sub_paths.user && !act_sub_paths->user) ||
|
||||
(sub_paths.head && !act_sub_paths->head) ||
|
||||
(sub_paths.left && !act_sub_paths->left) ||
|
||||
(sub_paths.right && !act_sub_paths->right) ||
|
||||
(sub_paths.gamepad && !act_sub_paths->gamepad)) {
|
||||
const char* str = NULL;
|
||||
size_t length = 0;
|
||||
|
||||
oxr_path_get_string(log, inst, path, &str, &length);
|
||||
|
||||
return oxr_error(log, XR_ERROR_PATH_INVALID,
|
||||
"(%s == '%s') the subaction path was "
|
||||
"not specified at action creation",
|
||||
variable, str);
|
||||
}
|
||||
|
||||
*out_sub_paths = sub_paths;
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Other verification.
|
||||
|
|
96
src/xrt/state_trackers/oxr/oxr_xdev.c
Normal file
96
src/xrt/state_trackers/oxr/oxr_xdev.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Various helpers for accessing @ref xrt_device.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup oxr_main
|
||||
*/
|
||||
|
||||
#include "math/m_api.h"
|
||||
#include "oxr_objects.h"
|
||||
|
||||
|
||||
void
|
||||
oxr_xdev_update(struct xrt_device* xdev, struct time_state* timekeeping)
|
||||
{
|
||||
if (xdev != NULL) {
|
||||
xdev->update_inputs(xdev, timekeeping);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
oxr_xdev_find_input(struct xrt_device *xdev,
|
||||
enum xrt_input_name name,
|
||||
struct xrt_input **out_input)
|
||||
{
|
||||
*out_input = NULL;
|
||||
if (xdev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < xdev->num_inputs; i++) {
|
||||
if (xdev->inputs[i].name != name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*out_input = &xdev->inputs[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
oxr_xdev_find_output(struct xrt_device *xdev,
|
||||
enum xrt_output_name name,
|
||||
struct xrt_output **out_output)
|
||||
{
|
||||
if (xdev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < xdev->num_outputs; i++) {
|
||||
if (xdev->outputs[i].name != name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*out_output = &xdev->outputs[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
oxr_xdev_get_pose_at(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
struct xrt_device *xdev,
|
||||
enum xrt_input_name name,
|
||||
struct xrt_pose *pose,
|
||||
int64_t *timestamp)
|
||||
{
|
||||
struct xrt_pose *offset = &xdev->tracking->offset;
|
||||
|
||||
struct xrt_space_relation relation = {0};
|
||||
xdev->get_tracked_pose(xdev, name, inst->timekeeping, timestamp,
|
||||
&relation);
|
||||
|
||||
// Add in the offset from the tracking system.
|
||||
math_relation_accumulate_transform(offset, &relation);
|
||||
|
||||
// clang-format off
|
||||
bool valid_pos = (relation.relation_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) != 0;
|
||||
bool valid_ori = (relation.relation_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0;
|
||||
// clang-format on
|
||||
|
||||
if (valid_ori) {
|
||||
pose->orientation = relation.pose.orientation;
|
||||
} else {
|
||||
// If the orientation is not valid just use the offset.
|
||||
pose->orientation = offset->orientation;
|
||||
}
|
||||
|
||||
if (valid_pos) {
|
||||
pose->position = relation.pose.position;
|
||||
} else {
|
||||
// If the position is not valid just use the offset.
|
||||
pose->position = offset->position;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue