IrrlichtСтатьи

Пермещение по сферической поверхности

Автор:

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

Перемещение по сфере

Написанное в данной статье относится к графическому движку IrrLicht. Однако она не посвящена каким-либо особенностям данного движка.  Основная идея статьи может быть легко перенесена на любой другой графический движок.

Итак, представьте себе, что вам захотелось написать стратегию или экшен, но поверхность, на которой происходит действие не  плоская, а сферическая. Конечно, данная идея не является новой, эта идея реализована в очень многих современных компьютерных играх. Но все-таки, если мы решили сделать именно такую игру, какие проблемы могут у нас возникнуть? Для начала предлагаю определиться с целями, выбрать, что именно мы хотим сделать.
Итак в игре у нас должно быть реализовано следующее:
1.В сцене у нас имеется сферическая поверхность (например, поверхность планеты). Для простоты примем, что поверхность абсолютно круглая, без возвышенностей и углублений. Для красоты добавим туда солнышко, небольшой спутник и звездное небо.
2.Необходимо реализовать перемещение камеры по данной поверхности, а именно движение вперед, назад, влево, вправо, а так же повороты камеры влево и вправо. Управление реализуем с клавиатуры. Итого 6 клавишь.
3.Для того чтобы нам не было скучно летать по пустой планете, добавим несколько объектов со случайными координатами и направлением.
Вот скриншот нашей будущей игры
pic1 | Пермещение по сферической поверхности
А теперь как же нам все это реализовать? Давайте рассмотрим по порядку следующие вопросы:
1.Какую систему координат использовать? Как хранить данные о положении и ориентации в пространстве объекта?
2.Как нам собрать сцену?
3.Как нам реализовать перемещение камеры?

Система координат. Хранение данных

Я предлагаю использовать матрицы. Матрица - это двумерный массив вещественных чисел. В компьютерной графике используются матрицы размерностью 4х4. Матрица такого размера позволяет хранить данные об ориентации объекта и о положении его в пространстве. Рассмотрим небольшой пример для чайников.
pic1_ | Пермещение по сферической поверхности
У нас имеется глобальная система координат (оси X, Y, Z). А так же имеется некоторый объект в пространстве. Помимо того, что этот объект имеет определенные координаты в пространстве по отношению к глобальной системе координат, он еще определенным образом ориентирован в пространстве. Т.е. у него имеется своя система координат (оси X’, Y’, Z’). Для того, чтобы описать его ориентацию, достаточно описать координаты векторов X’, Y’, Z’. Вся эта информация содержится в матрице размерностью 4х4.
Если мы рассмотрим все это с точки зрения нашей задачи, то придем к выводу, что для описания положения и ориентации одного объекта нам одной матрицы более чем достаточно. Я имею в виду, что нам даже не обязательно хранить информацию о положении, оно следует из его ориентации.
pic2 | Пермещение по сферической поверхности
Если с этим все понятно, давайте переедем к следующему вопросу.

Сцена

