How to port animation from one skeleton to another?
- by shawn
While I need to do this in a Blender3D modeler script, the math should be similar for other modelers or realtime engines.
Blender3D specific terminology:
Armature = skeleton
EditBone = rest pose bone (stores the rest pose matrix)
PoseBone = can store a different pose (animation matrix) for each frame of your animation
I need to share animations (Blender Actions) between Armatures which have EditBones with same names and which have the same positions, but can have different (rest pose) angles and scales. Plus the Armatures might have different bone hierarchy (bone parenting/ no bone parenting).
Why I need this:
I've made an importer/exporter for a 3d format for a game. The format doesn't store enough info to connect/parent the bones, which makes posing/animating character models in a 3d modeller nearly impossible (original model files for the 3d modeler don't exist, this is for modding).
As there are only 2 character skeleton types in the game, I decided to optionally allow to generate the bone from a hardcoded data in the model importer and undo that in the exporter. This allows to easily pose the model for checking weights, easily create weights, makes it easier for Blender to generate automatic weights and of course makes animating possible.
This worked perfectly: the importer optionally generated the Armature itself and the exporter removed those changes, so the exported model works with existing animations in the game.
But now I'm writing an importer and exporter for the game's animation format and here come the problems of:
Trying to make original animations work in Blender with my "custom" (modified) Armature
Trying to make animations created by using the "custom" (modified) Armature work with the original models in the game (and Blender).
Constraints or bone snapping inside Blender won't work as they don't care that the bones have different angles in the rest pose, they will still face the same direction.
It seems I just need to get the "difference" between the EditBone matrices of all EditBones for the two Armatures somehow and apply that difference to PoseBone matrices of all PoseBones, for all frames of my animation. I need to know how to get that difference and how to apply it.
BTW, PoseBone matrices are relative to rest pose, they are by default
[1.000000, 0.000000, 0.000000, 0.000000](matrix [row 0])
[0.000000, 1.000000, 0.000000, 0.000000](matrix [row 1])
[0.000000, 0.000000, 1.000000, 0.000000](matrix [row 2])
[0.000000, 0.000000, 0.000000, 1.000000](matrix [row 3])
So the question is: How to get the difference between two bone (EditBone) matrices to apply that difference to the animation matrices (PoseBone matrices)?
Please be easy on the matrix math.