Converting Mixamo 3D models from fbx to gltf

Hi everyone,
I would be curious to know if there is a way (perhaps using a java library or a script) to automate the conversion of the 3D models available on the Mixamo site, from the fbx to gltf format. To save disk space, I usually download the 3D model and animations separately.
Then I merge them in Blender, correct the rotations and the scale and export them in gltf or glb format (see guides).

Have any of you ever tried to experiment with something else or use the FbxLoader plugin of the jme3-plugins module?

https://digitalrune.github.io/DigitalRune-Documentation/html/6f749972-9cb2-4274-b283-c327ba45e379.htm

withskin without-skin

Thanks in advance!

Afaik JME Fbx loader in jme3-plugins does not support animation.

Have not tried this myself but there is this website you can use to batch convert FBX to GLTF. I don’t know if it supports animations.

1 Like

Hi guys,
I did some testing with the ybot model. FbxLoader supports animations. The only format that works is FBX7.4.

Using the FbxDump class I found that some cluster nodes of the fbx file do not contain the definition of the indexes and weights.

// Parse single nodes in FBXTree.Objects.Deformer
// The top level skeleton node has type 'Skin' and sub nodes have type 'Cluster'
// Each skin node represents a skeleton and each cluster node represents a bone

//This is no good
    Deformer: 83304816, "Cluster mixamorig:Spine::SubDeformer", "Cluster" {
        Version: 100
        UserData: "", ""
        Transform: 1,0000000000,0,0000000000,0,0000000000,0,0000000000,0,0000000000,1,0000000000,0,0000000000,0,0000000000,0,0000000000,0,0000000000,1,0000000000,0,0000000000,-0,0000005648,-109,5955268942,0,9802827957,1,0000000000
        TransformLink: 1,0000000000,0,0000000000,0,0000000000,0,0000000000,-0,0000000000,1,0000000000,0,0000000000,0,0000000000,0,0000000000,-0,0000000000,1,0000000000,0,0000000000,0,0000005648,109,5955268942,-0,9802827957,1,0000000000
    }

//This is good
    Deformer: 83261600, "Cluster mixamorig:Spine1::SubDeformer", "Cluster" {
        Version: 100
        UserData: "", ""
        Indexes: 382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763
        Weights: 1,0000000000,1,0000000000,1,0000000000,...
        Transform: 1,0000000000,0,0000000000,0,0000000000,0,0000000000,0,0000000000,1,0000000000,0,0000000000,0,0000000000,0,0000000000,0,0000000000,1,0000000000,0,0000000000,0,0001383004,-121,2409671109,2,4026240445,1,0000000000
        TransformLink: 1,0000000000,0,0000000000,0,0000000000,0,0000000000,-0,0000000000,1,0000000000,0,0000000000,0,0000000000,0,0000000000,-0,0000000000,1,0000000000,0,0000000000,-0,0001383004,121,2409671109,-2,4026240445,1,0000000000
    }

I have read on some forums that a solution could be to skip these nodes.
To avoid a NullPointerException I added this code snippet to the FbxMesh class before line 127.

//snippet
if (positionIndices == null || weights == null) {
    System.out.println(this.name + " --Skip FbxCluster: " + bone.getName());
    return;
}

These are the nodes that are being ignored:

  • Alpha_Joints --Skip FbxCluster: mixamorig:Spine
  • Alpha_Joints --Skip FbxCluster: mixamorig:Spine2
  • Alpha_Joints --Skip FbxCluster: mixamorig:Head
  • Alpha_Joints --Skip FbxCluster: mixamorig:LeftShoulder
  • Alpha_Joints --Skip FbxCluster: mixamorig:RightShoulder
  • Alpha_Joints --Skip FbxCluster: mixamorig:RightToeBase
  • Alpha_Joints --Skip FbxCluster: mixamorig:LeftToeBase

The result is this: the model works with the old animation system but is completely buggy.

I tried the new animation system using the AnimMigrationUtils class.

	@Override
	public void simpleInitApp() {

		Spatial model = assetManager.loadModel("Models/Running7.4-skin.fbx");
		AnimMigrationUtils.migrate(model);
		model.setLocalScale(0.01f);
		rootNode.attachChild(model);
		
//		AnimControl animControl = model.getControl(AnimControl.class);
//		AnimChannel animChannel = animControl.createChannel();
//		animChannel.setAnim("mixamo.com");

		AnimComposer animComposer = AnimUtils.getAnimComposer(model);
		animComposer.setCurrentAction("mixamo.com");
	}

As soon as I set up the animation I get the following error:

java.lang.ArrayIndexOutOfBoundsException: -3
	at com.jme3.animation.CompactVector3Array.deserialize(CompactVector3Array.java:95)
	at com.jme3.animation.CompactVector3Array.deserialize(CompactVector3Array.java:42)
	at com.jme3.animation.CompactArray.get(CompactArray.java:142)
	at com.jme3.anim.interpolator.FrameInterpolator$TrackDataReader.getEntryClamp(FrameInterpolator.java:138)
	at com.jme3.anim.interpolator.AnimInterpolators$4.interpolate(AnimInterpolators.java:97)
	at com.jme3.anim.interpolator.AnimInterpolators$4.interpolate(AnimInterpolators.java:92)
	at com.jme3.anim.interpolator.FrameInterpolator.interpolate(FrameInterpolator.java:72)
	at com.jme3.anim.TransformTrack.getDataAtTime(TransformTrack.java:258)
	at com.jme3.anim.tween.action.ClipAction.interpolateTransformTrack(ClipAction.java:41)
	at com.jme3.anim.tween.action.ClipAction.doInterpolate(ClipAction.java:31)
	at com.jme3.anim.tween.action.BlendableAction.interpolate(BlendableAction.java:52)
	at com.jme3.anim.AnimComposer.controlUpdate(AnimComposer.java:421)
	at com.jme3.scene.control.AbstractControl.update(AbstractControl.java:118)
	at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:743)
	at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:890)
	at com.jme3.scene.Node.updateLogicalState(Node.java:228)
	at com.jme3.scene.Node.updateLogicalState(Node.java:239)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:262)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:160)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:201)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:242)
	at java.lang.Thread.run(Thread.java:748)

