Vlog 02: FbxLoader Fixes: Mixamo models now loading in jME!
adi.barda:
In Unity, it’s really convenient that you can download any FBX animation you like (without the Skin - only animation) then attach it to a model which has Mixamo bones and it works just fine. so you can have one FBX animation used by many Mixamo models - cool feature.
Yes, I know, it’s a good idea: my glTF pipeline is based exactly on this concept. However, Mixamo models can have different skeletons — both in bone names and total number of bones — so you can’t assume that an FBX file containing only animations will work on any model. If the skeletons are different, you’ll need to download the animation that matches each specific model.
After a lot of effort, I also managed to fix the bugs in the AnimMigrationUtils class to migrate the old animation system used by FbxLoader to the new one. With the help of AI, I also tried converting the FBX Phong material parsing pipeline to a PBRMaterial. To get a correct result, I had to generate the model tangents, otherwise the normal map wouldn’t work.
As I mentioned before, no loader works 100%. Each model requires a custom conversion pipeline to fix potential issues, because models often contain anomalies.
One last aspect I still need to explore is automatic conversion from centimeters to meters for FBX models, so I don’t have to manually scale them by 0.01 every time (see my previous Java snippet).
In conclusion, if you don’t produce your own models from scratch, you always have to ‘get your hands dirty’ to make them work properly in jME — whether that means using tools like Blender, fixing issues manually, or writing custom jME scripts.
Here’s an example of an FBX model converted using FbxLoader that uses the new animation system and PBRMaterial:
Spatial model = assetManager.loadModel("Models/Mixamo/Swat.fbx");
TangentBinormalGenerator.generate(model, true); // generate missing tangents
AnimMigrationUtils.migrate(model); // migrate from old animation system
FbxModelCorrector.centerRootJoint(model); // root joint (Hips) Y start position is 0.99f instead of 0
model.setLocalScale(0.01f);
rootNode.attachChild(model);
AnimComposer animComposer = model.getControl(AnimComposer.class);
animComposer.setCurrentAction("mixamo.com");
...
fpp.addFilter(dlsf);
fpp.addFilter(ssao);
fpp.addFilter(fxaa);
fpp.addFilter(toneMap);
Previous version with Lighting Material and no Filters
Discussion in the ATmosphere