st/oxr: XR_HTC_facial_tracking state-tracker clean-up

Moves the XR_HTC_facial_tracking state-tracker implementation
out of oxr_api_session.c into dedicated files, following
api/monado conventions.
This commit is contained in:
Korcan Hussein 2024-05-21 15:33:13 +01:00
parent 360eeb535d
commit ecb0ae2254
5 changed files with 226 additions and 165 deletions

View file

@ -113,6 +113,10 @@ if(XRT_FEATURE_OPENXR_BODY_TRACKING_FB)
target_sources(st_oxr PRIVATE oxr_api_body_tracking.c oxr_body_tracking.c)
endif()
if(XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC)
target_sources(st_oxr PRIVATE oxr_api_face_tracking.c oxr_face_tracking.c)
endif()
target_link_libraries(
st_oxr
PRIVATE

View file

@ -0,0 +1,92 @@
// Copyright 2024, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief face tracking related API entrypoint functions.
* @author Korcan Hussein <korcan.hussein@collabora.com>
* @ingroup oxr_api
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "util/u_trace_marker.h"
#include "oxr_objects.h"
#include "oxr_logger.h"
#include "oxr_api_funcs.h"
#include "oxr_api_verify.h"
#include "oxr_handle.h"
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrCreateFacialTrackerHTC(XrSession session,
const XrFacialTrackerCreateInfoHTC *createInfo,
XrFacialTrackerHTC *facialTracker)
{
OXR_TRACE_MARKER();
struct oxr_logger log;
XrResult ret = XR_SUCCESS;
struct oxr_session *sess = NULL;
struct oxr_facial_tracker_htc *facial_tracker_htc = NULL;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrCreateFacialTrackerHTC");
OXR_VERIFY_SESSION_NOT_LOST(&log, sess);
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, createInfo, XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC);
OXR_VERIFY_EXTENSION(&log, sess->sys->inst, HTC_facial_tracking);
ret = oxr_facial_tracker_htc_create(&log, sess, createInfo, &facial_tracker_htc);
if (ret != XR_SUCCESS) {
return ret;
}
OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc);
*facialTracker = oxr_facial_tracker_htc_to_openxr(facial_tracker_htc);
return XR_SUCCESS;
}
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrDestroyFacialTrackerHTC(XrFacialTrackerHTC facialTracker)
{
OXR_TRACE_MARKER();
struct oxr_logger log;
struct oxr_facial_tracker_htc *facial_tracker_htc = NULL;
OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialTracker, facial_tracker_htc, "xrDestroyFacialTrackerHTC");
return oxr_handle_destroy(&log, &facial_tracker_htc->handle);
}
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrGetFacialExpressionsHTC(XrFacialTrackerHTC facialTracker, XrFacialExpressionsHTC *facialExpressions)
{
OXR_TRACE_MARKER();
struct oxr_logger log;
struct oxr_facial_tracker_htc *facial_tracker_htc = NULL;
OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialExpressions, facial_tracker_htc,
"xrGetFacialExpressionsHTC");
OXR_VERIFY_SESSION_NOT_LOST(&log, facial_tracker_htc->sess);
OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc->xdev);
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, facialExpressions, XR_TYPE_FACIAL_EXPRESSIONS_HTC);
OXR_VERIFY_ARG_NOT_NULL(&log, facialExpressions->expressionWeightings);
#define OXR_VERIFY_FACE_EXPRESSION_COUNT(fttype) \
if (facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_##fttype##_DEFAULT_HTC && \
facialExpressions->expressionCount < XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC) { \
return oxr_error( \
&log, XR_ERROR_SIZE_INSUFFICIENT, \
"\"expressionCount\" (%d) size is less than the minimum size (%d) required for " #fttype \
" expressions.\n", \
facialExpressions->expressionCount, XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC); \
}
OXR_VERIFY_FACE_EXPRESSION_COUNT(EYE)
OXR_VERIFY_FACE_EXPRESSION_COUNT(LIP)
#undef OXR_VERIFY_FACE_EXPRESSION_COUNT
return oxr_get_facial_expressions_htc(&log, facial_tracker_htc, facialExpressions);
}

