Demo of a 3D model on the engine

Continuing work on the custom 3D engine

Basic support for gltf/glb animations

Date:

These past few months I've resumed work on my custom engine. Last time I had already added basic support for loading a mesh and a basic texture, but I hadn't yet had the opportunity to implement animation reading until now.

Revisiting the gltf/glb format

The gltf/glb format is quite curious, and since it's designed to optimize the way animation data is stored, trying to read it is like untangling spaghetti, jumping from one index to another.

It's important to note that to load the animation, we need access to two pieces of data: the skeleton, which is what's moving, and the animation, which is the description of the transformations that each bone performs.

Fortunately, the Khronos Group provides a very comprehensive manual on the structure of gltf/glb on how each piece works in detail.

Some headaches

The drawing of two gorilas, one green representing myself, and one brow representing Claude, both in front of a computer.
Matrix math is complicated

Although the structure of the gltf/glb format is quite understandable, one of the main challenges was solving the differences between the handling of mathematics within the engine and the file

In the custom engine we use a convention for row-major order matrices while the matrices in a gltf focus on column-major order. Once that was well defined, I had to review the mathematics of the engine and fix some inconsistencies. I was reviewing some points with Claude AI, although it seems it had as little idea about mathematics as I did 🙃. Once the review of the mathematics library was completed, the next step was to load the skeleton correctly, taking into account its bone hierarchy

Once the bones could be loaded, the next step was to properly understand the information about how the data on how each bone should move was stored in channels. Putting that together, we could see the first animation in the engine.

The next step was obviously to be able to move the skeleton data and know which vertices of the model's mesh they referred to. This presented its own problems since it was necessary to review again the data we were taking when parsing the mesh to know which bone it referred to in the vertices and their influences.

One of the problems that arose from all this was seeing that although the mesh data referenced the correct bones, it was deforming incorrectly, and after carefully reviewing, we went back to the drawing board to see how we were loading each part and the way in which we were reproducing the animations.

After a couple of days of careful review, we came to see that the root was in that we were not properly referencing the bones in the index that the animation required, which was fixed by creating a table that mapped the orders of the indices to what the position of the vertices expected with those of the bones. Once that was done, we were able to authentically load our first animations onto the models.

A more adequate test

With all the work done, what remained was to create a new model from scratch that would work as a simple test on the engine, with a more complex and interesting animation to see

Display of the model of our dino girl alongside their uv map texture inside Blender
Blender is a lovely program.

We opted to create our own model for testing and at the same time serve for future tests. As well as being able to distribute it completely. (the glb file can be downloaded right here)

With that detail out of the way, we could have a more interesting animation test.

Details to improve

Although the engine works, it only has a small subset of the entire specification of gltf files, an example is what happens with models with multiple skeletons.

The picture shows a 3D model how appears in the preview of sketchfab vs how is deformed in the engine.
Expectations of a more complex model, compared to the unfortunate result in which the engine interprets it, will haunt me in my nightmares
(model created by Chavafei )

What's next

The path to developing an engine is long and full of technical challenges, but each step we take brings us closer to our goal. Each obstacle overcome not only improves the engine, but also my understanding of 3D graphics.