Probando un modelo 3D en el engine.

Continuando el trabajo en el engine custom 3D

Soporte básico para animaciones del gltf/glb

Fecha:

Estos meses he retomado el trabajo en mi engine custom, la vez pasada ya se había agregado soporte básico para cargar una malla y una textura básica, aún no tenía oportunidad de implementar la lectura de las animaciones hasta ahora.

Revisitando el formato gltf/glb

El formato gltf/glb es bastante curioso, y al estar pensado en optimizar la forma en la cual se almacenan los datos de la animación, intentar leerlo es como desenmarañar un espagueti, saltando de un índice a otro.

Es importante notar que para cargar la animación, necesitamos tener acceso a dos datos, el esqueleto que es lo que se está moviendo, y la animación que es la descripción de las transformaciones que realiza cada hueso.

Por suerte, el Khronos Group contiene un muy comprensible manual sobre la estructura del gltf/glb sobre cómo funciona a detalle cada pieza.

Algunos dolores de cabeza

La imagen muestra dos gorilas frente a una computadora, uno verde representandome, y uno cafe reprecentando a claude
Las matemáticas de matrices son complicadas

Aunque la estructura del formato gltf/glb es bastante comprensible, uno de los principales retos fue solucionar las diferencias entre el manejo de las matemáticas dentro del engine y del archivo

El engine custom utilizamos una convención para utilizar matrices en orden superior de fila mientras que las matrices de un gltf se enfocan en orden superior de columnas. Una vez bien definido eso fue darle una revisión a las matemáticas del engine y arreglar algunas inconsistencias. Estuve revisando algunos puntos con la IA Claude, aunque parece que tenía tan poca idea como yo sobre matemáticas 🙃. Una vez solucionada la revisión a la librería de matemáticas, lo siguiente fue poder cargar el esqueleto correctamente tomando en cuenta su jerarquía de huesos

Una vez se pudieron cargar los huesos, el siguiente paso fue entender de forma apropiada la información sobre cómo estaba almacenada en canales los datos sobre cómo cada hueso debía moverse. Poniendo eso junto pudimos ver la primera animación en el engine.

El siguiente paso era obviamente poder mover los datos del esqueleto y saber a cuáles vértices de la malla del modelo se referían. Lo cual presentó sus propios problemas ya que se necesitaba volver a revisar los datos que tomábamos al parsear la malla para saber a cuál hueso se refería en los vértices y sus influencias.

Uno de los problemas que surgió de todo esto fue ver que aunque los datos de la malla hacían referencia a los huesos correctos, ésta se deformaba de maneras incorrectas, y después de revisar cuidadosamente regresamos a la mesa de dibujo a ver cómo estábamos cargando cada parte y la forma en la cual reproducíamos las animaciones.

Después de un par de días revisando con cuidado, llegamos a ver que la raíz se encontraba en que no estábamos referenciando apropiadamente los huesos en el índice que la animación requería, lo cual se arregló creando una tabla que mapeaba los órdenes de los índices a lo que esperaba la posición de los vértices con los de los huesos. Una vez con eso, pudimos cargar nuestras primeras animaciones auténticamente sobre los modelos.

Una prueba más adecuada

Con todo el trabajo realizado, lo que quedaba era crear un nuevo modelo desde cero que funcionara como una prueba simple sobre el engine, con una animación más compleja e interesante de ver

Muestra el modelo 3d de nuestra chica dinosaurio junto a sus texturas uv en Blender
Blender es un amor de programa.

Se optó por crear un modelo propio para poder testear y al mismo tiempo servir para futuras pruebas. Así como poder distribuirlo completamente. (el archivo glb puede ser descargado aquí mismo)

Con ese detalle fuera del camino, se pudo tener una prueba de animación más interesante.

Detalles por mejorar

A pesar de que el engine funciona, solo tiene un pequeño subconjunto de toda la especificación de los archivos gltf, un ejemplo es lo que ocurre con modelos con múltiples esqueletos.

La imagen muestra un modelo 3d como aparece en la vista previa de sketchfab y lo compara contra la forma distocionada en que el engine lo carga.
Expectativas de un modelo más complejo, comparado con el resultado lamentable en el cual el engine lo interpreta, me perseguirá en mis pesadillas
(modelo creado por Chavafei )

Lo que sigue

El camino para desarrollar un motor es largo y está lleno de desafíos técnicos, pero cada paso que damos nos acerca más a nuestra meta. Cada obstáculo superado no solo mejora el engine, sino también mi entendimiento de los gráficos 3D.