В этой заметке я хочу рассказать об идее и Proof-Of-Concept добавления объектов реального мира в Виртуальную Реальность.

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

Уже много лет я продумываю конструкцию гидравлической кабины для симулятора МехВоина.

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

Но это не мешает периодически обдумывать всевозможные варианты конструкции.
Раньше я планировал размещать внутри кабины множество дисплеев, часть из которых будет работать по назначению, а вторая часть будет эмулировать «окна»/бойницы.

Однако в современном мире в голову приходит другое решение — VR-шлем (Head-Mounted Display). Добиваться качественного погружения гораздо проще, работая со шлемом, т.к. не требуется тщательно вылизывать интерьер реальной кабины. Да и переделывать дизайн в разы проще, но есть НО.

Нормальный пульт управления мехом — сложная и интересная штука. Самый простой аутентичный контроллер выглядит вот так:

image

Делать в серьезном симуляторе что-то проще (например управление с геймпада) — не вариант.
Предположим, замоделить панель управления и поместить её в VR-мир не составляет проблемы.
Однако, управление таким количеством мелких тумблеров «наощупь» — очень плохая идея.
Но как же быть, ведь пользователь не видит своих рук в VR-мире.

Конечно, есть

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

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

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

Очевидным решением является прикрутить камеру глубины на VR шлем и накладывать полученную геометрию на VR-мир. Но почему-то этого никто не делает.

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

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

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

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

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

Меш с картой высот, задающей Z смещение вершины.

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

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

Построение меша вручную на низком уровне.

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

Реализация на базе UProceduralMeshComponent

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

Почему нужно использовать второй вариант, а не этот?

Потому что данный компонент не предназначен для работы с динамической геометрией. Он заточен под то, чтобы мы один раз (или как минимум не очень часто и желательно не в реалтайме) передаем ему геометрию, она медленно считается и дальше мы с ней быстро работаем. У нас не тот случай…

Но для теста сойдет. Тем более сцена пустая и компьютеру больше нечего считать, так что ресурсов с запасом.

Визуализировать объекты их изображением с камеры — вариант не очень. Очень сильно выделяются реальные фото на фоне виртуального мира.

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



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

Стоит отметить, что этот эффект сильно заметен при взгляде сбоку (сидим перед столом, а кинект сверху). Если же камера глубины будет направлена параллельно взгляду и исходить из точки, близкой к реальным органам зрения пользователя — этот эффект будет направлен вперед и значительно менее заметен.

Как можно заметить на видео — реальные руки вполне работают внутри VR-мира. Единственный серьезный недостаток — дискретность перемещения.

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


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

Как пощупать самому
Что-то мне подсказывает, что людей, у которых будет одновременно HMD (не обязательно), Kinect, умение работать с UE и желание попробовать этот проект достаточно мало (нисколько?). Поэтому смысла выкладывать исходники на гитхаб не вижу.

Выкладываю в виде архива исходники плагина.

Добавляем как обычный плагин в любой UE проект.
Я не стал разбираться как подключить lib файл с помощью относительного пути, поэтому в OpenNI2CameraAndMesh.Build.cs прописываем полный путь до OpenNI2.lib
Далее размещаем ADepthMeshDirect в нужном нам месте.
При старте уровня вызываем метод startOpenNICamera из UTools.
Не забываем, что для работы с кинектом используется libfreenect2, а значит драйвер на кинект надо переопределить на libusbK в соответствии с инструкцией на странице libfreenect2

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

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

Сейчас границы игровой зоны отмечаются условным кубом.

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

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

