Готовый перевод Ogre3D Intermediate Tutorials / Промежуточные туториалы Ogre3D: Intermediate Tutorial 5: Static Geometry

Внимание! Этот перевод, возможно, ещё не готов, так как модераторы установили для него статус «перевод редактируется»

ВВЕДЕНИЕ

Существует немало ситуаций, когда вам нужны объекты на сцене, ну вообще не нуждающиеся в перемещении.

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

Для этих ситуаций Ogre предоставляет класс статической геометрии StaticGeometry, который позволяет вам создавать пачки (batch) объектов для отрисовки одной большой группой.

Это обычно быстрее, чем делать вручную с помощью узлов сцены.

В этом уроке мы рассмотрим основные применения статической геометрии в вашей программе.

Мы также рассмотрим еще несколько вещей, которые вы можете сделать с помощью ManualObject.

Смотрите <b>предыдущий урок</b> об использовании ManualObject.

В этом уроке мы вручную создадим сетку травы и затем добавим большое их количество к объекту статической геометрии в нашей сцене.

Полный код данного урока вы сможете найти <b>здесь</b>.

Так как вы проходите урок, вы должны медленно добавлять код в ваш проект и наблюдать результаты, когда мы собираем его.

Обратите внимание, что этот урок основан на кодовой базе демки Трава (Grass), являющейся частью примеров Ogre.

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

ПРЕДВАРИТЕЛЬНЫЕ УСЛОВИЯ

Создайте новый проект на Каркасе уроков Ogre и настройте его, чтобы он выглядел так:

Перед тем, как продолжать, убедитесь, что приложение компилируется и запускается.

Вы должны увидеть робота, стоящего на плоской поверхности.

СОЗДАНИЕ СЦЕНЫ

СОЗДАНИЕ СЕТКИ

Первым делом нам нужно создать сетку травы, которую мы будем отрисовывать.

Общая идея - создать три квадратных четырехугольника, перекрывающих друг друга.

Каждый четырехугольник будет иметь текстуру травы на себе, поэтому, с какого бы направления, кроме вертикального, вы на него не посмотрите, он будет немного походить на 3D траву.

Самый простой способ создать перекрывающиеся четырехугольники - это создать один, потом другой, повернутый на 60 градусов и третий, повернутый еще на 60 градусов.

Как и в предыдущем уроке, мы будем использовать ManualObject для генерации нашего объекта, но, в отличие от предыдущего урока, мы действительно создадим сетку вместо простого списка линий (что потребует от нас создание индексного буфера, определяющего, как будут образованы треугольники).

Первым делом объявим некоторые базовые переменные.

Так как мы собираемся вращать четырехугольник, который мы определим, будет легче, если мы будем для математики использовать конструкции Ogre, такие как Vector3 и Quaternion, вместо попытки выполнить все вручную.

Наш план - создать Vector3 с координатами X и Z в нем, создать один четырехугольник из него, затем повернуть его с помощью кватерниона и повторить.

Найдите функцию-член createGrassMesh() и добавьте следующий код:

Теперь, когда мы подготовили наши переменные, нам нужно начать определение объекта ManualObject.

В отличие от предыдущего урока, мы назначим материал для использования этим объектом.

Также наша операция визуализации будет установлена в список треугольников, что означает, что после объявления наших вершин мы должны объявить список треугольников, которые создадут грани на нашем четырехугольнике:

Для каждого четырехугольника мы собираемся определить четыре вершины, одну на каждый угол.

Для каждой вершины мы, кроме того, определим текстурные координаты.

Текстурные координаты сообщают Ogre, как производить выборку текстуры, которую мы определили в материале Examples/GrassBlades.

Мы сделаем верхний левый угол точкой (0, 0) на текстуре, нижний правый угол точкой (1, 1) и так далее:

Теперь, когда мы определили четыре угла нашего четырехугольника, нам требуется создать грани.

Как кратко упоминалось в предыдущем уроке, вы должны определить грани созданием треугольников и вы должны убедиться, что произвели обход против часовой стрелки, чтобы они смотрели на вас.

Для каждого четырехугольника мы создадим два треугольника.

Первый будет основан вершинами (0, 3, 1), а второй - вершинами (0, 2, 3).

Это корректно определяет четырехугольник.

Также вспомните, что мы повторяем действия несколько раз, и каждый раз мы создаем 4 вершины, поэтому мы должны использовать переменную смещения для выбора соответствующей вершины:

Затем мы должны повернуть вектор, использованный нами при создании текущего четырехугольника и продолжить цикл.

После того, как цикл завершится, мы должны вызвать ManualObject::end() для завершения объекта:

Теперь, когда мы имеем описанный объект ManualObject, мы почти готовы начать создавать статическую геометрию.

Последнее, что мы сделаем, это создадим сетку из нашего ManualObject.

Сетки чуть более оптимизированы для отрисовки, чем использование объекта ManualObject.

Для этого нам просто нужно вызвать ManualObject::convertToMesh() с желаемым именем для сохраненной сетки:

Теперь мы закончили создание сетки травы.

