Впервые на русском: Документация Oculus для разработчиков. Руководство ПК SDK для разработчика. Инициализация и перечень сенсоров

Продолжаем публикацию эксклюзивной информации для разработчиков от Oculus. Новый раздел посвящён инициализации и перечню сенсоров. 

  1. Документация Oculus для разработчиков:
    1. Введение в рекомендации
    2. Бинокулярное зрение, стереоскопическая визуализация и индикаторы глубины
    3. Поле зрения и масштаб
    4. Методы рендеринга
    5. Движение
    6. Отслеживание
    7. «Болезнь симуляции»
    8. Пользовательский интерфейс
    9. Пользовательский ввод и навигация
    10. Заключение
    11. Введение в SDK для ПК
    12. Руководство разработчика
    13. Руководство по началу работы с ПК SDK
    14. Руководство ПК SDK для разработчика. Интеграция LibOVR
    15. Инициализация и перечень сенсоров
    16. Рендеринг в Oculus Rift
    17. Расширенная настройка рендеринга
    18. Управление связью с виртуальной реальностью
    19. Система безопасности Oculus Guardian
    20. Аудио Oculus Rift
    21. Контроллеры Oculus Touch
    22. Дополнительная информация об Oculus Touch
    23. Примеры использования SDK и геймпада
    24. Оптимизация вашего приложения
    25. Подключение контроллеров Oculus Touch
    26. Асинхронный SpaceWarp
    27. Дополнительная информация о подключении контроллеров Oculus Touch
    28. Справочная информация

Чтобы оставаться в курсе новостей о виртуальной реальности, подписывайтесь на наш Telegram!

В этом примере инициализируется LibOVR и запрашивается информация о доступном шлеме виртуальной реальности.

Просмотрите следующий код:

 

// Include the OculusVR SDK

#include <OVR_CAPI.h>

void Application()

{

ovrResult result = ovr_Initialize(nullptr);

if (OVR_FAILURE(result))

return;

 

ovrSession session;

ovrGraphicsLuid luid;

result = ovr_Create(&session, &luid);

if (OVR_FAILURE(result))

{

ovr_Shutdown();

return;

}

 

ovrHmdDesc desc = ovr_GetHmdDesc(session);

ovrSizei resolution = desc.Resolution;

 

ovr_Destroy(session);

ovr_Shutdown();

}

Как вы можете видеть, ovr_Initialize вызывается перед любыми другими функциями API, а ovr_Shutdown вызывается для завершения работы библиотеки перед выходом из программы. В промежутках между этими вызовами функций вы можете создавать объекты шлема виртуальной реальности, контролировать состояние отслеживания и выполнять рендеринг приложения.

В этом примере ovr_Create(&session &luid) создает шлем виртуальной реальности. Используйте LUID, возвращаемый функцией ovr_Create(), для того, чтобы выбрать IDXGIAdapter, на котором создается ваш ID3D11Device или ID3D12Device. В конце необходимо вызвать ovr_Destroy для того, чтобы очистить шлем виртуальной реальности перед завершением работы библиотеки.

Вы можете использовать ovr_GetHmdDesc() для того, чтобы получить описание шлема виртуальной реальности.

Если Oculus Rift не подключен, ovr_Create(&session, &luid) возвращает сбившийся ovrResult, если виртуальный шлем виртуальной реальности не подключён через RiftConfigUtil. Хотя виртуальный шлем виртуальной реальности не будет подключать какой-либо сенсор, он может быть полезен для отладки кода рендеринга, совместимого с Oculus Rift, а также для общей разработки без физического устройства.

