← к содержанию

Урок 9. Создание меша вручную

До сих пор мы загружали данные мешей из готовых файлов-ресурсов (файл с расширением .me). В подавляющем большинстве случаев так и делается (а в уроке 11 будет показан ещё более простой способ, когда из ресурсов загружается весь объект с материалами и текстурами). Тем не менее, возможны редкие ситуации, когда вам понадобится строить меш самостоятельно в программе. DDD допускает такой подход, и именно об этом наш сегодняшний урок. Если вы не собираетесь заморачиваться подобными сложностями, то спокойно можете пропустить этот урок.

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




Синими стрелками обозначен первый треугольник, красными – второй. Цифрами по порядку обозначены все вершины, которые мы будем подавать в конструктор создания Меша. Как мы видим по рисунку, вершины при построении треугольника должны поступать против часовой стрелки. Координаты левого нижнего угла сделаем равными (0, 0, 0), правого верхнего – (1.5, 1, 0).

  1. Откройте модуль scena.d. Т.к. мы теперь сами будем вызывать конструктор класса Меш, то нам нужно проимпортировать соответствующий модуль, добавьте в строку импорта DDD модуль ddd.mesh. У меня она теперь выглядит вот так:

import ddd, ddd.mesto, ddd.lamp, ddd.vector, ddd.quaternion, ddd.ddd_object, ddd.mesh;
  1. Создайте новую функцию прямоугольник, она будет возвращать экземпляр класса Меш:

Меш прямоугольник() {
}
  1. Зададим координаты 4-х вершин. Внутри функции впишите:

    float[] координаты_вершин = [0,0,0, 1.5f,1,0, 0,1,0, 1.5f,0,0];

Координаты задаются плоским массивом, по три значения координаты (x, y, z) на каждую вершину.

  1. Теперь нужно задать текстурные координаты. Даже если мы не собираемся прицеплять текстуру к новому 3D-объекту, конструктор меша требует текстурные координаты вторым аргументом. Мы же, всё-таки, некую текстуру на наш прямоугольник повесим. Текстурные координаты имеют по два значения на каждую вершину:

    float[] координаты_текстур = [0,1, 1,0, 0,0, 1,1];

Если у вас возник вопрос, откуда взялись именно эти координаты, то вот ответ: координаты в графических файлах начинаются с левого верхнего угла, координата X направлена вправо, координата Y – вниз. Поэтому первая вершина (с индексом 0) будет иметь текстурные координаты (0, 1), и дальше уже можно понять текстурные координаты остальных вершин.

  1. Вслед за текстурными идут координаты нормалей. Они снова имеют по три значения на вершину, и у каждой вершины должен получиться вектор, перпендикулярный плоскости нашего прямоугольника. Т.к. весь наш меш находится в одной плоскости, то все вектора нормалей получаются направленными одинаково и равными (0, 0, 1):

    float[] координаты_нормалей = [0,0,1, 0,0,1, 0,0,1, 0,0,1];
  1. Последним создадим массив индексов. Тут всё просто — нужно перечислить индексы вершин в том порядке, в каком они должны образовывать треугольники:

    ushort[] индексы = [0, 1, 2, 0, 3, 1];
  1. Осталось только создать сам меш и вернуть его из функции:

    return new Меш(координаты_вершин, координаты_текстур, координаты_нормалей, индексы);
  1. В функции сцена добавьте эти строки, их назначение уже должно быть вам понятно из предыдущих уроков:

    auto меш3 = прямоугольник(); 
    auto место3 = менеджер.начальное_место.создать_ребёнка("Место объекта3", 
                                                   Вектор3(0.9f, 0, 1.5f),
                                                   Кватернион.НОЛЬ);
    auto объект3 = new Объект("объект3", меш3);
    место3.присоединить_объект(объект3);
    объект3.получить_материал.задать_диффузную_текстуру(менеджер.получить_текстуру("схема"));

Местоположение нового объекта (0.9f, 0, 1.5f) подобрано так, чтобы наш прямоугольник располагался справа от обезьяны с цилиндром и не перекрывался ими.

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

  2. Откомпилируйте и запустите программу. Должно получиться примерно такое изображение: