three.js
three.js copied to clipboard
FBXLoader loads default Unreal model with wrong rotation
Description
Here are two FBX models, one from Mixamo, one from Unreal:
https://rawcdn.githack.com/trusktr/assets/fe18e72007bafeaa6d37f3c4a5816fd3da63e413/mixamo-michele.fbx https://rawcdn.githack.com/trusktr/assets/fe18e72007bafeaa6d37f3c4a5816fd3da63e413/unreal-manny.fbx
In Blender, they both load in the correct upright orientation, but in Threejs the Unreal model loads in an orientation off by 90 degrees.
Reproduction steps
Create a scene that loads both models.
Code
new FBXLoader().load('https://rawcdn.githack.com/trusktr/assets/fe18e72007bafeaa6d37f3c4a5816fd3da63e413/unreal-manny.fbx', model => {
model.position.x += 50
scene.add(model)
})
new FBXLoader().load('https://rawcdn.githack.com/trusktr/assets/fe18e72007bafeaa6d37f3c4a5816fd3da63e413/mixamo-michele.fbx', model => {
model.position.x -= 50
scene.add(model)
})
Live example
https://codepen.io/trusktr/pen/JjVwvNo
Screenshots
Screenshot of Blender (I spaced the characters apart or else they would overlap):
Screenshot of Threejs (each model moved apart by 100 "centimeters"):
Version
r163
Device
No response
Browser
No response
OS
No response
When converting to GLTF using Blender fbx2gltf, the result is correct in Threejs. Maybe Blender knows something about FBX models that Threejs does not handle yet.
The tool https://github.com/facebookincubator/FBX2glTF emits a warning
Warning: node /RootNode/SKM_Manny uses unsupported transform inheritance type 'eInheritRrSs'.
(Further warnings of this type squelched.)
May that have anything to do with it? EDIT: Maybe that's a missing feature of the tool, but maybe it hints at a missing feature in FBXLoader?
My workaround for now (while keeping FBX) is:
if (directionFromAnkleToHeadIsMostParallelToZAxis(model))
model.rotation.x -= Math.PI / 2
where directionFromAnkleToHeadIsMostParallelToZAxis
- calculates a vector between an ankle bone and head (could be pelvis and head too, or similar, depends on your model),
- then finds if that vector is more aligned with X, or with Z,
- then if it happens to be more aligned with Z returns true, otherwise returns false.
When converting to GLTF using Blender fbx2gltf
Which tool did you use to convert? Did it display correctly after using FBX2glTF, or only after using Blender?
I don't think anyone has done work on the loader in the last few years so manually rotating or converting to glTF is the best solution for now. Likewise, nobody has worked on FBX2glTF in several years.
Even if someone does take it up, FBX transforms are mind-meltingly complex since they support multiple different apps and exporters, all of which do their own thing. Maya transforms are especially weird so if the model originated there it's often a cause of these errors. See this comment about the eInheritRrSs warning from FBX2glTF.
The best thing to do, for the intrepid explorer who wants to fix this, would be to explore code for FBX2glTF and the Blender importer. To my knowledge those are the two most complete open source importers/converters.
Which tool did you use to convert? Did it display correctly after using FBX2glTF, or only after using Blender?
Correct,
Maybe Blender knows something about FBX models that Threejs does not handle yet.
The output GLTF from blender after running fbx2gltf, works fine, the model is upright.