Файл WaveFront OBJ хранит данные для построения 3D-модели. Любой уважающий себя 3D-редактор обязан уметь экспортировать 3D-модель в этот формат. Если хотим работать в 3D, крайне необходимо уметь читать этот формат. Познакомимся со структурой файла.
OBJ-файл
Описание
Файл Wavefront OBJ содержит геометрию трёхмерных объектов: координаты вершин, данные нормалей, текстур и рёбер. Также, предоставляет информацию по материалу, который относится к текущей поверхности.
Помимо этого, OBJ-файл может хранить информацию по объектам свободной формы. Если полигональная геометрия использует точки, линии и грани для определения объектов, то геометрия свободной формы используются кривые и поверхности. Так вот, объекты свободной геометрии мы пока рассматривать не будем. Это интересно, но не в этот раз.
Файл является текстовым, и его можно открыть в любом текстовом редакторе. Одна строка файла — один законченный блок информации. О том, что содержится в строке, сообщает слово, находящееся в начале строки. Такое определяющее слово называется оператор.
Например:
1 2 3 4 5 6 7 8 9 |
# Blender v2.76 (sub 0) OBJ File: 'Viking boat.blend' mtllib Viking boat.mtl o Sail_Plane v 0.521383 2.496831 0.075511 vn -0.286000 0.417300 0.862600 vt 0.375954 0.722144 usemtl White s off f 540/965/523 481/1063/601 628/1001/547 479/966/524 |
Любая строка, начинающаяся с оператора #, является комментарием, в котором можно писать всё, что угодно. Например, какую-то дополнительную информацию, относящуюся именно к этой части детали: ГОСТ, производитель, страна и т.д. Парс таких комментариев пусть делает автор таких комментариев.
Все операторы OBJ-файла можно условно разделить на три категории: простые, групповые и ссылочные. Область действия простого оператора ограничена текущей строкой. Например, оператор вершины:
1 |
v 0.521383 2.496831 0.075511 |
Это строка говорит нам, что в ней содержатся такие-то x,y,z-коордианты какой-то вершины. И всё, информация закончилась. Чтобы её дополнить не надо смотреть в другую строку.
Область действия группового оператора длится до тех пор, пока не встретится другой такой-же групповой оператор.
1 2 3 4 5 6 7 8 9 10 11 |
o Sail_Plane v 0.521383 2.496831 0.075511 ... usemtl White f 540/965/523 481/1063/601 628/1001/547 f 656/1064/602 657/1065/603 630/1038/577 ... usemtl Black f 482/2439/476 481/2440/1494 540/1453/818 483/1079/477 f 700/1118/1083 703/1830/1091 702/2441/1085 701/1119/1087 f 1153/2076/1056 668/1086/1078 667/1085/1044 1148/1789/1046 |
Здесь мы видим, что все строки относятся к объекту Sail_Plane. Потом начинает действовать материал White, до тех пор пока не встретился такой же оператор материала Black.
Ссылочные операторы связывают индексы массивов вершин. Также, они могут учитывать материал, который был задан ранее, группу или объект.
Простые операторы
Простые операторы задают некие параметры, на которых потом будет построена модель. Геометрическая вершина, координаты текстуры, коэффициенты нормали. Ссылка на эти данные осуществляется по индексу. Представим, что для каждого типа оператора существует свой массив. Первая строка в файле соответствующего типа — это первая строка в массиве. Вторая — второй элемент.
Нумерация продолжается последовательно на протяжении всего файла. Часто файлы имеют несколько списков данных вершин. Эта последовательность нумерации продолжается даже тогда, когда данные вершин разделены другими данными.
Вершина | v x y z w |
Оператор v задаёт геометрическую вершину в координатах x, y, z. Кривые и поверхности требуют четвертую координату w, которая называется весом. Если значение w не указано, значит по умолчанию равно 1.0. x, y, z, w — числа с плавающей запятой. Примечание: Рекомендуется положительное значение веса. Использование нуля или отрицательного значения может привести к неопределенной точке на кривой или поверхности. | |
Нормаль | vn a b c |
Задает вектор нормали с коэффициентами a, b, c. Нормали вершин влияют на плавное затенение и рендеринг. a, b, c — числа с плавающей запятой. | |
Текстура | vt u v w |
Задаёт вершину текстуры и её координаты. u — значение горизонтального направления текстуры. v — значение для вертикального направления текстуры (необязательный аргумент). По умолчанию 0. w — значение глубины текстуры (необязательный аргумент). По умолчанию 0. u, v, w — числа с плавающей запятой. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Координаты вершин v -2.053972 22.247374 0.131160 v -2.053972 22.271700 -0.003374 v -2.053972 22.905918 -0.014444 ... # Коэффициенты нормалей vn -0.9970 0.0512 -0.0582 vn -0.8355 0.4815 0.2648 vn -0.9699 -0.2237 -0.0958 ... # Текстурные координаты vt 0.631841 0.719898 vt 0.648648 0.731125 vt 0.628247 0.744237 |
Групповые операторы
Групповые операторы на логику построения модели не влияют, он призваны навести порядок в предоставлении данных. Но есть операторы, влияющие на внешний вид модели. Например, это группы сглаживания и текущий материал. Их отсутствие на построение 3D-модели не влияет никак, но их присутствие делает модель намного симпатичнее.
Объект | o object_name |
Объекты группируют информацию, содержащуюся в файле, по разным смысловым объектам. Парус-корабль-дно, и т.д. | |
Группа | g group_name1 group_name2 . . . |
Оператор задаёт имя группы для элементов, которые следуют за ним. Можно задать несколько групп. Если в одном месте есть несколько групп, данные, которые следуют за ней, принадлежат всем перечисленным группам. Информация о группе не является обязательной. | |
Сглаживание | s group_number |
Устанавливает группу сглаживания для элементов, которые следуют за ней. Если сглаживание не требуется, будет указано «off» или значение 0. | |
Материал | usemtl material_name |
Оператор устанавливает материал для всех элементов, следующих за ним. Если материал назначен, его нельзя отключить. Его можно только заменить. Описание материала находится в файле MTL, который, как правило, имеет то же имя, что и OBJ-файл, и лежит где-то рядом. В любом случае, список файлов с описанием материалов должен следовать за оператором mtllib. Смотрим описание MTL-файла. |
Ссылочные операторы
Пока рассмотрим только оператор face. Представлен буковкой f за которой идут тройки чисел, разделённых косой чертой (/).
1 2 |
f 97/116/56 96/115/55 95/114/54 f 99/137/58 98/138/57 95/114/54 |
Каждая тройка чисел определяет индексы геометрической вершины (v), вершины текстуры (vt), и нормали вершины (vn). Индексы должны следовать именно в таком порядке и должны быть разделены косой чертой (/) без пробелов внутри.
Если индекса в тройке не существует, то в таком случае будут стоять две косых черты друг за другом. Например, в примере выше уберём индексы для текстурных вершин.
1 |
f 97//56 96//55 95//54 |
Количество таких троек может быть больше чем одна серия из трёх вершин. Это значит, что здесь описаны треугольники, которые начинаются в одной точке и имеют общую грань.
1 |
f 1/1/1 2/2/2 3/3/3 4/4/4 |
Тут вначале идёт треугольник 1-2-3, затем 1-3-4 и так далее.
Как ранее говорилось, массивы вершин работают на весь OBJ-файл. Поэтому индекс из face тройки действителен для любого места в файле. Здесь индексы массивов начинаются с единицы. Ноль означает, что нет индекса, его не пишут, но подразумевают. Поэтому, в реализации, где массивы начинаются с 0-го индекса, это надо учитывать.
Таким образом, оператор face связывает геометрические вершины, нормали и текстурные координаты в одну сущность, для которой может быть установлен материал, которая может принадлежать группе и объекту.
MTL-файл
Описание
MTL-файл описывает материалы, которые используются при моделировании поверхностей объектов, описанных в OBJ-файле. В самом OBJ-файле ссылка на библиотеку материалов даётся оператором mtllib filename1 filename2 . . . Как правило, подобный оператор стоит первой строкой после комментариев в OBJ.
Файл MTL содержит последовательность определений материалов, каждое из которых начинается с ключевого слова newmtl и имени материала. Например:
1 2 3 4 5 6 7 8 9 |
newmtl Wind_Turbine_001_Material Ka 1.000000 1.000000 1.000000 Kd 0.640000 0.640000 0.640000 Ks 0.500000 0.500000 0.500000 Ns 96.078431 Ni 1.000000 d 1.000000 illum 2 map_kd turbine_texture.png |
Атрибуты материала
Имя материала | newmtl material_name |
Название материала, которое используется в OBJ-файле в операторе usemtl и уникально его идентфицирует | |
Окружающий свет | Ka r g b (float) |
Определяет окружающий цвет для учета света, рассеиваемого по всей сцене [см. статью в Википедии о модели отражения Фонга], используя значения от 0 до 1 для компонентов RGB. | |
Диффузный свет | Kd r g b (float) |
Определяет диффузный цвет, который обычно вносит большую часть цвета в объект [см. статью в Википедии о диффузном отражении]. В примере выше Kd представляет серый цвет, который будет изменен цветной текстурной картой, указанной в операторе map_Kd. | |
Зеркальный свет | Ks r g b (float) |
Определяет зеркальный цвет, который виден там, где поверхность блестит и подобна зеркалу [см. статью в Википедии о зеркальном отражении]. | |
Фокус бликов | Ns n (float) |
Определяет фокус зеркальных бликов в материале. Значения Ns обычно находятся в диапазоне от 0 до 1000, при этом высокое значение приводит к плотному, концентрированному блику. | |
Оптическая плотность | Ni n (float) |
Определяет оптическую плотность (показатель преломления) в текущем материале. Значения могут быть в диапазоне от 0.001 до 10. Значение 1.0 означает, что свет не преломляется при прохождении через объект. | |
Растворение (dissolve) | d n (float) |
Определяет коэффициент для dissolve, насколько этот материал растворяется в фоне. Коэффициент 1.0 полностью непрозрачен. Коэффициент 0.0 полностью прозрачен. | |
Модель освещения | illum n (int) |
Номер модели освещения. Вариантов больше, чем три, приведу основные: 1) illum 0 : модель постоянного цветового освещения, использующая Kd для материала 2) illum 1 : модель рассеянного освещения с использованием ламбертовского затенения, учитывающая Ka, Kd, интенсивность и положение каждого источника света, а также угол, под которым он падает на поверхность. 3) illum 2 : модель рассеянного и зеркального освещения с использованием ламбертовского затенения и интерпретации Блинном модели зеркального освещения Фонга, учитывающей Ka, Kd, Ks, а также интенсивность и положение каждого источника света и угол, под которым он падает на поверхность. Остальные номера ищем в спецификациях или придумываем сами. | |
Файл текстуры | map_kd texture_file_name |
Определяет файл цветовой текстуры, который будет применен к диффузной отражательной способности материала Kd. Во время рендеринга, значения из файла map_Kd умножаются на значения Kd для получения компонентов RGB. |
Ссылки
Скачать
Исходники тут: WaveFront OBJ-файл: Прочитать 3D-модель