Descompactando o antigo formato de compressão de animação

imagem



Um dia assisti a vários vídeos no YouTube relacionados aos personagens do programa Vocaloid (não é uma descrição muito precisa, mas continuarei a chamá-lo apenas de vocaloids). Um desses vídeos foi o chamado PV do jogo Hatsune Miku: Projeto DIVA 2. Nomeadamente, as relações musicais de The Idolmaster, que foi interpretado pelos vocaloids Megurine Luka e Kagamine Rin. Ambos os personagens são da Crypton Future Media. Depois de navegar na net, percebi que ninguém conseguia converter as animações deste jogo? Mas por que? Sobre isso sob o corte.



O jogo em si usa o Alchemy Engine, que foi desenvolvido pela Intrinsic Graphics e mais tarde comprado pela Vicarious Visions. Isso pode ser visto nos arquivos com a extensão ".igb" (doravante - IGB), bem como nas linhas correspondentes nos mesmos. Os próprios arquivos são binários. Pesquisando um pouco, encontrei um roteiro do Comrade. minmode para o conhecido programa Noesis em certos círculos . Nós o lançamos, com o script jogado na pasta, tentamos abrir o arquivo de animação e ... Pegamos a abóbora.



imagem



Como camarada. minmode em seu post no DeviantArt, este script não pode ler animações compactadas por alguns Enbaya. Nas patentes do Google, só encontrei algo semelhante . As próprias patentes já têm 19-20 anos, então presumo que o algoritmo de compressão em si também seja antigo. E o próprio sitedicas sobre isso também (disponível apenas por meio do arquivo da web). Depois de pesquisar um pouco mais, percebi que esse algoritmo fazia parte de um determinado ProGATE da empresa Enbaya. Mas isso não nos dá nada.



Voltemos ao IGB. Ao reescrever o código do IGB que pude encontrar, e também ao usar o script do Noesis, em C #, a imagem começou a ficar mais clara.



Abaixo darei uma tabela de elementos, como foi alinhada nos arquivos IGB deste jogo (desculpe ser desajeitado. Não posso fazer de outra forma). Darei apenas os elementos de que precisamos



Esclarecimento - * Lista - um conjunto de elementos *



igAnimationDatabase
--igSkeletonList
---igSkeleton - , , ,   
----igSkeletonBoneInfoList
-----igSkeletonBoneInfo -  
--igAnimationList
---igAnimation -  
----igAnimationBindingList
-----igAnimationBinding -   igSkeleton.      
----igAnimationTrackList
-----igAnimationTrack -   
------igEnbayaTransformSource
-------igEnbayaAnimationSource
--------igData -      Enbaya
igData -   ,     .


Dessa forma, consegui obter os dados brutos para um estudo mais aprofundado. Com a ajuda de PPSSPP, Ghidra e um plugin para ele, comecei a estudar o binário do jogo. Não me lembro exatamente como encontrei as funções necessárias, mas darei funções específicas de EBOOT.BIN de ULJM05681 [ou NPJH50300] (neste caso, este é o primeiro Projeto Diva 2, e não o segundo, a chamada Versão Barganha ou Projeto Diva 2 ° #) :



0x08A08050 - inicialização da função de descompressão baseada no cabeçalho de igData

0x08A0876C - solicitação de dados em um momento específico (sim. Enbaya trabalha com o tempo, não com os quadros).



O próprio código é descompilado e postado no GitLab . Está escrito em C. Compila no Visual Studio e gcc. Funciona em x86 e x64.



Não vou entrar no algoritmo em si. Meu código vai te dizer melhor para mim.



Mas, em resumo, Enbaya usa um delta para dados de deslocamento e quatérnio. Ele aplica o delta simplesmente adicionando / subtraindo-o aos dados anteriores / atuais. A tradução permanece como está e o quaternion é normalizado para uso posterior. O algoritmo permite que você volte no tempo sem recarregar o arquivo. Além disso, ele opera não com uma taxa de quadros, mas com amostras por segundo. Para fazer isso, ele armazena dois estados na memória - a amostra anterior e a próxima, e o próprio mecanismo interpola o valor entre eles. No entanto, devido ao fato de que os dados do arquivo estão em todos os lugares na forma inteira, devemos dividi-los por algo (mais precisamente, multiplicá-los, por exemplo, por 0,0002) para obter um número fracionário. Este número é indicado no título. Por causa dessa divisão (na verdade, multiplicação, mas não a essência), com cada adição e subtração, a precisão varia um pouco.



E isso é tudo. Para ser honesto, eu me diverti revertendo tudo. Espero que meu trabalho não tenha sido em vão.



PS Usando os dados igSkeleton, já podemos obter a animação finalizada e exportá-la, por exemplo, para o Maya. Através do mesmo Noesis.






All Articles