One of the links you posted provides a method, and two equations describing how to calculate the offset matrix. See the section titled Back into Initialization - The Offset Matrix
I.e., one of the equations -
offsetMatrix = MeshFrame.ToRoot * Inverse( bone.ToParent * parent.ToParent * ... * root.ToParent );
Each bone frame has a matrix transforming that bone into it's parent's space (called in that article the ToParent matrix). That sounds like your bone "local matrix." Combine each bone's ToParent matrix with it's parent's ToParent recursively done to the root. Take the inverse of that matrix to form the offset matrix.
Note: that method also accounts for the transform for the mesh vertices (MeshFrame.ToRoot) to transform the vertices from world space into root frame space, if required. Be sure to check whether the mesh data that you import has vertices in world space, or in root frame space. IF, and only IF, the root frame is at the world origin, then MeshFrame.ToRoot can be omitted (or set to the Identity matrix.)
In your post, you have:
Compute "inverse bindpos matrices", beeing the inverse of each bones "local matrix" in bindposition
It's not clear what you mean by in bindposition. If, by in bindposition, you mean each bone's local matrix combined with it's parent's "local matrix" combined with the parent's parent's "local matrix," etc., then it appears your "inverse bindpos matrix" is the offset matrix. Compare how you calculate your "inverse bindpos matrix" with the method for calculating the "offset matrix" posted above.
If your inverse bindpos matrix is just the inverse of the bone's local matrix (not combined with its parent's local matrix), that's incorrect. The local matrices (from bone to parent to parent..to root) must be combined before you take the inverse.
Also, in that same article, the Final Matrix is calculated as:
FinalMatrix[ boneIndex ] = OffsetMatrix[ boneIndex ] * boneFrame.TransformationMatrix;
where boneFrame.TransformationMatrix is the combined animation transforms (bone.localAnimMat * parent.localAnimMat * parent's-parent.localAnimMat..)
It appears that's what you're trying to do with your CalcCombinedMatrix function, but, as noted above and below, your code is incorrect.
Note the order of the matrix multiplication of offset * TransformationMatrix.The order is important. It appears you have the order reversed in your posted code.
In general, it's a bit difficult to determine whether you're talking about bind pose matrices or animation matrices at various places in your code and discussion. For me, that's causing a bit of confusion.
Also, are you using row-major matrices, and multiplying matrices in left-to-right order? That's more common in DirectX code, but you may be doing it differently.
Maybe a litte review: the goal is to transform vertices from bind pose to animation pose.
N.B. Assuming left-to-right multiplication order-
anim-pose-vertex = bind-pose-vertex * offset-matrix * anim-pose-matrix
If you think in terms of the order of operations required to do that:
1. Transform the bind-pose vertex from model-bind-pose-space into local-bone-bind-space. That's done by applying the offset-matrix first.
It's the equivalent of:
offset-matrix = root-toChildA * childA-toChildB * ... * to-influence-bone
[ it appears that your "local" bone matrices are bind-pose-from-parent-to-child matrices. ]
influence-bone-bind-space-vertex-position = model-space-vertex-position * offset-matrix
2. Transform the influence-bone-bind-space-vertex to the animation position, i.e., from influence-bone-bind-pose-space to model-animation-space, by applying the anim-pose-matrix
where:
anim-pose-matrix = influence-bone-local-anim-mat * parent-local-anim-mat * ... * root-anim-mat
and
anim-pose-vertex = influence-bone-bind-space-vertex * anim-pose-matrix
Putting it all together:
anim-pose-vertex = model-space-vertex-position * offset-matrix * anim-pose-matrix
That is, from that last equation, the matrix used to transform a model-space-vertex to animation-space-vertex for one of its influence bones is:
offset-matrix * anim-pose-matrix
where those matrices are for a specific influence bone.
And, again, that assumes you're using left-to-right multiplication order.
Hopefully that doesn't confuse things more.
Don't know if you're still having problems, but one thing you said leads me to believe you may not be interpreting things correctly. Specifically, I'm curious if you're confusing what a ToParent matrix is, and how a ToParent matrix is applied.
what the article refers to as the "ToParent Matrix" is the same as my "local Matrix". But should it not be the inverse, since it is supp[o]sed to transform from the bone back to the parents space?
When you say "should it not be the inverse..?" what you refer to as it, isn't clear. However, if you're referring to the ToParent matrix, the answer is "no." If you're referring to your "local matrix," and it is the same as the ToParent matrix, then the answer is still "no."
That is, the ToParent matrix transforms from bone space to the parent's space. I.e., that's why it's termed "to parent."
An example of a ToParent matrx:
1. Assume that the root frame is the origin of the skeletal hierarchy.
2. Assume that the root frame has a child frame Hip, located 6 units in the +Y direction from the root frame.
The Hip frame's ToParent matrix is, in row-major order:
1 0 0 0
0 1 0 0
0 0 1 0
0 6 0 0
That is a matrix with no rotation, and a translation of +6 along the Y axis.
Assume a mesh vertex is positioned in space coincident with the origin of the Hip frame. By definition, origin is ( 0, 0, 0 ) in the Hip reference frame. To determine that vertex position in the root reference frame, transform the vertex position as defined in Hip space by the Hip's ToParent matrix to transform the vertex from Hip space to root space. I.e.,
( 0, 0, 0) * Hip-ToParent-matrix = ( 0, 6, 0)
As mentioned, a vertex positioned at the origin of the Hip frame (that frame already specified to be located at +6 along the Y axis), is also positioned at +6 along the Y axis in the root reference frame.
Now consider a vertex positioned at ( 0, 6, 0) in the root reference frame. To correctly apply rotations in the Hip reference frame, the vertex must be transformed from root frame space to Hip reference frame space. See the section of the article titled "A Slight Diversion from the Initialization Process." To transform from root frame to Hip frame, a ToChild matrix is needed. That matrix can be calculated as the inverse of the ToParent matrix.
The inverse of the Hip's ToParent matrix is:
1 0 0 0
0 1 0 0
0 0 1 0
0 -6 0 1
So, root-frame-position * ToChild-matrix = Hip-frame-position
I.e., ( 0, 6, 0) * ToChild-matrix = ( 0, 0, 0)
And, indeed, the vertex at ( 0, 6, 0) in the root reference frame is located at ( 0, 0, 0) in the Hip reference frame.