Usando o formato .x para exportar um modelo do Blender, posso carregar uma malha, armadura e animação. Não tenho problemas para gerar a malha e visualizar modelos no jogo. Além disso, tenho animações e a armadura carregadas corretamente nas estruturas de dados apropriadas.
Meu problema é aplicar corretamente a animação aos modelos. Eu tenho a estrutura para aplicar os modelos e o código para selecionar animações e percorrer os quadros.
Pelo que entendi, o AnimationKey
s dentro do AnimationSet
fornece as transformações para transformar a pose de ligação na pose no quadro animado. Como pequeno exemplo:
Animation {
{Armature_001_Bone}
AnimationKey {
2; //Position
121; //number of frames
0;3; 0.000000, 0.000000, 0.000000;;,
1;3; 0.000000, 0.000000, 0.005524;;,
2;3; 0.000000, 0.000000, 0.022217;;,
...
}
AnimationKey {
0; //Quaternion Rotation
121;
0;4; -0.707107, 0.707107, 0.000000, 0.000000;;,
1;4; -0.697332, 0.697332, 0.015710, 0.015710;;,
2;4; -0.684805, 0.684805, 0.035442, 0.035442;;,
...
}
AnimationKey {
1; //Scale
121;
0;3; 1.000000, 1.000000, 1.000000;;,
1;3; 1.000000, 1.000000, 1.000000;;,
2;3; 1.000000, 1.000000, 1.000000;;,
...
}
}
Portanto, para aplicar o quadro 2, eu pegaria a posição, a rotação e a escala do quadro 2, criaria uma matriz de transformação (chamada Transform_A
) a partir delas e aplicaria a essa matriz os vértices controlados por Armature_001_Bone
seus pesos. Então, eu enfiava TransformA
no shader e transformava o vértice. Algo como:
vertexPos = vertexPos * bones[ int(bfs_BoneIndices.x) ] * bfs_BoneWeights.x;
Onde bfs_BoneIndices
e bfs_BoneWeights
são valores específicos para o vértice atual.
Ao carregar nos vértices da malha, eu os transformo pelo rootTransform
e pelo meshTransform
. Isso garante que eles sejam orientados e redimensionados corretamente para visualizar a pose de ligação.
O problema é que, quando eu crio essa matriz de transformação (usando a posição, rotação e escala da animação), ela não transforma adequadamente o vértice. Provavelmente há mais do que apenas usar os dados da animação. Eu também tentei aplicar as hierarquias de transformação óssea, ainda sem dados. Basicamente, acabo com alguns modelos distorcidos. Deve-se notar também que estou trabalhando em openGL, portanto, qualquer transposição de matriz que precise ser aplicada deve ser considerada.
Quais dados eu preciso e como combiná-los para aplicar animações .x aos modelos?
Fiz alguns modelos da aparência, caso isso seja útil.
Primeiro, eu queria apenas testar a tradução, esta é uma cabeça oscilante, como é no Blender:
http://i.stack.imgur.com/NAc4B.gif
E como fica no jogo (não importa as cores):
http://i.stack.imgur.com/nj2du.gif
Então, apenas para rotação, a animação foi a cabeça girando 360 graus em torno do eixo vertical. Isto é o que parece no jogo:
http://i.stack.imgur.com/gVyUW.gif
Observe que não deve haver inclinação, apenas rotação como um carrossel.
Atualizar
Eu tenho a parte da tradução da animação funcionando. Mas parece meio hacky e não vejo como aplicá-lo à rotação.
A tradução funciona seguindo estas etapas:
- Assuma a posição do quadro de animação e troque os valores
y
ez
- Traduzir a matriz de transformação pela posição alterada
- Transponha a matriz de transformação
- Aplique a matriz de transformação aos vértices
Então é assim que pode funcionar, mas como deve funcionar geralmente para posição, escala e rotação?
fonte
Respostas:
Talvez essa seja a chave, você já tentou negar algumas coordenadas Z para converter de coordenadas esquerdas do DirectX para destras do OpenGL?
Você pode negar todos os Zs antes de aplicar suas transformações e renegar quando terminar, para ver se a saída melhora.
EDITAR
Trocar as coordenadas Y e Z é outra maneira de mudar de posição. Então você precisa adaptar suas transformações, consulte este documento para obter detalhes .
O fato de você ter que transpor sua matriz também significa que você vai da linha principal para a coluna principal ou vice-versa. Isso deve ser menos complicado, provavelmente você só precisará encontrar o "lugar" certo para fazê-lo em seu pipeline. Estou apenas supondo, mas fazê-lo em quaterniões pode significar simplesmente alterá-los para matrizes, transpor e voltar quaterniões, se sua biblioteca de matemática oferecer essa opção.
fonte
OK, dediquei mais tempo a isso e o fiz funcionar para vários ossos, e consideravelmente menos parecido com um hack (embora ainda um pouco). O sistema que eu tinha originalmente estava quase correto. No entanto, os principais problemas foram:
Meu código para converter um Quaternion em uma matriz estava incorreto. Na verdade, ainda não sei por que isso está incorreto, mas sei que o seguinte código funciona, como parte da minha classe Quaternion:
Fora isso, é apenas:
finalMatrix = boneMatrix * skinMatrix * invertedBindMatrix;
Observe que eles
boneMatrix
devem usar matrizes animadas para cada osso, em vez das matrizes de ligação. Ele também deve obter todas as matrizes pai da seguinte forma:E isso funciona. Deixe um comentário se precisar de esclarecimentos.
fonte