Разработка
Разработка
Выберите платформу

Отслеживание движений глаз в Movement SDK для OpenXR

В этой статье представлены:
  • обзор отслеживания движений глаз для Meta Quest Pro;
  • правила;
  • Руководство по использованию расширения Eye Tracking OpenXR
  • Ссылки на смежные темы

Что такое отслеживание движений глаз?

Отслеживание движений глаз для Meta Quest Pro распознает движение глаз и позволяет Eye Gaze API управлять трансформацией глаз воплощенного персонажа пользователя, когда он осматривается вокруг. Абстрактное представление взгляда, которое предоставляет этот API, позволяет отображаемому персонажу пользователя устанавливать зрительный контакт с другими пользователями, что значительно улучшает социальное присутствие. Его также можно использовать для определения того, куда человек смотрит в трехмерном пространстве, что может обеспечить хорошее понимание интересующих его областей или даже использоваться для нацеливания в играх.

Правила и отказ от ответственности

При использовании Eye Tracking API вы должны всегда соблюдать лицензионное соглашение Oculus SDK и Политику использования данных для разработчиков, а также все применимые правила, положения и условия Oculus и Meta. На использование вами Movement могут распространяться действующие законы о конфиденциальности и защите данных.
В частности, вы должны опубликовать и соблюдать общедоступную и легкодоступную политику конфиденциальности, в которой четко регламентируется сбор, использование, хранение и обработка данных с помощью Eye Tracking API. Вы обязаны обеспечить предоставление пользователям четкой и полной информации о доступе к абстрагированным данным о взгляде и их использовании до начала сбора, в том числе в соответствии с требованиями действующего законодательства о конфиденциальности и защите данных, и пользователь должен дать согласие на это.
Обратите внимание: мы оставляем за собой право контролировать использование вами Eye Tracking API для обеспечения соблюдения наших правил.
Когда пользователь включает отслеживание движений глаз, приложение получает доступ к абстрагированным данным о взгляде в режиме реального времени, которые в соответствии с Правилами использования данных разработчиками представляют собой пользовательские данные. Вам явным образом запрещается использовать эти данные в запрещенных практиках использования данных, описанных в Правилах использования данных разработчиками. Отслеживание движений глаз основано на нашей технологии Eye Tracking API.

Образец приложения XrEyes

Создание образца приложения XrEyes

Скачайте Oculus Mobile OpenXR SDK (версии 47 или более поздней), а затем создайте пример приложения XrEyes с помощью:
adb uninstall com.oculus.sdk.xreyes
cd XrSamples/XrEyes/Projects/Android
../../../../gradlew installDebug

Использование образца приложения XrEyes

Как пользователь, открыв пример приложения, вы увидите таблицу с привязкой к миру, которая содержит записи данных о взгляде для обоих глаз. Для каждого глаза вращение указано в 4 кватернионах и 3 углах Эйлера вместе с положениями глаз и значением достоверности. Направление взгляда в приложении указывается в системе координат мира.
Using the XrEyes Sample App
Когда вы вращаете головой и следите за таблицей с привязкой к миру, вы заметите, что вращение глаз практически не меняется. Такое поведение ожидаемо и свидетельствует о том, что движение ваших глаз отслеживается правильно. Вместо этого, если вы подвигаете глазами и сделаете запись экрана, то вы заметите, что взгляд обновляется правильно. Вы также увидите, что значение достоверности отслеживания взгляда составляет 0,5 и не изменяется. И снова, это ожидаемо, поскольку достоверность отслеживания взгляда, обеспечиваемая трекером, в настоящее время не абсолютно надежна и установлена ​​на уровне 0,5.

Разрешения

Чтобы использовать функцию отслеживания движений глаз в своем приложении, вы должны указать разрешение "com.oculus.permission.EYE_TRACKING" в манифесте Android.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"><uses-feature android:name="oculus.software.eye_tracking" android:required="true" /><uses-permission android:name="com.oculus.permission.EYE_TRACKING" />

    ....