Описание дескриптора шлема виртуальной реальности (ovrHmdDesc) можно получить, вызвав ovr_GetHmdDesc(session). Ниже описаны поля:

  • Type (ovrHmdType): тип шлема виртуальной реальности, например, ovr_DK2 или ovr_DK2.
  • ProductName (char[]): название продукта в виде строки.
  • Manufacturer (char[]): название производителя.
  • VendorId (short): идентификатор поставщика, который передаётся с USB-устройства шлема.
  • ProductId (short): идентификатор продукта, который передаётся с USB-устройства шлема.
  • SerialNumber (char[]): строка серийного номера, который передаётся с USB-устройства шлема.
  • FirmwareMajor (short): основная версия прошивки сенсора.
  • FirmwareMinor (short): дополнительная версия прошивки сенсора.
  • AvailableHmdCaps (unsigned int): биты возможностей, которые описываются в ovrHmdCaps, которые в настоящее время поддерживает шлем виртуальной реальности.
  • DefaultHmdCaps (unsigned int): биты возможностей по умолчанию, которые описываются в ovrHmdCaps, которые в настоящее время поддерживает шлем виртуальной реальности.
  • AvailableTrackingCaps (unsigned int): биты возможностей, которые описываются в ovrTrackingCaps, которые в настоящее время поддерживает шлем виртуальной реальности.
  • DefaultTrackingCaps (unsigned int): биты возможностей по умолчанию, которые описываются в ovrTrackingCaps, которые в настоящее время поддерживает шлем виртуальной реальности.
  • DefaultEyeFov (ovrFovPort[]): рекомендуемое оптическое поле зрения для каждого глаза.
  • MaxEyeFov (ovrFovPort[]): максимальное оптическое поле зрения, которое можно на практике визуализировать для каждого глаза.
  • Resolution (ovrSizei): разрешение полного экрана шлема виртуальной реальности (оба глаза) в пикселях.
  • DisplayRefreshRate (float): номинальная частота обновления шлема виртуальной реальности в циклах в секунду во время создания шлема виртуальной реальности.

Описание дескриптора сенсора (ovrTrackerDesc) можно получить, вызвав ovr_GetTrackerDesc(sensor). Ниже описаны поля:

  • FrustumHFovInRadians (float): горизонтальное поле зрения усечённого позиционного сенсора.
  • FrustumVFovInRadians (float): вертикальное поле зрения усечённого позиционного сенсора.
  • FrustumNearZInMeters (float): расстояние от положения сенсора до границ около усечённого конуса.
  • FrustumNearZInMeters (float): расстояние от положения сенсора до крайних усечённых границ.
Отслеживание головы и сенсоры

Аппаратная часть Oculus Rift содержит ряд микроэлектромеханических (MEMS) датчиков, среди которых гироскоп, акселерометр и магнитометр.

Существует также сенсор для отслеживания положения шлема виртуальной реальности. Информация от каждого из этих сенсоров объединяется посредством процесса слияния сенсоров для определения движения головы пользователя в реальном мире и синхронизации представления пользователя в режиме реального времени.

После создания ovrSession вы можете проверить слияние сенсора для положения головы и ориентации, вызывая ovr_GetTrackingState. Эти вызовы можно продемонстрировать в следующем коде:

 

// Query the HMD for ts current tracking state.

ovrTrackingState ts = ovr_GetTrackingState(session, ovr_GetTimeInSeconds(), ovrTrue);

 

if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked))

{

ovrPosef pose = ts.HeadPose.ThePose;

}

В этом примере инициализируются сенсоры с ориентацией, коррекцией искажения и возможностью отслеживания положения. Если сенсор недоступен во время вызова, но подключается позже, сенсор автоматически активируется SDK.

После инициализации сенсоров состояние сенсора доступно путем вызова ovr_GetTrackingState. Это состояние включает прогнозируемую позу головы и текущее состояние отслеживания шлема виртуальной реальности, что описывается с помощью StatusFlags. Это состояние может изменяться во время рантайма на основе доступных устройств и поведения пользователя. Например, the ovrStatus_PositionTracked передаётся только тогда, когда HeadPose включает в себя данные полного позиционного отслеживания от сенсора.

Упомянутый ovrPoseStatef включает в себя полные данные отслеживания головы шести степеней свободы (6DoF), включая ориентацию, позицию и их первую и вторую производные. Значение позиции сообщается для заданного точного момента времени с использованием прогноза, как правило, соответствующего времени в будущем, чтобы изображение этого кадра отображалось на экране. Для облегчения прогнозирования ovr_GetTrackingState принимает точное время в секундах в качестве второго аргумента. Текущее значение абсолютного времени может быть получено вызовом ovr_GetTimeInSeconds. Если время, прошедшее в ovr_GetTrackingState, является текущим временем или более ранним, состояние отслеживания возвращается и будет основано на последних показаниях сенсора без прогнозирования. Тем не менее в приложении по производству контента вы должны использовать вычисленное в реальном времени значение, возвращаемое GetPredictedDisplayTime. Прогнозирование более подробно рассматривается в разделе «Временные рамки».

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

Рисунок 3. Система координат Oculus Rift

Плоскость x-z совмещена с землёй независимо от ориентации камеры.

Как видно из диаграммы, система координат использует следующие определения осей:

  • Y является положительным в направлении вверх.
  • X является положительным в направлении направо.
  • Z является положительным в направлении назад.

