logo2x

Skinned mesh animation with collada

Demo: engine.xogames.org/demo_skinning/

During development of my just-for-fun game engine I needed to add support for skinned mesh animations.
I decided to take collada as intermediate format and make a script that converts collada into a custom binary format.

It was really a lot of work (mostly with collada parsing and exporting).

My plan was to make debug draw for the CPU skinning and then transfer it to the GPU. And it finally worked.

The must-read docs for collada format processing are spec and reference card.
There I found a nice formula that explains vertices calculation:

Screen Shot 2018-01-06 at 21.10.46

I premultiply vertices with bind-shape matrices during export.
The joints become a hierarchy of GameObjects within the engine. So objects can be easily attached to the joints just by adding them as a child.

I support only collada files with baked transforms into the matrices. Matrix then decomposed into translation, rotation quaternion and scale (TRS) and in this form is written into the file.
But here is the tricky part.

Here is the approach I use for getting rotation quaternion from the matrix.
It turned out that it works only for orthogonal matrices (actually it was specified in the doc but who reads it?) but joint matrices in collada export may be non-orthogonal (e.g. contain scale). I spent a lot of time trying to find out why I was getting a wrong matrix after conversion matrix -> TRS -> matrix.
Finally I was advised to normalize matrix basis before getting rotation quaternion. It solved the problem.

Note that obtaining scale should happen before matrix normalization.

Moving vertex calculation to the GPU was pretty straightforward.

girl_front

Finally, I would say that I’m comfortable with collada but using SDKs such as FBX SDK may make things easier. Also native Maya collada export doesn’t support custom properties so OpenCollada plugin may be needed to make export from the 3D modelling tool.

Export script:
running example:
> node scripts/collada-convert.js resources/models/girl.dae
Script sources: https://github.com/Division/engine/blob/demo-skinning/scripts/collada-convert.js

Demo:
Play: engine.xogames.org/demo_skinning/
Demo sources: https://github.com/Division/engine/tree/demo-skinning

Running demo:
> npm install
> npm run serve

References:

  1. Collada specs
  2. Nice video guide