Ввод с взгляда на глаза в DirectX

Примечание

Эта статья связана с устаревшими собственными API-интерфейсами WinRT. Для новых проектов собственных приложений рекомендуется использовать API опенкср.

в Windows Mixed Reality для определения того, что видят пользователи, используется ввод с глазом и с помощью взгляда на голову. Данные можно использовать для управления первичными входными моделями, такими как head-взгляд и Commit, и предоставления контекста для различных типов взаимодействия. Есть два типа векторов взгляда, доступных через API: «Head-взгляд» и «глаз-взгляд». Оба объекта предоставляются в виде трехмерного луча с исходным и направленным координатами. Приложения могут райкаст в фоновом режиме или в реальном мире, а также определить назначение пользователя.

Заголовок-взгляд представляет направление, на которое указывает заголовок пользователя. Обдумайте голову как расположение и направление вперед самого устройства, в качестве центральной точки между двумя дисплеями. Головной взгляд доступен на всех устройствах смешанной реальности.

Глаз . Наблюдатель представляет направление, в котором просматриваются глаза пользователя. Источник располагается между глазами пользователя. Он доступен на устройствах смешанной реальности, включающих систему отслеживания глаз.

И те, и другие лучи доступны через API спатиалпоинтерпосе . Вызовите метод спатиалпоинтерпосе:: трижетаттиместамп , чтобы получить новый объект спатиалпоинтерпосе в указанной метке времени и системе координат. Этот Спатиалпоинтерпосе содержит источник и направление головного взгляда. Он также содержит источник глаза и направление взгляда, если отслеживание взгляда доступно.

Поддержка устройств

Компонент HoloLens (1-го поколения) HoloLens 2 Иммерсивные гарнитуры
Направление головы ✔️ ✔️ ✔️
Взгляд — взгляд ✔️

Использование Head-взгляда

Чтобы получить доступ к Head, начните с вызова спатиалпоинтерпосе:: трижетаттиместамп , чтобы получить новый объект спатиалпоинтерпосе. Передайте следующие параметры.

  • Объект спатиалкурдинатесистем , представляющий нужную систему координат для головного взгляда. Он представлен переменной курдинатесистем в следующем коде. Дополнительные сведения см. в нашем разделе, посвященном разработчику систем координат .
  • Отметка времени , представляющая точное время запроса Head. Как правило, используется метка времени, соответствующая времени, когда будет отображаться текущий кадр. Эту прогнозируемую отметку экрана можно получить из объекта холографикфрамепредиктион , доступного через текущий холографикфраме. Этот объект Холографикфрамепредиктион представляется переменной прогноза в следующем коде.

После получения допустимого Спатиалпоинтерпосе расположение головного и прямого направления можно получить в виде свойств. В следующем коде показано, как получить доступ к ним.

using namespace winrt::Windows::UI::Input::Spatial;
using namespace winrt::Windows::Foundation::Numerics;

SpatialPointerPose pointerPose = SpatialPointerPose::TryGetAtTimestamp(coordinateSystem, prediction.Timestamp());
if (pointerPose)
{
   float3 headPosition = pointerPose.Head().Position();
   float3 headForwardDirection = pointerPose.Head().ForwardDirection();

   // Do something with the head-gaze
}

Использование глаза-взгляд

Чтобы пользователи могли использовать ввод с глазным взглядом, каждый пользователь должен пройти по калибровке пользователя с отслеживанием взгляда при первом использовании устройства. API взгляда на глаза похож на «голова-взгляд». Он использует тот же API спатиалпоинтерпосе , который предоставляет происхождение и направление луча, которые можно райкаст на сцене. Единственное отличие заключается в том, что необходимо явно включить отслеживание взгляда перед его использованием:

  1. Запрос разрешения пользователя на использование отслеживания взгляда в приложении.
  2. Включите функцию "Ввод взгляда" в манифесте пакета.

Запрос доступа к входным данным взгляда

При запуске приложения вызовите эйеспосе:: рекуестакцессасинк , чтобы запросить доступ к отслеживанию глаз. Система запросит пользователя при необходимости и возвратит газеинпутакцессстатус:: Allowed после предоставления доступа. Это асинхронный вызов, поэтому для него требуется некоторое дополнительное управление. В следующем примере показано, как отсоединить отсоединенный std:: Thread для ожидания результата, который он сохраняет в переменную-член с именем m_isEyeTrackingEnabled.

using namespace winrt::Windows::Perception::People;
using namespace winrt::Windows::UI::Input;

std::thread requestAccessThread([this]()
{
    auto status = EyesPose::RequestAccessAsync().get();

    if (status == GazeInputAccessStatus::Allowed)
        m_isEyeTrackingEnabled = true;
    else
        m_isEyeTrackingEnabled = false;
});

requestAccessThread.detach();

Запуск отсоединенного потока — это только один вариант для обработки асинхронных вызовов. Можно также использовать новые функции co_await , поддерживаемые C++/винрт. Вот еще один пример для запроса разрешения пользователя:

  • Эйеспосе:: An () позволяет приложению активировать диалоговое окно разрешения только при наличии средства записи глаз.
  • Газеинпутакцессстатус m_gazeInputAccessStatus; Это позволяет предотвратить повторное извлечение запроса на разрешение.
GazeInputAccessStatus m_gazeInputAccessStatus; // This is to prevent popping up the permission prompt over and over again.

