[C, Компьютерная анимация, Программирование, Реверс-инжиниринг] Разжимаем древний формат сжатия анимаций
Автор
Сообщение
news_bot ®
Стаж: 6 лет 8 месяцев
Сообщений: 27286
В один день я просматривал различные видео на 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
===========
Похожие новости:
- [Аналитика мобильных приложений] «Набор профессионала»: какие инструменты app-аналитики используют крупные компании?
- [Биотехнологии, Здоровье] Presbyopia: «menopause» of the eyes in men and women (перевод)
- [Браузеры, Информационная безопасность, Серверное администрирование] Почему удостоверяющие центры не соблюдают требование CA/Browser к сертификатам
- [Amazon Web Services, Облачные сервисы, Сетевые технологии, Учебный процесс в IT] Как IT-гиганты помогают образованию? Часть 3: Amazon Web Services
- [Биотехнологии, Здоровье, Лазеры] Presbyopia: «menopause» of the eyes in men and women (перевод)
- [Виртуализация, Настройка Linux] Сравниваем лучшее программное обеспечение для виртуализации в 2020 году: Hyper-V, KVM, vSphere и XenServer (перевод)
- [JavaScript, Программирование, Разработка веб-сайтов, Учебный процесс в IT] Задачки для фронтенд-тренировки: doodle-place, Apple Podcasts, Site Blocker, парсинг CSV-файлов (перевод)
- [Agile, DevOps, Управление разработкой, Учебный процесс в IT] DevOps vs Agile: В чем разница (перевод)
- [Космонавтика, Научно-популярное, Тестирование IT-систем] Тестировать больше и лучше: Закончился разбор аварийного полета Boeing Starliner
- [Информационная безопасность, Сетевые технологии, Системное администрирование] NGFW для малого бизнеса. Новая линейка CheckPoint 1500 Security Gateway
Теги для поиска: #_c, #_kompjuternaja_animatsija (Компьютерная анимация), #_programmirovanie (Программирование), #_reversinzhiniring (Реверс-инжиниринг), #_animatsija (анимация), #_igrovye_animatsii (игровые анимации), #_skeletnaja_animatsija (скелетная анимация), #_alchemy, #_animation, #_enbaya, #_intrinsic_alchemy, #_vucarious_visions, #_c, #_kompjuternaja_animatsija (
Компьютерная анимация
), #_programmirovanie (
Программирование
), #_reversinzhiniring (
Реверс-инжиниринг
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 01-Ноя 04:15
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 8 месяцев |
|
В один день я просматривал различные видео на 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 =========== Похожие новости:
Компьютерная анимация ), #_programmirovanie ( Программирование ), #_reversinzhiniring ( Реверс-инжиниринг ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 01-Ноя 04:15
Часовой пояс: UTC + 5