</manifest>
Подробнее см. в руководстве Поддержка OpenXR для гарнитур Meta Quest.
com.oculus.permission.EYE_TRACKING — это разрешение "среды выполнения", поэтому приложение должно явно запросить его у пользователя. Подробнее о разрешениях среды выполнения см. в статье Разрешения среды выполнения. Вот пример основного действия для обработки разрешений:
  private static final String PERMISSION_EYE_TRACKING = "com.oculus.permission.EYE_TRACKING";
  private static final int REQUEST_CODE_PERMISSION_EYE_TRACKING = 1;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestEyeTrackingPermissionIfNeeded();
  }

  private void requestEyeTrackingPermissionIfNeeded() {
    if (checkSelfPermission(PERMISSION_EYE_TRACKING) != PackageManager.PERMISSION_GRANTED) {
      requestPermissions(
          new String[] {PERMISSION_EYE_TRACKING}, REQUEST_CODE_PERMISSION_EYE_TRACKING);
    }
  }

Расширение для отслеживания движений глаз

XR_FB_eye_tracking_social вводит расширение для включения социальных приложений, отличное от существующего расширения XR_EXT_eye_gaze_interaction, которое предназначено для включения взаимодействия с помощью взгляда. Расширение XR_FB_eye_tracking_social предоставляет вам направление взгляда каждого из глаз вместе с их соответствующим положением. Кроме того, значение достоверности взгляда каждого глаза также выводится как число с плавающей точкой в ​​диапазоне [0, 1], хотя в настоящее время оно зафиксировано как 0,5. Поскольку социальные приложения основаны на фиксации взгляда на точке или человеке в пространстве, направление взгляда обоих глаз временно сглаживается и обязательно сходится перед пользователем.
Поскольку отслеживание движения глаз осуществляется с помощью специальных датчиков на устройстве, API поддерживается на Meta Quest Pro, но не поддерживается на Meta Quest 2 и более старых устройствах, которые не оснащены такими датчиками.
Полную справку по API см. в статье Справочник по API движения.

Настройка

Добавление заголовков

Добавьте в исходный код следующий заголовок для отслеживания движений глаз:
   #include <openxr/openxr.h>

Инициализация OpenXR

Перед использованием отслеживания движений глаз необходимо инициализировать сеанс OpenXR и включить расширение. Подробнее об инициализации сеанса см. в статье Создание экземпляров и сеансов.

Инициализация

Прежде чем приложение получит доступ к функциям определенного расширения OpenXR, необходимо создать сеанс OpenXR и включить требуемое расширение OpenXR. Эта часть приложения служит общей для всех расширений.
Во время инициализации вы можете создать следующий набор объектов, который будет общим для всех расширений OpenXR приложения:
XrInstance instance;
XrSystemId system;
XrSession session;
XrSpace sceneSpace;
Подробнее см. в заголовке SampleXrFramework/Src/XrApp.h в Oculus OpenXR Mobile SDK.
Процесс описан в спецификации OpenXR:
Подробнее о реализации см. в SampleXrFramework/Src/XrApp.cpp в Oculus OpenXR Mobile SDK.

Включение расширений

Все расширения должны быть явно перечислены для создания XrInstance:
std::vector<const char*> extensions;

// ...

XrInstance Instance = XR_NULL_HANDLE;

XrInstanceCreateInfo instanceCreateInfo = {XR_TYPE_INSTANCE_CREATE_INFO};

// ...
instanceCreateInfo.enabledExtensionCount = extensions.size();
instanceCreateInfo.enabledExtensionNames = extensions.data();

// ...
OXR(initResult = xrCreateInstance(&instanceCreateInfo, &Instance));
Подробнее о реализации см. в SampleXrFramework/Src/XrApp.cpp в Oculus OpenXR Mobile SDK.

Инициализация отслеживания движений глаз

Необходимо инициализировать расширение OpenXR один раз и использовать его совместно со всеми вызовами OpenXR API. Если вы сделаете это успешно, у вас будут следующие данные:
    XrSession Session;
    XrSpace StageSpace;