View file

@ -679,168 +679,3 @@ oxr_xrSetAndroidApplicationThreadKHR(XrSession session, XrAndroidThreadTypeKHR t
}
#endif
#ifdef OXR_HAVE_HTC_facial_tracking
static enum xrt_facial_tracking_type_htc
oxr_to_xrt_facial_tracking_type_htc(enum XrFacialTrackingTypeHTC ft_type)
{
return (enum xrt_facial_tracking_type_htc)ft_type;
}
static enum xrt_input_name
oxr_facial_tracking_type_htc_to_input_name(enum xrt_facial_tracking_type_htc ft_type)
{
switch (ft_type) {
case XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC: return XRT_INPUT_HTC_LIP_FACE_TRACKING;
case XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC:
default: return XRT_INPUT_HTC_EYE_FACE_TRACKING;
}
}
static XrResult
oxr_facial_tracker_htc_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb)
{
struct oxr_facial_tracker_htc *face_tracker_htc = (struct oxr_facial_tracker_htc *)hb;
free(face_tracker_htc);
return XR_SUCCESS;
}
XrResult
oxr_facial_tracker_htc_create(struct oxr_logger *log,
struct oxr_session *sess,
const XrFacialTrackerCreateInfoHTC *createInfo,
struct oxr_facial_tracker_htc **out_face_tracker_htc)
{
bool supports_eye = false;
bool supports_lip = false;
oxr_system_get_face_tracking_htc_support(log, sess->sys->inst, &supports_eye, &supports_lip);
const enum xrt_facial_tracking_type_htc facial_tracking_type =
oxr_to_xrt_facial_tracking_type_htc(createInfo->facialTrackingType);
if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC && !supports_eye) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC eye facial tracking");
}
if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC && !supports_lip) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC lip facial tracking");
}
struct xrt_device *xdev = GET_XDEV_BY_ROLE(sess->sys, face);
if (xdev == NULL) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "No device found for face tracking role");
}
if (!xdev->face_tracking_supported) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "Device does not support HTC facial tracking");
}
struct oxr_facial_tracker_htc *face_tracker_htc = NULL;
OXR_ALLOCATE_HANDLE_OR_RETURN(log, face_tracker_htc, OXR_XR_DEBUG_FTRACKER, oxr_facial_tracker_htc_destroy_cb,
&sess->handle);
face_tracker_htc->sess = sess;
face_tracker_htc->xdev = xdev;
face_tracker_htc->facial_tracking_type = facial_tracking_type;
*out_face_tracker_htc = face_tracker_htc;
return XR_SUCCESS;
}
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrCreateFacialTrackerHTC(XrSession session,
const XrFacialTrackerCreateInfoHTC *createInfo,
XrFacialTrackerHTC *facialTracker)
{
OXR_TRACE_MARKER();
struct oxr_logger log;
XrResult ret = XR_SUCCESS;
struct oxr_session *sess = NULL;
struct oxr_facial_tracker_htc *facial_tracker_htc = NULL;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrCreateFacialTrackerHTC");
OXR_VERIFY_SESSION_NOT_LOST(&log, sess);
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, createInfo, XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC);
OXR_VERIFY_EXTENSION(&log, sess->sys->inst, HTC_facial_tracking);
ret = oxr_facial_tracker_htc_create(&log, sess, createInfo, &facial_tracker_htc);
if (ret != XR_SUCCESS) {
return ret;
}
OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc);
*facialTracker = oxr_facial_tracker_htc_to_openxr(facial_tracker_htc);
return XR_SUCCESS;
}
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrDestroyFacialTrackerHTC(XrFacialTrackerHTC facialTracker)
{
OXR_TRACE_MARKER();
struct oxr_logger log;
struct oxr_facial_tracker_htc *facial_tracker_htc = NULL;
OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialTracker, facial_tracker_htc, "xrDestroyFacialTrackerHTC");
return oxr_handle_destroy(&log, &facial_tracker_htc->handle);
}
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrGetFacialExpressionsHTC(XrFacialTrackerHTC facialTracker, XrFacialExpressionsHTC *facialExpressions)
{
OXR_TRACE_MARKER();
struct oxr_logger log;
struct oxr_facial_tracker_htc *facial_tracker_htc = NULL;
OXR_VERIFY_FACE_TRACKER_HTC_AND_INIT_LOG(&log, facialExpressions, facial_tracker_htc,
"xrGetFacialExpressionsHTC");
OXR_VERIFY_SESSION_NOT_LOST(&log, facial_tracker_htc->sess);
OXR_VERIFY_ARG_NOT_NULL(&log, facial_tracker_htc->xdev);
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, facialExpressions, XR_TYPE_FACIAL_EXPRESSIONS_HTC);
OXR_VERIFY_ARG_NOT_NULL(&log, facialExpressions->expressionWeightings);
#define OXR_VERIFY_FACE_EXPRESSION_COUNT(fttype) \
if (facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_##fttype##_DEFAULT_HTC && \
facialExpressions->expressionCount < XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC) { \
return oxr_error( \
&log, XR_ERROR_SIZE_INSUFFICIENT, \
"\"expressionCount\" (%d) size is less than the minimum size (%d) required for " #fttype \
" expressions.\n", \
facialExpressions->expressionCount, XRT_FACIAL_EXPRESSION_##fttype##_COUNT_HTC); \
}
OXR_VERIFY_FACE_EXPRESSION_COUNT(EYE)
OXR_VERIFY_FACE_EXPRESSION_COUNT(LIP)
#undef OXR_VERIFY_FACE_EXPRESSION_COUNT
const bool is_eye_tracking =
facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC;
const size_t expression_count =
is_eye_tracking ? XRT_FACIAL_EXPRESSION_EYE_COUNT_HTC : XRT_FACIAL_EXPRESSION_LIP_COUNT_HTC;
struct xrt_facial_expression_set facial_expression_set_result = {0};
float *expression_weights = is_eye_tracking
? facial_expression_set_result.eye_expression_set_htc.expression_weights
: facial_expression_set_result.lip_expression_set_htc.expression_weights;
memset(expression_weights, 0, sizeof(float) * expression_count);
const enum xrt_input_name ft_input_name =
oxr_facial_tracking_type_htc_to_input_name(facial_tracker_htc->facial_tracking_type);
xrt_device_get_face_tracking(facial_tracker_htc->xdev, ft_input_name, &facial_expression_set_result);
facialExpressions->isActive = facial_expression_set_result.base_expression_set_htc.is_active;
if (facialExpressions->isActive == XR_FALSE)
return XR_SUCCESS;
const struct oxr_instance *inst = facial_tracker_htc->sess->sys->inst;
facialExpressions->sampleTime = time_state_monotonic_to_ts_ns(
inst->timekeeping, facial_expression_set_result.base_expression_set_htc.sample_time_ns);
memcpy(facialExpressions->expressionWeightings, expression_weights, sizeof(float) * expression_count);
return XR_SUCCESS;
}
#endif

