Help needed with bones and matrix rotations

I’m working on an importer and exporter for the Studiomdl Data format. It’s all going very well except for bones.

Here are the problems:

  • SMD bones are 1D points with euler rotation, relative to their parent
  • Blender bones have a head and a tail, relative to the whole armature
  • SMD bones point down the Z axis
  • Blender bones point down the Y axis
  • SMD is right-handed
  • Blender is left-handed

This is a solvable problem, I just don’t have the skills to succeed. Can anyone help me?

My current theory on the process required for export is:

  • Convert bone vector to euler
  • Convert euler to matrix
  • Multiply euler by inverse parent matrix, write euler
  • Multiply matrix by parent’s equivalents
  • Subtract parent head from bone head
  • Multiply location by inverse matrix, write location

And for import:

  • Convert euler to matrix
  • Convert location to matrix
  • Combine matrices
  • Head location = location * parent matrix
  • Tail rotation = location + ([0,0,1] * parent matrix)

The offending functions are readFrames() and writeFrames(), if you want to have a poke. There are a bunch of SMDs available here for import, but unless you already have the Half-Life Model Viewer the only way to test export is going to be with the Alien Swarm SDK, which is about 2GB…