Подробнее см. в заголовке SampleXrFramework\Src\XrApp.h.
В качестве имени расширения рекомендуется использовать константу XR_FB_EYE_TRACKING_SOCIAL_EXTENSION_NAME.

Проверка совместимости

Необходимо проверить, поддерживает ли гарнитура пользователя отслеживание движений глаз. Для этого XrInstance необходимо получить системные свойства, вызвав функцию xrGetSystemProperties, чтобы это проверить.
Для этого используйте структуру XrSystemEyeTrackingPropertiesFB, которая описывает, поддерживает ли система отслеживание движений глаз. Ниже приводится определение.
typedef struct XrSystemEyeTrackingPropertiesFB {
   XrStructureType type;
   void* XR_MAY_ALIAS next;
   XrBool32 supportsEyeTracking;
} XrSystemEyeTrackingPropertiesFB;
Подробнее об этой структуре см. XrSystemEyeTrackingPropertiesFB в Справочнике по Movement API.
В следующем примере показано, как проверить поддержку отслеживания движений глаз.
        XrSystemEyeTrackingPropertiesFB eyeTrackingSystemProperties{
            XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB};
        XrSystemProperties systemProperties{
            XR_TYPE_SYSTEM_PROPERTIES, &eyeTrackingSystemProperties};
        OXR(xrGetSystemProperties(GetInstance(), GetSystemId(), &systemProperties));
        if (!eyeTrackingSystemProperties.supportsEyeTracking) {
            return;
        }
Если поле eyeTrackingSystemProperties структуры XrSystemEyeTrackingPropertiesFB возвращает значение true, отслеживание движений глаз поддерживается.

Получение указателей функций

Чтобы создать трекер движений глаз, необходимо получить ссылки на все функции расширения перед его использованием. Подробнее см. в разделе xrGetInstanceProcAddr в спецификации OpenXR. Вот пример того, как этого можно достичь.
    PFN_xrCreateEyeTrackerFB xrCreateEyeTrackerFB_ = nullptr;
    PFN_xrDestroyEyeTrackerFB xrDestroyEyeTrackerFB_ = nullptr;
    PFN_xrGetEyeGazesFB xrGetEyeGazesFB_ = nullptr;

        OXR(xrGetInstanceProcAddr(
            GetInstance(), "xrCreateEyeTrackerFB", (PFN_xrVoidFunction*)(&xrCreateEyeTrackerFB_)));
        OXR(xrGetInstanceProcAddr(
            GetInstance(),
            "xrDestroyEyeTrackerFB",
            (PFN_xrVoidFunction*)(&xrDestroyEyeTrackerFB_)));
        OXR(xrGetInstanceProcAddr(
            GetInstance(), "xrGetEyeGazesFB", (PFN_xrVoidFunction*)(&xrGetEyeGazesFB_)));

Использование расширения

Создание трекера движений глаз

Вы можете создать трекер движений глаз, вызвав функцию xrCreateEyeTrackerFB. Эта функция используется для создания и получения дескриптора XrEyeTrackerFB к трекеру движений глаз. Определение функции следующее:
XrResult xrCreateEyeTrackerFB(
	XrSession session,
	const XrEyeTrackerCreateInfoFB* createInfo,
	XrEyeTrackerFB* eyeTracker);
Для вызова этой функции необходимо использовать структуру XrEyeTrackerCreateInfoFB, которая описывает запрошенные функциональные возможности для создания трекера движений глаз. Определение структуры следующее:
typedef struct XrEyeTrackerCreateInfoFB {
   XrStructureType type;
   const void* XR_MAY_ALIAS next;
} XrEyeTrackerCreateInfoFB;
Подробнее см. XrEyeTrackerCreateInfoFB в Справочнике по Movement API. Следующий пример демонстрирует, как их использовать.
   XrEyeTrackerFB eyeTracker_ = XR_NULL_HANDLE;
         XrEyeTrackerCreateInfoFB createInfo{XR_TYPE_EYE_TRACKER_CREATE_INFO_FB};
         OXR(xrCreateEyeTrackerFB_(GetSession(), &createInfo, &eyeTracker_));
