[C, Компьютерная анимация, Программирование, Реверс-инжиниринг] Разжимаем древний формат сжатия анимаций

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
13-Июл-2020 16:30


В один день я просматривал различные видео на YouTube, связанные с персонажами программы Vocaloid (не совсем точное описание, но дальше буду называть просто вокалоидами). Одним из таких видео было так называемое PV из игры Hatsune Miku: Project DIVA 2nd. А именно песня relations из The Idolmaster, которую исполняли вокалоиды Megurine Luka и Kagamine Rin. Оба персонажа от Crypton Future Media. Порыскав по сети я понял, что никто так и не смог сконвертировать анимации из этой игры? Но почему? Об этом под катом.
Сама игра использует Alchemy Engine, который разработала Intrinsic Graphics, а позже купила Vicarious Visions. Это можно увидеть по файлам, имеющим расширение ".igb" (далее — IGB), а также соответствующим строкам в них. Сами файлы бинарные. Погуглив немного я нашёл скрипт от тов. minmode для известной в определённых кругах программы Noesis. Запускаем её, с перекинутым в папку скриптом, пытаемся открыть файл анимаций и… Получаем тыкву.

Как объяснил тов. minmode в своём посте на DeviantArt, этот скрипт не может прочитать анимацию, сжатую некоей Enbaya. В Google Patents я смог найти только подобное. Самим патентам уже лет 19-20, поэтому я и предполагаю, что сам алгоритм сжатия тоже древний. Да и сам сайт на это тоже намекает (доступен только через веб-архив). Поискав ещё немного я понял, что этот алгоритм был в составе некоего ProGATE от компании Enbaya. Но это ничего нам не даёт.
Вернёмся же к IGB. Переписав код для IGB, который я смог найти, а также воспользовавшись скриптом для Noesis, на C#, картина начала проясняться.
Ниже я приведу таблицу элементов, как она была выстроена в файлах IGB в этой игре (простите за корявость. Иначе не умею). Приведу только нужные нам элементы
Уточнение — *List — массив из элементов *
igAnimationDatabase
--igSkeletonList
---igSkeleton - Скелет, который, возможно, будет использоваться нами
----igSkeletonBoneInfoList
-----igSkeletonBoneInfo - Нода скелета
--igAnimationList
---igAnimation - Наша анимация
----igAnimationBindingList
-----igAnimationBinding - Ссылается на igSkeleton. Служит для линковки скелета к анимации
----igAnimationTrackList
-----igAnimationTrack - Сам трек анимации
------igEnbayaTransformSource
-------igEnbayaAnimationSource
--------igData - Тут уже хранятся сырые данные Enbaya
igData - Нода с данными, которые уже не являются нодами.

Таким образом я смог достать сырые данные для дальнейшего изучения. С помощью PPSSPP, Ghidra и плагина для неё я начал изучать бинарник игры. Я уже не особо помню как именно нашёл нужные функции, но приведу конкретные функции из EBOOT.BIT из ULJM05681 (в данном случае это не первая, а вторая, так называемая Bargain Version или же Project Diva 2nd#):
0x08A08050 — инициализация функции декомпрессии на основе заголовка из igData
0x08A0876C — запрос данных по конкретному времени (да. Enbaya работает со временем, не кадрами).
Сам код декомпилирован и выложен на GitLab. Написан он на Си. Компилируется как в Visual Studio, так и в gcc. Работает как в x86, так и в x64.
Я не стану углубляться в сам алгоритм. За меня лучше расскажет мой код.
Но если кратко, то Enbaya использует дельту для данных о перемещении и кватернионах. Дельту оно применяет, просто прибавляя/отнимая её к/от предыдущим/текущих данных. Перемещение остаётся как есть, а кватернион нормализуется для дальнейшего использования. Алгоритм позволяет вернуться назад во времени, не перезагружая файл. При этом он оперирует не частотой кадров, а семплами в секунду. Для этого он в памяти хранит два состояния — предыдущий семпл и следующий, а движок сам интерполирует значение между ними. Однако в следствии того, что у нас данные в файле везде в целочисленном виде, мы должны их на что-то делить (точнее умножить. например на 0.0002), чтобы получить дробное число. Это число указывается в заголовке. Из-за этого деления (на самом деле умножения, но не суть) с каждым сложением и вычитанием точность немного уплывает.
А на этом всё. Честно говоря, мне было весело реверсить всё это. Надеюсь, что мои труды не прошли даром.
P.S. Используя данные igSkeleton мы уже можем получить готовую анимацию и экспортировать её, например в Maya. Через тот же Noesis.
Извините, данный ресурс не поддреживается. :(
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_c, #_kompjuternaja_animatsija (Компьютерная анимация), #_programmirovanie (Программирование), #_reversinzhiniring (Реверс-инжиниринг), #_animatsija (анимация), #_igrovye_animatsii (игровые анимации), #_skeletnaja_animatsija (скелетная анимация), #_alchemy, #_animation, #_enbaya, #_intrinsic_alchemy, #_vucarious_visions, #_c, #_kompjuternaja_animatsija (
Компьютерная анимация
)
, #_programmirovanie (
Программирование
)
, #_reversinzhiniring (
Реверс-инжиниринг
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 16-Май 14:27
Часовой пояс: UTC + 5