Ah i finally solved this in a sane way just today. In a few days ill put the changes up on github.
Nothing on the outside changed except the ability to draw transformations per mesh that i added for someone else. Tons of work in clean up todo still though.
I put this down for a bit because i didn’t know how to tackle it any way that would not just force me to rework the entire data structure assimp hands you.
Basically the problem is that some exported models have multiple inverse bind pose offsets for the same node transform essentially for the same bone but different bind poses to different meshes of that same bone.
This presented a big problem of how to make it work without rebuilding the node tree and being forced to handle each mesh with more work as the chained transforms aren’t cumulative.
However this is not quite true nor was most of the information i found on what the offsets represent which are really themselves … takes a deep breath …
static inverse mesh bind pose matrices per mesh or common across all model meshes to the accumulated transformation parent node which can only be applicable to nodes that themselves represent bones. … yikes…
So i solved this today, very happy as this took quite a bit of time to figure out.
So now i have the original busted model working as well as the secondary squashed exported version.
Still have to clean it up and i badly broke most of my visualization classes to see the bones and stuff to make it work. So it will take a bit to fix it back up then ill make the changes to the github project.
I still have yet to add normal maps and other texture types not sure if i will do that yet as im not sure how to approach it with the same shader or a new one conditionally because there are just so many other types of textures that can be applied to a model.
I may eventually just write a tutorial myself on the assimp intended data structure usage and maybe include code too if i can find the time to really make it look pretty.
this is the jist of what i had to do
private void UpdateNodes(RiggedModelNode node)
if (node.parent != null)
node.CombinedTransformMg = node.LocalTransformMg * node.parent.CombinedTransformMg;
node.CombinedTransformMg = node.LocalTransformMg;
for (int i =0; i < node.uniqueMeshBones.Count; i++)
var nodeBoneToMesh = node.uniqueMeshBones[i];
meshes[nodeBoneToMesh.meshIndex].globalShaderMatrixs[nodeBoneToMesh.meshBoneIndex] = nodeBoneToMesh.OffsetMatrixMg * node.CombinedTransformMg;
foreach (RiggedModelNode n in node.children) // call children
and in draw
public void Draw(GraphicsDevice gd, Matrix world)
foreach (RiggedModelMesh m in meshes)
Not insane now but the loader and the references are more complex.
I also added nearly all the data that assimp has to my model class.
so it’s there to be used after the assimp instance is tossed away.
Now if i could think of a way to put even more on the shader like the animation data or somehow put the transforms themselves on it. That would be really cool.