View file

@ -0,0 +1,117 @@
// Copyright 2024, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief face tracking related API entrypoint functions.
* @author Korcan Hussein <korcan.hussein@collabora.com>
* @ingroup oxr_main
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "oxr_objects.h"
#include "oxr_logger.h"
#include "oxr_handle.h"
static enum xrt_facial_tracking_type_htc
oxr_to_xrt_facial_tracking_type_htc(enum XrFacialTrackingTypeHTC ft_type)
{
return (enum xrt_facial_tracking_type_htc)ft_type;
}
static enum xrt_input_name
oxr_facial_tracking_type_htc_to_input_name(enum xrt_facial_tracking_type_htc ft_type)
{
switch (ft_type) {
case XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC: return XRT_INPUT_HTC_LIP_FACE_TRACKING;
case XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC:
default: return XRT_INPUT_HTC_EYE_FACE_TRACKING;
}
}
static XrResult
oxr_facial_tracker_htc_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb)
{
struct oxr_facial_tracker_htc *face_tracker_htc = (struct oxr_facial_tracker_htc *)hb;
free(face_tracker_htc);
return XR_SUCCESS;
}
XrResult
oxr_facial_tracker_htc_create(struct oxr_logger *log,
struct oxr_session *sess,
const XrFacialTrackerCreateInfoHTC *createInfo,
struct oxr_facial_tracker_htc **out_face_tracker_htc)
{
bool supports_eye = false;
bool supports_lip = false;
oxr_system_get_face_tracking_htc_support(log, sess->sys->inst, &supports_eye, &supports_lip);
const enum xrt_facial_tracking_type_htc facial_tracking_type =
oxr_to_xrt_facial_tracking_type_htc(createInfo->facialTrackingType);
if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC && !supports_eye) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC eye facial tracking");
}
if (facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC && !supports_lip) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "System does not support HTC lip facial tracking");
}
struct xrt_device *xdev = GET_XDEV_BY_ROLE(sess->sys, face);
if (xdev == NULL) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "No device found for face tracking role");
}
if (!xdev->face_tracking_supported) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED, "Device does not support HTC facial tracking");
}
struct oxr_facial_tracker_htc *face_tracker_htc = NULL;
OXR_ALLOCATE_HANDLE_OR_RETURN(log, face_tracker_htc, OXR_XR_DEBUG_FTRACKER, oxr_facial_tracker_htc_destroy_cb,
&sess->handle);
face_tracker_htc->sess = sess;
face_tracker_htc->xdev = xdev;
face_tracker_htc->facial_tracking_type = facial_tracking_type;
*out_face_tracker_htc = face_tracker_htc;
return XR_SUCCESS;
}
XrResult
oxr_get_facial_expressions_htc(struct oxr_logger *log,
struct oxr_facial_tracker_htc *facial_tracker_htc,
XrFacialExpressionsHTC *facialExpressions)
{
const bool is_eye_tracking =
facial_tracker_htc->facial_tracking_type == XRT_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC;
const size_t expression_count =
is_eye_tracking ? XRT_FACIAL_EXPRESSION_EYE_COUNT_HTC : XRT_FACIAL_EXPRESSION_LIP_COUNT_HTC;
struct xrt_facial_expression_set facial_expression_set_result = {0};
float *expression_weights = is_eye_tracking
? facial_expression_set_result.eye_expression_set_htc.expression_weights
: facial_expression_set_result.lip_expression_set_htc.expression_weights;
memset(expression_weights, 0, sizeof(float) * expression_count);
const enum xrt_input_name ft_input_name =
oxr_facial_tracking_type_htc_to_input_name(facial_tracker_htc->facial_tracking_type);
xrt_device_get_face_tracking(facial_tracker_htc->xdev, ft_input_name, &facial_expression_set_result);
facialExpressions->isActive = facial_expression_set_result.base_expression_set_htc.is_active;
if (facialExpressions->isActive == XR_FALSE)
return XR_SUCCESS;
const struct oxr_instance *inst = facial_tracker_htc->sess->sys->inst;
facialExpressions->sampleTime = time_state_monotonic_to_ts_ns(
inst->timekeeping, facial_expression_set_result.base_expression_set_htc.sample_time_ns);
memcpy(facialExpressions->expressionWeightings, expression_weights, sizeof(float) * expression_count);
return XR_SUCCESS;
}

View file

@ -2667,6 +2667,7 @@ oxr_event_push_XrEventDataPassthroughStateChangedFB(struct oxr_logger *log,
#endif // OXR_HAVE_FB_passthrough
#ifdef OXR_HAVE_HTC_facial_tracking
/*!
* HTC specific Facial tracker.
*
@ -2691,6 +2692,18 @@ struct oxr_facial_tracker_htc
enum xrt_facial_tracking_type_htc facial_tracking_type;
};
XrResult
oxr_facial_tracker_htc_create(struct oxr_logger *log,
struct oxr_session *sess,
const XrFacialTrackerCreateInfoHTC *createInfo,
struct oxr_facial_tracker_htc **out_face_tracker_htc);
XrResult
oxr_get_facial_expressions_htc(struct oxr_logger *log,
struct oxr_facial_tracker_htc *facial_tracker_htc,
XrFacialExpressionsHTC *facialExpressions);
#endif
#ifdef OXR_HAVE_FB_body_tracking
/*!
* FB specific Body tracker.