Приложения дополненной реальности становятся все более популярными. Рано или поздно, но кто-нибудь в России обязательно выпустил бы SDK для создания таких приложений. И вот, это произошло — российская компания Sectar выпустила свой продукт Swarp SDK для создания таких приложений на платформе .NET. Далее я опишу Swarp и покажу, как быстро и просто создать свое AR-приложение.
Обзор
После скачивания и установки продукта (на момент написания статьи актуальна версия 1.0.249.925) можно увидеть 5 поддиректорий:
- Bin — тут лежат все сборки Swarp SDK, а также библиотеки движка Managed Ogre (Mogre), который используется для рендеринга.
- Docs — хранит в себе (помимо лицензионного соглашения и ReleaseNotes'ов) очень интересный файлик «Documentation.chm». В нем находится вся документация по Swarp'у, включая описание классов и туториал. Кстати, вся документация на русском языке и выполнена в стиле MSDN, что по идее должно облегчить восприятие разработчику на .NET.
- Examples — это папка с примерами, которые написали разработчики Sectar. В данной версии SDK присутствуют 3 примера, которые демонстрируют работу с системой распознавания, с системой рендеринга, основанной на Mogre — .Net-обертке Ogre3D, а также механизм динамического связывания 3D-модели с маркером. Все примеры представляют собой солюшены для Visual Studio 2010.
- Trackable — содержит несколько маркеров Swarp SDK. Забегая вперед, скажу, что можно самому создавать маркеры, используя утилиту SquareMarkerCreator.
- Utilities — здесь можно найти утилиты SquareMarkerCreator, HID и LicenseViewer. Две последние служат для регистрации продукта и просмотра установленной лицензии, так что особого внимания я им не уделяю, если кому-то интересно, то про них можно прочитать в документации. А вот про SquareMarkerCreator я расскажу отдельно.
Маркеры
В Swarp SDK используется своеобразная система маркеров. Маркер представлен в виде XML-файла с расширением .trackable. Содержимое одного из стандартных маркеров приведено ниже.
Как выглядит маркер на бумаге:
и его содержимое в .trackable файле:
<?xml version="1.0" encoding="utf-8"?>
<Trackable Type="Sectar Square Marker" Description="Marker with square detection element" Version="1.0" Company="Sectar">
<SquareMarker MarkerSize="500" FrameWidth="80" CellsCount="4" FrameMargin="15" CellMargin="5" CellsType="Circle">
<Code>111100010101</Code>
</SquareMarker>
</Trackable>
У многих возникнет вопрос: как преобразовать .trackable файл в банальный .jpg или .png, чтобы распечатать его на бумаге? Все просто: утилита SquareMarkerCreator.exe придет на помощь.
Утилита создания маркеров (SquareMarkerCreator)
Как видно из названия, эта утилита служит для создания маркеров, используемых в Swarp SDK. После ее запуска появляется визуальный редактор маркеров:
Изменять цвет ячейки маркера можно просто кликая мышкой по соответствующей ячейке. Тут же можно изменить такие параметры маркера, как отступы, ширина рамки, размерность матрицы ячеек и прочие.
Для того, чтобы преобразовать маркер из XML-формата в графический — надо загрузить маркер, нажав на кнопку «Загрузить из XML», а потом сохранить маркер в .EMF-файл, нажав на кнопку «Сохранить изображение».
«Hello, world!» на Swarp SDK
Самое время попробовать написать свое AR-приложение. Я хочу разобрать пример OgreSimpleSceneExample, который будет использовать первую попавшуюся камеру и использовать Mogre для рендеринга одной 3D-модели.
Создадим проект консольного Win32-приложения. И добавим в Reference используемые сборки:
А в код добавим ссылки на используемые пространства имен:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Mogre;
using Swarp.Examples.OgreSimpleSceneExample.Properties;
using Swarp.SDK.Management;
using Swarp.SDK.Ogre3DRendering;
using Swarp.SDK.Rendering;
using Swarp.SDK.Target.SquareMarkerTracking;
using Swarp.SDK.Tracking;
using Swarp.SDK.DirectShowInput;
Теперь надо добавить поля в статический класс Program, которые будут реализовывать процесс дополненной реальности. Нам понадобится класс AugmentedRealityManager, который будет обеспечивать взаимодействие и управление различными модулями SDK. Еще нам будет нужен интерфейс ITrackable для описания используемого маркера. После добавления этих полей у нас получится такой код:
static class Program
{
/// <summary>
/// Менеджер дополненной реальности.
/// </summary>
private static AugmentedRealityManager _arManager;
/// <summary>
/// Объект отслеживания.
/// </summary>
private static ITrackable _houseTrackable;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
}
}
Теперь у нас есть точка входа в приложение. Возникает вопрос — что же делать дальше? Дальше я приведу картинку из документации Swarp SDK:
На картинке красной рамкой выделены действия, которые должен выполнить разработчик.
На текущем этапе необходимо инициализировать камеру. Для этого служит класс CameraManager:
// Находим первую попавшуюся работающую камеру.
var camera = CameraManager.Instance.GetFirstWorkedCamera();
// Если не удалось найти камеру, то не продолжать работу данного примера.
if (camera == null)
{
MessageBox.Show(Resources.CameraNotFoundString, Resources.WarningString,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
var displayParameters = new DisplayParameters(30, new Size(800, 600));
// Если запрашиваемые параметры отображения не поддерживаются камерой, то выбираем первые попавшиеся.
camera.DisplayParameters = camera.IsSupportedDisplayParameters(displayParameters)
? displayParameters
: camera.GetSupportedDisplayParameters()[0];
Затем надо указать, какие маркеры будут использованы в приложении. Это делается таким способом:
var tracker = new SquareMarkerTracker(1);
// Регистрируем 1 объект отслеживания. Данные об объекте загружаются из файла.
_houseTrackable = new SquareMarker("House Marker", "Trackable\5.trackable");
tracker.TrackableObjects.Add(_houseTrackable);
Таким образом, мы указываем, что маркер Trackable5.trackable будет искаться системой трекинга маркеров.
А теперь нам надо инициализировать систему рендеринга, основанную на Mogre:
// Создаем окно, в котором будет отображаться дополненная реальность.
var ogreSimpleSceneForm = new Form
{
Size = new Size(1066, 600),
Text = Resources.SwarpSDKExampleString,
Icon = Resources.Swarp,
};
// Инициализируем рендерер.
// plugins.cfg - файл со списком доступных плагинов для Ogre3D.
// ogre.cfg - файл с настройками подсистемы рендеринга, которую будет использовать Ogre3D.
// ogre.log - лог-файл, в котором будет сохраняться последние действия Ogre3D.
// Размер отрендеренного изображения будет масштабироваться таким образом,
// чтобы сохранить пропорции изображения с камеры и вписаться в окно.
var renderer = new Ogre3DRenderSystem(ogreSimpleSceneForm.Handle,
"OgreConfig\plugins.cfg", "OgreConfig\ogre.cfg", "OgreConfig\ogre.log")
{
SizeMode = SizeMode.Autosize
};
// Загружаем ресурсы с файла конфигурации.
// В данном файле хранятся пути к ресурсам
// (3D моделям, текстурам и т.д., которые будет использовать Ogre3D в приложении).
renderer.LoadResources("OgreConfig\resources.cfg");
// Создаем сцену. Загружаем модель.
var houseScene = new Ogre3DScene(renderer.Root, "House Scene");
renderer.Scenes.Add(houseScene);
LoadScene(houseScene.SceneManager);
Работа с Managed Ogre инкапсулирована в класс Ogre3DRenderingSystem, что существенно упрощает жизнь разработчику, так как берет на себя большую часть рутинных операций. Вообще, Mogre это отдельная и очень большая тема, так что если кому-нибудь интересно, то в конце статьи ссылка на Mogre wiki.
Swarp SDK не ограничивает разработчика только Ogre'ом. В принципе, разработчик может интегрировать другое средство рендеринга. Для этого необходимо создать два класса, наследуемых от Renderer и Scene, находящихся в пространстве имен Swarp.SDK.Rendering.
Вернемся к нашему приложению. При вызове конструктора Ogre3DRenderSystem указываются 4 параметра: handle формы или контрола, с которым будет работать Mogre, пути к файлам конфигурации Ogre, описывающим плагины и настройки системы рендеринга, а также путь к лог-файлу.
Далее загружаются ресурсы Ogre. Для загрузки 3D-моделей необходимо, чтобы в файле конфигурации ресурсов были даны ссылки на них. К примеру, у меня файл конфигурации ресурсов выглядит так:
# Resource locations to be added to the 'boostrap' path
# This also contains the minimum you need to use the Ogre example framework
[Bootstrap]
# Resource locations to be added to the default path
[General]
FileSystem=
FileSystem=Resources
Zip=Resources/House.zip
Здесь загружается только одна модель House.zip, которая находится в ZIP-архиве.
Затем вызывается метод LoadScene. Он нужен для того, чтобы создавать сцену Mogre и добавлять в нее модель. Подробнее про это можно прочитать в Mogre wiki. Описание метода приведено ниже:
private static void LoadScene(SceneManager sceneManager)
{
// Подробнее о графе сцены Mogre, создании и загрузке сцен,
// анимации и т.д. см. http://www.ogre3d.org/tikiwiki/Mogre+Tutorials.
// Создаем узел, относительно которого будет отображаться модель.
var houseNode = sceneManager.RootSceneNode.CreateChildSceneNode("HouseNode");
// Создаем сущность модели (загружаем ее из файла).
var houseEntity = sceneManager.CreateEntity("House", "House.mesh");
houseNode.AttachObject(houseEntity);
houseNode.Scale(6.0f, 6.0f, 6.0f);
}
Теперь все готово для инициализации менеджера и запуска:
// Инициализируем менеджер дополненной реальности.
_arManager = new AugmentedRealityManager(camera, trackers, renderer);
// Запускаем камеру.
// Генерация изображения происходит в отдельном потоке.
camera.Start();
// Запускаем процесс дополненной реальности.
// Трекинг происходит в отдельном потоке.
_arManager.Start();
ogreSimpleSceneForm.Show();
while (ogreSimpleSceneForm.Created)
{
// Обновляем положение сцен связанных с найденными в кадре объектами,
// а также скрываем те сцены, связанные с ненайденными объектами в кадре.
UpdateScenes();
// Отрисовываем кадр вручную.
// Важно, чтобы кадр отрисовывался в том же потоке,
// в котором происходила инициализация окна рендеринга.
_arManager.Renderer.RenderFrame();
// Вызываем обработку всех событий в приложении.
Application.DoEvents();
}
// Перед закрытием окна приложения необходимо очистить ресурсы.
_arManager.Dispose();
renderer.Dispose();
camera.Dispose();
Важный момент: перед запуском процесса дополненной реальности необходимо включить захват с камеры.
Метод UpdateScenes ориентирует модель (если она найдена трекером) соответственно положению маркера в пространстве:
private static void UpdateScenes()
{
// Копируем список с найденными значения,
// так как пока идет рендеринг, эта коллекция может измениться в другом потоке.
var foundTrackableObjects = new List<ITrackable>(_arManager.Trackers[0].LastDetectedObjects);
// Для каждой сцены сравниваем объект отслеживания.
foreach (var scene in _arManager.Renderer.Scenes)
{
// Если его нет среди найденный объектов отслеживания, то скрыть сцену.
if (foundTrackableObjects.Contains(_houseTrackable))
{
// Если нашли объект отслеживания, связанный с данной сценой.
scene.Visible = true;
// Находим положение объекта отслеживания.
var trackablePose =_arManager.Trackers[0].GetPose(_houseTrackable);
// Поворачиваем сцену согласно новой позицией объекта отслеживания.
scene.OrientScene(trackablePose);
}
else
{
scene.Visible = false;
}
}
}
Таким образом, у нас получилось первое AR-приложение, своеобразный «Hello, world!» в мире дополненной реальности. Я заскриншотил то, что у меня получилось:
Симпатичный домик, не правда ли?
В заключение
Вот, вроде бы и все, что необходимо, чтобы создать свое AR-приложение. У меня ушло около 2 часов, чтобы прочитать документацию по SDK и понять принципы работы.
Надеюсь, что статья поможет тем, кто захочет разобраться в Swarp. В следующих статьях попробуем написать приложение посерьезнее и посложнее. Спасибо Вам что прочитали.
Ссылки
Сайт разработчиков: www.sectar.ru
Ссылка на скачивание SDK: Swarp SDK
Managed Ogre: Mogre wiki
Автор: DarkFIxED