TerrainGridListener attached piggy-backed model disappears

I have a model called level_0_0.j3o that I want to load when grid (0,0) is loaded. I the code below does thing fine except that when I move around in the terrain, the model level_0_0.j3o disappears and appears even though the grid (0,0) is still on screen.

[java]
terrain.addListener(new TerrainGridListener() {

        public void gridMoved(Vector3f newCenter) {
        }

        public void tileAttached(Vector3f cell, TerrainQuad quad) 
        {
            try
            {                        
                currentModels = (Node)assetManager.loadModel("Models/level1/level_" + (int)cell.x+ "_" + (int)cell.z + ".j3o");
                currentModels.setName("level_" + (int)cell.x+ "_" + (int)cell.z);
                sceneNode.attachChild(currentModels);               
            }
            catch (Exception e)
            {
                
            }
                               

        }

        public void tileDetached(Vector3f cell, TerrainQuad quad)
        {
            if(sceneNode.getChild("level_" + (int)cell.x+ "_" + (int)cell.z) != null);
            {
                sceneNode.detachChildNamed("level_" + (int)cell.x+ "_" + (int)cell.z);
            }
        }
    });

[/java]

why don’t you attach it to the terrainquad instead? Then, when the terrainquad gets detached, the child will too.

It solves the problem, but now it loses the collision detection. Which means my player falls though the quad level_0_0 was attached to.

Below is the code with the parts where collision detection is created.

[java]
terrain.addListener(new TerrainGridListener() {

        public void gridMoved(Vector3f newCenter) {
        }

        public void tileAttached(Vector3f cell, TerrainQuad quad) {
            Texture alpha = null;
            Node currentModels;

            try {
                alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_" + (int)cell.x+ "_" + (int)cell.z + ".png");
            } catch (Exception e) {
                alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_default.png");
            }
            quad.getMaterial().setTexture("AlphaMap", alpha);
            
            // Add physics
            quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0));
            bulletAppState.getPhysicsSpace().add(quad);
            
            updateMarkerElevations();
            
            
            try
            {                        
                currentModels = (Node)assetManager.loadModel("Models/level1/level_" + (int)cell.x+ "_" + (int)cell.z + ".j3o");
                currentModels.setName("level_" + (int)cell.x+ "_" + (int)cell.z);
                quad.attachChild(currentModels);               
            }
            catch (Exception e)
            {
                
            }
                               

        }

        public void tileDetached(Vector3f cell, TerrainQuad quad) {
            // Add physics
            if (quad.getControl(RigidBodyControl.class) != null) 
            {
                bulletAppState.getPhysicsSpace().remove(quad);
                quad.removeControl(RigidBodyControl.class);
            }
            
            updateMarkerElevations();

        }
    });

[/java]

I presume the terrain is not attached to the sceneNode, which is what you use for collision checking? I guess we are switching one problem for another here. It might be easier to find out why the terraingrid is firing the detached event when it isnt detaching…

I hope you are aware that this complete API (TerrainGrid) will be removed in jME 3.1

The terrain is attached to the root node.

[java]
this.rootNode.attachChild(this.terrain); [/java]

@normen

Any ideas of what should I use then?

The rest of the engine, you will have to invent a lot of solutions for your game anyway.

I wrote a terrain tiling system myself here: https://github.com/jayfella/TerrainWorld

If you don’t use nightlies, you can remove line “lodControl.setExecutor(threadpool);” of World.java.
Its a multi-threaded terrain loader with load/unload events and a cache, amongst other things. The code is robust and has been tested quite extensively. Feel free to use, abuse and butcher as you see fit.

2 Likes

@jayfella Wow, your terrain system works right out of the box. Thanks. I’m already using it on my game.

I think this should replace terrain grid. What do you think @normen ? I don’t want other JMonkeys to be left out, without a terrain system :).

@Pixelapp said: @jayfella Wow, your terrain system works right out of the box. Thanks. I'm already using it on my game.

I think this should replace terrain grid. What do you think @normen ? I don’t want other JMonkeys to be left out, without a terrain system :).

The terrain system is not going away. Just the randomly generation part that someone started and didn’t complete.

In my opinion, these things work better as a plugin like what jayfella has done. He can iterate and fix things without having to wait for a new version of JME to get (finally) released. It also avoids the issue of having these partially implemented things hanging around in the core download.

1 Like

@pspeed Ok, I get it.

@jayfella Are there any special considerations to be taken when using the ImageBasedWorld “createWorldWithImages();”? It doesn’t load the .jpg.
But when I use the NoiseBasedWorld it works just fine, but that’s not what I want right now.

Edit: I guess is a bug. I’ll fix it.

@pixelapp the console should let you know if the image wasnt found. You do of course, need some heightmap images for it to load.

@jayfella You provided the .jpg(s). When they are not found it clearly tells you on the console, but for the 4 jpgs you provided it doesn’t complain and they don’t show up either. Which is the problem.

Edit: I use my own image and still doesn’t show up.

ooooh. I took a look myself. Its the height multiplication. It needs to be multiplied. The values of each pixel in the image are returned between 0 and 1, so they need to be multiplied by the world height:

See here, add line 94 to ImageBasedWorld.java

@jayfella Awesome! It works now. 5 stars customer support right there :D.