Assimp-based model import and the MonkeyWrench library

I was curious to see how Assimp handled FBX files. :slight_smile:

Thanks

1 Like

In my experience it handles them better than jme3-plugins does, but that’s a very low bar! :wink:

2 Likes

Yeah, I know, that’s why I wanted to give it a try :laughing:

1 Like

I loaded ā€œRPM_RandomAvatar.glbā€ using jme3-plugins-3.6.1-stable and got garbage meshes:

As you reported, jme3-plugins created both an AnimComposer and a SkinningController. However the AnimComposer didn’t contain any animation clips.

When I disabled GPU skinning, the SkinningControl threw an ArrayIndexOutOfBoundsException. I plan to file an issue for that crash later today.

When I loaded the same model using MonkeyWrench-0.6.0, it created a MorphControl and a SkinningControl but no AnimComposer, as you reported. The lack of an AnimComposer is reasonable because the file doesn’t contain any animations.

2 Likes

Correct, ā€œRPM_xxx.glbā€ files themselves typically don’t contain animations.

The missing AnimComposer when using MonkeyWrench can be a hurdle if you wanted to add animations from external glTF files. Is there any way to solve this problem?

1 Like

Oh no you didn’t :smiley:

Is there any way to solve this problem?

If you want your model to include an AnimComposer with no clips, you could instantiate one and add it to the model.

1 Like

It’s no secret that JME’s FBX support is minimal. :slight_smile: We don’t ā€˜officially’ support it, in my opinion.

1 Like
1 Like

If you want your model to include an AnimComposer with no clips, you could instantiate one and add it to the model.

I just remembered something … for best results, the AnimComposer should precede the SkinningControl, so:

        SkinningControl sc = (SkinningControl) RagUtils.findSControl(modelRoot);
        Spatial controlledNode = sc.getSpatial();
        AnimComposer composer = new AnimComposer();
        controlledNode.addControlAt(0, composer);
2 Likes

Kim integrated the fix for issue 5461 today, so I imagine it has a good chance of being included in LWJGL v3.3.4 .

4 Likes

Hi @sgold ,
I hope this message finds you well.
I’m considering using MonkeyWrench as an alternative to the GltfLoader.
Specifically, I’d like to know if MonkeyWrench currently supports loading custom properties from glTF files.
If not, would it be possible to integrate an external component like GltfExtrasLoader alongside MonkeyWrench to achieve this functionality?

Thanks for your time and insights!

Here are some examples I am referring to:

.gltf

"nodes" : [
        {
            "mesh" : 0,
            "extras" : {
                "testString" : "I am string",
                "testFloat" : 1,
                "testBoolean" : "true"
            },
            "name" : "Cube"
        }
    ],
public class GltfUserDataLoader implements ExtrasLoader {

    @Override
    public Object handleExtras(GltfLoader loader, String parentName, JsonElement parent, JsonElement extras, Object input) {
        // if its a geometry, we want to add all the geometry userdata 
        if (input instanceof Spatial) {
            if (extras.isJsonObject()) {
                JsonObject ext = extras.getAsJsonObject();
                for(Entry<String, JsonElement> element : ext.entrySet()) {
                    Spatial spatial = (Spatial) input;
                    if (element.getKey().equals("open")) {
                        spatial.setUserData(element.getKey(), element.getValue().getAsBoolean());
                    }
                }
            }
        }
        return input;
    }
}

Usage example:

    public void setupScene() {
        GltfModelKey key = new GltfModelKey("MyScene.gltf");
        key.setExtrasLoader(new GltfUserDataLoader());
        Spatial scene = assetManager.loadModel(key);
        ...
    }
1 Like

Specifically, I’d like to know if MonkeyWrench currently supports loading custom properties from glTF files.

MonkeyWrench relies on the Open Asset Importer Library to load asset files. Assimp parses ā€œextraā€ properties in glTF files as long as the properties do not have array values. (I filed a GitHub issue regarding this in October.) Assimp records non-array ā€œextraā€ properties in its node metadata.

MonkeyWrench logs node metadata (if the isVerboseLogging parameter is set in the AssetKey) but it currently doesn’t do anything else with them:

Node metadata:
 testBoolean: "true"
 testFloat: 1
 testString: "I am string"

Converting node metadata to JME user data would entail a minor enhancement to MonkeyWrench.

Would string, float, and boolean extras be sufficient for your use case, or are there other types you require?

1 Like

Thanks again for your assistance regarding MonkeyWrench and custom properties.
I’ve compiled a list of potential value types assignable via Blender:

  • String
  • Float
  • Integer
  • Boolean

Excluding array types, I believe these should cover most use cases I can foresee.

It would be great if you could update MonkeyWrench to convert this metadata to JME UserData. :wink:

1 Like

If I release now, would you rather target

  • jme3-lwjgl3-3.6.1-stable and LWJGL v3.3.2 OR
  • jme3-lwjgl3-3.7.0-beta1 and LWJGL v3.3.3

?

1 Like

The first one: jme3-lwjgl3-3.6.1-stable and LWJGL v3.3.2

1 Like

@capdevon

Please try MonkeyWrench v0.6.1.

5 Likes

@sgold Thanks so much for your help! The new feature is working great!

// Usage example:
String[] extensions = { "3ds", "3mf", "blend", "bvh", "dae", "fbx", "glb", "gltf",
                    "lwo", "meshxml", "mesh.xml", "obj", "ply", "stl" };
assetManager.registerLoader(LwjglAssetLoader.class, extensions);

LwjglAssetKey key = new LwjglAssetKey("Models/TestCube.gltf");
key.setVerboseLogging(true);
Spatial model = assetManager.loadModel(key);
rootNode.attachChild(model);

Dumper dumper = new Dumper();
dumper.setDumpMatParam(true);
dumper.setDumpUser(true);
dumper.dump(model);

Output:

Building "Material" material for the "CubeMesh" mesh...
Node metadata:
 pBool: true
 pFloat: 1.0
 pInteger: 1
 pString: "CubeNode"
...

n[12] "Scene" (has parent)
  n[12] "Cube" pBool=true pString="CubeNode" pFloat=1.0 pInteger=1
    g[12] "CubeMesh"
     mat"Material" def"PBR Lighting" dTest,dWrite,NOwireframe,faceCull=Off,blend=Off with 11 parms:
       BackfaceShadows: false
       BaseColor: r=0.8 g=0.042 b=0.04
       Emissive: rgb=0
       EmissiveIntensity: 1
       EmissivePower: 3
       Glossiness: 1
       Metallic: 0
       NormalType: -1
       ParallaxHeight: 0.05
       Roughness: 0.5
       Specular: rgb=1
     Mesh mode=Triangles numV=24 bufs[Position%3f Normal%3f TexCoord%2f Tangent%4f Binormal%3f Index%3ubyte]

I’m confident sharing this detailed information will lead others to your valuable library. Thanks again for your help! :wink:

7 Likes

Today I uploaded a new version of the Erika character model to the characters-for-jme repo.

  • The new version was generated using top-of-tree MonkeyWrench, using a hack to resolve the eyelid issue @capdevon pointed out last December.
  • Unlike the previous version of Erika, it’s saved as a version-3 J3O (so it probably won’t load in JME 3.6.1 or earlier).
  • Its animations were re-targeted using a new algorithm that preserves translations and scaling.

The characters-for-jme models are probably not useful for serious games, but they serve as a proof-of-concept for MonkeyWrench and ImportMixamo and could be used in demos and tests.

7 Likes

Today a new version of MonkeyWrench was released: version 0.6.2.

The new release is something of a trade-off: it benefits from various improvements made to Assimp during April-September 2023, but it also requires JME 3.7. Due to the a serialization format change (PR #2093), models saved using JME 3.7+ cannot be loaded using JME 3.6.1 or earlier.

6 Likes