Steps to reproduce (use the zip attached below [Download here] for fbx files):
- Import flagpole.comp.fbx as SkeletalMesh like so (allowing it to create Skeleton based on it, bConvertScene and bForceFrontXAxis MUST be checked):
- Notice that in the SkeletalMesh/Skeleton the root node has transform of 0,0,0 position and rotation as expected:
- Import one of the animations (0_anim1.fbx or 1_anim2.fbx or 2_anim3.fbx) (bConvertScene and bForceFrontXAxis must again be checked, select the Skeleton made in last step if its not auto-selected for you):
- Notice that the pole of the flagpole is skinned wrong, and if you inspect the animation’s root node, it now has a (90, 0, -90) rotation, which causes a mismatch with the actual SkeletalMesh/Skeleton (in fact all the nodes in the animation will have different local transforms when compared with the SkeletalMesh/Skeleton)
If you repeat all the above steps but with bForceFrontXAxis unchecked (for both mesh and anim), the pole will face the Y axis instead of the X axis, however, both the SkeletalMesh/Skeleton and imported Animation will have the same transforms in the reference pose, and skinning will look correct.
So what happened here ?
Well around 4.15 when bForceFrontXAxis was added, the way bone joints are imported from FBX files has changed, before 4.15 all that happened when bConvertScene was checked was that the root node received a transformation matrix that would bring it from whatever FBX’s coordinate system to Unreal’s coodrdinate system. The same happened in SkeletalMesh and Animation import, so aside from some caveats resulting from the root node not having Identity transform (childmodels attached wrong to bones/sockets without a compensation transform), it worked fine.
With 4.15, SkeletonMesh import was changed so that bConvertScene would NO LONGER change the root node’s transform (so it would preserve the transform from DDC, this is more ideal), so the Reference Pose/Skeleton in the SkeletalMesh now had the coordinate system conversion “baked in” into all of the nodes. This is great, except that it necessitates always using bTransformVertexToAbsolute when importing SkeletalMeshes, otherwise only the joints will receive the conversion, not the vertices (using bTransformVertexToAbsolute is fine though, you cant really uncheck it, it always comes back).
However, the same IS NOT DONE TO THE IMPORTED ANIMATIONS. Imported animations will STILL use the old “add a relative transform to the root node” trick when bConvertScene is used, which means that now all the nodes inside animations have COMPLETELY DIFFERENT TRANSFORMS in their reference pose vs the SkeletalMeshes they will get applied to, resulting is incorrect skinning; the example above only has the problem on one bone, but having a more complicated character just messes ALL their skinning up, like so:
So Epic, please fix this (by baking in all the node transforms on Animation joints just like you do with SkeletalMeshes), until you do, I will have to go back to the old hack way of adding the relative transform to the root node (to both SkeletalMeshes and Animations, just by commenting out this line:
JointOrientationMatrix.SetR(FbxVector4(-90.0, -90.0, 0.0));
And please, test the features your internal team doesnt necessarily use (they dont use bForceFrontXAxis which is the correct way of facing your models anyway, because history and Maya, afaicr)