Разрешен только один трекер движений глаз на сеанс, и многократные вызовы функции xrCreateEyeTrackerFB вернут один и тот же дескриптор. Этот дескриптор уникален для каждого процесса и не может быть общим для всех.
Важно! Для успешного вызова функций xrCreateEyeTrackerFB приложения должны запросить разрешение com.oculus.permission.EYE_TRACKING в своем манифесте, а пользователь должен предоставить это разрешение.

Извлечение данных о направлении взгляда

Данные о направлении взгляда, в том числе о положении глаза, вычисляются и предоставляются трекером движений глаз для каждого глаза. Данные о направлении взгляда, поступающие с помощью отслеживания движений глаз, будут доступны немедленно через вызов функции xrGetGazesFB после завершения вызова xrCreateEyeTrackerFB. Вызовы функции xrGetEyeGazeFB получают позицию глаз пользователя в определенное время и в определенной системе координат.
Определение функции xrGetGazesFB следующее:
XrResult xrGetEyeGazesFB(
   XrEyeTrackerFB eyeTracker,
   const XrEyeGazesInfoFB* gazeInfo,
   XrEyeGazesFB* eyeGazes);
Подробнее см. xrGetGazesFB в Справочнике по Movement API. Структура XrEyeGazesInfoFB, которая является параметром xrGetGazesFB, содержит запрошенное время и пространство для требуемых положений взгляда. Вызывающие элементы должны запрашивать время, равное прогнозируемому времени отображения кадра, для которого выполнен рендеринг. Затем система применит соответствующее моделирование, чтобы предоставить направление взгляда в это время. Определение структуры XrEyeGazesInfoFB следующее:
typedef struct XrEyeGazesInfoFB {
   XrStructureType type;
   const void* XR_MAY_ALIAS next;
   XrSpace baseSpace;
   XrTime time;
} XrEyeGazesInfoFB;
Вызов функции xrGetGazesFB возвращает структуру XrEyeGazesFB, которая содержит массив положения взгляда и уверенности для каждого глаза, а также предоставляет метки времени. Структура XrEyeGazesFB определяется следующим образом:
typedef struct XrEyeGazesFB {
   XrStructureType type;
   void* XR_MAY_ALIAS next;
   XrEyeGazeFB gaze[XR_EYE_INDEX_COUNT_FB];
   XrTime time;
} XrEyeGazesFB;
Подробнее об этой структуре см. XrEyeGazesFB в Справочнике по Movement API. Примечание. Индекс 0 массива gaze представляет левый глаз пользователя, а индекс 1 — правый глаз.
В следующем примере показано, как вызвать функцию xrGetEyeGazesFB.
XrEyeGazesFB eyeGazes{XR_TYPE_EYE_GAZES_FB};
eyeGazes.next = nullptr;

XrEyeGazesInfoFB gazesInfo{XR_TYPE_EYE_GAZES_INFO_FB};
gazesInfo.baseSpace = GetStageSpace();
gazesInfo.time = GetPredictedDisplayTime();

OXR(xrGetEyeGazesFB_(eyeTracker_, &gazesInfo, &eyeGazes));
Для использования данных отслеживания направления взгляда необходимо убедиться, что взгляд является действительным. Общий шаблон выглядит следующим образом:
for (int eye = 0; eye < 2; ++eye) {
    if (eyeGazes.gaze[eye].isValid) {
        // eyeGazes.gaze[eye].gazePose.orientation contains orientation of an eye gaze
        // eyeGazes.gaze[eye].gazeConfidence contains confidential
        ....
    }
}

Уничтожение трекера

Перед завершением приложения рекомендуется освободить ресурсы с помощью функции xrDestroyEyeTrackerFB.
OXR(xrDestroyEyeTrackerFB_(eyeTracker_));
Логотип навигации
Русский
© 2026 Meta