Хабрахабр

HMD + Kinect = Дополненная виртуальность


В этой заметке я хочу рассказать об идее и Proof-Of-Concept добавления объектов реального мира в Виртуальную Реальность.
На мой взгляд, описанная идея в ближайшее время будет реализована всеми игроками VR-рынка. ИМХО, единственная причина, по которой это до сих пор не сделано — желание выкатить идеальное решение, а это не так-то просто.
Уже много лет я продумываю конструкцию гидравлической кабины для симулятора МехВоина.

Её я, конечно, никогда не сделаю.

требует достаточно существенных вложений, при этом вполне понятно, что интерес к ней потеряется сразу по окончанию реализации проекта. Т.к. Хранить полученную бандуру негде, а коммерческой жилки, чтобы её кому-то продать/сдать, у меня нет.

Но это не мешает периодически обдумывать всевозможные варианты конструкции.
Раньше я планировал размещать внутри кабины множество дисплеев, часть из которых будет работать по назначению, а вторая часть будет эмулировать «окна»/бойницы.
Однако в современном мире в голову приходит другое решение — VR-шлем (Head-Mounted Display). Добиваться качественного погружения гораздо проще, работая со шлемом, т.к. не требуется тщательно вылизывать интерьер реальной кабины. Да и переделывать дизайн в разы проще, но есть НО.
Нормальный пульт управления мехом — сложная и интересная штука. Самый простой аутентичный контроллер выглядит вот так:
image
Делать в серьезном симуляторе что-то проще (например управление с геймпада) — не вариант.
Предположим, замоделить панель управления и поместить её в VR-мир не составляет проблемы.
Однако, управление таким количеством мелких тумблеров «наощупь» — очень плохая идея.
Но как же быть, ведь пользователь не видит своих рук в VR-мире.
Конечно, есть

специальные перчатки

image

но сегодня не о них…

Первыми о них заявили Microsoft со своим Кинектом. На данный момент активно развиваются камеры глубины. Однако дело не умерло, как можно было подумать. К сожалению, МС решили что Кинект экономически не оправдан и закрыли проект. Apple внедрила камеру глубины в последний iPhone, именно такая камера отвечает за распознавание лица владельца.
MS тоже не отказалась от технологии, VR-шлемы на платформе Windows Mixed Reality используют технологию inside-out tracking на основе камер глубины.

Но почему-то этого никто не делает.
ZED Mini вроде бы умеют строить 3Д-мир и крепятся на шлем, но вживую я их не видел, а все проморолики используют информацию о мире только для наложения 3Д моделей на него, но не наоборот. Очевидным решением является прикрутить камеру глубины на VR шлем и накладывать полученную геометрию на VR-мир. Полагаю, проблема в низком качестве полученной модели, что будет сразу видно при попытке визуализации.

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

Перейдем к проекту (разбора кода не будет, только теория и немного картинок)

С помощью libfreenect2 и OpenNI — получаем карту высот.
Как визуализировать эту карту высот?
Очевидных вариантов в Unreal Engine три.

Меш полностью статический, меняется только текстуры (что очень быстро). Меш с картой высот, задающей Z смещение вершины.
Очевидный и самый быстрый вариант.

С точки зрения физики такой меш — абсолютно плоский и цельный. К сожалению у этого метода есть серьезный недостаток:
Отсутствие возможниости прикрутить физику. То что у нас часть вершин прозрачные и отрезаны альфа тестом — физика не видит. Простой прямоугольник. То, что у нас вершины модифицируются по Z координате — физика не видит.

Это низкоуровневый подход, дающий лучшую скорость.
Основной недостаток — достаточно высокая сложность реализации.
Если делать полноценно — именно этот вариант и стоит избрать.
Но т.к. Построение меша вручную на низком уровне.
Для этого нам нужно перекрыть UPrimitiveComponent и реализовать новый компонент с использованием SceneProxy. передо мной стояла задача сделать быстро и просто, я воспользовался третьим вариантом.

Он заточен под то, чтобы мы один раз (или как минимум не очень часто и желательно не в реалтайме) передаем ему геометрию, она медленно считается и дальше мы с ней быстро работаем. Реализация на базе UProceduralMeshComponent
Это встроенный в UE компонент, который позволяет легко и просто создавать меш и даже сразу считать объект для рассчета коллизий.
Почему нужно использовать второй вариант, а не этот?
Потому что данный компонент не предназначен для работы с динамической геометрией. Тем более сцена пустая и компьютеру больше нечего считать, так что ресурсов с запасом. У нас не тот случай…
Но для теста сойдет.

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

На скриншоте видно эффект «стекания» геометрии. Получилось вполне приемлемо. Явно вырожденные пиксели кинект помечает значением 0, но, к сожалению, не все и часть из них «шумит», не вырождаясь. Это связано с неспособностью камер глубины нормально обрабатывать грани с углом близким к 90 градусов к камере. Если же камера глубины будет направлена параллельно взгляду и исходить из точки, близкой к реальным органам зрения пользователя — этот эффект будет направлен вперед и значительно менее заметен. Я сделал набор несложных манипуляций, чтобы убрать основной шум, но полностью избавиться от «стекания» не получилось.
Стоит отметить, что этот эффект сильно заметен при взгляде сбоку (сидим перед столом, а кинект сверху).

Единственный серьезный недостаток — дискретность перемещения.
Меш не морфирует плавно в новое состояние, а удаляется и создается заново. Как можно заметить на видео — реальные руки вполне работают внутри VR-мира. Из-за чего при резком движении физические объекты проваливаются сквозь него, поэтому двигаем медленно и аккуратно:

Прошу прощения за темное видео — занимался проектом по вечерам после работы, на превью видео показалось нормальным, когда уже всё оборудование снял и перенес видео на комп — оказалось, что оно очень темное.

Как пощупать самому

Что-то мне подсказывает, что людей, у которых будет одновременно HMD (не обязательно), Kinect, умение работать с UE и желание попробовать этот проект достаточно мало (нисколько?). Поэтому смысла выкладывать исходники на гитхаб не вижу.
Выкладываю в виде архива исходники плагина:
drive.google.com/open?id=1dQrMLWzx72xB8CSa3W3kTNmBs4SDzmL1
Добавляем как обычный плагин в любой UE проект.
Я не стал разбираться как подключить lib файл с помощью относительного пути, поэтому в OpenNI2CameraAndMesh.Build.cs прописываем полный путь до OpenNI2.lib
Далее размещаем ADepthMeshDirect в нужном нам месте.
При старте уровня вызываем метод startOpenNICamera из UTools.
Не забываем, что для работы с кинектом используется libfreenect2, а значит драйвер на кинект надо переопределить на libusbK в соответствии с инструкцией на странице libfreenect2

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

Если же говорить — зачем такая система нужна во всех VR системах без исключения — это безопасность.
Сейчас границы игровой зоны отмечаются условным кубом.
Но редко кто из нас может позволить себе выделить абсолютно пустое пространство под VR.
В итоге в комнате остаются предметы, иногда опасные.
Основное что, я уверен, будет сделано — это виртуальное отображение всей комнаты перед игроком в виде едва различимого призрака, который с одной стороны не мешает восприятию игры, а с другой — позволяет не споткнуться и не умереть.

S>
Хочу выразить огромную благодарность компании <которую нельзя называть вне корпоративных блогов>, руководство которой выделило мне техническую базу для работы над этим проектом. P.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть