Loaded tree shows leaves with boxes

I’m trying to load a tree that I downloaded online. The tree shows up but with boxes. Here’s my code for loading it.

Spatial treeGeo = assetManager.loadModel(
“Models/tree_oak.obj”);
treeGeo.setLocalTranslation(Vector3f.ZERO);
treeGeo.setQueueBucket(Bucket.Transparent);
rootNode.attachChild(treeGeo);
rootNode.attachChild(treeGeo);

https://firebasestorage.googleapis.com/v0/b/fir-authdemo-f6260.appspot.com/o/treeProblem.png?alt=media&token=99dad6d5-cf08-4896-a580-f530921ea9c2

That’s how the tree looks like.

Set the alpha discard threshold on the Material, I guess.
Are you using an alpha Map? If so you can also try to merge it with the diffuse Map. If not try the opposite

I’m just using the textures that came with the tree. They are in dds format. It came with an mtl file.

How can I set the alpha threshold for this one? I didn’t use any material as the texture was loaded by the mtl file. I can’t set the texture on the program because the tree came with 3 texture files for its different parts. Thanks in advance!

You can use a SceneGraphVisitor or how it is called over all geometries in that spatial and Set the Parameter in Code (each geometry has a material)

Or you Generate Materials out of the sdk (there are even youtube Videos about that)

The material (j3m) should also have BlendMode.Alpha. In code:
treeGeo.getMaterial().getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
If treeGeo in this case is a Node, it won’t work. You need to apply this to the Geometry

Thanks for the reply. How can I set the blendmode alpha for a spatial? I tried casting it to a geometry but I get an error. It seems that I can’t cast a spatial loaded from a model to a geometry. The problem is I can’t set a material for this tree because the textures are loaded from a dds file.

The treeGeo(Spatial) does not have a getMaterial method. :sob:

Try casting it to a node and print out the children (getChildren()). Likely the leaves are a Geometry of their own.

I get this error when I cast it to a node. Seems like I can’t cast it to a node either.

ClassCastException: com.jme3.asset.AssetKey cannot be cast to com.jme3.asset.TextureKey

Please post the code you use.

Here’s my code. I’m able to cast it to a node now. The size of the children of the node is 2

@Override
    public void simpleInitApp() {
        loadLight();
        flyCam.setMoveSpeed(50);
        Spatial treeSpatial = assetManager.loadModel(
                "Models/tree.obj");
        
        Node treeNode = (Node) treeSpatial;
        System.out.println(treeNode.getChildren().size());
        rootNode.attachChild(treeNode);
    }

OK, so one of those children is the trunk and the other the leaves (most likely). Find out which is which and apply the line posted above to that.

1 Like

Thanks! Got it to work! You saved my day.

Here’s the final code.

loadLight();
flyCam.setMoveSpeed(50);
Spatial treeSpatial = assetManager.loadModel(
                "Models/tree.obj");
Node treeNode = (Node) treeSpatial;
Geometry leaves = (Geometry) treeNode.getChildren().get(0);
leaves.setQueueBucket(Bucket.Transparent);
leaves.getMaterial().getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
rootNode.attachChild(treeNode);

Or do what i recommended: instead of writing your own recursive Methods use the SceneGraphVisitor

Sure. I will check on that too.

As an alternative: You also can edit your model over the SDK. You can create material files for your tree and directly add those to your model in the scene composer. Material files have the ending .j3m.
To do so you just have to open your .j3o file / model, click on the leave geometry and add the right material by using the properties window on the right.

3 Likes

As @Domenic said, you should convert your model to .j3o and them create a .j3m material for it, setting the textures and alpha.

This way you’re reduced to three lines of code.

Spatial treeSpatial = assetManager.loadModel("Models/tree.j3o");
treeSpatial.setQueueBucket(Bucket.Transparent);
rootNode.attachChild(treeNode);

Also loading .j3o models if AFAIK faster since it’s a special format for the engine.

1 Like

I have another problem though. Even though the background of the leaves have become transparent, they seem to affect the shadow cast on the house; they actually remove the shadow cast on the house.Also, I have set the shadow mode of the leaves and the trunk to ShadowMode.Cast but the leaves seem to have some shadows. My light sources are only ambient and directional light.

https://firebasestorage.googleapis.com/v0/b/fir-authdemo-f6260.appspot.com/o/transparent_cast.jpg?alt=media&token=288c2b04-2b87-413f-8df6-237f5aee3bd8

    Spatial treeSpatial = assetManager.loadModel(
            "Models/trees/tree.j3o");
    Node treeNode = (Node) treeSpatial;
    treeNode.setLocalTranslation(new Vector3f(speed, speed, 50));
    treeNode.scale(0.5f);

    Geometry leaves = (Geometry) treeNode.getChildren().get(0);
    leaves.setQueueBucket(RenderQueue.Bucket.Transparent);
    leaves.getMaterial().getAdditionalRenderState().
            setBlendMode(RenderState.BlendMode.Alpha);
 
    leaves.setShadowMode(ShadowMode.Cast);

    Geometry trunkNode = (Geometry) treeNode.getChildren().get(1);
    trunkNode.setShadowMode(ShadowMode.Cast);

    rootNode.attachChild(treeNode);

I have fixed it by changing the Alpha Discard Threshold to 0.1f. Thanks to everyone for helping!