It's all pretty complicated, isn't it?
I'm assuming the offset matrix is the same as the inverse bindpose matrix I'm trying to compute:
Depends on what you're going to use the matrix for! NOTE: The last set of data you posted looks like the origin-related orientation, and can be used to calculate the offset matrix - with one additional check: some modeling programs put the vertex data in a separate frame. That has to be accounted for, as mentioned in the section of that article "Back into Initialization - The Offset Matrix."
Modeling programs often export the pre-calculated offset matrix for each joint, in addition to the "to-parent" data. I'm not familiar with FBX, but, for instance, DirectX x-file exports provide "to-parent" transforms for each bone, and (separately) the offset matrices for each bone with the mesh data. Those mesh-data offset matrices include the mesh frame's "to-root" transform as mentioned above. It appears that the data you posted does NOT account for the mesh frame transform. However, IF the mesh-data is NOT in a separate frame (the data is relative to the origin) OR the mesh-frame transform is the identity matrix, then the data you posted can be used to calculate the offset matrix.
I think that's what you're referring to here:
"offsetMatrix = MeshFrame.ToRoot * Inverse( bone.ToParent * parent.ToParent * ... * root.ToParent )"
"MeshFrame.ToRoot is the transform for moving the mesh into root-frame space" - is that the matrix that goes from Model space to the root joint's space ?
IF "MeshFrame" is frame which parents the mesh data (the vertices), then that all appears to be correct. However, N.B., IF there are multiple sets of vertex data, that offset matrix is used ONLY for the vertex data for which it was calculated. If you only have ONE mesh in the model, that's fine. I mention that because I have several models with separate meshes for (e.g.) the head, the body, several weapons, a helmet, etc. There are separate sets of offset matrices for each mesh.
IF the data you posted above IS appropriate "to-root" data, then calculating the offset matrix using the above formula can be done using Inverse(bone.ToRoot) instead. Perhaps you should calculate the offsets as shown, and compare them to the inverse of the "to-root" data you posted.
What is root.ToParent ? I thought roots don't have parents.
The "root.ToParent" is what positions the root relative to the model origin. It's a fine distinction but important: the root's "to-root" is the identity matrix. The root's "to-parent" positions the root relative to the origin.
From the article:
// ... calculate all the Frame ToRoot matrices
CalcToRootMatrix( RootFrame, IdentityMatrix ); // the root frame has no parent - EDIT: Apologies. This may have confused you.
// I probably should have made it clear that FOR THE PURPOSES OF A TO-ROOT CALCULATION, the root should be considered
// not to have a parent, as the recursive routine uses "to-parent" matrices.
In the data you just posted:
shoulder (root):
T: (-2.0, 0, 0)
R: (0, 0, -180.0)
That's the root "to-parent" orientation as it positions the root relative to the origin.
As a refresher, skinned mesh animation is the process of rendering vertices (and the associated textured triangles) in a 3D world coordinate system. To do that, using the matrix approach mentioned in the article:
1. Move each vertex from model space into root space - that's what I'm assuming you're calling MeshFrame.ToRoot.
2. Move the vertex into bone space (joint/node space) - that's the bone's inverse-to-root matrix.
NOTE: steps 1 and 2 are combined in the offset matrix calculation you posted. Those matrices are calculated just once as they are "bind pose" related and the bind pose doesn't change.
The animation process then comprises calculations to move the vertex into 3D world space.
Have I sufficiently confused you?