In case anyone is interested in fixing the plugin, I hope my analysis is useful. I know it’s not easy, but it would be cool if jmonkey supported internal conversion of Mixamo models like Unity and Godot. It would allow people less familiar with Blender to be able to use a lot of ready-made animations. It might be worth investing some time.

@Ali_RS thanks for the tip. Unfortunately the AnyConv site does not convert FBX files well.

Edit:
added more screenshots and details

1 Like

It imports animations, at least in some cases. However, it hasn’t been converted to the new system.

1 Like

The model has 2 geometries:

  • Alpha Joints
  • Alpha Surface

This is the skeleton hierarchy:

mixamorig:Hips bone
-mixamorig:Spine bone
--mixamorig:Spine1 bone
---mixamorig:Spine2 bone
----mixamorig:Neck bone
-----mixamorig:Head bone
------mixamorig:HeadTop_End bone
------mixamorig:LeftEye bone
------mixamorig:RightEye bone
----mixamorig:LeftShoulder bone
-----mixamorig:LeftArm bone
------mixamorig:LeftForeArm bone
-------mixamorig:LeftHand bone
--------mixamorig:LeftHandMiddle1 bone
---------mixamorig:LeftHandMiddle2 bone
----------mixamorig:LeftHandMiddle3 bone
-----------mixamorig:LeftHandMiddle4 bone
--------mixamorig:LeftHandThumb1 bone
---------mixamorig:LeftHandThumb2 bone
----------mixamorig:LeftHandThumb3 bone
-----------mixamorig:LeftHandThumb4 bone
--------mixamorig:LeftHandIndex1 bone
---------mixamorig:LeftHandIndex2 bone
----------mixamorig:LeftHandIndex3 bone
-----------mixamorig:LeftHandIndex4 bone
--------mixamorig:LeftHandRing1 bone
---------mixamorig:LeftHandRing2 bone
----------mixamorig:LeftHandRing3 bone
-----------mixamorig:LeftHandRing4 bone
--------mixamorig:LeftHandPinky1 bone
---------mixamorig:LeftHandPinky2 bone
----------mixamorig:LeftHandPinky3 bone
-----------mixamorig:LeftHandPinky4 bone
----mixamorig:RightShoulder bone
-----mixamorig:RightArm bone
------mixamorig:RightForeArm bone
-------mixamorig:RightHand bone
--------mixamorig:RightHandMiddle1 bone
---------mixamorig:RightHandMiddle2 bone
----------mixamorig:RightHandMiddle3 bone
-----------mixamorig:RightHandMiddle4 bone
--------mixamorig:RightHandThumb1 bone
---------mixamorig:RightHandThumb2 bone
----------mixamorig:RightHandThumb3 bone
-----------mixamorig:RightHandThumb4 bone
--------mixamorig:RightHandIndex1 bone
---------mixamorig:RightHandIndex2 bone
----------mixamorig:RightHandIndex3 bone
-----------mixamorig:RightHandIndex4 bone
--------mixamorig:RightHandRing1 bone
---------mixamorig:RightHandRing2 bone
----------mixamorig:RightHandRing3 bone
-----------mixamorig:RightHandRing4 bone
--------mixamorig:RightHandPinky1 bone
---------mixamorig:RightHandPinky2 bone
----------mixamorig:RightHandPinky3 bone
-----------mixamorig:RightHandPinky4 bone
-mixamorig:RightUpLeg bone
--mixamorig:RightLeg bone
---mixamorig:RightFoot bone
----mixamorig:RightToeBase bone
-----mixamorig:RightToe_End bone
-mixamorig:LeftUpLeg bone
--mixamorig:LeftLeg bone
---mixamorig:LeftFoot bone
----mixamorig:LeftToeBase bone
-----mixamorig:LeftToe_End bone

For example the Three.js framework seems to be able to read Mixamo’s fbx files.
https://threejs.org/examples/#webgl_animation_skinning_additive_blending

I was thinking of converting some javascript code to java or use it as a reference to find the error in the com.jme3.scene.plugins.fbx.FbxLoader. What do you think? Any suggestions?

PS: I added more details in my previous post.

I thought Blender had a way to convert models from the command line?

Once you have them in GLTF then JmeConvert can also be used from the command line to convert them to j3o… and run post-processing scripts on the model to correct issues, etc… (GitHub - Simsilica/JmeConvert: A command line utility for converting models to J3O and copying their dependencies to a new target structure.)

Supporting different formats is really hard and that’s why we tend to expend the most effort into the “industry standard” GLTF.

I guess Mixamo doesn’t support GLTF directly?

Hi Paul,
Mixamo exports models only in fbx and dae format.
The jme fbx plugin already seems well structured. It may not take long to update.

1 Like

Yeah, but ultimately FBX is a dead end in the long run. it’s a proprietary format. And from an effort-expenditure standpoint, it would be better to use time fixing any issues with gltf if all things are equal.

I didn’t drill into any of the links but from some quick googling it seems like there might be command line tools to convert from mixamo to gltf.