MDL — различия между версиями
Материал из GTAModding.ru
Majestic (обсуждение | вклад) |
Majestic (обсуждение | вклад) |
||
(не показаны 7 промежуточных версий 3 участников) | |||
Строка 12: | Строка 12: | ||
== Структура == | == Структура == | ||
− | |||
− | |||
Общее для всех [[MDL|<code>*.mdl</code>]] - наличие глобального заголовка и atomic-заголовка. Остальные секции [[MDL|<code>*.mdl</code>]] строго специфические для каждой из поддерживаемых платформ - PSP или PS2 | Общее для всех [[MDL|<code>*.mdl</code>]] - наличие глобального заголовка и atomic-заголовка. Остальные секции [[MDL|<code>*.mdl</code>]] строго специфические для каждой из поддерживаемых платформ - PSP или PS2 | ||
− | + | ===Заголовок dump-контейнера MDL=== | |
+ | |||
+ | 0х00 4b: сигнатура "ldm" | ||
+ | 0х04 4b: 0 | ||
+ | 0х08 4b: размер dump-контейнера MDL | ||
+ | 0х0С 4b: размер данных внутри MDL-контейнера | ||
+ | 0х10 4b: указатель на Pointer Reallocation table (содержит указатели на все указатели в файле для перевода их от локальных к глобальным в памяти) | ||
+ | 0х14 4b: количество указателей в Pointer Reallocation table | ||
+ | 0х18 4b: указатель на Methods table (Разделен на 2 секции) | ||
+ | 0х1С 2b: количество указателей в первой секции Methods table (Virtual, используется только в DTZ) | ||
+ | 0х1E 2b: количество указателей во второй секции Methods table (Rendering, имеется в MDL и DTZ, ссылается на спец. поле в Atomic). | ||
− | + | ===Заголовок MDL=== | |
− | + | Является не уникальным, а заранее подготовленным заголовком, данными которого после загрузки MDL игрой (а соответственно при переводе всех указателей в файле к абсолютному значению) переносятся в соответсвующие поля бинарного IDE в DTZ. | |
− | ''' | + | '''Заголовок MDL простых объектов:''' |
− | + | 0x0 Xb: массив из указателей на Atomic моделей. Кол-во указателей (т.е отдельных моделей) определено в IDE модели. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | '''Заголовок MDL, содержащей модель авто:''' | |
− | ... | + | |
+ | Единственное различие между заголовками LCS и VCS - это увеличенный массив указателей на primary-материалы. | ||
+ | |||
+ | Версия Liberty City Stories: | ||
+ | |||
+ | 0x0 4b: указатель на Clump | ||
+ | 0x4 4b: количество extra | ||
+ | 0х8 4b: указатель на массив указателей на Atomic моделей extra | ||
+ | 0xC 100b: 25 указателей на материалы, перекрашиваемые primary-цветом | ||
+ | 0x70 100b: 25 указателей на материалы, перекрашиваемые secondary-цветом | ||
+ | |||
+ | Версия Vice City Stories: | ||
+ | |||
+ | 0x0 4b: указатель на Clump | ||
+ | 0x4 4b: количество extra | ||
+ | 0х8 4b: указатель на массив указателей на Atomic моделей extra | ||
+ | 0xC 120b: 30 указателей на материалы, перекрашиваемые primary-цветом | ||
+ | 0x84 100b: 25 указателей на материалы, перекрашиваемые secondary-цветом | ||
+ | |||
+ | '''Заголовок MDL, содержащей модель ped'ов:''' | ||
+ | |||
+ | 0x0 4b: указатель на коллизию (как правило, встроена в MDL) | ||
+ | 0x4 4b: указатель на Clump | ||
+ | |||
+ | '''Заголовок MDL, катсценовских педов или объектов:''' | ||
+ | |||
+ | 0x0 16b: Clump | ||
+ | |||
+ | ===Clump:Struct=== | ||
+ | |||
+ | Содержит т.н. под-секцию Clump-Atomic cycle для цикличного перехода по всем атомикам, принадлежащим данному Clump и спользуется для привязки Atomic к Clump. | ||
+ | Аналогичная под-секция присутсвует в Atomic. | ||
+ | Важно отметить и то, что extra в моделях авто загружаются отдельно и не принадлежат Clump модели (Не участвуют в цикле Clump-Atomic cycle). | ||
+ | |||
+ | 0x0 4b: ID секции | ||
+ | 0x4 4b: переход на главный фрейм (Root Frame) | ||
+ | Под-секция Clump-Atomic cycle: | ||
+ | 0x8 4b: указатель на под-секцию Clump-Atomic cycle первого атомика (если атомиков нет, то ссылается на саму себя) | ||
+ | 0xC 4b: указатель на под-секцию Clump-Atomic cycle последнего атомика (если атомиков нет, то ссылается на саму себя) | ||
− | == | + | ====Clump:FrameList:Struct==== |
− | + | Содержит т.н. под-секцию Frame-Atomic cycle для цикличного перехода по атомикам, принадлежащим данному фрейму и спользуется для привязки Atomic (а соответственно и геометрии) к фрейму. | |
− | + | Аналогичная под-секция присутсвует в Atomic. | |
− | + | ||
− | + | '''Версия Liberty City Stories PS2:''' | |
− | 4b: | + | 0x0 4b: тип секции |
− | 4b: | + | 0x4 4b: смещение на родительский фрейм (Parent Frame) |
− | + | ||
− | 4b: | + | Под-секция Frame-Atomic cycle: |
− | + | 0x8 4b: указатель на под-секцию Frame-Atomic cycle первого атомика (если привязанных атомиков нет, то ссылается на саму себя) | |
− | 4b: | + | 0xC 4b: указатель на под-секцию Frame-Atomic cycle последнего атомика (если привязанных атомиков нет, то ссылается на саму себя) |
− | + | ||
− | + | 0x10 64b: matrix4x4: матрица трансформации для фрейма и привязанной к ней геометрии относительно родительского фрейма | |
− | 4b: | + | (для вычисления глобальной трансформации фрейма необходимо умножить данную матрицу на матрицу родительского фрейма) |
− | 4b: | + | 0x50 64b: matrix4x4: глобальная матрица трансформации для фрейма или привязанной к ней геометрии |
− | 4b: | + | (в LCS у моделей со скелетом обычно единичная матрица) |
− | 4b: | + | 0x90 4b: указатель на фрейм нижнего уровня (Child Frame) |
− | 4b: | + | 0x94 4b: указатель на фрейм одного уровня в иерархии с данным фреймом (Sibling Frame) |
− | 4b: | + | 0x98 4b: указатель на главный фрейм (Root Frame) |
− | 4b: | + | 0x9C 4b: ID кости. (только для моделей педов и CS объектов, в остальных случаях = -1). |
− | 4b: | + | 0xA0 4b: Указатель на параметры костей (только для моделей педов и CS объектов) |
− | 4b: | + | 0xA4 4b: указатель на имя фрейма |
− | + | 0xA8 4b: ID информационного узла модели, используется только в моделях авто. | |
− | 4b: | + | |
− | 4b: | + | '''Версия Liberty City Stories PSP, Vice City Stories PSP, Vice City Stories PS2:''' |
− | + | ||
− | + | 0x0 4b: тип секции | |
− | 4b: | + | 0x4 4b: смещение на родительский фрейм (Parent Frame) |
− | 4b: | + | |
− | 4b: | + | Под-секция Frame-Atomic cycle: |
− | 4b: выравнивание ( | + | 0x8 4b: указатель на под-секцию Frame-Atomic cycle первого атомика (если привязанных атомиков нет, то ссылается на саму себя) |
− | 4b: | + | 0xC 4b: указатель на под-секцию Frame-Atomic cycle последнего атомика (если привязанных атомиков нет, то ссылается на саму себя) |
− | 4b: | + | |
− | 4b: неизвестно | + | 0x10 64b: matrix4x4: матрица трансформации для фрейма и привязанной к ней геометрии относительно родительского фрейма |
+ | (для вычисления глобальной трансформации фрейма необходимо умножить данную матрицу на матрицу родительского фрейма) | ||
+ | 0x50 64b: matrix4x4: глобальная матрица трансформации для фрейма или привязанной к ней геометрии | ||
+ | (в LCS у моделей со скелетом обычно единичная матрица) | ||
+ | 0x90 4b: указатель на фрейм нижнего уровня (Child Frame) | ||
+ | 0x94 4b: указатель на фрейм одного уровня в иерархии с данным фреймом (Sibling Frame) | ||
+ | 0x98 4b: указатель на главный фрейм (Root Frame) | ||
+ | 0x9C 4b: выравнивание | ||
+ | 0xA0 4b: ID кости. (только для моделей педов и CS объектов LCS, в остальных случаях = -1, в VCS не используется и равно 0). | ||
+ | 0xA4 4b: Указатель на параметры костей (только для моделей педов и CS объектов) | ||
+ | 0xA8 4b: указатель на имя фрейма | ||
+ | 0xAC 4b: ID информационного узла модели, используется только в моделях авто. | ||
+ | |||
+ | '''ID информационных узлов авто в Liberty City Stories:''' | ||
+ | |||
+ | 0 - простой фрейм | ||
+ | 1 - wheel_rf_dummy | ||
+ | 2 - wheel_rm_dummy | ||
+ | 3 - wheel_rb_dummy | ||
+ | 4 - wheel_lf_dummy | ||
+ | 5 - wheel_lm_dummy | ||
+ | 6 - wheel_lb_dummy | ||
+ | 7 - bump_front_dummy | ||
+ | 8 - bump_rear_dummy | ||
+ | 9 - wing_rf_dummy | ||
+ | 10 - wing_rr_dummy | ||
+ | 11 - door_rf_dummy | ||
+ | 12 - door_rr_dummy | ||
+ | 13 - wing_lf_dummy | ||
+ | 14 - wing_lr_dummy | ||
+ | 15 - door_lf_dummy | ||
+ | 16 - door_lr_dummy | ||
+ | 17 - bonnet_dummy | ||
+ | 18 - boot_dummy | ||
+ | 19 - windscreen_dummy | ||
+ | |||
+ | '''ID информационных узлов авто в Vice City Stories:''' | ||
+ | |||
+ | 0 - простой фрейм | ||
+ | 1 - неизвестно | ||
+ | 2 - wheel_rf_dummy | ||
+ | 3 - wheel_rm_dummy | ||
+ | 4 - wheel_rb_dummy | ||
+ | 5 - wheel_lf_dummy | ||
+ | 6 - wheel_lm_dummy | ||
+ | 7 - wheel_lb_dummy | ||
+ | 8 - door_rf_dummy | ||
+ | 9 - door_rr_dummy | ||
+ | 10 - door_lf_dummy | ||
+ | 11 - door_lr_dummy | ||
+ | 12 - bump_front_dummy | ||
+ | 13 - bump_rear_dummy | ||
+ | 14 - wing_rf_dummy | ||
+ | 15 - wing_lf_dummy | ||
+ | 16 - wing_rr_dummy | ||
+ | 17 - wing_lr_dummy | ||
+ | 18 - bonnet_dummy | ||
+ | 19 - boot_dummy | ||
+ | 20 - windscreen_dummy | ||
+ | |||
+ | |||
+ | ===Clump:TextureList:Struct=== | ||
+ | |||
+ | 4b: тип секции | ||
4b: 0 | 4b: 0 | ||
+ | 4b: 1 | ||
+ | 4b: указатель на Clump:TextureList:String | ||
+ | 4b: количество текстур | ||
+ | 4b: количество текстур (повторяется) | ||
+ | 4b: указатель на таблицу инвертированных матриц костей | ||
+ | 4b: выравнивание (AAAAAAAA) | ||
− | ==Clump== | + | ===Clump:GeometryHeader:Struct=== |
+ | 4b float: Координата Х ограничивающей модель сферы | ||
+ | 4b float: Координата Y ограничивающей модель сферы | ||
+ | 4b float: Координата Z ограничивающей модель сферы | ||
+ | 4b float: Радиус ограничивающей модель сферы | ||
+ | 4b: размер модели + кол-во материалов (первые 12 бит - кол-во материалов, оставшиеся 20 бит - размер). | ||
+ | 4b: флаг, по которому движок игры определяет какие дополнительные секции параметров вертексов присутствуют в модели (нормали, прилайт, скиннинг, UV развертка) | ||
+ | 2b: общее кол-во вертексов в модели | ||
+ | 2b: смещение на первый тристрип. | ||
+ | 12b: 6x2b ограничивающая коробка (MinX,MinY,MinZ,MaxX,MaxY,MaxZ типа signed short, расшифровываются аналогично | ||
+ | коордиатам вертексов с применением ScaleFactor и TranslateFactor). | ||
+ | 4b float: множитель координаты X (ScaleFactorX) | ||
+ | 4b float: множитель координаты Y (ScaleFactorY) | ||
+ | 4b float: множитель координаты Z (ScaleFactorZ) | ||
+ | 4b float: смещение координаты X (TranslateFactorX) | ||
+ | 4b float: смещение координаты Y (TranslateFactorY) | ||
+ | 4b float: смещение координаты Z (TranslateFactorZ) | ||
− | + | ===Atomic=== | |
− | + | ||
− | + | ||
− | + | 0x0 4b: тип секции | |
+ | 0x4 4b: указатель на родительский фрейм | ||
+ | |||
+ | Под-секция Frame-Atomic cycle: | ||
+ | 0x8 4b: указатель на под-секцию Frame-Atomic cycle следующего атомика (если последний, то ссылается на Frame-Atomic cycle фрейма) | ||
+ | 0xC 4b: указатель на под-секцию Frame-Atomic cycle предыдущего атомика (если первый, то ссылается на Frame-Atomic cycle фрейма) | ||
+ | |||
+ | 0x10 4b: может содержать любое значение | ||
+ | 0x14 4b: смещение на геометрию | ||
+ | 0x18 4b: смещение на Clump | ||
+ | |||
+ | Под-секция Clump-Atomic cycle: | ||
+ | 0x1C 4b: указатель на под-секцию Clump-Atomic cycle следующего атомика (если последний, то ссылается на Clump-Atomic cycle клампа, если не привязан к клампу, то = 0) | ||
+ | 0x20 4b: указатель на под-секцию Clump-Atomic cycle предыдущего атомика (если первый, то ссылается на Clump-Atomic cycle клампа, если не привязан к клампу, то = 0) | ||
+ | |||
+ | 0x24 4b: id метода рендеринга | ||
+ | 0x28 2b: IDE ID, выставляется движком. В файле обычно = -1 | ||
+ | 0x2A 2b: параметры ломающихся/отделяющихся запчастей авто. | ||
+ | 0x2C 4b: указатель на параметры костей (только для моделей педов и CS объектов) | ||
+ | 0x30 4b: может содержать любое значение | ||
− | |||
− | |||
− | + | ||
− | + | ||
− | + | ||
− | ==Список материалов== | + | ===Список материалов=== |
− | + | ||
− | + | ||
====MDL-версия==== | ====MDL-версия==== | ||
− | + | ||
− | + | 12b: point3 X Y Z (не используется) | |
+ | 4b: множитель U | ||
+ | 4b: множитель V | ||
+ | 4b: цвет материала (не используется) | ||
+ | 4b: переход на начало тристрипцев (относительно секции геометрии) | ||
+ | 2b: количество тристрипцев в материале | ||
+ | 2b: номер текстуры из TextureList | ||
====WRLD-версия==== | ====WRLD-версия==== | ||
Строка 106: | Строка 245: | ||
Заголовок WRLD версии PS2: | Заголовок WRLD версии PS2: | ||
− | количество материалов[ | + | [2b int] количество материалов |
+ | [2b int] размер секции материалов | ||
Заголовок WRLD версии PSP: | Заголовок WRLD версии PSP: | ||
− | количество материалов[ | + | [4b int] количество материалов |
+ | [4b float] неизвестно, У ЛОДов обычно равно 0 | ||
Длина строки списка геометрии '''LCS PS2''': = 22 байт. | Длина строки списка геометрии '''LCS PS2''': = 22 байт. | ||
− | id текстуры[ | + | [2b int] id текстуры |
− | + | [2b int] Размер тристрипа (необходима логическая операция '''and''' 0x7FFF, т.к. первый бит является флагом backface culling) | |
+ | [2b half float] множитель для U | ||
+ | [2b half float] множитель для V | ||
+ | [2b] неизвестно, возможно флаги | ||
+ | [12b 6x signed int] ограничивающая коробка | ||
Длина строки списка геометрии '''VCS PS2''': = 24 байт. | Длина строки списка геометрии '''VCS PS2''': = 24 байт. | ||
− | + | [4b int] Размер тристрипа (необходим разделить на 2 нацело, если делится с остатком 1 - на текущем тристрипе включен backface culling) | |
− | + | [2b int] id текстуры | |
+ | [2b half float] множитель для U | ||
+ | [2b half float] множитель для V | ||
+ | [2b] неизвестно, возможно флаги | ||
+ | [12b 6x signed int] ограничивающая коробка | ||
− | Длина строки списка геометрии '''LCS PSP''' может быть в 2х вариантах: 10 байт или 24 байт. Определяется с помощью | + | Длина строки списка геометрии '''LCS PSP''' может быть в 2х вариантах: 10 байт или 24 байт. Определяется с помощью float в заголовке: если float <>0 то длина строки = 24 байт, если =0 то, соответственно, 10 байт. |
− | id текстуры[ | + | [2b int] id текстуры |
+ | [2b int] количество вершин в тристрипе (необходима логическая операция '''and''' 0x7FFF, т.к. первый бит является флагом backface culling) | ||
+ | [2b half float] множитель для U | ||
+ | [2b half float] множитель для V | ||
+ | [2b] неизвестно, возможно флаги | ||
+ | [2b] неизвестно, возможно флаги (секция может отсутствовать) | ||
+ | [12b 6x signed int] ограничивающая коробка (секция может отсутствовать) | ||
Длина строки списка геометрии '''VCS PSP''': = 24 байт. | Длина строки списка геометрии '''VCS PSP''': = 24 байт. | ||
− | id текстуры[ | + | |
+ | |||
+ | [2b int] id текстуры | ||
+ | [2b int] количество вершин в тристрипе (необходима логическая операция '''and''' 0x7FFF, т.к. первый бит является флагом backface culling) | ||
+ | [2b half float] множитель для U | ||
+ | [2b half float] множитель для V | ||
+ | [2b] неизвестно, возможно флаги | ||
+ | [2b] неизвестно, возможно флаги | ||
+ | [12b 6x signed int] ограничивающая коробка | ||
+ | |||
+ | '''Координаты ограничивающей коробки''' расшифровываются аналогично расшифровке координат тристрипа (делением каждого int на 32768 и умножением на скайлинг модели) | ||
'''Множители U и V''' представляют собой half precision floating point. Описание см. [http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%BF%D0%BE%D0%BB%D0%BE%D0%B2%D0%B8%D0%BD%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8 здесь] | '''Множители U и V''' представляют собой half precision floating point. Описание см. [http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%BF%D0%BE%D0%BB%D0%BE%D0%B2%D0%B8%D0%BD%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8 здесь] | ||
Строка 140: | Строка 305: | ||
==Список геометрии== | ==Список геометрии== | ||
+ | |||
+ | [[Изображение:Tri-Strip.png|200px|thumb|right|''Tri-Strips'' - серия связанных треугольников и вершин. Специально используется в играх данной серии для быстрого рендеринга.]] | ||
====PS2-версия==== | ====PS2-версия==== | ||
Строка 148: | Строка 315: | ||
Далее идут собственно блоки, содержащие элементы модели: | Далее идут собственно блоки, содержащие элементы модели: | ||
− | * Блок 79 - '''Гео''' - содержит все координаты вершинок в тристрипсе. Одна координата закодирована | + | * Блок 79 - '''Гео''' - содержит все координаты вершинок в тристрипсе. Одна координата закодирована типом Short (2b) #signed и вычиляется следующим образом: |
+ | |||
+ | (maxscript) | ||
+ | CoordX = (CoordX as Float)/32768*ScaleFactorX+TranslateFactorX | ||
+ | аналогично Y и Z | ||
+ | |||
+ | Размер блока = заголовок блока (4 байта) + (XYZ (6 байтов) * количество вершинок в тристрипсе). | ||
Блок геометрии заканчивается техническим блоком 50505020, который необходим для движка (для импорта модели он не важен). | Блок геометрии заканчивается техническим блоком 50505020, который необходим для движка (для импорта модели он не важен). | ||
− | * Блок 76 - '''UV''' - содержит все координаты UV-маппинга в тристрипсе. Одна координата закодирована | + | * Блок 76 - '''UV''' - содержит все координаты UV-маппинга в тристрипсе. Одна координата закодирована типом Byte (1b) #unsigned, вычисляется делением на 255 для моделей из WRLD/LVZ или делением на 128 для MDL. Размер блока = заголовок блока (4 байта) + (UV (2 байта) * количество вершинок в тристрипсе). |
+ | |||
+ | * Блок 6F - '''Прилайт Stories''' - содержит RGBA для предварительного освещения вершинки. Используется только в [[GTA LCS]] и [[GTA VCS]]. Хранится в 16 битном формате RGBA 5551. Размер блока = заголовок блока (4 байта) + (RGBA (2 байта) * количество вершинок в тристрипсе). | ||
− | * Блок | + | * Блок 6Е - '''Прилайт Manhunt 2''' - содержит RGBA для предварительного освещения вершинки. Используется только в [[Manhunt 2]]. Каждый цвет закодирован одним байтом. Размер блока = заголовок блока (4 байта) + (RGBA (4 байта) * количество вершинок в тристрипсе). Считывать необходимо как BGRA |
− | * Блок 6A - '''Нормали''' - содержит все координаты векторов нормалей в трипстрипсе. Одна координата закодирована | + | * Блок 6A - '''Нормали''' - содержит все координаты векторов нормалей в трипстрипсе. Одна координата закодирована типом Byte (1b) #signed и вычисляется делением на 127. Размер блока = заголовок блока (4 байта) + (XYZ (3 байта) * количество вершинок в тристрипсе). |
− | * Блок 6С - '''Скиннинг''' - содержит таблицу весов вершинок для их анимации. Это id косточки (1 байт) + её вес (3 байта). Соответственно, каждая вершинка содержит 4 id (т.е. в анимации она управляется 4 косточками). Размер блока = заголовок блока (4 байта) + ((id_weight (4 байта) * 4) * количество вершинок в тристрипсе. | + | * Блок 6С - '''Скиннинг''' - содержит таблицу весов вершинок для их анимации. Это id косточки (1 байт, необходимо делить на 4 нацело) + её вес (3 байта). Соответственно, каждая вершинка содержит 4 id (т.е. в анимации она управляется 4 косточками). Размер блока = заголовок блока (4 байта) + ((id_weight (4 байта) * 4) * количество вершинок в тристрипсе. |
Чтение следующего тристрипса начинается сразу же за флагом окончания тристрипса - 14000006. Общее количество тристрипсев в модели так же записано в клампе. | Чтение следующего тристрипса начинается сразу же за флагом окончания тристрипса - 14000006. Общее количество тристрипсев в модели так же записано в клампе. | ||
Строка 202: | Строка 377: | ||
====Структура файла==== | ====Структура файла==== | ||
− | |||
'''Главный заголовок''' | '''Главный заголовок''' | ||
− | Заголовок 1 имеет типичную структуру во всех файлах движка, отличается лишь сигнатурой. | + | Заголовок 1 имеет типичную структуру во всех файлах движка, отличается лишь сигнатурой (см. ''пункт Структура главного заголовка MDL'') |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
'''Заголовок MDL и цикл чтения моделей''' | '''Заголовок MDL и цикл чтения моделей''' | ||
Строка 225: | Строка 388: | ||
Размер заголовка = 8 байт | Размер заголовка = 8 байт | ||
− | 4b - | + | 4b - Переход на первую строку цикла поиска моделей. |
− | 4b - | + | 4b - Переход на последнюю строку цикла поиска моделей. |
Текущая версия на 18:42, 26 октября 2016
MDL – внутренный формат моделей игр от Rockstar Leeds (не путайте его с другими MDL-файлами, содержащимися в прочих видеоиграх), используемый в GTA LCS, GTA VCS и Manhunt2. Данный формат жестко привязан к игровой платформе (PSP/PS2), т.е. не является кроссплатформенным в отличие от DFF, использовавшегося в предыдущих играх серии GTA до покупки RenderWare фирмой EA Games.
Содержание |
Основные данные
PSP-версия MDL была разобрана J-Fox, им же написана программа, читающая структуру MDL-файлов с рендерингом геометрии и UV-координат с текстурами из *.chk
-файлов. Как и остальной многочисленный софт для GTA: LCS и GTA: VCS, программа от J-Fox не была автором выложена в открытый доступ.
PS2-версия MDL разобрана AK-73 aka Alex, им же написан уникальный скрипт к 3D Studio Max для импорта любого *.mdl
-файла PS2-версии. Подробнее о скрипте читайте в статье о MDL importer.
Структура
Общее для всех *.mdl
- наличие глобального заголовка и atomic-заголовка. Остальные секции *.mdl
строго специфические для каждой из поддерживаемых платформ - PSP или PS2
Заголовок dump-контейнера MDL
0х00 4b: сигнатура "ldm" 0х04 4b: 0 0х08 4b: размер dump-контейнера MDL 0х0С 4b: размер данных внутри MDL-контейнера 0х10 4b: указатель на Pointer Reallocation table (содержит указатели на все указатели в файле для перевода их от локальных к глобальным в памяти) 0х14 4b: количество указателей в Pointer Reallocation table 0х18 4b: указатель на Methods table (Разделен на 2 секции) 0х1С 2b: количество указателей в первой секции Methods table (Virtual, используется только в DTZ) 0х1E 2b: количество указателей во второй секции Methods table (Rendering, имеется в MDL и DTZ, ссылается на спец. поле в Atomic).
Заголовок MDL
Является не уникальным, а заранее подготовленным заголовком, данными которого после загрузки MDL игрой (а соответственно при переводе всех указателей в файле к абсолютному значению) переносятся в соответсвующие поля бинарного IDE в DTZ.
Заголовок MDL простых объектов:
0x0 Xb: массив из указателей на Atomic моделей. Кол-во указателей (т.е отдельных моделей) определено в IDE модели.
Заголовок MDL, содержащей модель авто:
Единственное различие между заголовками LCS и VCS - это увеличенный массив указателей на primary-материалы.
Версия Liberty City Stories:
0x0 4b: указатель на Clump 0x4 4b: количество extra 0х8 4b: указатель на массив указателей на Atomic моделей extra 0xC 100b: 25 указателей на материалы, перекрашиваемые primary-цветом 0x70 100b: 25 указателей на материалы, перекрашиваемые secondary-цветом
Версия Vice City Stories:
0x0 4b: указатель на Clump 0x4 4b: количество extra 0х8 4b: указатель на массив указателей на Atomic моделей extra 0xC 120b: 30 указателей на материалы, перекрашиваемые primary-цветом 0x84 100b: 25 указателей на материалы, перекрашиваемые secondary-цветом
Заголовок MDL, содержащей модель ped'ов:
0x0 4b: указатель на коллизию (как правило, встроена в MDL) 0x4 4b: указатель на Clump
Заголовок MDL, катсценовских педов или объектов:
0x0 16b: Clump
Clump:Struct
Содержит т.н. под-секцию Clump-Atomic cycle для цикличного перехода по всем атомикам, принадлежащим данному Clump и спользуется для привязки Atomic к Clump. Аналогичная под-секция присутсвует в Atomic. Важно отметить и то, что extra в моделях авто загружаются отдельно и не принадлежат Clump модели (Не участвуют в цикле Clump-Atomic cycle).
0x0 4b: ID секции 0x4 4b: переход на главный фрейм (Root Frame) Под-секция Clump-Atomic cycle: 0x8 4b: указатель на под-секцию Clump-Atomic cycle первого атомика (если атомиков нет, то ссылается на саму себя) 0xC 4b: указатель на под-секцию Clump-Atomic cycle последнего атомика (если атомиков нет, то ссылается на саму себя)
Clump:FrameList:Struct
Содержит т.н. под-секцию Frame-Atomic cycle для цикличного перехода по атомикам, принадлежащим данному фрейму и спользуется для привязки Atomic (а соответственно и геометрии) к фрейму. Аналогичная под-секция присутсвует в Atomic.
Версия Liberty City Stories PS2:
0x0 4b: тип секции 0x4 4b: смещение на родительский фрейм (Parent Frame) Под-секция Frame-Atomic cycle: 0x8 4b: указатель на под-секцию Frame-Atomic cycle первого атомика (если привязанных атомиков нет, то ссылается на саму себя) 0xC 4b: указатель на под-секцию Frame-Atomic cycle последнего атомика (если привязанных атомиков нет, то ссылается на саму себя) 0x10 64b: matrix4x4: матрица трансформации для фрейма и привязанной к ней геометрии относительно родительского фрейма (для вычисления глобальной трансформации фрейма необходимо умножить данную матрицу на матрицу родительского фрейма) 0x50 64b: matrix4x4: глобальная матрица трансформации для фрейма или привязанной к ней геометрии (в LCS у моделей со скелетом обычно единичная матрица) 0x90 4b: указатель на фрейм нижнего уровня (Child Frame) 0x94 4b: указатель на фрейм одного уровня в иерархии с данным фреймом (Sibling Frame) 0x98 4b: указатель на главный фрейм (Root Frame) 0x9C 4b: ID кости. (только для моделей педов и CS объектов, в остальных случаях = -1). 0xA0 4b: Указатель на параметры костей (только для моделей педов и CS объектов) 0xA4 4b: указатель на имя фрейма 0xA8 4b: ID информационного узла модели, используется только в моделях авто.
Версия Liberty City Stories PSP, Vice City Stories PSP, Vice City Stories PS2:
0x0 4b: тип секции 0x4 4b: смещение на родительский фрейм (Parent Frame) Под-секция Frame-Atomic cycle: 0x8 4b: указатель на под-секцию Frame-Atomic cycle первого атомика (если привязанных атомиков нет, то ссылается на саму себя) 0xC 4b: указатель на под-секцию Frame-Atomic cycle последнего атомика (если привязанных атомиков нет, то ссылается на саму себя) 0x10 64b: matrix4x4: матрица трансформации для фрейма и привязанной к ней геометрии относительно родительского фрейма (для вычисления глобальной трансформации фрейма необходимо умножить данную матрицу на матрицу родительского фрейма) 0x50 64b: matrix4x4: глобальная матрица трансформации для фрейма или привязанной к ней геометрии (в LCS у моделей со скелетом обычно единичная матрица) 0x90 4b: указатель на фрейм нижнего уровня (Child Frame) 0x94 4b: указатель на фрейм одного уровня в иерархии с данным фреймом (Sibling Frame) 0x98 4b: указатель на главный фрейм (Root Frame) 0x9C 4b: выравнивание 0xA0 4b: ID кости. (только для моделей педов и CS объектов LCS, в остальных случаях = -1, в VCS не используется и равно 0). 0xA4 4b: Указатель на параметры костей (только для моделей педов и CS объектов) 0xA8 4b: указатель на имя фрейма 0xAC 4b: ID информационного узла модели, используется только в моделях авто.
ID информационных узлов авто в Liberty City Stories:
0 - простой фрейм 1 - wheel_rf_dummy 2 - wheel_rm_dummy 3 - wheel_rb_dummy 4 - wheel_lf_dummy 5 - wheel_lm_dummy 6 - wheel_lb_dummy 7 - bump_front_dummy 8 - bump_rear_dummy 9 - wing_rf_dummy 10 - wing_rr_dummy 11 - door_rf_dummy 12 - door_rr_dummy 13 - wing_lf_dummy 14 - wing_lr_dummy 15 - door_lf_dummy 16 - door_lr_dummy 17 - bonnet_dummy 18 - boot_dummy 19 - windscreen_dummy
ID информационных узлов авто в Vice City Stories:
0 - простой фрейм 1 - неизвестно 2 - wheel_rf_dummy 3 - wheel_rm_dummy 4 - wheel_rb_dummy 5 - wheel_lf_dummy 6 - wheel_lm_dummy 7 - wheel_lb_dummy 8 - door_rf_dummy 9 - door_rr_dummy 10 - door_lf_dummy 11 - door_lr_dummy 12 - bump_front_dummy 13 - bump_rear_dummy 14 - wing_rf_dummy 15 - wing_lf_dummy 16 - wing_rr_dummy 17 - wing_lr_dummy 18 - bonnet_dummy 19 - boot_dummy 20 - windscreen_dummy
Clump:TextureList:Struct
4b: тип секции 4b: 0 4b: 1 4b: указатель на Clump:TextureList:String 4b: количество текстур 4b: количество текстур (повторяется) 4b: указатель на таблицу инвертированных матриц костей 4b: выравнивание (AAAAAAAA)
Clump:GeometryHeader:Struct
4b float: Координата Х ограничивающей модель сферы 4b float: Координата Y ограничивающей модель сферы 4b float: Координата Z ограничивающей модель сферы 4b float: Радиус ограничивающей модель сферы 4b: размер модели + кол-во материалов (первые 12 бит - кол-во материалов, оставшиеся 20 бит - размер). 4b: флаг, по которому движок игры определяет какие дополнительные секции параметров вертексов присутствуют в модели (нормали, прилайт, скиннинг, UV развертка) 2b: общее кол-во вертексов в модели 2b: смещение на первый тристрип. 12b: 6x2b ограничивающая коробка (MinX,MinY,MinZ,MaxX,MaxY,MaxZ типа signed short, расшифровываются аналогично коордиатам вертексов с применением ScaleFactor и TranslateFactor). 4b float: множитель координаты X (ScaleFactorX) 4b float: множитель координаты Y (ScaleFactorY) 4b float: множитель координаты Z (ScaleFactorZ) 4b float: смещение координаты X (TranslateFactorX) 4b float: смещение координаты Y (TranslateFactorY) 4b float: смещение координаты Z (TranslateFactorZ)
Atomic
0x0 4b: тип секции 0x4 4b: указатель на родительский фрейм Под-секция Frame-Atomic cycle: 0x8 4b: указатель на под-секцию Frame-Atomic cycle следующего атомика (если последний, то ссылается на Frame-Atomic cycle фрейма) 0xC 4b: указатель на под-секцию Frame-Atomic cycle предыдущего атомика (если первый, то ссылается на Frame-Atomic cycle фрейма) 0x10 4b: может содержать любое значение 0x14 4b: смещение на геометрию 0x18 4b: смещение на Clump Под-секция Clump-Atomic cycle: 0x1C 4b: указатель на под-секцию Clump-Atomic cycle следующего атомика (если последний, то ссылается на Clump-Atomic cycle клампа, если не привязан к клампу, то = 0) 0x20 4b: указатель на под-секцию Clump-Atomic cycle предыдущего атомика (если первый, то ссылается на Clump-Atomic cycle клампа, если не привязан к клампу, то = 0) 0x24 4b: id метода рендеринга 0x28 2b: IDE ID, выставляется движком. В файле обычно = -1 0x2A 2b: параметры ломающихся/отделяющихся запчастей авто. 0x2C 4b: указатель на параметры костей (только для моделей педов и CS объектов) 0x30 4b: может содержать любое значение
Список материалов
MDL-версия
12b: point3 X Y Z (не используется) 4b: множитель U 4b: множитель V 4b: цвет материала (не используется) 4b: переход на начало тристрипцев (относительно секции геометрии) 2b: количество тристрипцев в материале 2b: номер текстуры из TextureList
WRLD-версия
Содержится исключительно в *.wrld
и является сжатой по сравнению с *.mdl
-версией для быстрого чтения и экономии памяти консоли. Вместо имён текстур содержит их id (хэши).
Заголовок WRLD версии PS2:
[2b int] количество материалов [2b int] размер секции материалов
Заголовок WRLD версии PSP:
[4b int] количество материалов [4b float] неизвестно, У ЛОДов обычно равно 0
Длина строки списка геометрии LCS PS2: = 22 байт.
[2b int] id текстуры [2b int] Размер тристрипа (необходима логическая операция and 0x7FFF, т.к. первый бит является флагом backface culling) [2b half float] множитель для U [2b half float] множитель для V [2b] неизвестно, возможно флаги [12b 6x signed int] ограничивающая коробка
Длина строки списка геометрии VCS PS2: = 24 байт.
[4b int] Размер тристрипа (необходим разделить на 2 нацело, если делится с остатком 1 - на текущем тристрипе включен backface culling) [2b int] id текстуры [2b half float] множитель для U [2b half float] множитель для V [2b] неизвестно, возможно флаги [12b 6x signed int] ограничивающая коробка
Длина строки списка геометрии LCS PSP может быть в 2х вариантах: 10 байт или 24 байт. Определяется с помощью float в заголовке: если float <>0 то длина строки = 24 байт, если =0 то, соответственно, 10 байт.
[2b int] id текстуры [2b int] количество вершин в тристрипе (необходима логическая операция and 0x7FFF, т.к. первый бит является флагом backface culling) [2b half float] множитель для U [2b half float] множитель для V [2b] неизвестно, возможно флаги [2b] неизвестно, возможно флаги (секция может отсутствовать) [12b 6x signed int] ограничивающая коробка (секция может отсутствовать)
Длина строки списка геометрии VCS PSP: = 24 байт.
[2b int] id текстуры [2b int] количество вершин в тристрипе (необходима логическая операция and 0x7FFF, т.к. первый бит является флагом backface culling) [2b half float] множитель для U [2b half float] множитель для V [2b] неизвестно, возможно флаги [2b] неизвестно, возможно флаги [12b 6x signed int] ограничивающая коробка
Координаты ограничивающей коробки расшифровываются аналогично расшифровке координат тристрипа (делением каждого int на 32768 и умножением на скайлинг модели)
Множители U и V представляют собой half precision floating point. Описание см. здесь
DTZ-версия
MDL-файлы, "вшитые" внутри DTZ-файла. Формат ничем не отличается, поэтому MDL importer может прочитать DTZ как MDL и импортировать модели.
Список геометрии
PS2-версия
Вся геометрия модели разбита на тристрипсы (поддержка тристрипсов присутствует и в DFF-файлах GTA: SA).
Чтение первого тристрипса в MDL начинается сразу после списка материалов. Началом чтения геометрии тристрипса служит флаг 6С018000. За флагом 2 раза повторяется количество вершинок в тристрипсе. Затем идёт технический сектор 40404020, который необходим для движка (для импорта модели он не важен).
Далее идут собственно блоки, содержащие элементы модели:
- Блок 79 - Гео - содержит все координаты вершинок в тристрипсе. Одна координата закодирована типом Short (2b) #signed и вычиляется следующим образом:
(maxscript) CoordX = (CoordX as Float)/32768*ScaleFactorX+TranslateFactorX аналогично Y и Z
Размер блока = заголовок блока (4 байта) + (XYZ (6 байтов) * количество вершинок в тристрипсе).
Блок геометрии заканчивается техническим блоком 50505020, который необходим для движка (для импорта модели он не важен).
- Блок 76 - UV - содержит все координаты UV-маппинга в тристрипсе. Одна координата закодирована типом Byte (1b) #unsigned, вычисляется делением на 255 для моделей из WRLD/LVZ или делением на 128 для MDL. Размер блока = заголовок блока (4 байта) + (UV (2 байта) * количество вершинок в тристрипсе).
- Блок 6F - Прилайт Stories - содержит RGBA для предварительного освещения вершинки. Используется только в GTA LCS и GTA VCS. Хранится в 16 битном формате RGBA 5551. Размер блока = заголовок блока (4 байта) + (RGBA (2 байта) * количество вершинок в тристрипсе).
- Блок 6Е - Прилайт Manhunt 2 - содержит RGBA для предварительного освещения вершинки. Используется только в Manhunt 2. Каждый цвет закодирован одним байтом. Размер блока = заголовок блока (4 байта) + (RGBA (4 байта) * количество вершинок в тристрипсе). Считывать необходимо как BGRA
- Блок 6A - Нормали - содержит все координаты векторов нормалей в трипстрипсе. Одна координата закодирована типом Byte (1b) #signed и вычисляется делением на 127. Размер блока = заголовок блока (4 байта) + (XYZ (3 байта) * количество вершинок в тристрипсе).
- Блок 6С - Скиннинг - содержит таблицу весов вершинок для их анимации. Это id косточки (1 байт, необходимо делить на 4 нацело) + её вес (3 байта). Соответственно, каждая вершинка содержит 4 id (т.е. в анимации она управляется 4 косточками). Размер блока = заголовок блока (4 байта) + ((id_weight (4 байта) * 4) * количество вершинок в тристрипсе.
Чтение следующего тристрипса начинается сразу же за флагом окончания тристрипса - 14000006. Общее количество тристрипсев в модели так же записано в клампе.
PSP-версия
Информация будет добавлена позже...
Геометрия представляет собой массив тристрипсов, UV координат и прилайта и нормалей.
Геометрия WRLD
Количество вершин в тристрипсе записано в строке материала.
Первый тристрипс наченается сразу после списка материалов
Размер тристрипса = количество вершин * 1 строка массива вершин (в WRLD = 10 байт)
Каждый следующий тристрипс начинается после конца предыдущего
Одна строчка массива вершин = 10 байт
2b: UV (координаты рассчитываются аналогично PS2)
2b: Vcol (расчет прилайта аналогичен PS2)
2b: xCoord (рассчитывается с учетом скайлинга в WRLD)
2b: yCoord (рассчитывается с учетом скайлинга в WRLD)
2b: zCoord (рассчитывается с учетом скайлинга в WRLD)
MDL версии Manhunt 2
MDL версии Manhunt 2 на всех версиях кроме Wii имеет схожую структуру и может быть легко сконвертирован в любую из версий простым преобразованием формата, в котором игра хранит геометрию модели.
MDL может содержать как одну, так и нескольно моделей, принцип чтения которых описан ниже.
MDL версии PS2 и PSP имеет расширение .DFF
Структура файла
Главный заголовок
Заголовок 1 имеет типичную структуру во всех файлах движка, отличается лишь сигнатурой (см. пункт Структура главного заголовка MDL)
Заголовок MDL и цикл чтения моделей
Представляет собой цикл считывания каждой отдельной модели.
Размер заголовка = 8 байт
4b - Переход на первую строку цикла поиска моделей. 4b - Переход на последнюю строку цикла поиска моделей.
Строка цикла поиска моделей:
4b - Смещение на следующую суб-модель. 4b - Смещение на предыдущую суб-модель. 4b - Смещение на текущую суб-модель.
При переходе на смещение на текущую суб-модель игра считывает еще одно промежуточное смещение, которое, наконец, приводит к циклу чтения геометрии текущей суб-модели.
Геометрия версии PC
Заголовок
Размер заголовка 180 байт
4b - Смещение на список использованных текстур. Первой текстуре присваивается индекс 0, второй 1 и т.д. 4b - количество использованных текстур в модели. 4b - Смещение на кости для текущей модели. Если =0 - модель не имеет привязанных костей. 4b - неизветно 4b - неизвестно, обычно 1 12b - padding 4b - сигнатура (0х45D454) 4b - размер модели 4b - неизвестно, обычно 0 4b - количество материалов в модели 4b - количество индексов полигонов. (кол-во полигонов = количество индексов полигонов/3) 16b - 4 float - X Y Z и радиус ограничивающей сферы 12b - 3 float, обычно 1.0 1.0 1.0 4b - количество вершин в модели. 12b - padding 4b - шаг чтения одной вершины 44b - неизвестные данные, при любом их изменении или обнулении никакого эффекта в игре не проявляется 4b - параметры вертексов (по данным параметрам игра определяет какие секции имеют вершины - Normals, VCol, Skin и тд) 32b - неизвестные данные, при любом их изменении или обнулении никакого эффекта в игре не проявляется
Список материалов
Расположен сразу за заголовком, длина строки материала = 44 байт
24b - 6 floats - ограничивающая коробка 2b - количество индексов полигонов текущего материала (кол-во полигонов = количество индексов полигонов текущего материала/3). 2b - ID текстуры 2b - количество индексов полигонов, пропускаемых перед началом чтения необходимых индексов для текущего материала. 14b - неизвестно, при любом их изменении или обнулении никакого эффекта в игре не проявляется
Индексы полигонов
Таблица индексов полигонов располагается сразу после списка материалов. Каждый индекс = 2b. Количество индексов указано в заголовке.
Структура вершин и привязанные к ней параметры
В отличии от DFF, где все параметры вертексов расположены в отдельных таблицах, в MDL версии PC все параметры считываются сразу после координат вертекса.
Размер строки вертекса задается параметрами вертексов в заголовке.
Примерная структурная последовательность параметров вертексов в MDL версии PC.
12b - 3 floats - X Y Z 20b - Скиннинг (4 floats[4b] - веса, 4 bytes [1b] - ID костей) 8b - Нормали (3 words [2b] - X Y Z нормали, 2b -0) 4b - VCol (4b, хранится в BGRA а не в RGBA) 8b - UV1 (2 floats) 8b - UV2 (2 floats - обычно встречается в моделях персонажей, развертка для текстур кровяных пятен на теле)