mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-29 18:08:29 +00:00
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:
parent
360eeb535d
commit
ecb0ae2254
|
@ -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
|
||||
|
|
92
src/xrt/state_trackers/oxr/oxr_api_face_tracking.c
Normal file
92
src/xrt/state_trackers/oxr/oxr_api_face_tracking.c
Normal 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);
|
||||
}
|
|
@ -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
|
||||
|
|
117
src/xrt/state_trackers/oxr/oxr_face_tracking.c
Normal file
117
src/xrt/state_trackers/oxr/oxr_face_tracking.c
Normal 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;
|
||||
}
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue