В лабораторной работе №2 (идентификация лица) сказано: - в FaceTracking.cs: удалим или закомментируем функцию SimplePipeline, класс MyUtilMPipeline и изменим функцию AdvancedPipeline... Класса MyUtilMPipeline нет в проекте вообще; Функции AdvancedPipeline так же нет. Материалов к лабораторной №2 в начале работы (по ссылке открывается та же страница) тоже нет.Это ошибки или используется другая версия примера? |
Возможности использования Intel Perceptual Computing SDK в игровых приложениях
Цель лабораторной работы
Разработка учебного приложения в Unity с реализацией жестового управления игровыми объектами, используя Intel Perceptual Computing SDK
Задачи лабораторной работы
- создать учебный проект в Unity и настроить его на работу с Intel Perceptual Computing SDK;
- разработать скрипт, реализующий жестовое управление игровым объектом
Введение (постановка задачи)
В данной работе не стоит цели создать настоящее игровое приложение, основная задача научиться реализовывать жестовое управление игровыми объектами. Поэтому для достижения цели лабораторной работы, настроим простые игровые объекты в Unity, в нашем случае ограничимся плоскостью и шариком. Далее реализуем управление шариком, заключающееся в следующем: пользователь перед камерой воспроизводит воображаемый руль (см. рис. 6.1), шарик на экране двигается в соответствии с движениями руля.
Создание проекта в Unity и настройка на работу с Intel Perceptual Computing SDK
1. Создание проекта
- Запустим Unity и создадим новый проект, зададим ему подходящее имя.
- Сохраним сцену File->Save Scene, зададим ей имя, например, MiniGame. Можно проверить в папке, в которой расположен Unity проект, должна быть папка Assets, а в ней файл MiniGame.unity.
- Создадим плоскость, по которой будет кататься наш шарик: Game Object- >Create Other->Plane.
- Создадим, собственно, сам шарик: Game Object- >Create Other->Sphere.
На данном этапе создания проекта окно Unity выглядит примерно так, как изображено на рис. 6.2. Справа вкладка Inspector, в которой отображаются основные свойства игровых объектов. Имеет смысл обратить внимание на расположение координатных осей в Unity.
- добавим освещение: Game Object- >Create Other->Directional light, настроим освещение, как показано на рис. 6.3 вкладка Inspector
- для большей реалистичности настроим тени: во вкладке Inspector для объекта Direction light, необходимо настроить пункт Shadows, как показано на рис. 6.3.
На этом собственно создание игровых объектов в Unity закончим, такого простого решения для наших целей вполне достаточно.
2. Настройка на работу с Intel Perceptual Computing SDK
Intel Perceptual Computing SDK работает в Unity, как плагин и его использование ограничено версией Unity Pro. Существует возможность получить бесплатно пробную версию Unity Pro на 30 дней, этого времени достаточно для экспериментов с SDK. Как показал опыт, после окончания этого срока тоже можно работать с Intel Perceptual Computing SDK, если каждый раз при проверке работы приложения выполнять его построение и запускать получившийся исполняемый файл (т. е. использовать File->Build & Run).
Чтобы настроить приложение на работу с Intel Perceptual Computing SDK, необходимо в директории <project>/Assets/ создать папку Plugins и скопировать в эту папку три файла:
- libpxcupipeline.dll
- pxcm-structures.cs
- pxcupipeline.cs
Эти файлы можно найти в папке: $(PCSDK_DIR)/framework/Unity/hellounity/Assets/Plugins, где $(PCSDK_DIR) путь к директории, в которой установлен SDK.
Разработка скрипта, реализующего жестовое управление игровым объектом
Создадим C# скрипт: Assets->Create->C# Script, назовем его, например, SphereControl. Скрипт создан для управления шариком, для этого свяжем его с игровым объектом Sphere. Во вкладке Inspector, для объекта Sphere, необходимо нажать кнопку Add Component, далее выбрать Scripts и выбрать нужный скрипт из списка (в нашем случае в списке ровно один, только что созданный скрипт).
Непосредственно после создания скрипт выглядит, как на рис. 6.4.
Скрипт описывает класс SphereControl (имя класса должно совпадать с названием скрипта). Для работы с жестами необходимо объявить две переменные, как поля класса SphereControl:
private PXCUPipeline.Mode mode = PXCUPipeline.Mode.GESTURE; private PXCUPipeline pp;
первая из них сообщает, что будет использоваться жестовый режим, вторая - является экземпляром класса PXCUPipeline, являющегося C# оболочкой класса UtilPipeline.
1. Настройка метода Start()
В этом методе выполним первоначальные настройки:
- создадим экземпляр класса PXCUPipeline и присвоим его переменной pp;
pp = new PXCUPipeline();
- настроим объект pp на работу в режиме, указанном в переменной mode, в режиме распознавания жестов.
pp.Init(mode);
Полностью метод Start() представлен в листинге 6.1.
2. Настройка метода Update()
В этом методе выполняется основная работа скрипта. Первое, что сделаем - зададим две переменные, которые отвечают за положение рук относительно камеры, так как для имитации руля нам потребуется две руки:
PXCMGesture.GeoNode mainHand; //главная рука PXCMGesture.GeoNode secondaryHand;
Нам необходимо запрашивать данные, которые может предоставить Intel Perceptual Computing SDK, в нашем случае данные о положении рук. Чтобы получать данные от SDK в каждом фрейме, используем следующую конструкцию:
if (!pp.AcquireFrame(true)) return;
Получать данные будем с помощью метода класса PXCUPipeline:
bool QueryGeoNode(PXCMGesture.GeoNode.Label body, out PXCMGesture.GeoNode data);
Первый аргумент метода задает объект, который необходимо отслеживать, в нашем случае - рука.
Второй аргумент после выполнения метода содержит данные о местоположении объекта.
Получим данные о положении рук:
pp.QueryGeoNode(PXCMGesture.GeoNode.Label.LABEL_BODY_HAND_LEFT | PXCMGesture.GeoNode.Label.LABEL_HAND_MIDDLE, out mainHand); pp.QueryGeoNode(PXCMGesture.GeoNode.Label.LABEL_BODY_HAND_RIGHT | PXCMGesture.GeoNode.Label.LABEL_HAND_MIDDLE, out secondaryHand);
После получения данных от SDK необходимо освободить фрейм, используя следующий метод:
pp.ReleaseFrame();
Отвлечемся от программирования и обсудим, как определяется положение рук в пространстве. В трехмерном пространстве для задания положения объекта чаще всего используется трехмерный радиус-вектор (вектор, направленный из начала координат к объекту). Следует иметь ввиду, что координаты объектов вычисляются в системе координат, определяемой камерой. На рис. 6.5 хорошо видно, как направлены координатные оси в этой системе координат.
Вернемся к задаче, нам необходимо определять поворот воображаемого руля. В рассмотренной системе координат поворот будет определяться изменением координаты z. На рис. 6.6 показано, как математически можно описать поворот "воображаемого" руля. Становится понятным зачем мы определяли главную и не главную руки, поворот вычисляется, как разность z-координат главной и второй руки. Если разность положительная, то поворот направо, если отрицательная - налево.
Вернемся к программированию, нам необходимо как-то получить z-координаты рук. Для этого воспользуемся переменными mainHand и secondaryHand. Каждая из этих переменных получила сведения о положении соответствующей руки, во время запроса данных от SDK. Чтобы вытащить координаты z, воспользуемся следующими конструкциями:
float mainHandZ = mainHand.positionWorld.z; float secondaryHandZ = secondaryHand.positionWorld.z;
Теперь эти координаты можно использовать по назначению, передав их в метод:
controlTurn(mainHandZ, secondaryHandZ);
На этом метод Update() можно закончить.
Рассмотрим реализацию метода controlTurn(), в нашем случае эта реализация очень простая.
void controlTurn(float mainHandZ, float secondaryHandZ){ float turn = mainHandZ - secondaryHandZ; Vector3 move = new Vector3 (turn, 0, 0); transform.Translate (move); }
В первой строке находим разность z-координат главной и не главной рук.
Во второй строке создаем вектор, который задает смещение шарика.
В третьей строке выполняем смещение.
Возможные пути развития задачи
В данной работе рассмотрена только возможность связать жесты и поведение игрового объекта: шарика. Пример получился очень учебным, но он пригоден для дальнейшего развития, в связи с этим предлагаем несколько заданий для самостоятельной работы:
- В созданное приложение добавить жестов для управления шариком, например, движение рук вверх и вниз заставляло бы шарик двигаться вперед-назад (возможны, разумеется, другие варианты).
- Для создания реалистичных игр, необходимо использовать возможности Unity, задавать физические свойства объектов, сцен. Но данный курс не предусматривает серьезного изучения Unity, поэтому создание реалистичных игр с использованием возможностей Intel Perceptual Computing SDK оставим в качестве самостоятельной работы.
- Самый простой вариант развития полученного приложения видится в создании на плоскости некоторого лабиринта, добавление правильного физического поведения (например, шарик отскакивает от стен, а не проходит сквозь них) и программирование управления доской (плоскостью) с помощью жестов. В результате должен появиться аналог детской игры "Лабиринт" с задачей загнать шарик в лунку.
- Раз уж в приложении использовался воображаемый руль, явным продолжением развития идей подобного управления было бы создание игры "Гонки". Для создания этой игры необходимо научиться использовать возможности Unity, а также продумать систему жестов для торможения и разгона.
- Нельзя пройти мимо существующего решения, в котором реализовано управление самолетом с помощью жестов: https://www.youtube.com/watch?v=KPE332rX5Yc#t=20. Данный проект может служить источником идей для вдохновения, а также предлагает некоторые мысли, необходимые для реализации взаимодействия с Intel Perceptual Computing SDK при разработке похожих приложений: описание.
using UnityEngine; using System.Collections; public class SphereControl : MonoBehaviour { private PXCUPipeline.Mode mode = PXCUPipeline.Mode.GESTURE; private PXCUPipeline pp; // Use this for initialization void Start () { pp = new PXCUPipeline(); pp.Init(mode); } // Update is called once per frame void Update () { PXCMGesture.GeoNode mainHand; //главная рука PXCMGesture.GeoNode secondaryHand; if (!pp.AcquireFrame(true)) return; pp.QueryGeoNode(PXCMGesture.GeoNode.Label.LABEL_BODY_HAND_LEFT | PXCMGesture.GeoNode.Label.LABEL_HAND_MIDDLE, out mainHand); pp.QueryGeoNode(PXCMGesture.GeoNode.Label.LABEL_BODY_HAND_RIGHT | PXCMGesture.GeoNode.Label.LABEL_HAND_MIDDLE, out secondaryHand); pp.ReleaseFrame(); float mainHandZ = mainHand.positionWorld.z; float secondaryHandZ = secondaryHand.positionWorld.z; controlTurn(mainHandZ, secondaryHandZ); } void controlTurn(float mainHandZ, float secondaryHandZ){ float turn = mainHandZ - secondaryHandZ; Vector3 move = new Vector3 (turn, 0, 0); transform.Translate (move); } }Листинг 6.1. Скрипт, реализующий жестовое управление шариком