Usando el formato .x para exportar un modelo desde Blender, puedo cargar una malla, armadura y animación. No tengo problemas para generar la malla y ver modelos en el juego. Además, tengo animaciones y la armadura cargada correctamente en las estructuras de datos apropiadas.
Mi problema es aplicar correctamente la animación a los modelos. Tengo el marco para aplicar los modelos y el código para seleccionar animaciones y recorrer cuadros.
Por lo que entiendo, la AnimationKey
s dentro de las AnimationSet
fuentes proporciona las transformaciones para transformar la pose de enlace a la pose en el marco animado. Como pequeño ejemplo:
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;;,
...
}
}
Entonces, para aplicar el marco 2, tomaría la posición, la rotación y la escala del marco 2, crearía una matriz de transformación (llamada Transform_A
) a partir de ellos y aplicaría esa matriz a los vértices controlados por Armature_001_Bone
sus pesos. Así que me metería TransformA
en mi sombreador y transformaría el vértice. Algo como:
vertexPos = vertexPos * bones[ int(bfs_BoneIndices.x) ] * bfs_BoneWeights.x;
Donde bfs_BoneIndices
y bfs_BoneWeights
son valores específicos del vértice actual.
Al cargar en los vértices de malla, los transformo por el rootTransform
y el meshTransform
. Esto garantiza que estén orientados y escalados correctamente para ver la pose de enlace.
El problema es que cuando creo esa matriz de transformación (usando la posición, rotación y escala de la animación), no transforma adecuadamente el vértice. Es probable que haya más que solo usar los datos de animación. También intenté aplicar las jerarquías de transformación ósea, aún sin dados. Básicamente termino con algunos modelos retorcidos. También se debe tener en cuenta que estoy trabajando en openGL, por lo que se debe considerar cualquier transposición de matriz que deba aplicarse.
¿Qué datos necesito y cómo los combino para aplicar animaciones .x a los modelos?
He hecho algunas maquetas de cómo se ve esto, en caso de que sea útil.
Primero, solo quería probar la traducción, esta es una cabeza flotante, cómo se ve en Blender:
http://i.stack.imgur.com/NAc4B.gif
Y cómo se ve en el juego (no importa los colores):
http://i.stack.imgur.com/nj2du.gif
Luego, solo para la rotación, la animación era la cabeza girando 360 grados alrededor del eje vertical. Así es como se ve en el juego:
http://i.stack.imgur.com/gVyUW.gif
Tenga en cuenta que no debe haber inclinación, solo rotación como un tiovivo.
Actualizar
Tengo la parte de traducción de la animación funcionando. Pero se siente un poco hacky y no veo cómo aplicarlo a la rotación.
La traducción funciona siguiendo estos pasos:
- Tome la posición del cuadro de animación e intercambie los valores
y
yz
- Traslade la matriz de transformación por la posición alterada
- Transponer la matriz de transformación
- Aplicar la matriz de transformación a los vértices.
Así es como puede funcionar, pero ¿cómo se supone que funciona en general para la posición, la escala y la rotación?
fuente
Respuestas:
Tal vez esa sea la clave, ¿ha intentado negar algunas coordenadas Z para convertir las coordenadas de DirectX para zurdos en OpenGL para diestros?
Puede negar todas las Z antes de aplicar sus transformaciones, y volver a negar cuando haya terminado, ver si la salida mejora.
EDITAR
Intercambiar las coordenadas Y y Z es otra forma de cambiar las manos. Para que tenga que adaptar sus transformaciones, consulte este documento para obtener más detalles .
El hecho de que tenga que transponer su matriz también significa que va de mayor a mayor de columna o al revés. Esto debería ser menos complicado de manejar, probablemente solo tendrá que encontrar el "lugar" adecuado para hacerlo en su tubería. Solo estoy adivinando, pero hacerlo en cuaterniones podría simplemente significar cambiarlas a matrices, transponer y volver a cuaterniones, si su lib matemática le ofrece esta opción.
fuente
De acuerdo, dediqué un poco más de tiempo a esto y lo hice funcionar para varios huesos, y considerablemente menos como un pirateo (aunque todavía un poco). El sistema que tenía en su lugar originalmente era casi correcto. Sin embargo, los principales problemas fueron:
Mi código para convertir un Quaternion en una matriz era incorrecto. En realidad, todavía no estoy seguro de por qué esto es incorrecto, pero sé que el siguiente código funciona, como parte de mi clase Quaternion:
Aparte de eso, es solo:
finalMatrix = boneMatrix * skinMatrix * invertedBindMatrix;
Tenga en cuenta que
boneMatrix
debería usar las matrices animadas para cada hueso en lugar de las matrices de unión. También debería obtener todas sus matrices principales de la siguiente manera:Y funciona. Deja un comentario si necesitas una aclaración.
fuente