Как разрабатывать приложения смешанной реальности для Microsoft HoloLens: взаимодействие с окружающим пространством

В предыдущей части мы создали нашу первую голограмму и научились с ней взаимодействовать. Теперь мы соединим нашу голограмму с реальным миром.

Смешанная реальность

Как было отмечено в первой части, Hololens — это устройство, позволяющее комбинировать реальный и виртуальный мир. Представьте, что можно поместить у себя на стене таблицу Менделеева или поставить на столе макет дома. В прошлый раз мы с вами создали голограмму автомобиля и научились с ней взаимодействовать.

Однако автомобиль каждый раз появляется на одном и том же месте, что не очень удобно. Можно, конечно, воспользоваться классом GestureTest и перетащить автомобиль в любую точку окружающего пространства. Но проблема в том, что часть автомобиля может оказаться за стеной. Или вы захотите поставить его на пол. А теперь представьте: вы захотите написать игру, в которой из стен должны появляться враги и нападать на пользователя (аналог — RoboRaid). Иными словами, вы хотите, чтобы голограммы взаимодействовали с объектами реального мира, а объекты реального мира — с голограммами. В таких случаях необходимо обладать информацией об окружающем пространстве.

В Hololens есть 4 камеры для анализа поверхностей, а также камера глубины и IMU-сенсор, благодаря чему можно провести очень точный геометрический анализ окружающего пространства: стен, столов, стульев и даже человеческого тела. При этом данные сохраняются на устройстве и обновляются по мере необходимости. Представьте, что можно без проблем расположить голограмму на голове ничего не подозревающего товарища.

Spatial Mapping

Процесс комбинирования голограмм и реального мира называется Spatial Mapping. Сначала приложение предоставляет устройству ограничитель, выполненный в виде многогранника, который отвечает за свою часть пространства. По мере сканирования ограничитель формирует набор полигонов. Чем больше полигонов, тем точнее геометрические данные и тем больше нагрузка на устройство. Так, например, на картинке сверху считывание идёт из расчёта 500 полигонов на кубический метр.

Непрерывное перемещение пользователя в пространстве и изменение положения объектов (например, передвижение стола) также влияют на точность Spatial Mapping. При разработке приложений это необходимо учитывать. Затем на основе полигонов определяются типы поверхностей, будь то пол, стол или стена, и вы сможете научить голограммы взаимодействовать с ними.

Spatial Anchor

Положение голограмм в пространстве можно фиксировать, присваивая им объекты Spatial Anchor (далее по тексту — пространственные якоря). Таким образом, при следующей загрузке приложения вы сможете увидеть их ровно на том же месте, на котором оставили в прошлый раз.

Spatial Mapping в Unity

HoloToolkit содержит готовые компоненты для работы со Spatial Mapping, основными из которых являются:

  1. Spatial Mapping, основной компонент.
  2. Remote Mapping, позволяющий делиться данными об окружающем пространстве.
  3. Spatial Understanding — решение, предоставленное разработчиками «Young Conker», позволяет получить более детальный анализ поверхностей. Что значит более детальный? Это значит, что ваши стены, пол и потолок разбиваются на плоскости, что позволяет оптимизировать положение голограмм.

В части 2 мы добавили SpatialPerceptions в Capabilities. Если вы ещё не сделали этого, сделайте, т.к. иначе Spatial Mapping работать не будет. Если вы хотите впоследствии работать с Remote Mapping, включите в Capabilites поддержку сети. Добавьте в сцену префаб SpatialMapping.

Основными компонентами префаба являются три скрипта:

  1. SpatialMappingObserver. Является оболочкой для Surface Observer, сканера поверхностей. Позволяет задать количество полигонов на кубометр, объём в пространстве (наш ограничитель) и частоту обновлений.
  2. ObjectSurfaceObserver. Позволяющий загрузить в Unity модель комнаты.
  3. SpatialMappingManager. Управляет текущим источником поверхностей, т.е. компонентами 1) и 2). Позволяет настраивать параметры отображения и материал для поверхности.

Первым делом добавьте модель комнаты в ObjectSurfaceObserver. Во вкладке Project в строке поиска введите «SRMesh«. Добавьте его в поле Room Model. После этого вы должны увидеть в Unity следующую картину:

Это — наша тестовая комната. Вы можете загрузить свою собственную модель комнаты. О том, как это можно сделать, я расскажу в следующей части.
Настройте префаб так же, как на картинке. Обязательно отключите AutoStartObserver, мы будем делать это из кода.

Создайте пустой объект, добавьте скрипт SurfaceMeshesToPlane. Скрипт позволяет отобразить доступные для работы поверхности в виде объекта SurfacePlane. Вы можете указать скрипту, какие поверхности отобразить, а какие удалить.

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

Если вы не удаляли поверхности, то должны увидеть следующую картину в Unity (белая поверхность — пол, синяя — стол):

Попробуем установить автомобиль на горизонтальную поверхность. В первую очередь добавьте компонент BoxCollider родительскому элементу автомобиля. Настройте коллайдер так, чтобы автомобиль полностью находился внутри. Напишем скрипт, реализующий данную возможность:

Теперь автомобиль будет двигаться вместе с вами по комнате. Каким образом вы будете его устанавливать — голосом или жестами — зависит от вас. Как это сделать вы уже знаете.

SpatialAnchor в Unity

Для работы с пространственными якорями в Unity есть специальный компонент WorldAnchor, а также класс WorldAnchorStore, предназначенный для сохранения якорей на устройстве.

Теперь представьте: вот вы установили один раз автомобиль и хотите, чтобы он оставался на том же самом месте и при следующем запуске программы. Первым делом добавьте свойство в скрипт PlaceObjectOnHorizontalSurface, а в методе Awake уберите установку поля в true:

Прикрепите к родительскому объекту Car следующий скрипт (все пояснения в комментариях):

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

В данной статье мы изложили основные принципы взаимодействия голограмм с окружающим пространством. Фактически наше приложение готово. Мы можем смело загружать его на устройство. О том, как это сделать, будет рассказано в следующей статье.


Выражаем благодарность Тимуру Ахметову, разработчику из компании HoloGroup и департаменту стратегических технологий Microsoft за предоставленный материал.

Для справки: HoloGroup является одним из первых разработчиков для HoloLens в России и 1 сентября 2016 года выпустила первое русскоязычное приложение HoloStudy.