Реверс-инжиниринг из детства - вытаскиваем данные из Carmageddon TDR2000 - часть 2
Ну что, двигаем дальше?) В прошлый раз Реверс-инжиниринг из детства - вытаскиваем данные из Carmageddon TDR2000 удалось распаковать архив с данными, самое время эти данные визуализировать!
Итак, погнали. За что цепляется взгляд?
tga - очевидно, текстуры, до них дойдем в последний момент
dcol - в PAK локаций я видел scol, логично предположить, что это Динамический КОЛлайдер
mshs - судя по всему - меш (MESH)
hie - какой то текстовый файл, описание модели?
Как и обычно в таких случаях - начинаю с меша (как оказалось потом - зря:) )
Открываем хекс-редактором
Первое, что запоминаем, это порядок байт - Little endian.
Что мы можем найти?
целые числа - обычно четыре байта, можно узнать по нулям в правых байтах.
float - 4 непонятных байта :)), но в редакторе можно выделить - и в анализе данных будет вполне адекватное значение.
а есть читабельные флоаты, например 00 00 80 3F - это 1
еще есть такой маркер - если корень суммы квадратов 3-х чисел равен 1 - значит перед нами нормаль :)
В общем, просто накидал простой парсер, который бинарные данные дампит по такой логике в таблицу - так разобрать куда легче )
Опыт работы с такими данными подсказывает, что пачки флоатов в начале - это вершины. Иногда они идут вместе с UV. Но здесь есть закономерность именно по 3 числа - что как бы намекает, что перед нами список векторов. Предполагаем, что число 30 перед этим блоком - количество векторов. Умножаем на 12... Ну, почти совпадает :)
Опущу эксперименты с визуализацией, у меня получилась такая схема:
Дальше начинается интересное, если отбросить следующие 3 флоата (анализ которых говорит что это нормаль), дальше идут числа 0, 1, 2 - ну, собственно, вот они, номера вершин полигона. И такой паттерн повторяется каждые 132 байта. Значит, каждые такой блок - это полигон.
Смотрим, сколько таких блоков? оу, 38, прям как было в первом числе.
Итак, в начале имеем количество полигонов и количество вершин, далее - данные. Но файл на этом не заканчивается. Далее... снова знакомый паттерн. количество поликов - 0 - 1 - количество вершин. И так до конца файла.
Итог - mshs файл это некоторое количество мешей, каждый меш состоит из вершин и поликов. Вот что с этим делать? Как они позиционируются? Я слегка забуксовал, думая, что позиции мешей записаны в самом файле, но нет, ключ был в файле hie, с которого и стоило начинать анализ :)
Number of textures, number of materials - тут всё логично, есть материалы, материалы ссылаются на текстуры (те tga, что мы видели при распаковке, очевидно)
Что особенно интересно:
Matrices
Nodes
Meshes - а блин, количество как раз совпадает с количеством блоков, считанных в mshs )))
Взгляд цепляется за Nodes, как будто это те данные, которые выстраивают иерархию модели, вот только узлов как то многовато. Если данные развернуть в дерево, то получится довольно громоздкая структура.
Ответ в поле TYPE. каждый узел этого дерева иерархии отвечает за свой тип.
Ну, осталось только сопоставить где какой тип :)
Я заметил такую закономерность, для каждого типа узла есть свой диапазон значения в поле INDEX.
Что получаем?
1 - в пределах количества Matrices
2 - в пределах количества Textures
3 - в пределах количества Meshes
4 - в пределах количества Expressions (не упоминал ранее, но есть в HIE-файле)
5 - в пределах количества Materials
7 - в пределах количества Collision Meshes
Значит, алгоритм следующий.
Элементы типа 1 представляю собой собственно иерархию "костей", к каждой кости применяем матрицу преобразования, которая ей соответствует.
элемент типа 2 - устанавливает тектуру.
элемент типа 3 - читает меш из файла mshs
элемент типа 4 - применяет expression из самого файла hie (но, каюсь, не доразобрался зачем оно надо:) )
элемент типа 5 - устанавливает материал
элемент типа 7 - читает коллизию из файла *col (на данной стадии мне не особо это важно было, поэтому не парсил)
Пара скринов процесса :)
Применил логику ко всем машинам в карме - ну, не всё прям прочиталось отлично, где то проблемы с текстурами, но эксепшны не лезут - уже успех :))
Что дальше? Надо расковырять локации! А пока пока - вот вам скрин тачки из Carmageddon TDR2000 на трассе из Need for Speed 3 (которую я расковырял уже давно) :)
Надеюсь, до встречи следующей части! План - расковырять локации :)












