Hi there,
I am doing some decompilation work for an old video game that has a proprietary file format.
the armature bones are described as such:
{
name: bone_name,
parent: parent_bone_name,
to_parent: [
rotation: Quaternion,
translation: Vector3
],
to_world_origin: [
rotation: Quaternion,
translation: Vector3
],
to_local_armature: [
rotation: Quaternion,
translation: Vector3
],
}
animation file is described as follows:
{
name: bone_name
keyframe_timings: list[int]
transformations: [
[
rotation: Quaternion,
translation: Vector3
],
...
]
There are a variety of issues that I have, I want to mention them in-case it matters somewhere…
- The original file format uses a Left Handed, Y-Up axis. For now, I don’t care that the skeleton and animation are incorrectly flipped / wrong axis.
- I am unsure whether the Quaternions are using a (W,X,Y,Z) scheme or (X, Y, Z, W) scheme.
- I am unsure whether the initial bone roll matters / taken into account.
- I am not too familiar with Blender, and whilst I think I have the correct settings for the bones (such as the local location, inherit rotation, etc), I am not certain these are correct.
Skeleton
When constructing the skeleton:
- If the parent is blank, set the head to
0, 0, 0
- Set the tail using the translation to origin
- Set the bone roll by using:
Quaternion().to_axis_angle()[1]
use_connect = True
, as I guess the Vector and Quaternion seem to be referencing the tail.
This seems to work fine. I end up with a “person-shaped” armature.
Note: At this point, most of the bone settings dont have much if any impact.
All of the issues I mentioned have no impact yet
_Note2: There is a bone that has 0 length, Blender doesn’t like this, so I have added a fractional amount in the Y axis)
Animation
When adding keyframes:
- I am creating a translation matrix with:
Matrix.Translation(Vector())
- I am creating a rotation matrix with:
Quaternion().to_matrix().to_4x4()
full_matrix = translation @ matrix
- then applying
full_matrix
to the pose bone usingPoseBone.matrix()
- Finally, I add the keyframe information with:
PoseBone.keyframe_insert(data_path="location", frame=keyframe_number)
PoseBone.keyframe_insert(data_path="rotation_quaternion", frame=keyframe_number)
and this is where my problems start to arise…
Does my methodology seem sound?
I can post the information that comes with the skeleton and animation if someone wants to take a deep dive into this.
Thanks!