Вращение поддерживается как единичный кватернион, однако также оно может быть представлено в форме поворотов-наклонов. Положительное вращение против часовой стрелки (CCW, направление стрелок вращения на диаграмме) при поиске в отрицательном направлении каждой оси и вращении компонента:

  • Pitch – это поворот вокруг X, положительный при качке вверх.
  • Yaw – это поворот вокруг Y, положительный при повороте налево.
  • Roll – это поворот вокруг Z, положительный при наклоне влево в плоскости XY.

Самый простой способ извлечения yaw-pitch-roll из ovrPose – это использование вспомогательных классов C++ OVR Math, которые входят в библиотеку. В следующем примере используется прямое преобразование для того, чтобы назначить ovrPosef эквивалентному классу C++ Posef. Затем вы можете использовать Quatf::GetEulerAngles<> для получения углов Эйлера в нужном порядке вращения оси.

Все простые типы C math, предоставляемые OVR, такие как ovrVector3f и ovrQuatf, имеют соответствующие типы C++, которые предоставляют конструкторы и операторы для удобства. Эти типы могут использоваться взаимозаменяемо.

Если приложение использует левостороннюю систему координат, оно может использовать функцию ovrPosef_FlipHandedness для переключения любого правостороннего ovrPosef, предоставляемого функциями ovr_GetTrackingState, ovr_GetEyePoses или ovr_CalcEyePoses, которые должны быть левосторонними. Имейте в виду, что RenderPose и QuadPoseCenterrequested, которые запрашиваются для ovrLayers, должны по-прежнему использовать правую систему координат.

Позиционное отслеживание

Усеченный конус определяется горизонтальным и вертикальным полем обзора, а также расстоянием от передней и до задней плоскостей усечённого конуса.

Приближенные значения для этих параметров можно получить через структуру ovrTrackerDesc следующим образом:

 

ovrSession session;

ovrGraphicsLuid luid;

if(OVR_SUCCESS(ovr_Create(&session, &luid)))

