Japanese
Leave Your Message

Объяснение структуры файла модели FBX

Формат FBX поддерживается практически всеми 3D-движками и является собственным форматом 3D-моделей, разработанным компанией Autodesk. Он поддерживает вершины, индексы, нормали, UV-координаты, материалы и анимацию.
Компания Autodesk официально предоставляет FBX SDK, который позволяет импортировать и экспортировать FBX-файлы или другие библиотеки с аналогичными целями. SDK предоставляет два интерфейса: один на C++, а другой на Python.
Также можно писать собственные парсеры FBX, чтобы избежать зависимостей от других библиотек.
В этой статье описана структура файла FBX. Понимание этой структуры позволит нам написать собственный, легковесный парсер FBX. Примеры пользовательских парсеров FBX можно найти в плагине Blender FBX Importer/Exporter.
Формат FBX доступен в текстовом формате (ASCII) или в двоичном формате.

    1. Структура файла FBX

    Это пример файла FBX.
    Прежде всего, следует отметить, что некоторые строки начинаются с точки с запятой: это комментарии, и их следует игнорировать при чтении файла.
    После начального комментария находится идентификатор FBXHeaderExtension. Это первый основной узел структуры файла. Формат файла FBX действительно представляет собой древовидную структуру, следующую следующую схему:
    Объяснение структуры файла модели FBX (1)
    Каждый узел или дочерний узел может иметь свои собственные специфические атрибуты. Атрибуты также могут находиться вне основного узла, но обычно их можно игнорировать. В общем, базовая структура узла выглядит следующим образом:
    Имя узла: eventual_properties {
    Node_Property_1: значение
    Node_Property_2: значение
    Subnode1 : {
    Subnode_Property_1: value
    […]
    }
    Node_Property_3: значение
    […]
    }
    Это узел (первый), найденный в примере файла:
    FBXHeaderExtension: {
    FBXHeaderVersion: 1003
    FBXVersion: 6100
    CreationTimeStamp: {
    Версия: 1000
    Год: 2014
    Месяц: 03
    День: 20
    Час: 17
    Минута: 38
    Второй: 29
    Миллисекунда: 0
    }
    Создатель: "FBX SDK/FBX Plugins build 20070228"
    OtherFlags: {
    FlagPLE: 0
    }
    }
    Понимание структуры является основой для написания эффективного парсера.
    В первом узле мы находим два атрибута (FBXHeaderVersion и FBXVersion), значениями которых являются версии формата. В данном случае это версия 6.1. Остальную информацию можно игнорировать, если только вы не хотите также прочитать дату создания (CreationTimeStamp).

    2. Узлы объектов FBX

    Самым важным узлом, безусловно, является объектный узел.
    Узел объекта содержит вершины, индексы, нормали, UV-координаты и материалы модели. Его структура выглядит следующим образом:
    Объекты: {
    Модель: 'название модели', 'Сетка' {
    [...]
    Вершины: [...]
    PolygonVertexIndex: [...]
    LayerElementNormal: { }
    LayerElementUV: { }
    }
    Материал: 'название материала', '' { }
    [...]
    }

    3. Вершина FBX

    Как мы уже видели, вершины можно найти в свойстве 'Vertex' дочерних узлов модели.
    Синтаксис следующий:
    Вершины: v1_x, v1_y, v1_z, v2_x, v2_y, v2_z, [...]
    Каждая вершина имеет три пространственные координаты (x, y, z), разделённые запятыми (которые также разделяют одну вершину от другой). Координаты, очевидно, выражены в десятичной форме с помощью точек.
    Пример выглядит следующим образом:
    Вершины: 0.000000,0.104800,39.291698,0.000000,0.043400,-44.424301,0.000000,38.654301,-41.818802,-0.000000,39.455002,44.424400
    Модель будет состоять из следующих вершин:
    v1(0.000000,0.104800,39.291698)
    v2(00.000000,0.043400,-44.424301)
    v3(0.000000,38.654301,-41.818802)
    v4(0.000000,39.455002,44.424400)

    4. Индекс вершины многоугольника FBX

    Индекс можно найти в свойстве PolygonVertexIndex.
    Файлы FBX могут экспортировать трехугольные многоугольники (треугольники) или их больше. Большинство файлов экспортируют четырехугольные многоугольники (квадраты). Синтаксис похож на синтаксис вершин, но следует отметить одну особенность:
    PolygonVertexIndex: i1, i2, -i3, i4, i5, -i6, [...]
    PolygonVertexIndex: i1, i2, i3, -i4, i5, i6, i7, -i8, [...]
    Индексы, составляющие многоугольник, располагаются в порядке возрастания: отрицательный индекс означает, что это последний индекс многоугольника. Индекс необходимо установить в положительное число, а затем вычесть из него 1!
    [Если вам интересно, почему, то это потому, что исходный индекс имеет тип "всё или ничего" с -1. Например, индекс 3 становится -4]
    Пример выглядит следующим образом:
    PolygonVertexIndex: 8,7,3,-7,4,8,7,-3,0,5,8,-5
    Модель будет состоять из следующих многоугольников:
    p1(8,7,3,6)
    p2(4,8,7,2)
    p3(0,5,8,4)
    Обратите внимание, что индекс, указывающий на конец многоугольника, установлен на положительное число, и затем вычтите из него 1.
    Напоминание: видеокарты не работают с четырехугольниками, поэтому каждый многоугольник с четырьмя сторонами необходимо разделить на два треугольника перед отображением модели.

    5. Нормали FBX

    Нормали можно найти в дочернем узле LayerElementNormal свойства Normals (который, в свою очередь, является дочерним узлом узла Model). Синтаксис тот же, что и для одной из вершин, то есть для последовательности координат (x,y,z).
    Нормали: n1_x, n1_y, n1_z, n2_x, n2_y, n2_z, [...]
    Необходимо обратить внимание на свойство MappingInformationType, которое может принимать следующие значения:
    ▪ ByPolygon: по полигону, что означает, что каждый полигон модели имеет нормаль.
    ▪ ByPolygonVertex: обрабатывается по вершинам многоугольника, что означает, что каждая вершина каждого многоугольника модели имеет свою нормаль. Например, если модель имеет 8 вершин, образующих четыре четырехугольника, то будет 16 нормалей (1 нормаль * 4 многоугольника * 4 вершины многоугольника). Обратите внимание, что обычно игровым движкам требуется, чтобы вершина определяла только одну нормаль. Поэтому, если вы обнаружите вершину с более чем одной нормалью, вы можете либо игнорировать нормали, найденные после первой, либо вычислить среднее значение всех нормалей (сглаживание нормалей).
    ▪ ByVertex: обработка по вершинам, что означает, что каждая вершина модели имеет нормаль. Иногда называется ByVertice, как написано в экспортере Blender. Думаю, автор — испанец.
    ▪ ByEdge: обрабатывается по ребру, это означает, что каждое ребро модели имеет нормаль (редко)
    ▪ AllSame: это означает, что каждая вершина модели имеет одинаковую нормаль, что редко встречается или невозможно для большинства моделей.
    Ещё одним важным свойством является свойство ReferenceInformationType, которое может принимать следующие значения:
    ▪ Прямой: указывает на то, что нормали упорядочены.
    ▪ IndexToDirect (или index в более старых версиях формата FBX): указывает, что порядок нормалей задается свойством NormalsIndex.
    Ниже приведён графический пример, который может быть понятнее текста. Примерная модель представляет собой плоскость по осям X и Y (поэтому все вершины будут иметь Z-координату 0), состоящую из 9 вершин и 4 многоугольников (четырёхугольников). На изображении показан вид плоскости сверху.
    Объяснение структуры файла модели FBX (2)

    6. UV-координаты FBX

    UV-координаты можно найти в свойстве UV дочернего узла LayerElementUV (который, в свою очередь, является дочерним узлом узла Model). Синтаксис аналогичен синтаксису для вершин и нормалей, но, конечно, здесь будет две координаты вместо трех.
    UV: u1, v1, u2, v2, [...]
    Вам по-прежнему необходимо обращать внимание на свойства MappingInformationType и ReferenceInformationType! Эти два свойства могут иметь те же значения, что и нормали, поэтому применяются те же правила. Свойство index (если оно существует, т.е. определен IndexToDirect) — это UVIndex.