Сцена включает в себя объекты, которые нам надо отобразить, камеры, системы частиц и. т.п. Но сцена – это не просто набор этих элементов. В любом уважающем себя графическом движке (к которым относится IrrLicht),  все эти элементы расположены в определенной иерархии, в виде дерева. И координаты каждого объекта задаются не относительно глобальной системы координат, а относительно родительского узла (Node).
Рассмотрим дерево нашей сцены.
pic4 | Пермещение по сферической поверхности
В самом верху находится корневая нода – глобальная система координат.
К ней мы привяжем солнце в виде билбоарда с какими-нибудь ненулевыми координатами, например (300, 300, 300).
Так же к корневой ноде приделаем сутую ноду, к которой приделаем меш астероида – спутника. При чем пустая нода будет иметь нулевые координаты, а меш не нулевые (70, 0, 0). Все это делается для того, чтобы анимировать вращение спутника вокруг планеты. Т.е. мы будем вращать пустую ноду,  и спутник будет вращаться вместе с ним. Для красоты добавим еще вращение спутника вокруг своей оси. Для того, чтобы нам не заморачиваться со всеми этими вращениями используем такой элемент, как ISceneNodeAnimator. Мы просто добавим его в самом начале и благополучно забудем.
И конечно не забудем приделать к корневой ноде саму сферу – нашу планету. Она будет иметь нулевые координаты. Используем меш, который содержит сферу единичного радиуса, а потом используем setScale, чтобы растянуть нашу сферу до нужного размера SPHERE_RADIUS. Потом можно будет поиграться с этим значением.
Создадим скайбокс. Это будат наше звездное небо.
Камеру мы тоже не будем прибавлять непосредственно к корневой ноде. Создадим пустую ноду, а затем уже к ней добавим камеру. Пустая нода будет иметь нулевые координаты, камера имеет координаты (0, 15, -2). Так же нам потребуется еще одна пустая нода, чтобы указать, куда должна смотреть камера. Пускай у неё будут координаты (0, 10, 3). Я специально сделал Z = 3, а не 0, потому что это гораздо удобнее, когда камера вращается не вокруг того места, на которое смотрит. Вы сами можете в этом убедиться. Тут нужно еще пояснение по поводу того, зачем же нам создавать эту ноду. Дело в том что при создании камеры мы указываем её координаты и координаты того места, куда она смотрит. Но почему-то в IrrLicth сделано так, что её координаты привязаны к родительской ноде (что нам собственно и нужно), а координаты её цели указываются в глобальных координатах. В этом есть определенная гибкость, например, мы можем камерой следить за объектом, который привязан к совершенно другой ветке нашего дерева. Постараюсь объяснить, что мы собственно сделали. Мы привязали пустую ноду цели к родительской ноде камеры. Т.е. эта нода будет двигаться в зависимости от поворота родительской ноды камеры, как собственно и сама камера. На каждом кадре мы будем запрашивать глобальные координаты целевой ноды и устанавливать эти координаты для камеры в качестве цели.
Запомните, в нашей программе ось X показывает в сторону, Y – вверх, а Z – вперед. Хотя это очень условно и могло бы быть совсем по другому.
pic5 | Пермещение по сферической поверхности
И еще один момент, на который стоит обратить внимание. Помимо координат камеры и координат её цели, ориентацию определяет так называемый вертикальный вектор. Если у нас имеется какой-нибудь шутер, в котором мы движемся по плоскости, то «верх» для нас всегда находится вверху и мы можем даже не задумываться над этим. Хотя если нам вдруг понадобиться чтобы камера наклонилась набок, допустим нас убили или мы просто выглядываем из-за угла, то нам уже придется поработать с этим самым вертикальным вектором. Когда мы движемся по сфере, то без вертикального вектора нам не обойтись, т.к. направление «верх» всегда меняется, в зависимости от того, где мы находимся. В нашей программе в качестве вертикального вектора вполне подойдут координаты цели камеры.
И последнее, что у нас имеется в сцене – это несколько произвольных объектов. Их иерархия будет похожа на иерархию камеры, которую мы только что рассмотрели, только в ней нам не понадобится лишняя пустая нода. Я на всякий случай повторюсь и объясню еще раз. Взглянем на рисунок.
pic6 | Пермещение по сферической поверхности
К глобальной ноде (которая здесь не нарисована) мы добавляем пустую ноду с нулевыми координатами. К пустой ноде добавляем наш объект. Координаты объекта (0, SHPERE_RADIUS, 0). Они не меняются за время игры, если мы конечно не хотим создать неровный ландшафт. Единственное, что меняется это ориентация нашей пустой ноды, которую мы будем хранить в отдельной матрице. На приведенном ниже рисунке показано, как меняется положение объекта в зависимости от ориентации корневой пустой ноды.
pic7 | Пермещение по сферической поверхности
Большие стрелочки - это глобальные координаты, а маленькие – это корневая пустая нода объекта.

Перемещение камеры

Взгляните на картинку. Если вы вспомните, что перемещение нашей камеры – это всего лишь поворот нашей корневой ноды вокруг соответствующей оси, то сразу все поймете.
pic8 | Пермещение по сферической поверхности

Страницы: 1 2 Следующая »

11 ноября 2008

Комментарии [2]