jMonkeyEngine v3.7.0-beta1 release

Hi Everyone,
jMonkeyEngine v3.7.0-beta1 is available for testing :partying_face:.
From initial testing on my project it looks great. so far I have no complains.
There is a release page containing the engine updates which are included in this version (related to alpha3.1 ).
While in feature freeze phase, new features / fixes can be streamed to “master” branch as usual but only fixes to features included in the coming release will also go to the release branch and eventually to production.



I have found a new regression from version 3.6.1 to 3.7.0. Still using the “boss” model that is being used in this test app
In version 3.6.1, I can list it’s animations:

While in version 3.7.0-beta1 the animations list is empty:

However, this is an old model which has its animations assembled in Blender a few years ago. I’ll try to re-assemble it and hopefully it will fix this issue but even if it fixes the problem, chances that it will happen to somebody else so I think it’s best to find the problem anyway at least to know what happened.

I’ll update about the results after I re-assemble it.

1 Like

BTW, looking at those two pictures I can clearly notice that the model in version 3.7.0 is more blurred. I don’t know which feature has caused it and I don’t know if it’s good or bad. It’s just different and I hope that it is a desired effect and not side effect of something else…


It looks like the normal map is missing in the bottom screenshot, based on the way the shiny/reflective parts of the model in the bottom image are much smoother, and the bottom model is also missing the folds in the shirt near the buttons, as well as other small shading details like the wrinkles in the skin.

so maybe the normal map isn’t getting applied to the material when converting from j3o in the new version, or the NormalScale parameter could be getting set as 0.0 somehow.


I compared it with two more models and it seems to be consistent - the models (all GLTFs/GLBs BTW) are looking blurred in v3.7.0 compared to v3.6.1.
So, so far we have 2 issues:
First, one model (the “boss”) is loaded without its set of animations and even though it’s a regression from 3.6.1 it might be my fault of not assembling it right in Blender,
And second, by default models are loaded more blurred compared to v3.6.1


For anyone who wants to test with a VR application I’ve released Tamarin 2.6.0-beta1 (which has been updated to be compatible with the LWJGL version change made in JME 3.7.0). I’ve tested in my own VR application and it looks to be working well but I’ll keep running with it and let you know if there are any problems


the models (all GLTFs/GLBs BTW) are looking blurred in v3.7.0 compared to v3.6.1

Can you identify the Git commit where the blurriness first appeared?

Heads up on potential backwards compatibility issue with glb/gltf scenes.