Комментарии (25)


  1. ebragim
    15.04.2018 17:28

    Если цель в совмещении реального контроллера (как я понимаю, для большей полноты погружения и обратной связи) и модели в HMD — то это как-то очень сложно и мудрёно выходит.
    Окулусы давно такие реализовали в своей гарнитуре: ставим на пальцы метки (да хотя бы обычной краской, светящейся в ИК), камеры привязаны к кабине, а значит позиция джоя относительно камер статична. По положению меток на пальцах можно достроить остальную руку. Трекать всю физику совершенно излишне, так как физика реальной руки жёстко ограниченна доступными углами суставов.
    Да, с вашим способом можно внести в систему предмет из реального мира… но только если он запрограммирован заранее. То есть снова проще сделать несколько точек для трекинга на нём.


    1. AllexIn Автор
      15.04.2018 17:32

      Ну так и речь идет о том, что предметы запрограммированы заранее. Типа того же пульта управления мехом. И задача сориентирвоать игрока — где тумблер, А где его пальцы относительно тумблера.
      По факту физика рукам вообще не нужна, я её сделал просто «потому что могу».

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


      1. Goodkat
        15.04.2018 22:10

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


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


        1. AllexIn Автор
          16.04.2018 08:02

          Система и так предупреждает, когда выходишь из относительно небольшого куба, в котором камера отслеживает шлем и контроллеры.

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

          Мешать ничего не будет. Если у вас пустая комната — вы ничего и не увидите, если у вас комната не пустая — лучше видеть чем не видеть. Да и стенки куба же не мешают, почему увеличение детализации должно мешать?


  1. pavel_kudinov
    16.04.2018 00:55

    > Очевидным решением является прикрутить камеру глубины на VR шлем и накладывать полученную геометрию на VR-мир. Но почему-то этого никто не делает.

    Microsoft Hololens вроде делает именно это. Пробовал это девайс сам: он сканирует помещение и сканирует жесты рук именно камерой глубины, в некоторых режимах он её показывает в полигональном представлении, очень круто выглядит дополненная реальность, когда все реальные объекты начинают быть обтекаемыми своей картой глубины. Полный VR режим там тоже есть (когда видно только виртуальное изображение)


    1. AllexIn Автор
      16.04.2018 08:03

      Давненько мечатю добраться до Hololens, но к сожалению возможности такой пока не представилось. Дорогой, блин.


  1. 3aicheg
    16.04.2018 04:46

    Если я правильно понял постановку задачи, то у вас какой-то овер-инжиниринг 80-го уровня. Почему не натянуть зелёный экран для хромакея на стол и стену за ним, не поставить джойстики на него, брать тупо видео с дешёвой веб-камеры и накладывать поверх 3Д-сцены, обрезая по зелёному? Веб-камера — не кинект, можно маленькую взять и без проблем прикрутить на шлем или на лицо куда-нибудь. Собственно, идея не нова — вот есть такой, к примеру, кэноновский девайс антигуманной ценовой категории:


    1. AllexIn Автор
      16.04.2018 08:04

      А как вы предметам глубины добавите, если просто вырежете их с зеленого фона?
      ДЕшевая вебка не сможет же определить расстояние до точек. А значит в лучшем случае у вас будет контур рук, но без возможности поднимать/опускать их.


      1. kvazimoda24
        16.04.2018 09:01

        Две дешёвых вебки?


        1. AllexIn Автор
          16.04.2018 09:03

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


  1. Sklott
    16.04.2018 09:36

    Мне кажется тут больше подошел бы вариант AR. Т.е. не полное VR погружение, а прорисовка только части деталей. Можно например как предлагалось только окна, можно почти всю кабину кроме контроллеров. Только надо делать не хромокей, а маркеры. Таким образом во-первых идет довольно точная привязка виртуальных объектов к реальной картинке, а во-вторых с их помощью можно настроить систему так чтобы руки не перекрывались виртуальным изображением (хотя это на порядок сложнее и я не уверен есть ли уже готовые решения, в это сторону копать не приходилось...).
    AR с маркерами в принципе уже отработанная тема и есть много движков, да даже в OpenCV есть функции их распознавания.

    ЗЫ: Вдруг подумалось, а может просто совместить хормокей, для прорисовки рук, с маркерами, для позиционирования виртуальных объектов. И все получится? :)


  1. Ztare
    16.04.2018 10:23

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


    1. AllexIn Автор
      16.04.2018 10:23

      А название/ссылку?


      1. Ztare
        16.04.2018 11:04
        +1

        shop-orbbec3d-com.3dcartstores.com (Astra Mini) есть маленькие модели, мне когда пришло я сильно удивился насколько небольшое устройство, правда потом радиаторы на него ставить нужно (идут в комплекте)


        1. AllexIn Автор
          16.04.2018 11:11

          СПасибо. В принципе цена нормальная, как у самого кинекта, когда он еще продавался.


          1. Ztare
            16.04.2018 11:33

            Да если будете брать, и при этом без корпуса, сразу кабель запасной в комплект берите, либо смотрите на форуме как разъем называется и берите штекеры с али. Я взял кабель в запас, но все равно заколебался чинить, там крайне неудачное решение по кабелю — <очень толстый USB> + <тонкие короткие проводки до маленького штекера уже с преднатяжением> ломается только в путь, как аккуратно не обращайся. В конце психанул припаял мягкий кабель и изоляцию убрал на 5см. Пока живет, но все равно стремно — не зря же они так все экраном накрыли и максимально короткие проводки оставляли без экрана


          1. Ztare
            16.04.2018 18:51

            Кстати там слепая зона 60см от камеры (не S модели). Это нужно учитывать если хотите и комнату видеть и жесты обрабатывать.


    1. bukkaa
      16.04.2018 13:30

      Хороший аналог киннекта, разработанный специально для мелкой моторики рук — контроллер Leap Motion. На борту вся необходимая оптика, изображение с внутренних камер тоже можно получить, а еще для него давно уже есть крепления для VR-шлемов.


      1. AllexIn Автор
        16.04.2018 13:31

        Да, Leap Motion в планах попробовать.


      1. Ztare
        16.04.2018 15:37

        Судя по характеристикам, он в таком плане только для рук и сгодится, для пространства комнаты его уже не хватит. Или я не прав?


        1. Vaskrol
          16.04.2018 17:06

          Да, Leap motion именно для рук, предназначен для трекинга ладоней и пальцев. Я трогал его и вертел в Unity. Честно признаться. точность распознавания меня не впечатлила. Может, я просто не смог в него. Обновление драйверов сильно повысило точность, но все равно точность движений не идет ни в какой сравнение с обычными клешнями от Htc Vive. Как бы в принципе разные контроллеры, но поиграв в оба — Leap отторгает.


          1. Ztare
            16.04.2018 18:17

            А в плане расстояния что он видит? Или он вообще пространство не показывает, а только скелет отдает?


            1. Vaskrol
              18.04.2018 13:40

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


            1. Vaskrol
              18.04.2018 14:09

              Да, модель именно помещения у меня он не строил, только скелет рук. Возможно, другой прошивкой или просто другим ПО можно и карту пространства построить. Но у меня не строил.


  1. alhel
    16.04.2018 16:56

    Leap motion малогабаритный, попробуйте его использовать