Набор средств разработки 3D-игр
Создание программы, позволяющей при помощи трехмерных моделей и скриптов на языке Lua создавать игровые уровни. Обзор и обоснование некоторых решений, принятых и реализованных в результате разработки программы. Алгоритмы и структуры данных разработки.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 02.09.2018 |
Размер файла | 4,4 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Правительство Российской Федерации
Федеральное государственное автономное образовательное учреждение высшего образования
"Национальный исследовательский университет "Высшая школа экономики"
Факультет компьютерных наук
Департамент программной инженерии
Выпускная квалификационная работа
на тему "Набор средств разработки 3D-игр"
по направлению подготовки 09.03.04 "Программная инженерия"
М.М. Кумсков
Москва 2018
Реферат
Игровая индустрия растет с каждым годом, и сотни игр с годами разработки и миллионами долларов бюджета выпускаются каждый год. В данной работе рассматривается создание набора средств разработки трехмерных игр. Можно выделить два основных модуля, необходимых для создания игры - редактор сцен и приложение для воспроизведения созданных сцен.
В ходе разработке каждого из модулей встречается множество проблем, таких, как взаимодейтсвие игрока с объектами на сцене, управление трехмерными объектами на основании пользовательских действий и зараннее настроенной логики, отрисовка игровой сцены в реальном времени, а также разработка архитектуры хранения игровых ресурсов.
В результате разработки создана программа, позволяющая при помощи трехмерных моделей и скриптов на языке Lua создавать игровые уровни. Для отрисовки интерфейса и игровых сцен используются библиотеки Qt и OpenGL.
Помимо описания основных структур данных, разработанных для организации работы приложений, будет также приведен обзор и обоснование некоторых решений, принятых и реализованных в результате разработки программы.
Ключевые слова: игры, 3D, OpenGL, разработка
Abstract
Game industry is growing with each passing year, with hundreds of games with years of development and multi-million dollar budgets released every year. This paper goes over the development of a 3D game development toolkit. Two distinct parts of a game development software can be distinguished - a scene editor and a program to load and play the created scenes.
During the development of each part of the software multiple problems are encountered, such as player interaction with objects on the scenes, 3d model control according to user input and game logic, level rendering in real time and developing the architecture of storing all resources.
As a result of the development a program for creating game scenes with 3D models and scripts was created, as well a program that allows playing created scenes. OpenGL and Qt frameworks were used for interface and scene rendering.
Aside from the process of creating all necessary data structures needed for the correct work of the program this paper describes the overview of some of the solutions implemented in this toolkit.
The paper contains 50 pages, 3 chapters, 36 illustrations, 4 appendices.
Keywords: Gamed, 3D, OpenGL, Development
Основные определения, термины и сокращения
Сцена - Набор трехмерных моделей.
Рендеринг - Процесс вывода (отрисовки) сцены на экран.
Игровой движок - Набор средств (редактор и программа для исполнения) для создания трехмерных игр.
Игра, Компьютерная игра - интерактивная развлекательная программа
Коллизия - соприкосновение трехмерных моделей друг с другом
Примитив - встроенная в редактор сцен трехмерная модель т. н. "примитивного" объекта - куба, конуса, цилиндра и т. д.
Оглавление
Введение
Глава 1. Обзор предметной области и анализ существующих решений
1.1 Наборы инструментов и библиотек с открытым исходным кодом
Глава 2. Алгоритмы и структуры данных разработанного решения
2.1 Структура данных
2.2 Алгоритмы
2.3 Априорный и апостериорный расчёт коллизий
Глава 3. Технические особенности реализации
3.1 Выбор библиотек
3.2 Функционирование программы
Заключение
Список использованных источников
Введение
Большинство существующих коммерческих и свободно доступных игровых движков предоставляют широкий спектр инструментов и возможностей для разработки компьютерных игр любых видов и жанров. Для исследования процесса создания игры было решено разработать собственный набор средств для создания трехмерных компьютерных игр. В результате разработки при помощи созданного решения пользователь сможет создавать трехмерные сцены из трехмерных моделей, а также иметь возможность воспроизвести сцены ("сыграть" в них).
Один из основных недостатков большинства существующих инструментариев для разработки трехмерных игр - это перегруженность функционалом. Несмотря на то, что подобные решения предоставляют широкий набор встроенных функций для создания игр, они также имеют высокий порог вхождения для новичка в области создания игр. Также существует проблема недоступности определенных инструментов на различных платформах. Так, например, библиотека DirectX (включающая в себя графическую библиотеку Direct3D) доступна только для использования в операционной системе Windows, из-за чего некоторые игровые движки и игры, разработанные с их помощью, не доступны на некоторых платформах.
Целью данной работы является разработка двух модулей: модуль создания трехмерных сцен и модуль воспроизведения созданных сцен.
Задачами выпускной квалификационной работы является:
1) Изучить предметную область.
2) Проанализировать существующие решения данной задачи.
3) Изучить технологию исполнения стороннего кода (скриптов Lua) при исполнении программы.
4) Освоить работу с OpenGL для рендеринга изображений в реальном времени.
5) Разработать структур данных игровых ресурсов, а также алгоритмов взаимодействия с ними.
6) Разработать архитектуру модуля редактирования сцен
7) Разработать и протестировать модуль редактирования сцен
8) Разработать архитектуру модуля для загрузки и исполнения действий, установленных на сцене.
9) Разработать и протестировать модуль загрузки и исполнения сцен
10) Оформить техническую документацию.
Работа состоит из трех глав. В первой главе описывается предметная область и различные аналоги, существующие на рынке. На основе данных описаний обосновывается необходимость создания программного продукта.
Во второй главе описывается разработанная архитектура приложения, а также описываются основные задачи, вставшие при разработке приложения. Для каждой задачи приводятся несколько вариантов решения и обосновывается принятое решение.
Третья глава описывает технические средства, использованные при разработке выпускной квалификационной работы, описывается разработанное решение. программа трехмерный игровой
Приложение содержит техническую документацию к проекту: техническое задание, программа и методика испытаний, руководство оператора, текст программы.
Глава 1. Обзор предметной области и анализ существующих решений
В данной главе приводится обзор предметной области, а также анализ существующих решений, как в области полноценных наборов инструментов, так и в виде разрозненных инструментов. В заключение приводится постановка задачи на разработку программного.
Предметная область
Предметная область данного проекта - разработка игр. В ходе создания игры пользователю (создателю игры) необходимо иметь возможность редактировать сцены и настраивать объекты, находящиеся на сцене. Также пользователю необходимо иметь возможность воспроизвести сцену - "сыграть" в созданные сцены.
Редактор сцен
Рисунок 1 - Редактор сцен коммерческого продукта Unreal Engine
Редактор сцен - это основной инструмент разработки игры. При помощи данного инструмента пользователь имеет возможность создавать уровни, а так же добавлять на каждый уровень объекты для взаимодействия с пользователем, будь то препятствие или игровой персонаж. Обычно редактор сцен содержит обзор текущей сцены и набор полей для взаимодейтсвия с пользователем - разработчиком игры. Одна из основных задач редактора сцен - заполнение уровня трехмерными моделями и настройка взаимодействия пользователя с ними. Также необходима возможность сохранения созданных сцен для дальнейшего воспроизведения. Ниже на рис.1 представлен пример существующего редактора сцен.
На данной иллюстрации демонстрируется редактор сцен Unreal Engine (Разработан компанией Unreal, https://www.unrealengine.com). Созданная сцена отображена в центре окна, и она окружена панелями инструментов. Так, например, слева от сцены находится список примитивов и специальных объектов сцены, таких, как источник света. В нижней части экрана отображен список директорий с данными, содержащимися на сцене, в то время, как справа находится список объектов сцены и управление параментрами объекта сцены (данная панель не отображена на скриншоте, так как ни один объект не выделен). В панели над областью отрисовки сцены находятся кнопки управления сценой - сохранение, воспроизведение и т.д.
Программа воспроизведения созданных сцен
В результате работы с редактором сцен получается набор сцен-уровней, которые необходимо "воспроизвести" - сыграть в них. В данном случае термин "воспроизвести" используется вместо термина "играть", поскольку также существуют жанры игр "визуальные новеллы" и "интерактивное кино", где интеракция с пользователем практически не происходит. Однако даже такие игры содержат набор сцен и объектов, которые взаимодействуют между собой.
Каждый игровой движок имеет свой уникальный формат хранения данных о созданных сценах, и соответственно каждый имеет свою уникальную программу для чтения и воспроизведения созданных сцен. Таким образом этот инструмент образует вторую необходимую состовляющую часть набора инструментов для создания игр.
Существующие решения
Существует множество как свободных решений с открытым исходным кодом, так и проприетарных, коммерческих наборов инструментов для создания трехмерных компьютерных игр. В данной секции рассматриваются оба вида инструментов.
Проприетарные продукты
Проприетарная программа - программа с закрытым исходным кодом и ограниченной лицензией на использование. В частности, три наиболее известных игровых движка - Unreal Engine, Unity3D (разработан Unity Technologies, https://unity3d.com) и CryEngine (разработан Crytek, https://www.cryengine.com/) позволяют свободное некоммерческое использование, но требуют покупку лицензии для возможности продажи игр, созданных на их базе. Также проприетарные продукты могут не позволять запуск на различных операционных системах. Так, например, редактор сцен Unity3D для ОС на базе ядра Linux все еще находится в тестировании, в то время, как CryEngine поддерживает работу только с OS Windows.
Также из-за конкуренции за рынок средств разработки игр каждый из коммерческих продуктов стремится иметь как можно более широкий функционал, тем самым повышая порог вхождения нового разработчика. В то же время зачастую из-за введения новых функций благодаря развитию технического оснащения современных персональных компьютеров данные продукта становится невозможно запустить на более старых ПК.
Помимо полноценных пакетов продуктов также существуют проприетарные библиотеки, рассчитанные на работу с определенной комплектацией компьютера разработчика или пользователя. Так, например, существует библиотека NVidia PhysX (разработка компании NVidia, https://developer.nvidia.com/physx-sdk), предоставляющая качественную физическую симуляцию нетвердых тел. Однако данная поддерживается только компьютерами с видеокартами NVidia 8 серии и выше. Аналогичные библиотеки предоставляет и компания AMD (https://www.amd.com/en/technologies/tressfx). Также на рынке существует коммерческая библиотека физической симуляции Havok (разработан компанией Havok, https://www.havok.com/), которая, однако, из-за высокой ценовой категории не позволяет энтузиастам использовать его в играх.
1.1 Наборы инструментов и библиотек с открытым исходным кодом
Существует множество различных реализаций инструментов, созданных энтузиастами. Зачастую основной задачей разработки такого инструмента стоит разработка библиотеки, позволяющей программисту включить ее в свою игру. Такими библиотеками являются Bullet Physics (http://bulletphysics.org/wordpress/) - свободная библиотека симуляции физических свойств объектов, или же SDL (https://www.libsdl.org/) - библиотека работы с пользовательским вводом, а также с выводом изображений и звука. Несмотря на широкий предоставляемый функционал, эти библиотеки требуют уже имеющихся наработок со стороны. Также существуют уже готовые инструменты для создания игр, однако из-за отсутствия коммерческой составляющей зачастую они являются нестабильными.
Анализ существующих решений
Основной недостаток коммерческих игровых движков, по мнению автора - это цена. Так, например, CryEngine и Unreal требуют 5% отчислений, в то время, как Unity требует подписки на использование Unreal Engine для возможности коммерческого распространения разработанных продуктов. Также CryEngine и Unity не имеют версий инструментов для ОС Mac OS X и Linux (стабильной версии в случае Unity), что является большим недостатком для пользователей данных ОС (коим является автор данной ВКР).
Unreal Engine позволяет создавать игровую логику как при помощи языков программирования (C++), так и с помощью встроенной системы "Blueprints" (рис. 2).
Система Blueprints предоставляет интерактивный интерфейс для создания игровой логики. Так, например, каждый блок является событием сцены либо объектом на сцене, где каждая точка внутри блока - это переменная либо метод. Связи между точками блока означают передачу данных (либо выходных значений метода) в другой метод, либо присваивание переменной. Как можно заметить, данная система дублирует объекты библиотеки Unreal при программировании логики на C++. Несмотря на визуальную нотацию и удобство использования, Blueprints требуют большего количества времени на создание алгоритмов логики, и, так же, как и библиотека Unreal для C++, страдает от избытка функций и объектов. Таким образом образуется высокий порог вхождения, где до того, как пользователь сможет создать собственную логику, ему необходимо изучить большое количество документации. Это явялется большим минусом.
Несмотря на доступность многих библиотек с открытым исходным кодом, они не предоставляют полноценный интерфейс для начала создания игр, и требуют дополнительных доработок со стороны программиста. Для данной разработки был выбран OpenGL (разработан Khronos Group, https://www.opengl.org/) как кросс-платформенная графическая библиотека, и Qt (https://www.qt.io/) для организации оконного интерфейса программы и работы с пользовательским вводом. Преимущество Qt по сравнению с библиотекой SDL состоит в том, что Qt позволяет использовать нативный для платформы интерфейс OpenGL на ОС Mac OS X, в то время, как библиотеки типа GLFW используют устаревшую MESA-версию OpenGL. Для реализации физических взаимодействий между объектами было решено реализовать свои алгоритмы для понижения скорости разработки (по сравнению с изучением и внедрением уже существующих решений, таких, как Bullet Physics).
Постановка задачи на разработку
В результате проведенного анализа рынка было принято решение разработать в рамках выпускной квалификационной работы программный продукт, соответствующий следующим требованиям:
- Программа должна позволять пользователю загружать трехмерные модели формата OBJ, или же создавать сцену при помощи заранее заданных "примитивных" моделей.
- Программа должна позволять пользователю изменять положение трехмерных моделей в пространстве сцены, а так же удаление их со сцены
- Программа должна позволять назначать исполняемые скрипты для объектов на сцене
- Программа должна иметь возможность сохранять и загружать файлы с данными сцен.
- Программа должна иметь возможность воспроизводить созданные файлы сцен и скрипты, установленные на объектах сцены
Выводы по главе
В этой главе подробно раскрывается предметная область, рассказывается о существующих решениях, проводится анализ аналогов и обосновывается разработка собственного программного решения. В конце главы приводится постановка задачи на разработку.
Глава 2. Алгоритмы и структуры данных разработанного решения
В данной главе рассматриваются архитектурные решения, принятые при разработке данной программы. В первой секции описывается разработанная структура данных для хранения информации об игре и обосновываются принятые решения. Далее описываются ключевые функции работы с программами, приводятся сравнения различных алгоритмов реализации данных функций и объясняется выбор реализованного алгоритма.
2.1 Структура данных
При разработке инструментов для разработки трехмерных игр возникла необходимость создания собственной структуры данных для хранения и работы с данными игровых ресурсов (скриптами, моделями, сценами и прочими). В этом разделе описываются основные детали разработанной структуры.
Структура хранения данных
Каждая игра состоит из нескольких сцен, которые необходимо пройти. Каждая из сцен представляет некоторую локацию с заданиями, которые нужно выполнить игроку для перехода на следующую сцену. Соответственно объект сцены является одни из ключевых при разработке структуры для хранения данных об игре.
Каждая сцена состоит из трех основных частей, необходимых для отрисовки на экране:
1. Камера (объект, обозначающий позицию и направление "взгляда" игрока)
2. Скайбокс (объект, представляющий окружающий мир при помощи 6 изображений)
3. Список объектов сцены:
a. Источников освещения
b. Набор экземпляров трехмерных моделей, находящихся на сцене.
Этих данных достаточно для отрисовки сцены на экране.
Каждый из экземпляров трехмерных объектов содержит список настроек, специфичных для данного объекта - его позицию в мире, параметры материала для отрисовки (блеск, прозрачность), его физические параметры (статичный или же подвижный, масса) и объект логики поведения, если он был назначен данному объекту. Поведение трехмерных объектов на основе заданной логики описывается в разделе 2.1.3.
Таким образом, в основе структуры данных, описывающих игру, лежит коллекция сцен, которые воспроизводятся по определенному принципу, заданному разработчиком игры при помощи скриптов (раздел 2.1.3). При реализации хранилища сцен использовалась структура данных "список", содержащий указатели на созданные сцены - таким образом, игра всегда начинает воспроизводиться с первой сцены в списке.
Репозиторий данных
Основной вид объекта, используемый для отрисовки трехмерных сцен на экране - это шейдерная программа - программа, исполняемая на GPU (Graphic Processing Unit, видеокарта). Во время отрисовки сцены могут использоваться одновременно несколько шейдерных программ, однако исполняются они поочередно. Для отрисовки каждого трехмерного объекта необходимо обозначить используемую шейдерную программу, после чего передать на отрисовку данные об объекте (текстуры и положения точек в пространстве). Данная операция происходит для каждого объекта, существующего на сцене. Однако одна и та же шейдерная программа может использоваться для разных объектов. Аналогично одна и та же модель может быть использована на сцене несколько раз, но с разными параметрами.
На рисунке 3 изображен пример сцены битвы из игры "Persona 5" (https://atlus.com/persona5/). Персонаж окружен четырьмя врагами, хотя каждый из них имеет одну и ту же трехмерную модель. Каждый из врагов имеет свои собственные параметры (место в пространстве, очки "жизней", очередь хода), но при этом информация для отображении модели на экране (точки в пространстве, текстуры, анимация) общая у всех четырех объектов.
Для оптимизации используемой памяти трехмерная модель загружается в память всего один раз - и сохраняется в "репозитории моделей". Данный репозиторий доступен в инструменте для редактирования сцен пользователю - при помощи него возможно добавлять объекты на сцену. При добавлении объекта на сцену создается объект "экземпляра модели", в котором хранится указатель на загруженную трехмерную модель, находящуюся в репозитории, а так же настройки этого экземпляра.
Аналогичный репозиторий используется и для шейдерных программ, однако он недоступнен для пользователя напрямую - использование шейдерных программ для отрисовки различных объектов определено строго и не поддается изменению.
Логика поведения трехмерных объектов
Во время воспроизведения сцены необходимо эмулировать не только взаимодействие объектов друг с другом, но и с окружающим миром. Для этого используются т.н. "скрипты" - некий алгоритм, описывающий поведение объекта в мире и его взаимодействие с окружающими его объектами. Такие алгоритмы обычно реализуются на скриптовых языках программирования, и написанный код исполняется во время исполнения самой игры.
Для скриптового языка, используемого в разрабатываемых средствах, был выбран язык Lua (ссылка). Для работы с объектами в интерпретаторе языка регистрируются основные методы работы с окружением объекта, а также данные самого объекта. При инициализации объекта загружается назначенный объект скрипта [4].
Методы работы с окружением
Во время исполнения сцены на некоторые объекты могут действовать физические силы (сила гравитации, столкновение с другими объектами). Для управления этими действиями в интерпретатор языка Lua (https://www.lua.org/) подается объект, обрабатывающий физические взаимодействия между объектами (далее - "физический движок", который подробнее описан в разделе 2.2.3), а также методы работы с ним. Так, например, при помощи обращения к физическому движку скрипт может отключить проверку на соприкосновения с другими объектами, либо же получить список ближайший объектов, с которыми возможно столкновение.
Данные объекта
Сам объект предоставляет все необходимые методы для работы с его позицией - это методы получения направления движения, текущего положения, методы для поворота, а также перемещения.
Несмотря на то, что движением объекта управляет физический движок, рассчитывая все действующие на объект силы, скрипт может "насильно" изменить положение объекта в пространстве, назначив объекту определенные координаты, но при этом сохраняя все силы, действующие на объекты. Аналогично при помощи скрипта можно добавить дополнительную силу к силам, действующим на объект, чтобы имитировать движение объекта.
Все логические скрипты пишутся пользователем - разработчиком игры при помощи сторонних текстовых редакторов. Скрипты могут быть назначены на объекты, находящиеся на сцене, и на саму сцену (глобальный скрипт). Пользователю доступны для использования методы, зарегистрированные в интерпретаторе Lua.
На рис. 4 продемонстрирована регистрация методов работы с объектом для последующего использования в игровых скриптах логики. Вызываемый метод будет применен к объекту, который зарегистрирован под именем "object".
На рис. 5 сверху показана регистрация объекта, используемая в коде разрабатываемого набора инструментов. В нижней части показывается пример использования - объект, зарегистрированный как "object" будет исполнять операции "moveUp" или же "moveDown" в зависимости от исполнения условия, определенного в скрипте.
Утилитные методы
Помимо методов работы над объектом и окружением объекта также существует несколько утилитных методов, позволяющих сохранять данные внутри объекта до следующего исполнения скрипта.
При отрисовке каждого кадра игры перед передачей всех объектов сцены на отрисовку в первую очередь исполняется логический скрипт, назначенный каждому объекту (если таковой имеется). После исполнения скрипта физический движок применяет все силы, действующие на объект, тем самым изменяя его положение в пространстве (транслируя его, подробнее это описано в разделе 2.2.2.2). Однако после исполнения скрипта все рассчитанные данные очищаются. Таким образом возникает необходимость предоставить скрипту некоторое хранилище данных, в котором было бы возможно хранить данные постоянно, вне зависимости от итерации исполнения скрипта.
В разрабатываемом наборе инструментов существует два типа хранилища данных - собственные данные объекта и данные сцены. Каждое из данных хранилищ является коллекцией переменных, доступных для чтения и изменения скриптом объекта, либо же логическими скриптами других объектов, способных взаимодействовать с данным объектом тем или иным способом.
Так, например, на рис. 4 представлен скриншот из игры (ссылка на игру), где существует 4 игровых персонажа (иконки персонажей изображены вертикально справа). Каждый из персонажей имеет набор параметров - очки "здоровья" (оранжевая полоса), по истечении которых игрок погибает и игра заканчивается, очки "действия" (синяя полоса), которые тратятся на действия во время игры (атаку монстров). Данные параметры могут изменяться при помощи логических скриптов - как собственных (восстановление здоровья), так и внешних (монстры на сцене при атаке снижают очки "здоровья" игроков). Очки "здоровья" и "действия" - это примеры собственных данных объекта.
Данные сцены - это "глобальные" данные, доступные для изменения и чтения всем объектам сцены. Эти данные используются для изменения состояния всех объектов, чьи логические скрипты проверяют определенный параметр данных сцены.
Пример использования глобальных данных сцене приведен на рис. 5, где изображена одна из сцен игры "Metal Gear Solid" (https://en.wikipedia.org/wiki/Metal_Gear_Solid). В данной игре игрок принимает на себя роль разведчика, проникающего в базу врага. В случае, если игрока заметят охранники - поднимется тревога, в течение которой охранники базы будут искать игрока. Это поведение обозначено красной табличкой "Alert" с таймером до окончания тревоги. Таким образом изменяется состояние всех врагов на сцене в зависимости от действий игрока. Для воссоздания такого поведения предлагается использовать данные сцены, в которых каждый из объектов сцены способен обновлять данные и тем самым оповещать другие объекты о каком-либо действии.
2.2 Алгоритмы
При разработке описанных инструментов возникла необходимость в реализации различных алгоритмов, описывающих внутриигровые процессы или же упрощающие создание игровых сцен. В данной секции описываются основные функции, реализованные в наборе инструментов, приводится описание существующих алгоритмов, реализующих данный функционал, а также приводится обоснование выбора реализованного алгоритма.
Управление моделью при помощи мышки
Во время создания трехмерной сцены разработчику необходимо расположить трехмерные объекты на сцене, а также иметь возможность перемещать объекты. Наиболее желаемой является возможность управлять положением объекта в пространстве при помощи мышки. Однако мышка перемещается по двухмерному пространству экрана, в то время как объекты сцены находятся в трехмерном пространстве. Существует два основных алгоритма, позволяющих решить эту задачу: Ray Casting и Color Picking.
Алгоритм Ray Casting
Один из алгоритмов, позволяющих определить, нажал ли пользователь на трехмерных объект - это проверить, пересекается ли "луч", определенный положением камеры и кликом мышки, с трехмерным объектом.
Имя алгоритма "Ray Casting" (в переводе на русский - "Пускание луча") говорит само за себя. При нажатии мышкой на экран создается "луч", начинающийся из позиции камеры (смотрящего в трехмерном пространстве) и проходящего через точку ближней плоскости, по которой нажал пользователь (рис. 8).
Однако координаты видимого пространства не совпадают с координатами трехмерного пространства, в котором существуют все трехмерные объекты сцены. При отрисовке каждого трехмерного объекта каждая точка проецируется на экран (двухмерное пространство), тем самым искажая координаты (рис. 9). Таким образом полученный луч необходимо "депроецировать" из видимого пространства в трехмерное для дальнейшей проверки пересечения трехмерной модели и луча.
Рисунок 9 - Проекция трехмерного пространства в видимое
Однако далее необходимо проверить, пересек ли луч одну из трехмерных моделей на сцене. Для этого необходимо либо проверять столкновение луча с каждым полигоном модели (что является крайне трудоемкой задачей для моделей, имеющих десятки или же сотни тысяч полигонов), либо рассчитывать охватывающую фигуру для каждой модели. Простейшей такой фигурой является параллелепипед, который полностью вмещает в себя трехмерную модель (иногда также используется сфера, или же прочие фигуры, легко описываемые при помощи математической формулы) (рис. 10).
Однако для такого алгоритма возможна ошибка, когда луч, пересекающий охватывающую фигуру, на деле не пересекается с трехмерной моделью. Возможно после пересечения луча с охватывающей фигурой проверить уже на столкновение с объектом, однако этот процесс может также занять долгое время из-за большого количества полигонов объекта.
Алгоритм Color Picking
При отрисовки сцены получается двухмерное изображение, которое пользователь (разработчик или же игрок) видит на своем экране. При помощи методов графических библиотек имеется возможность получить данное изображение, и также получить координаты пикселя, на который была наведена мышка во время клика (выбора модели). Каждый пиксель представлен несколькими байтами, которые определяют цвет, отображаемый на экране. Таким образом, если закодировать уникальный код модели в ее цвет - то возможно однозначно определить, какой объект был выбран пользователем.
Для использования данного алгоритма необходимо выполнить дополнительную отрисовку сцены. Она выполняется по клику мышкой и отрисовывается не на экран, а в буферный объект GPU. При дополнительной отрисовке для вычисления цвета пикселя не используются текстуры, расчет цвета от источников освещения, материалов и прочее. Для определения цвета пикселя используется монотонный цвет, соответствующий индексу объекта. Далее из буфера извлекается нужный пиксель (с координатами клика мышкой, риc. 11), и цвет декодируется в идентификатор объекта.
Данный алгоритм был использован при разработке функционала выбора объекта по клику мышкой из-за его скорости. Для выбора объекта методом "Color Picking" (в переводе на русский "Выбор цвета") не требуется производить сложных вычислений по расчету пересечения луча с трехмерным объектом и расчету охватывающей фигуры с трехмерным объектом. Все необходимые для идентификации объекта действия выполняются графической библиотекой и видеокартой, и время выбора объекта зависит только от времени отрисовки одного кадра трехмерной сцены. Однако этот метод накладывает ограничение: на сцене не может быть более трехмерных объектов. Это ограничение появляется из-за формата кодирования объекта.
Для кодирования используются 3 значения цвета, используемого для отрисовки объекта - R (Red, красный цвет), G (Green, зеленый цвет) и B (Blue, синий цвет). Каждый из данных цветов принимает значение от 0 до 255. Соответственно различные комбинации данных полей используются для кодирования объекта, за исключением цвета (0, 0, 0), который используется для кодирования пустоты.
На рис. 12 представлена реализация алгоритма Color Picking. Объект ObjectPicker с именем picker используется для инициализации буфера отрисовки, и при вызове метода start изменяет текущий буфер отрисовки на собственный (вместо экрана). После окончания отрисовки (вызова метода render) требуется переключить режим отрисовки обратно на экран (метод stop()). Далее извлекается массив из трех значений unsigned int - это описанные выше значения RGB пикселя. При помощи этих значений можно получить объект, который был выбран мышкой (метод сцены chooseEntity).
Проекция положения мышки на положение выбранного объекта
Зачастую пользователь выбирает объект для того чтобы изменить его положение в пространстве, для чего также желательно использовать мышку. Однако, как раннее упоминалось в разделе 2.2.1.1, мышка передвигается в двухмерном пространстве. Таким образом при использовании мышки объект можно передвигать только в плоскости. Такими плоскостями были выбраны плоскости, проходящие через центр координат модели, и параллельные осям XY, XZ и YZ. Далее эти плоскости называются плоскостями перемещения, и выбираются пользователем при помощи графического интерфейса редактора сцен.
Для определения новой координаты модели в трехмерном пространстве используются алгоритм "Ray Casting", однако вместо проверки на пересечение с моделью проверяется пересечение луча с плоскостью перемещения. Точка пересечения является новой точкой, которая должна совпадать с центром координат модели.
При расчете луча необходимо получить координаты нажатия мышки и "депроецировать" их в координаты пространства (раздел 2.2.1.1., рис. 13) при помощи матрицы обозрения и матрицы проекции. Данные матрицы принадлежат объекту Camera и получаются при помощи методов getViewMtr и getProjectionMatrix. Таким образом вектор луча, пущенного при помощи мышки, будет разностью координат нажатия мышкой ближней и дальней плоскости (mouseClickNear - mouseClickFar).
На рис. 14 представлен алгоритм, рассчитывающий новые координаты объекта. При помощи интерфейса указывается одна из плоскостей перемещения, которая задается тремя точками (plane.A, plane.B и plane.C). Эти точки проецирутся так, чтобы плоскость, пересечение с которой необходимо найти, проходила через центр координат тела, необходимого переместить. Далее находится точка пересечения луча и плоскости - эта точка является новой координатой центра координат тела [6].
Трансформация объекта
Необходимо иметь возможность перемещать, поворачивать и масштабировать каждый трехмерный объект. Эти три действия называются трансформацией объекта. Существует два типа трансформаций - относительная трансформация и абсолютная.
Редактор: Абсолютная трансформация
Абсолютная трансформация назначает объекту конкретно заданные параметры - координаты в пространстве, поворот, масштаб. Абсолютные изменения положения в пространстве используется при назначении объекту положение в пространстве мышкой (см. пункт 2.2.1.3). Абсолютные трансформации используются при работе с моделью в редакторе сцен.
Воспроизведение: Относительная трансформация
Относительные трансформации проводятся относительно текущего состояния объекта в пространстве. Это действия типа "продвинуться вперед" или же "повернуться вправо". Для этих действий необходимо заранее просчитать все необходимые параметры объекта - направление движения, текущий поворот, текущее положение. Подобные трансформации используются в основном логическими скриптами объектов при воспроизведении сцены.
Обработка взаимодействия объектов друг с другом
Во время воспроизведения сцены необходимо просчитывать столкновения и взаимодействия объектов друг с другом. Однако несмотря на то, что все объекты могут взаимодействовать друг с другом - не на все объекты действуют физические силы. Так, например, мячик, падающий на Землю, отскочит от Земли и продолжит свое движение, в то время как Земля не изменит свои параметры из-за столкновений с мячиком [2]. Таким образом стоит выделить два типа объектов на сцене - статичные объекты, не изменяющие свои параметры (не трансформирующиеся) из-за физического взаимодействия, и динамичные объекты, на которые действуют физические силы.
2.3 Априорный и апостериорный расчёт коллизий
Во время воспроизведения сцены необходимо проверять, не столкнулись ли трехмерные объекты друг с другом. В случае столкновения необходимо применить два действия - изменить положение объекта в пространстве, чтобы нейтрализовать видимое столкновение (трехмерные модели не должны пересекаться), а также приложить силы, которые отразят воздействие одного объекта на другой. Существует два способа обработки столкновений - априорный (проверки до применения всех сил) и апостериорный (после применения всех физических сил). Оба этих способа различаются методами пересчета сил, взаимодействующих на трехмерный объект.
В случае априорной проверки на столкновение помимо силы отталкивания объекта от того, с которым объект столкнулся, необходимо также добавить силу, которая бы "вытолкнула" объект, тем самым устранив столкновение.
Апостериорная проверка устраняет столкновения объектов путем абсолютного изменения положения объекта в пространстве, после чего применяется сила отталкивания.
При разработке данных инструментов была использована апостериорная проверка.
Охватывающая фигура
Как уже упоминалось в пункте 2.2.1.1. - рассчитывать столкновения с объектом напрямую - крайне трудоемкая задача. Однако в отличие от алгоритма "Ray Casting" для обработки столкновений объектов необходимо проверять попарно все полигоны, что значительно повышает трудоемкость задачи. Поэтому вводят в рассмотрение охватывающие фигуры ("Bounding Shape") [3].
Охватывающая фигура - это фигура, полностью включающая в себя трехмерную модель. На рис. 15 отображены наиболее простые охватывающие фигуры - сфера и параллелепипед. Основная причина использования таких форм - это возможность описать их математической формулой либо же наименьшим числом точек в пространстве (1 точка для сферы, 2 точки для параллелепипеда). Для минимизации "пустого" пространства (пространства, не занятого моделью внутри охватывающей фигуры) при разработке данного алгоритма был использован параллелепипед.
При создании охватываюзей фигуры используется алгоритм AABB (Axis-Aligned Bounding Box, "Параллельная осям координат охватывающая коробка"). При расчете охватывающей фигуры сохраняются минимальные и максимальные координаты x, y, и z точек модели. На основании этих координат создается "коробка", полностью охватывающая трехмерную модель. Ребра данной фигуры параллельны осям координат.
Однако далее во время симуляции (или изменения положения объекта в редакторе сцен) охватывающая фигура трансформируется вместе с трехмерным объектом, чтобы гарантировать охват всей модели, сохраняя при этом параллельность ребер осям координат (рис. 16).
На рис. 17 приведен реализованный алгоритм создания охватывающей фигуры по алгоритму AABB. Для вычисления необходимо найти минимальные и максимальные значения координат точек фигуры. Для этого необходимо перебрать все существующие точки (при реализации данные точки передаются в структуре данных типа "список"). Данные значения хранятся в виде 8 точек, описывающих параллелепипед, полностью охватывающих трехмерный объект.
При изменении трансформации объекта в пространстве (повороте, перемещении) матрица трансформации применяется к каждой из точек охватывающей фигуры, после чего рассчитывается новая охватывающая фигура на основании предыдущей, трансформированной охватывающей фигуры. Реализация показана на рис. 18 - ко всем точкам охватывающей фигуры (fld, frd и т. д.) применяется трансформация, после чего вызывается метод перерасчета охватывающей фигуры calcBox.
Проверка на близость с объектом
Один из алгоритмов уменьшения количества проверок на пересечение охватывающих фигур - это более грубая проверка на соприкосновение до того, как начнется "настоящая" проверка. Для реализации такой проверки необходимо знать только "центр" трехмерной модели и некое значение максимальной длины. Такие два параметра описывают сферу, которая полностью охватывает всю трехмерную модель. При реализации данной оптимизации принималась сфера, полностью охватывающая не саму модель, а параллелепипед, охватывающий трехмерную модель. Таким образом перед проверкой на пересечение охватывающих фигур сперва идет более грубая проверка - не сблизились ли модели ближе дозволенных значений для каждой из модели.
На рис. 19 схематично изображен пример работы такого алгоритма. Красным обозначена охватывающая фигура для каждой из модели, зеленым обозначена сфера предварительной проверки. Все объекты на сцене попарно проверяются сперва подобным алгоритмом. Поскольку проверка пересечения параллелепипедов - гораздо более времязатратная задача, чем проверка расстояния между двумя точками в пространстве - это позволяет отсеять большую часть объектов на сцене и проверять только те объекты, которые находятся слишком близко друг к другу.
Реализация этого алгоритма приведена на рис. 20 - объекты попарно сравниваются друг с другом на предмет чрезмерной "близости". Эта "близость" определена значением rad структуры охватывающего параллелепипеда, получаемого методом getBox. В случае, если объекты находятся слишком близко друг к другу - они добавляются в список пересчета столкновений.
"Острова" объектов
При увеличении количества объектов на сцене возрастает время обработки столкновения или даже сближения объектов между собой. Поскольку проверка требует попарного сравнения - количество проверок возрастает экспоненциально с добавлением каждого нового объекта на сцену. Для решения этой проблемы существует алгоритм построения "островов" объектов - объединения рядом находящихся подвижных объектов в группы.
Как показано на рис. 21 - динамические (подвижные) объекты, соприкасающиеся или находящиеся друг с другом ближе дозволенной погрешности (см. пункт 2.2.3.3) объединяются в группы (называемые "островами"). Каждый из островов имеет свое "расстояние дозволенной близости", как описано в предыдущим пункте, а также особый параметр "спокойствия", означающий, необходимо ли применять физические силы для объектов данного "острова". Так, например, если вся группа объектов перестала двигаться (из-за уравновешения всех сил, действующих внутри группы) - то для данной группы более не нужно применять физические силы до того момента, когда новый объект не попадет в данную группу.
В результате изменения положения трехмерных объектов в пространстве "острова" могут объединяться или же разбиваться на более малочисленные группы. В случае появления нового объекта в группе необходимо изменить параметр "спокойствия" и начать пересчитывать силы, действующие на объекты внутри острова. Также необходимо пересчитать "расстояние дозволенной близости" в момент, когда группа объектов вновь перейдет в состояние "спокойствия".
Благодаря этому алгоритму время обработки физических сил и расчета столкновений уменьшается в разы. Также в случае появления движущегося объекта на сцене не требуется проверять соприкосновение уже существующих объектов на сцене - достаточно проверить только соприкосновение одного движущегося объекта с каждым островом - тем самым избавляясь от необходимости попарной проверки между всеми объектами сцены.
На рис. 22 показан алгоритм создания "острова" из набора объектов objects. При создании "острова" объектов каждый остров считается единым, глобальным объектом, где так же, как и у обычного объекта есть центр и дозволенный радиус приближения объекта к острову, где центр острова рассчитывается как среднее всех центров объектов, а радиус - это сумма расстояния от центра острова до самого дальнего объекта и радиуса самого дальнего объекта. Однако в отличие от расчета соприкосновения объектов при приближении объекта к острову он регистрируется в острове, после чего рассчитываются новые параметры острова. Аналогично и при удалении объекта из острова. Данные алгоритмы продемонстрированы на рис. 23.
Выводы по главе
В этой главе описывается реализованная структура данных для хранения данных, описаны методы управления поведением объектов на сцене, а также описаны различные алгоритмы, использованные при разработке редактора сцен. Большинство из описанных алгоритмов и структур данных имеют иллюстрацию, демонстрирующую пример работы алгоритма или же возможности использования структуры данных. Для некоторых разработанных функций приведены примеры альтернативных алгоритмов, и приводится пояснение, почему они не были выбраны.
Глава 3. Технические особенности реализации
В данной главе описывается программная реализация данной ВКР: обосновывается выбор технических средств, использованных при разработке, а также описывается работа редактора.
3.1 Выбор библиотек
OpenGL
Одна из основных требуемых функций редактора сцен и программы воспроизведения сцен - это рендеринг трехмерных объектов и сцен на экране. Реализация этого функционала доступна при помощи библиотек OpenGL и Direct3D, а также набора библиотек-"оберток" над ними. Для реализации была выбрана библиотека OpenGL, поскольку она является кросcплатформенной, и при этом является самой низкоуровневой библиотекой для прямого управления действиями видеокарты (рендеринг объектов). Было принято решение не использовать сторонние библиотеки, упрощающие работу с OpenGL, для более тонкой настройки рендеринга сцен.
Qt
Поскольку OpenGL не поддерживает создание окон в оконном сервере операционной системы, возникает потребность использовать дополнительные библиотеки, обеспечивающие связь OpenGL с оконным интерфейсом. Аналогично требуется поддерживать пользовательский ввод данных с клавиатуры или же при помощи мышки. Существует множество библиотек, обеспечивающих связку OpenGL с оконным интерфейсом операционной системы (GLFW, http://www.glfw.org/, GLUT, https://www.opengl.org/resources/libraries/glut/, SDL, https://www.libsdl.org/)
Фреймворк Qt был выбран по двум причинам. Одно из преимуществ этого фреймворка перед большинством прочих библиотек - это дизайнер интерфейсов, позволяющий создавать графические объекты управления программой в окне (кнопки, поля ввода текста, слайдеры и пр.). Фреймворк Qt оперирует понятием "Виджет" - объектом, отрисовывающимся в окне. Все графические объекты окна Qt являются виджетами, и каждый из объектов может быть расширен и доработан пользователем по мере необходимости.
Один из видов виджетов, предоставляемых фреймворком Qt, является QOpenGLWidget - это виджет, в котором может отрисовываться изображение при помощи библиотеки OpenGL. Qt инициализирует контекст OpenGL при инициализации этого виджета, предоставляя интерфейс вызова всех доступных функций библиотеки OpenGL.
Вторая причина выбора Qt - это набор инструментов, предоставляемых разработчику при работе с OpenGL.
При отрисовке трехмерного объекта необходимо использовать математическую библиотеку, поддерживающую работу с векторами и матрицами. Каждая из трехмерных моделей, передаваемая на отрисовку в OpenGL, является набором точек в трехмерном пространстве. Изменение положения трехмерной модели в пространстве организуется при помощи матриц трансформации, несущих информацию об изменении положения точек в пространстве. Эти матрицы создается при помощи программы, исполняющейся на CPU, после чего передается на GPU (при помощи OpenGL)[1] вместе с точками-вершинами полигонов, которые необходимо нарисовать. Существует множество математических библиотек, реализующих операции с векторами и матрицами (glm, sb7-math), однако Qt имеет собственную реализацию данных операций как часть фреймворка.
Помимо математических библиотек зачастую необходимо использовать библиотеки для работы с изображениями. Помимо списка точек в пространстве трехмерные объекты могут иметь т. н. текстуры - изображения, накалывающиеся на модель.
В состав трехмерной модели часто входит изображение (или набор изображений), которые необходимо наложить на модель при отрисовке, вместе с набором правил наложения. На рис. 24 справа и слева вверху приведены примеры изображений, которые используется для наложения я на трехмерную модель (слева вверху - текстура головы и шлема, справа вверху - текстура тела). Каждому пикселю изображения текстуры соответствует точка трехмерной модели. Раскраска полигона (треугольника в трехмерном пространстве) соответствует треугольнику на текстуре.
Для использования изображения необходимо загрузить и декодировать файл изображения, после чего набор байт изображения передать в GPU. Qt предоставляет набор инструментов, позволяющих это сделать, а также перевести изображение в формат, передаваемый в OpenGL.
Assimp
Обычно трехмерные модели описаны набором полигонов (треугольников). Однако многие трехмерные модели могут иметь тысячи или же сотни тысяч полигонов. Чем выше количество полигонов - тем более высоко детализирована модель, и, следовательно, тем большее информации нужно записать для хранения трехмерной модели на жестком диске. Также многие трехмерные модели имеют дополнительную информацию - кадры анимации, наложение текстур, подгруппы полигонов, материалы и т.д.
Существует множество различных видов упаковки и хранения трехмерных моделей. Так, например, формат Wavefront OBJ является текстовым форматом, при использовании которого в файле последовательно хранятся вершины полигонов модели, нормали и координаты текстур вершин, а также сами полигоны. Однако большинство форматов являются бинарными и требуют реализации алгоритма извлечения данных модели из файла. Существует множество различных библиотек для распаковки файлов 3D моделей (OpenSceneGraph, http://www.openscenegraph.org, ObjLoader, http://www.kixor.net/dev/objloader/, COLLADA, https://www.khronos.org/collada/). При реализации данной программы была использована библиотека Assimp (http://www.assimp.org/) из-за большого набора поддерживаемых форматов загрузки трехмерных объектов по сравнению с остальными.
3.2 Функционирование программы
В данном разделе описывается функционал основного инструмента для создания трехмерных игр - редактор сцен. Приводится описание основных элементов интерфейса и их использования, а также скриншоты разработанной программы. Данная программа была разработана для 64-битной операционной системы Mac OS X версии не ниже 10.10. Скриншоты представляют интерфейс разработанного приложения, исполняемого при запуске приложения GCUEditor.app.
Редактор: Управление сценами
Как уже было упомянуто в разделе 2.1.1, сцена является одной из ключевых структур данных в разрабатываемой игре. При помощи редактора сцен можно создавать новые сцены, переименовывать их и перемещаться между ними. Также при создании сцены существует возможность загрузки скайбокса для сцены.
Редактор: Управление объектами на сцене
При помощи элементов интерфейса и мышки пользователь может создавать, удалять и изменять положение объектов на сцене. Верхняя панель целиком отвечает за управление положением объекта на сцене, в то время, как права панель позволяет загружать новые модели в репозиторий данных, создавать их на сцене или же удалять со сцены.
Также существуют утилитные функции интерфейса, облегчающие управление объектами на сцене - это "заблокировать выделение мышкой" и "сфокусироваться на объекте". При нажатии на кнопку "Focus" камера будет перемещена так, чтобы выделенный объект оказался в центре экрана.
Подобные документы
Создание программы, реализующей игру "Линии". Среда разработки программы, описание ее общего вида. Основные алгоритмы программы. Реализация программы в среде разработки Microsoft Visual Studio 2008 на языке объектно-ориентированного программирования С++.
курсовая работа [639,0 K], добавлен 16.03.2012Порядок описание процесса разработки модели для разрешения задачи программирования с помощью средств языка программирования. Структуры данных и основные принципы их построения. Этапы компьютерного моделирования. Этапы и значение написания программы.
курсовая работа [19,5 K], добавлен 19.05.2011Стадии разработки программного средства. Средства, методологии и методы его разработки. Оценка надежности и качества проекта. Обоснование необходимости разработки программы. Тестирование как процесс выполнения тестовой программы с намерением найти ошибки.
презентация [57,0 K], добавлен 27.12.2013Реализация анкеты "Литературные предпочтения" средствами разработки PHP, MYSQL. Структура баз данных и приложения. Программная реализация анкеты на языке программирования php, руководство пользователя. Разработка PHP скриптов. Листинг программы.
курсовая работа [351,1 K], добавлен 02.12.2010Создание компьютерной игры посредством среды программирования Delphi. Инструменты разработки, компоненты и методы для разработки программы. Логическая и физическая структуры, основные функции и элементы управления программы, ее тестирование и отладка.
курсовая работа [27,9 K], добавлен 26.07.2014Программный комплекс для разработки программы транслирующей программу с языка Pascal на язык С++. Построение логической и арифметической модели решения. Разработка компилятора для программы. Методы отладки программы и создание для нее документации.
курсовая работа [742,6 K], добавлен 03.07.2011Администрирование баз данных. Проектирование баз данных, язык запросов к базе данных. Анализ средств разработки приложений. Планирование разработки программы "Электронный каталог" для библиотеки ОГАУ, предварительный проект и практическая реализация.
дипломная работа [1,2 M], добавлен 02.06.2015Особенности разработки и отладки программы на языке Pascal (Delphi), в операционной системе Windows 7 Ultimate. Описание, назначение, функции, оборудование, программное обеспечение, алгоритмы, математическая основа, тесты и интерфейс программы DMC.exe.
курсовая работа [422,7 K], добавлен 28.05.2010Принципы визуального программирования. Создание программы, генерирующей звук через определенные промежутки времени. Visual Basic как средство разработки прототипов программы, для разработки приложений баз данных и компонентного способа создания программ.
лабораторная работа [1,1 M], добавлен 10.12.2014Краткий обзор и анализ ныне существующих программно-педагогических средств обучения. Методика и порядок разработки электронного учебника по предмету "Язык программирования C++". Общая характеристика и основные формы входных и выходных данных программы.
курсовая работа [232,6 K], добавлен 10.09.2010