I recently tested the latest version on my projects and noticed that objects previously loaded as Geometries are now interpreted as Nodes when loading scenes from GLB files. This change might be related to [Fix Gltf imported spatial names by riccardobl · Pull Request #2103 · jMonkeyEngine/jmonkeyengine · GitHub] and could potentially break compatibility with older scenes.

While I’m happy to adjust my scenes if maintaining a fast release cycle is a priority, I recommend adding a warning in the release notes about this potential backwards compatibility risk. This will help others anticipate and address any similar issues in their projects.


It’s true that it could be a backwards compatibility issue and it’s a good to put a warning.

…but my advice in general is that code that relies on some specific GLTF child to be a Geometry is already fragile to the point I’d consider it broken. There are better strategies for doing whatever it was that brought someone to that point.


I will try. What is your method for doing so? new branch then add commit after commit, compile locally and test?

1 Like

No, I would do a bisection search.


I think I’ve found a new bug. After swapping to 3.7.0.beta1 I have started getting this error. It doesn’t occur immediately but usually within 10 minutes of starting the application

    SEVERE: Uncaught exception thrown in Thread[#33,jME3 Main,5,main]
    java.lang.AssertionError: Invalid Matrix4f value Matrix4f
    NaN  NaN  NaN  NaN
    NaN  NaN  NaN  NaN
    NaN  NaN  NaN  NaN
    NaN  NaN  NaN  NaN
] for WorldViewProjectionMatrix
    at com.jme3.renderer.opengl.GLRenderer.updateUniform(
    at com.jme3.renderer.opengl.GLRenderer.updateShaderUniforms(
    at com.jme3.renderer.opengl.GLRenderer.setShader(
    at com.jme3.material.logic.DefaultTechniqueDefLogic.render(
    at com.jme3.material.Technique.render(
    at com.jme3.material.Material.render(
    at com.jme3.renderer.RenderManager.renderGeometry(
    at com.jme3.renderer.queue.RenderQueue.renderGeometryList(
    at com.jme3.renderer.queue.RenderQueue.renderQueue(
    at com.jme3.renderer.RenderManager.renderViewPortQueues(
    at com.jme3.renderer.RenderManager.flushQueue(
    at com.jme3.renderer.RenderManager.renderViewPort(
    at com.jme3.renderer.RenderManager.render(
    at com.jme3.system.lwjgl.LwjglWindow.runLoop(
    at java.base/

Although these assertions are new in 3.7 so perhaps I am doing something wrong and JME was just ignoring it before (assertions added in 7dfffb557550ba4b23b2a3435a0084a62a98e726)


GLB Scene Hierarchy Change in jme3.7.0

In jME3.7.0, the GLB loader encapsulates the Plane.007 geometry within two parent nodes.

  n[2] "Plane.007"
    n[2] "Plane.007"
      g[2] "Plane.007_0"
       mat"Mat_Gray" def"PBR Lighting" dTest,dWrite,NOwireframe,faceCull=Off,blend=Off with 13 parms
       Mesh mode=Triangles numV=4 bufs[Position%3f Normal%3f Index%3ushort]

In contrast, jME3 3.6.1 directly exposes the geometry.

g[2] "Plane.007"
   mat"Mat_Gray" def"PBR Lighting" dTest,dWrite,NOwireframe,faceCull=Off,blend=Off with 12 parms
   Mesh mode=Triangles numV=4 bufs[Position%3f Normal%3f Index%3ushort]

Here is the hierarchy in blender-3.6.1.


While the change in GLB scene hierarchy with the new loader in jME 3.7 seems to align with Blender exports, it could introduce backwards compatibility issues for users who rely on directly accessing geometries by name. Adding two parent nodes and a suffix to the geometry name might break existing code that expects the raw geometry to be directly accessible.

Please share your thoughts or suggestions on how to best address this change.

1 Like

What exactly you should do would depend on your exact requirements but as an example I have these two utility methods that I use when trying to interact with geometries in loaded models

public class GeometryUtilities{

     * Travels down the node stack, any geometries it finds it gives them to the consumer
    public static void actOnGeometry(Spatial spatial, Consumer<Geometry> actOnGeometry){
        if (spatial instanceof Node){
            ((Node) spatial).getChildren().forEach(n -> actOnGeometry(n, actOnGeometry));
        }else if (spatial instanceof Geometry){
            actOnGeometry.accept((Geometry) spatial);

    public static List<Geometry> findGeometries(Spatial spatial){
        List<Geometry> geometries = new ArrayList<>();
        actOnGeometry(spatial, geometries::add);
        return geometries;


If you’re looking for a geometry by name I’d suggest just doing a recursive search for it rather than assuming it will be at a particular level

1 Like

FYI, 3.7 has SceneGraphIterator, which I’ve found particularly handy for processing scenes.

for (Spatial s : new SceneGraphIterator(scene)) {
    if (s instanceof Geometry) {
        // do something...

Thanks for the explanation guys, I might have oversimplified my question. I’m familiar with basic techniques and was hoping you could shed light on more advanced prop manipulation or controller assignment methods. :slight_smile:

The included Heart library with Minie offers a convenient MySpatial.listGeometries method.

    public static List<Geometry> listGeometries(Spatial subtree) {
        Validate.nonNull(subtree, "subtree");
        List<Geometry> result = listSpatials(subtree, Geometry.class, null);
        return result;

However, for more granular control, I often leverage the SceneGraphVisitorAdapter class, which has been a staple since the engine’s inception.

        scene.depthFirstTraversal(new SceneGraphVisitorAdapter() {
            public void visit(Geometry geom) {
                // do something...

I’ll be updating my demos to address this issue. However, this introduces a backward compatibility concern. We can expect some users to encounter problems after the release due to older code.

thank you all

1 Like

My answer would greatly depend on why you specifically need a Geometry.


It’s important to note that there are some edge cases where the new approach might encounter issues.

// with the jme-3.7.0 version this will no longer work 
// because the scene hierarchy nodes and geometry names change.

// case 1:
scene.depthFirstTraversal(new SceneGraphVisitorAdapter() {
    public void visit(Geometry geom) {
        if (geom.getName().equals("Plane.00x")) {
            // do something with geom...
// case 2:
Geometry geom = (Geometry) scene.getChild("Plane.00x");

While I can easily work around them by removing this case from my demos, it’s best to be proactive and include a warning in the documentation to avoid confusion for other users who might encounter these scenarios

This is true and is not in contention.

This is the part I wonder about. I can’t really answer about better ways because I don’t know why specifically you need a GEOMETRY named “Plane.00x”. You’ve shown how you get it. And we can talk about 50 different ways to get it.

But why “Plane.00x”? Why a Geometry? Why not a Spatial?

See, I can spend the next three pages of text discussing this by guessing 100 out of the million reasons you might want to get a “scene object”… and then you’ll be reason 101 and my answers won’t matter.

So if anyone needs very specifically “it has to be a Geometry and can’t be anything else” and “it has to be by name because nothing else will indicate what I’m looking for” then I would need to know WHY (not how, not what, not who but WHY) else I cannot offer alternatives.

Because “I must have this specific Geometry with this specific name” is a super-fragile way to deal with any imported “model” from any format and there are almost always better ways to do what you want… but I would need to know the actual use to offer advice to make things less fragile.


I will investigate further and if I encounter any significant roadblocks, I’ll keep you updated and discuss potential solutions. Thank you for your patience and understanding.