Класс RenderMesh — различия между версиями

(Новая страница: «<div class="mw-parser-output"><div class="mw-parser-output"> = <span style="font-size:18.0pt"><span style="line-height:107%">Работа с RenderMesh</span></sp…»)
(нет различий)

Версия 13:33, 6 мая 2018

Работа с RenderMesh

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

Корова.jpg

Принцип

3D модель представлена как набор вершин, цветов, текстурных координат и полигонов, последние объединяют первые 3 в треугольники (каждая вершина треугольника является ссылкой на вершину, цвет и текстурные координаты). Из треугольников и создается модель.

Формат OBJ

Формат файлов .obj является достаточно распространенным не бинарным форматом 3D моделей, который поддерживают многие редакторы. RenderMesh позволяет одной функцией загружать модели из файлов с таким форматом. Загружаются данные о вершинах, текстурных координатах и полигонах, остальные данные избыточны и игнорируются.

API моделей

Создание: var mesh = new RenderMesh() - создает пустую модель

Основные методы для модификации:

mesh.addVertex(x, y, z, u, v) - добавляет вершину в модель, x, y, z - координаты в пространстве, u, v - координаты текстуры (от 0 до 1). Каждые 3 последовательно идущие вершины объединяются в треугольник, кол-во вершин обязательно должно быть кратно 3. 

mesh.setColor(r, g, b) - устанавливает цвет, который будет использован для всех добавленных далее вершин, пока цвет не изменится (по умолчанию белый) mesh.resetColor() - сбрасывает цвет обратно до белого

mesh.setBlockTexture("name", index) - данный метод нужен в случае, когда модель используется для блока. После вызова этого метода все текстурные координаты будут заданы для конкретной текстуры блока.

mesh.resetTexture() - сбрасывает состояние, полученное вызовом метода setBlockTexture.

mesh.clear() - очищает модель mesh.translate(x, y, z) - смещает всю модель на вектор x, y, z

mesh.scale(x, y, z) - изменяет размер модели по каждой координате соответственно в x, y, z раз

mesh.rebuild() - пересчитывает нормали всех треугольников, нужные для корректного освещения, нужно вызвать это после завершения модификации модели.

Импорт из файла

Для импорта модели из файла используется метод mesh.importFromFile(path, type, params) или конструктор с такими же аргументами. Импорт автоматически вызовет метод rebuild() после завершения.

Аргументы:

  • path - абсолютный путь к файлу
  • type - тип файла (на данный момент доступен только "obj")
  • params - объект настроек импорта или null, если настройки должны быть по умолчанию.

Формат объекта настроек и их значения по умолчанию:

{
    clear: false, // очищать ли модель перед импортом
    invertV: false, // в некоторых моделях вторая текстурная координатаинвертирована, это инвертирует ее обратно. 
    translate: [0, 0, 0], // аналогичен по действию метода translate, но происходит прямо во время импорта, что ускоряет процесс
    scale: [1, 1, 1] // аналогичен методу scale, вызывается после примененияпараметра translate 
}

Пример:

var mesh = new RenderMesh(__dir__ + "models/barrel.obj", "obj", null); // импортирует модель из "директория мода/models/barrel.obj" 

Использование для рендера мобов:

Модель RenderMesh может быть установлена для конкретной части рендера моба и тогда она будет отрисовываться в ее системе координат. Модель заменит остальные элементы этой части рендера, и они не будут отрисовываться.

Для того, чтобы установить модель в объекте ModelPart есть метод setMesh(mesh), который может принимать объект модели или null.

Пример:

var mesh = new RenderMesh(__dir__ + "models/barrel.obj", "obj", null); // создать модель из файла (см. прошлый пример)  
var render = new Render(); // создать пустой рендер 
var bodyPart = render.getPart("body"); // получить часть (ModelPart) с именем "body" 
bodyPart.setMesh(mesh); // установить модель для полученной части рендера моба

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

Нечто.jpg 

Использование для модели блока:

Модель RenderMesh может быть добавлена в модель объекта блока (BlockModel), при этом ее текстурой будет текстура всех блоков (см метод setBlockTexture). В одну модель блока может быть добавлено несколько моделей RenderMesh и они не будут заменять друг друга и другие части модели блока.

Для добавления RenderMesh в BlockModel используется метод последнего addMesh(mesh), который добавляет RenderMesh в модель блока, или конструктор new BlockModel(mesh), который создает модель блока из переданного RenderMesh.

В отличии от рендера мобов, рендер блоков имеет такую механику как culling (треугольники будут видны только с той стороны, с которой их вершины идут по часовой стрелке), это сделано в самом MCPE для оптимизации и при создании моделей для блоков это стоит учитывать.

Пример:

var mesh = new RenderMesh(); // создать пустую модель
mesh.setBlockTexture("quartz_block_side", 0); // установить текстуру кварца (можно добавить произвольную текстуру, как текстуру блока и использовать ее)
mesh.importFromFile(__dir__ + "models/barrel.obj", "obj", null); // загрузить из файла с использованием текстуры кварца 
var blockModel = new BlockRenderer.Model(mesh); // создать модель для рендера

После установки нашей модели блоку (к примеру с помощью ICRender), получаем результат:

Нечто блоком без текстуры.jpg

Заменяя текстуру кварца на развертку бочки, которая была использована до этого и добавляя ее в текстуры блоков получаем ту же самую модель, но для блока (подобные текстуры стоит изменять до квадрата размера степени 2, это оптимальнее и развертка при этом сохраняется):

Нечто блоком.jpg 

Освещение

Для моделей блоков актуальны настройки освещения моделей (для мобов оно рассчитывается самим MCPE). Они задаются следующими методами:setLightParams(min, max, smooth) - задает значения освещения, рассчитанного по нормалям, min, max - минимальное и максимальное (от 0 до 1), smooth - значение сглаживания (больше 0, 1 является нейтральным элементом, по умолчанию 1.9)

setLightDir(x, y, z) - устанавливает направление света, нужное для рассчета освещения по нормалям.

setLightIgnore(ignoreBlockLight, ignoreSkyLight) - задает игнорирование разных типов освещения мира (если тип игнорируется, то освещение всегда максимальное)

Одна и та же модель при значениях по умолчанию и после вызова setLightParams(0, 1,1):

Нечто блоком без текстуры.jpgНечто со светом.jpg