{

// Extract tracking frustum parameters.

float frustomHorizontalFOV = session->CameraFrustumHFovInRadians;

На следующем рисунке показан сенсор отслеживания и представление результирующей усечённой траектории слежения.

Рисунок 4. Отслеживание сенсора и отслеживания усечённого конуса

Ниже перечислены соответствующие параметры и типовые значения:

  • FrustumHFovInRadians (float): 1.292 радиан (74 градусов)
  • FrustumVFovInRadians (float): 0.942 радиан (54 градусов)
  • FrustumNearZInMeters              (float): 0.4 м
  • FrustumFarZInMeters (float): 2.5 м

Эти параметры дают разработчикам приложений визуальное представление траектории слежения. На предыдущем рисунке также показано исходное место отслеживания и связанная с ним система координат.

Примечание: Несмотря на то, что ось сенсора (и, следовательно, усечённая направляющая) слегка наклоняется вниз, система координат позиционного отслеживания всегда ориентирована горизонтально так, что оси параллельны земле.

По умолчанию источник позиционного отслеживания находится на расстоянии одного метра от сенсора в направлении оптической оси, но с той же высотой, что и сенсор. Начальная ориентация по умолчанию – уровень земли, отрицательная ось указывает на сенсор. Другими словами, угол поворота шлема виртуальной реальности, равный нулю, соответствует пользователю, смотрящему на сенсор.

Это можно изменить с помощью вызова API ovr_RecenterTrackingOrigin, который сбрасывает начало позиционного отслеживания в текущее местоположение шлема виртуальной реальности и задает исходное положение поворота текущему значению поворота в шлеме виртуальной реальности. Кроме того, его можно указать вручную в любом месте с помощью вызова API ovr_SpecifyTrackingOrigin.

Существует два типа источника позиционного отслеживания: уровень пола и уровень глаз. Уровень пола рекомендуется для масштабирования в помещении, когда пользователь стоит и когда пользователь взаимодействует с объектами на полу (хотя телекинез/силовой захват/захват взглядом – лучший вариант для захвата объектов). Для большинства других случаев, особенно когда пользователь сидит, предпочтение отдается уровню глаза. Чтобы получить текущий источник, используйте ovr_GetTrackingOriginType. Чтобы установить источник, используйте ovr_SetTrackingOriginType.

Примечание: Источник позиционного отслеживания устанавливается для каждого приложения; переключение фокуса между различными VR-приложениями также переключает источник позиционного отслеживания.

Поза головы возвращается при вызыве ovr_GetTrackingState. Возвращённая структура ovrTrackingState содержит несколько элементов, относящихся к отслеживанию позиции:

HeadPose включает положение головы и ориентацию.

Pose – поза сенсора относительно начала отслеживания.

CalibratedOrigin – поза источника, предварительно откалиброванная пользователем и сохранённая в профиле, который указан в новом зарегистрованном пространстве источника позиционного отслеживания. Это значение может измениться, когда приложение вызывает ovr_RecenterTrackingOrigin, хотя оно относится к одному и тому же местоположению в реальном мире. В противном случае он будет оставаться в качестве идентичной позы. Различные типы источника отслеживания сообщают о различных позах CalibrateOrigin, поскольку начало калибровки относится к фиксированной позиции в реальном мире, но два типа источника отслеживания относятся к разным уровням Y.

Переменная StatusFlags содержит следующие биты состояния, связанные с отслеживанием положения:

  • ovrStatus_PositionTracked – переменная, которая устанавливается только при активной проверке шлеме виртуальной реальности.

Существует несколько условий, которые могут привести к прерыванию отслеживания положения и к тому, чтобы переменная стала нулевой:

  • Шлем виртуальной реальности полностью или частично перемещается за пределы усечённого конуса.
  • Шлем виртуальной реальности принимает ориентацию, которую трудно отследить с помощью текущего оборудования (например, при взгляде, который направляется прямо от сенсора).
  • Внешняя сторона шлема виртуальной реальности частично или полностью закрыта с точки зрения сенсора (например, волосами или руками).
  • Скорость шлема виртуальной реальности превышает ожидаемый диапазон.

После прерывания в отслеживании, если вышеперечисленные условия больше неактуальны, отслеживание обычно возобновляется достаточно быстро и устанавливается переменная ovrStatus_PositionTracked

Если вы хотите получить позу и выровненную позу сенсора, вызовите ovr_GetTrackerPose. Возвращённая структура ovrTrackerPose содержит следующее:

  • Pose – поза сенсора относительно начала отслеживания.
  • LeveledPose – поза сенсора относительно начала отслеживания, но с нулевым креном и шагом. Вы можете использовать это как ориентир для визуализации объектов реального мира в нужном месте.
Интеграция ввода пользователя

Чтобы обеспечить наиболее комфортный, интуитивно понятный и удобный интерфейс для игрока, отслеживание головы должно быть интегрировано с существующей схемой управления для большинства приложений.

Например, в игре-шутере от первого лица (FPS) игрок обычно перемещается вперёд, назад, влево и вправо с помощью левого джойстика и смотрит с помощью правого джойстика влево, вправо, вверх и вниз. Используя Oculus Rift, игрок теперь может смотреть влево, вправо, вверх и вниз, используя свою голову. Тем не менее, от игроков не требуется часто поворачивать голову на 180 градусов, так как это создает неудачный пользовательский интерфейс. Как правило, им нужен способ переориентировать себя таким образом, чтобы им всегда было комфортно (так же, как мы поворачиваем наши тела, если хотим оглянуться позади себя и бросить более краткий взгляд).

Вкратце, разработчики должны тщательно обдумать свои схемы управления и то, как интегрировать отслеживание головы при разработке приложений для виртуальной реальности. Приложение OculusRoomTiny предоставляет образец исходного кода, который показывает, как интегрировать отслеживание головы Oculus с вышеупомянутой стандартной схемой управления от первого лица.

Для получения дополнительной информации о хорошей и плохой практике, обратитесь к «Практическим рекомендациям».

Предупреждение о безопасности и здоровье

Все приложения, использующиеся для Oculus Rift, периодически отображают предупреждение о безопасности и здоровье.

Это предупреждение появляется в течение короткого промежутка времени, когда пользователь носит Oculus Rift; его можно пропустить нажатием клавиши или управлением взглядом, указав на подтверждение. После закрытия окна оно не должно отображаться в течение как минимум 30 минут.

 

Примечание: Данный материал представлен для ознакомления, при перепечатывании ссылка на оригинал обязательна. Если вы хотите принять участие в помощи проекту, пишите на editor@vrgeek.ru

 

Если вы разработчик и вы хотите продолжить свою карьеру в лучших компаниях России, пишите на editor@vrgeek.ru с пометкой «Работа мечты», и мы поможем вам с этим.