// This will trigger to show the permission prompt to the user.
// Ask for access if there is a corresponding device and registry flag did not disable it.
if (Windows::Perception::People::EyesPose::IsSupported() &&
   (m_gazeInputAccessStatus == GazeInputAccessStatus::Unspecified))
{ 
    Concurrency::create_task(Windows::Perception::People::EyesPose::RequestAccessAsync()).then(
    [this](GazeInputAccessStatus status)
    {
        // GazeInputAccessStatus::{Allowed, DeniedBySystem, DeniedByUser, Unspecified}
            m_gazeInputAccessStatus = status;
        
        // Let's be sure to not ask again.
        if(status == GazeInputAccessStatus::Unspecified)
        {
                m_gazeInputAccessStatus = GazeInputAccessStatus::DeniedBySystem;    
        }
    });
}

Объявление возможности ввода с помощью взгляда

Дважды щелкните файл AppxManifest в Обозреватель решений. Затем перейдите к разделу возможностей и проверьте возможность ввода с помощью средства выбора.

Возможность ввода с клавиатуры

В раздел пакета в файле appxmanifest добавляются следующие строки:

  <Capabilities>
    <DeviceCapability Name="gazeInput" />
  </Capabilities>

Получение луча с глазом взгляда

После получения доступа к ET вы можете бесплатно захватить каждый кадр. Как и в случае с Head-взглядом, получите спатиалпоинтерпосе , вызвав Спатиалпоинтерпосе:: трижетаттиместамп с нужной меткой времени и системой координат. Спатиалпоинтерпосе содержит объект эйеспосе через свойство глаза . Это значение не равно null, только если включено отслеживание глаз. После этого можно проверить, имеет ли пользователь устройства калибровку отслеживания взгляда, вызвав эйеспосе:: искалибратионвалид. Затем Используйте свойство "наблюдатель", чтобы получить спатиалрай , содержащий расположение и направление взгляда. Свойство "взгляд" иногда может иметь значение null, поэтому обязательно проверьте это. Это может произойти, если калибровка пользователя временно закрывает свои глаза.

В следующем коде показано, как получить доступ к лучау глаза.

using namespace winrt::Windows::UI::Input::Spatial;
using namespace winrt::Windows::Foundation::Numerics;

SpatialPointerPose pointerPose = SpatialPointerPose::TryGetAtTimestamp(coordinateSystem, prediction.Timestamp());
if (pointerPose)
{
    if (pointerPose.Eyes() && pointerPose.Eyes().IsCalibrationValid())
    {
        if (pointerPose.Eyes().Gaze())
        {
            auto spatialRay = pointerPose.Eyes().Gaze().Value();
            float3 eyeGazeOrigin = spatialRay.Origin;
            float3 eyeGazeDirection = spatialRay.Direction;
            
            // Do something with the eye-gaze
        }
    }
}

Откат, когда отслеживание глаз недоступно

Как упоминалось в документах по проектированию отслеживания взгляда, проектировщики и разработчики должны знать экземпляры, в которых данные отслеживания взгляда могут быть недоступны.

Существуют различные причины недоступности данных.

  • Пользователь не откалиброван
  • Пользователь отклонил доступ к данным отслеживания взгляда на приложение.
  • временные помехи, такие как палец на HoloLensе делители или волосы, окклудинг глаз пользователя.

Хотя некоторые API-интерфейсы уже упоминались в этом документе, в следующей статье мы предоставляем сводку о том, как определить, что отслеживание взгляда доступно в качестве краткого справочника:

Кроме того, можно проверить, не устарели ли данные отслеживания взгляда, добавив время ожидания между полученными обновлениями данных отслеживания взгляда и иным образом выполнить откат до головного взгляда, как описано ниже.
Дополнительные сведения см. в разделе рекомендации по проектированию резервного проектирования .


Сопоставление взгляда с другими входными данными

Иногда может оказаться, что требуется спатиалпоинтерпосе , соответствующий событию в прошлом. Например, если пользователь выполняет касание Air, ваше приложение может захотеть узнать, что именно оно искало. Для этой цели простое использование спатиалпоинтерпосе:: трижетаттиместамп с прогнозируемым временем кадров будет неточным из-за задержки между системной обработкой входных данных и временем вывода. Кроме того, если для нацеливания используется глаз, наши глаза, как правило, переходят даже перед завершением действия фиксации. Это не является проблемой для простого касания воздуха, но становится более важным при объединении длинных голосовых команд с помощью передвижений с быстрым глазом. Одним из способов решения этого сценария является создание дополнительного вызова спатиалпоинтерпосе:: трижетаттиместампс использованием метки времени с предысторией, соответствующей входному событию.

Однако для входных данных, перенаправляющихся через Спатиалинтерактионманажер, существует более простой метод. Спатиалинтерактионсаурцестате имеет собственную функцию трижетаттиместамп . Вызов, который предоставит вполне коррелированный спатиалпоинтерпосе без предоставляя. Дополнительные сведения о работе с Спатиалинтерактионсаурцестатес см. в документации по DirectX .


Калибровка

Чтобы отслеживание отслеживания проработало правильно, каждый пользователь должен пройти по калибровке пользователя с отслеживанием взгляда. Это позволяет устройству настроить систему для более удобного и качественного просмотра для пользователя, а также для обеспечения точного отслеживания в то же время. Разработчикам не нужно ничего делать на своих концах для управления калибровкой пользователей. Система обеспечит пользователю запрос на калибровку устройства в следующих случаях:

  • Пользователь использует устройство впервые.
  • Пользователь ранее отказался от калибровки.
  • Не удалось выполнить калибровку в последний раз, когда пользователь работал с устройством.

Разработчикам следует обеспечить необходимую поддержку для пользователей, в которых данные отслеживания взгляда могут быть недоступны. Дополнительные сведения см. в разделе рекомендации по отслеживаниюрешений на HoloLens 2.


См. также раздел