Weekly Update - Content Pipeline Work

For the past couple weeks I've been working on the Mesh Importer and making improvements to ToiEngine's Skeletal Animation System.

This won't be news for anyone that's been following the project on Discord, but I wanted to provide an update for those watching the website or Patreon.

The Animations Problem

In the previous update here on the website I mentioned that I was about out of room avoiding the "animations problem". Some may recall that the animations in the Antilia MMO weren't all that good - they were hand-animated in a very primitive animation tool. (It only featured forward kinematics. No inverse kinematics and no motion capture.)

FBX Importer

My solution was to continue working on the FBX Importer and add support for loading skeletons, skinning weights, and animations. After spending a couple weeks on that I was able to load the skeleton and skinning weights - but the animation data eluded me. I started to worry there might even be something fundamentally wrong with the skeletal animation system implemented in ToiEngine or one of it's math libraries. Nevertheless, after several frustrating days of reading documentation and comparing my code with other open-source implementations... I was completely unable to get it to work reliably and had to take a break.

Mesh Importer

At this point I had to remind myself just what it was I was trying to accomplish. Was the objective to load FBX files? Not really. The objective was to get animation data into Toi Engine from Blender. Using FBX files is one popular way of doing that, but certainly not the only way.

This thought lead me on a search for a simpler mesh file format, and then quickly to the IQE format. The IQE format is a much simpler text-based format which as soon as I opened a sample file I was able to identify and understand the data I started playing with reading in the file and by the next afternoon I had all the data loading successfully - meshes, skeletons, skinning weights, and the animations.

Therefore the FBX Importer will now become the Mesh Importer, as it now supports both FBX (mesh only) and IQE files.

Info:The IQE format is not natively supported by Blender, but there is an export script available on GitHub.

In just a couple days I was able to get all data loading from IQE files - meshes, skeletons, skinning weights, and animations.

Too Many Bones!

But even with the skeletons and animation data loading I encountered yet another small snag: The ToiEngine is limited to a max of 60 bones per character/creature. Admittedly ToiEngine is showing it's age a little here, newer engines will support 128 or more. Rather than get sucked down another rabbit hole trying to increase this limit (by splitting the character into multiple render operations), I found a simpler solution was to write a function that would take a skeleton, mesh, and list of bones to prune from the skeleton. It wasn't a perfect solution, but it got the job done.

The skeleton loads in with 80 bones, which is too many. The new skeleton tab makes it easy to "prune" excess bones and get the mesh under the limit. The bones with an X next to them in the right hand pane will get pruned.

For the first time we're able to play animations on the wasp in ToiEngine. This animation is playing on the pruned skeleton.

Skeletal Animation Component

As I resumed work on combat, I quickly came to my next animation woe - characters and creatures are constructed differently in the Object Editor. It's a bit technical, but the Taipii characters use the CompositeMeshComponent which mixes together multiple meshes, textures, poses, and animations together based on the player's character design. That component also features an AnimationMixer that allows characters to play multiple animations together at the same time for movement, combat animations, facial expressions, etc. Creatures in Antilia tend to use the much simpler MeshComponent, which only allows for a single animation to be set at a time.

To bridge this annoying difference I created a new SkeletalAnimationComponent and moved the skeleton, pose and animation loading logic there, as well as the AnimationMixer. This component provides a Skeleton on the game object, which then MeshComponent or CompositeMeshComponent will try to use.

The new SkeletalAnimationComponent provides a better set of tools for blending and easing animations on creatures than I had previously.

New Creatures

For the past couple weeks now I've been saying "next week I'll be working to add more animated creatures into the game", and that'll be the goal again this week. I believe now I have a clear path for getting animated creatures out of Blender and into Antilia. The next challenge appears to be getting the animation to blend nicely and look good, and also get creature movement and rotation speeds tuned for each creature. As you can see from the animation below, animation tends to look "off" until everything is blended and timed just right - including getting the animation speed right so that feet (or scales in this case?) stick to pixels on the ground and don't slide around.

The serpent moves and the animation plays, but it's not very convincing yet.

That's all for this week, thanks for reading!