Создание голограмм для HoloLens без Unity

от автора

Хочу поделиться самым простым способом создания голограммок для HoloLens, для которых не потребуется сторонних редакторов. Всего лишь маленький нугет пакет и чуть-чуть документации. С возрастающим интересом к AR/VR, думаю, наличие простого инструмента для создания в частности и неигровых 3д приложений — никому не повредит. Основным рекомендуемым способом разработки под HoloLens является Unity. Да-да, большой редактор, программирование мышкой, закрытый код. Но также есть и шаблон проекта на чистом DirectX11 C++ (или C# через SharpDX), который, собственно показывает каким образом можно адаптировать любой движок (даже OpenGL only + ANGLE). Процесс довольно непростой, если будет интерес — могу подробно описать через какие грабли мне пришлось пройти.

Что можно с этим сделать

Для начала несколько демонстраций того, что уже написано с использованием этого простенького инструмента. Все примеры находятся в открытом доступе (как и сам движок) на GitHub с MIT лицензией.

  1. Hello World – маленький пример создания world-locked голограмм Земли с Луной.
  2. Hello World Advanced – усложненный первый пример, показывающий как писать свои шейдеры, для примера, вот такой. Он меняет примитивную Землю из первого во что-то более сложное (склеивая 5 текстур в одном шейдере). Если еще чуть-чуть дофантазировать, то в одном шейдере можно сделать такое:

    А вот еще вариация этого примера, которая показывает реальное относительное расстояние между Луной и Землей:
    Показать

  3. Пример использования голосовых команд Cortana, управления жестами и демонстрация высокополигонной фигурки со скелетной анимацией:
  4. Небольшой пример использования физики (под капотом – Bullet) – окружение сканируется и ко всем стенам, полу и потолку добавляются компоненты RigidBody + CollisionShape.
  5. Управление толпой (под капотом библиотека Recast & Detour). При желании можно довольно быстро сделать какой-нибдь HoloCraft ;-).
    Показать

  6. Сканирование окружения и создание миниатюры. Выглядит примерно так:
  7. Связка с Microsoft Cognitive Services для получения информации об окружении и распознавания текста.
    Показать

  8. Ну и последнее демо сейчас в разработке — помощь в планировании ремонта.

Создаем свою голограмму

Теперь немного подробнее о том, как же создать первую голограммку:
Нам понадобятся:

Создаем новый проект. Лучше всего это сделать при помощи подготовленного шаблона. Либо можно создать из шаблона “Hologrphic DirectX 11 App” и выкинуть оттуда почти всё, добавив нугет пакет UrhoSharp.HoloLens.

Весь код всего проекта умещается в пару десятков строк кода:

using System; using System.Collections.Generic; using Windows.ApplicationModel.Core; using Urho; using Urho.HoloLens; using Urho.Shapes;  namespace HelloHabr {     internal class Program     {         [MTAThread]         static void Main() => CoreApplication.Run(             new UrhoAppViewSource<App>());     }      public class App : HoloApplication     {         public App(ApplicationOptions opts) : base(opts) { }          protected override async void Start()         {             base.Start();                          var node = Scene.CreateChild();             node.Position = new Vector3(0, 0, 1);             node.SetScale(0.2f);              var sphere = node.CreateComponent<Sphere>();             sphere.Color = Color.Red;         }     } } 

Если запустить — увидим сферу красного цвета в метре от себя (координаты — в метрах, в качестве точки отсчета используется первый кадр) диаметром 20см. Довольно просто, не так ли? Urho использует некоторую вариацию популярной архитектуры Entity component system. В качестве Entity выступает Node. Из иерархии узлов и состоит сцена. Каждый узел может иметь коллекцию компонентов, отвечающих за физику, анимации, отображение моделек и т.п. Но также в него вынесены Position, Scale и Rotation. В нашем сниппете за базовую подготовку сцены отвечает base.Start(), который и создаст сцену (корневой Node), настроит камеры для глаз, освещение и тому подобное. Вам лишь остается дальше развивать подготовленную сцену. При желании, сцену можно описать в Shared Projects или PCL и сделать ее доступной сразу ко всему ряду поддерживаемых платформ:

  • iOS, tvOS (в виде UIView)
  • macOS (Cocoa, в виде NSView)
  • UWP, WPF, WinForms (в виде контрола)
  • Android (SurfaceView виджет)
  • Xamarin.Forms
  • Планируется: Google Cardboard, Daydream, Oculus, Vive

Рассмотрим некоторые HoloLens специфичные возможности. И хотя никто не запрещает использовать все системные API напрямую, основные вещи вынесены для удобства в базовый класс.

Text-to-speech.

Ну тут всё просто как грабли, один асинхронный метод базового класса:

await TextToSpeech("Hello World"); 

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

Speech-to-text

Нужно не забыть добавить «Микрофон» как Device Capability в манифесте и использовать это простое API для регистрации команд:

RegisterCortanaCommands(new Dictionary<string, Action>     {         {"idle", () => PlayAnimation(IdleAni)},         {"die", () => PlayAnimation(KillAni)},         {"look at me", LookAtMe },         {"help", Help }     }); 

Т.е. просто словарик из «команда» — действие.

Spatial mapping.

Для этого необходимо сперва его запустить через

await StartSpatialMapping(extents: new Vector3(50, 50, 50),        trianglesPerCubicMeter: 1200); 

Требуется задать объем «наблюдения» и желаемое количество треугольников на кубический метр.
Девайс возвращает окружение в виде коллекции поверхностей (поверхностью может быть часть пола + часть стены + часть потолка, т.е. они не плоские). Каждая коллекция имеет id и сохраняется во внутреннюю память самого устройства. По этому же id оно потом сообщает об изменениях. Поверхность состоит из большого количества вершин, нормалей и индексов (стандартный способ задания геометрии). Превращение этого добра в статичную модель уже реализовано в базовом классе, но при желании можно переопределить поведение.

Жесты

На данный момент есть четыре жеста: Tap, Double tap, Hold, Hold & Move. Пример для обработки «клика»:

EnableGestureTapped = true;  public override void OnGestureTapped() {     Ray cameraRay = LeftCamera.GetScreenRay(0.5f, 0.5f);     RayQueryResult? result = Octree.RaycastSingle(cameraRay); } 

Этим сниппетом можно узнать на какую именно геометрию (координаты, нормаль, компонент, узел) смотрит сейчас пользователь (Ray cast). К примеру, если по узлу вы поймете, что это часть Spatial geometry, то по нормали можно понять является ли это горизонтальной или вертикальной плоскостью. Пример с урной выше разрешает пользователю ставить урну только на горизонтальных плоскостях по этому принципу (код).

В качестве заключения

Движок не является конкурентом известным монстрам, но если интерес к неигровому 3д из-за VR/AR растет, то чем больше выбор инструментов (особенно простых и открытых) — тем лучше, не правда ли? По самому движку так же можно найти несколько интересных статей на хабре.
ссылка на оригинал статьи https://habrahabr.ru/post/314010/


Комментарии

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

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