
Приложения дополненной реальности становятся все более популярными. Рано или поздно, но кто-нибудь в России обязательно выпустил бы 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);
Таким образом, мы указываем, что маркер Trackable\5.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!» в мире дополненной реальности. Я заскриншотил то, что у меня получилось:

И немножко видео Swarp SDK в действии:
Симпатичный домик, не правда ли?
В заключение
Вот, вроде бы и все, что необходимо, чтобы создать свое AR-приложение. У меня ушло около 2 часов, чтобы прочитать документацию по SDK и понять принципы работы.
Надеюсь, что статья поможет тем, кто захочет разобраться в Swarp. В следующих статьях попробуем написать приложение посерьезнее и посложнее. Спасибо Вам что прочитали.
Ссылки
Сайт разработчиков: www.sectar.com
Ссылка на скачивание SDK: Swarp SDK
Managed Ogre: Mogre wiki
UPD: выложил видео.
UPD 2: Новости с полей: Sectar выкатили новый апдейт. В старой версии была ошибка с активацией триал-режима. Вроде исправили. В посте поправлены ссылки на скачивание.