Обратите внимание, что если вы таким образом создали очень сложную сетку, вы можете сохранить ее в файл и просто загрузить обратно вместо пересоздания объекта ManualObject каждый раз во время загрузки программы.

Чтобы сделать это, мы берем возвращаемое значение convertToMesh() (которое отбрасывается в рабочем коде) и передаем возвращенную им сетку в функцию MeshSerializer::exportMesh().

Вот пример того, как это сделать:

Теперь мы готовы создать статическую геометрию.

ДОБАВЛЕНИЕ СТАТИЧЕСКОЙ ГЕОМЕТРИИ

Метод createScene() уже заполнен некоторыми вещами.

Туда уже добавлен код для создания плоскости пола, добавления робота, установки позиции камеры и тому подобное, так как мы уже изучили эти вещи в предыдущих уроках.

Убедитесь, что понимаете текущее содержание этой функции перед продолжением.

Первая вещь, которую мы собираемся сделать сейчас - создать сущность, основанную на сетке травы, созданной ранее и создать объект StaticGeometry.

Обратите внимание, что мы создаем только одну сущность для использования с нашей статической геометрией.

Найдите метод createScene() и добавьте следующий код в его <b>конец</b>:

Переменная <code>size</code> определяет, насколько большую область мы покрываем травой, а переменная <code>amount</code> определяет, как много объектов мы поместим в каждый ряд нашего объекта StaticGeometry.

Следующая вещь, которую нам требуется сделать, это определить размер и начало координат статической геометрии.

Как только мы создаем объект (вызвав StaticGeometry::build()), мы больше не сможем изменить начало координат или область, определяемую статической геометрией.

Начало координат поместим в верхний левый угол области, определяемой статической геометрией.

Если вам нужно разместить статическую геометрию вокруг точки, вы должны установить <code>x</code> и <code>z</code>-координаты начала координат в половину размера области для <code>x</code> и <code>z</code>:

Это отцентрирует объект вокруг точки (0, 0, 0).

Для его центровки вокруг точки в 3D пространстве, вы должны сделать нечто вроде этого:

Где <code>x</code>, <code>y</code> и <code>z</code> &ndash; точка в 3D пространстве, вокруг которой необходимо отцентрировать объект.

Также обратите внимание, что мы <i>определяем</i> вертикальную высоту объекта, когда задаем область.

Убедитесь, что <code>y</code> компонент setRegionDimensions() не меньше, чем высочайший объект в статической геометрии.

Следующая вещь, которую мы должны сделать &ndash; добавить объекты к статической геометрии.

Следующая часть кода немного сложна, потому что мы добавляем целый газон травы к геометрии и придаем ей случайное смещение по позициям <code>x</code> и <code>z</code>, случайное вращение и случайный масштаб по вертикальной оси.

В действительности, здесь самой важной для понимания вещью является StaticGeometry::addEntity():

Функция addEntity() принимает используемую сущность, позицию объекта, ориентацию объекта и его масштаб.

Когда вы определяете статическую геометрию, вы будете использовать либо функцию addEntity(), либо функцию addSceneNode().

Функция addSceneNode() проходит по узлу сцены, добавляя все <i>сущности</i> к статической геометрии, используя позицию, ориентацию и масштаб дочерних узлов сцены вместо указания их вручную.

Обратите внимание, что если вы используете функцию addSceneNode(), убедитесь, что удалили узел из его родителя, так как addSceneNode() не удаляет его для вас.

Если вы не сделаете этого, Ogre отрисует и статическую геометрию, созданную вами, и оригинальный узел сцены, что не является тем, что вы хотели.

Наконец, мы должны построить статическую геометрию, прежде чем она будет отображена:

Скомпилировав и запустив ваше приложение, вы должны увидеть робота, стоящего на маленьком кусочке травы. Посмотрите, как он счастлив :).

ЗАКЛЮЧЕНИЕ

ИЗМЕНЕНИЕ ОБЪЕКТА STATICGEOMETRY

Однажды создав StaticGeometry, вы, как предполагается, не работаете с ним много, так как в противном случае его ценность стремится к нулю.

Вы можете, однако, делать вещи, вроде колыхания травы на ветру.

Если вам интересно, как сделать такое, взгляните на демку травы, которая поставляется с Ogre.

Функция GrassListener::waveGrass() изменяет траву для выполнения движения, подобного колыханию.

ПРОДВИНУТАЯ ОБРАБОТКА ОБЪЕКТОВ ПАКЕТАМИ

Это, естественно, только азы обработки объектов пакетами (object batching).

Вы должны использовать StaticGeometry в любом случае, когда вы имеете неподвижные объекты, сгруппированные вместе.

Если вы пытаетесь создать что-то столь же интенсивное или столь же расширяемое, как лес, или пытаетесь добавить траву на огромное количество земли, вы должны взглянуть в сторону более продвинутых техник пакетирования, вроде <b>движка страничной геометрии (PagedGeometry Engine)</b>

Внимание! Этот перевод, возможно, ещё не готов.
Его статус: перевод редактируется

Переведено на Нотабеноиде
http://notabenoid.org/book/20063/65477

Переводчики: Mingun, proVIDec

Настройки

Готово:

100.00% КП = 1.1