Question

I have started to learn game development using jMonkey engine. I am able to create single tile of terrain using TerrainQuad but as the next step i m stuck at making it infinite. I have gone through the wiki and want to use the TerrainGrid class but my code doesnot seem to work. I have looked around on the web and searched other forums but cannot find any other code example to help.

I believe in the below code, ImageTileLoader returns an image which is the heightmap for that tile. i have modified it to return the same image every time. But all i see is a black window. The Namer method is not even called. Appreciate if someone can help with some example or tutorial on net.

terrain = new TerrainGrid("terrain", patchSize, 513, new ImageTileLoader(assetManager, new Namer() {
        public String getName(int x, int y) {
            //return "Scenes/TerrainMountains/terrain_" + x + "_" + y + ".png";
            System.out.println("X = " + x + ", Y = " + y);
            return "Textures/heightmap.png";
        }
    }));

These are my sources: jMonkeyEngine 3 Tutorial (10) - Hello Terrain, TerrainGridTest.java, ImageTileLoader

This is the result when i use TerrainQuadenter image description here

My full code,

// Sample 10 - How to create fast-rendering terrains from heightmaps, and how to
// use texture splatting to make the terrain look good.
public class HelloTerrain extends SimpleApplication {

    private TerrainQuad terrain;
    Material mat_terrain;
    private float grassScale = 64;
    private float dirtScale = 32;
    private float rockScale = 64;

    public static void main(String[] args) {
        HelloTerrain app = new HelloTerrain();
        app.start();
    }
    private FractalSum base;
    private PerturbFilter perturb;
    private OptimizedErode therm;
    private SmoothFilter smooth;
    private IterativeFilter iterate;

    @Override
    public void simpleInitApp() {
        flyCam.setMoveSpeed(200);

        initMaterial();

        AbstractHeightMap heightmap = null;
        Texture heightMapImage = assetManager.loadTexture("Textures/heightmap.png");
        heightmap = new ImageBasedHeightMap(heightMapImage.getImage());
        heightmap.load();


        int patchSize = 65;
        //terrain = new TerrainQuad("my terrain", patchSize, 513, heightmap.getHeightMap()); // * This Works but below doesnt work*

        terrain = new TerrainGrid("terrain", patchSize, 513, new ImageTileLoader(assetManager, new Namer() {
            public String getName(int x, int y) {
                //return "Scenes/TerrainMountains/terrain_" + x + "_" + y + ".png";
                System.out.println("X = " + x + ", Y = " + y);
                return "Textures/heightmap.png";
                // set to return the sme hieghtmap image.
            }
        }));



        terrain.setMaterial(mat_terrain);
        terrain.setLocalTranslation(0,-100, 0);
        terrain.setLocalScale(2f, 1f, 2f);
        rootNode.attachChild(terrain);


        TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
        terrain.addControl(control);
    }

    public void initMaterial() {
        // TERRAIN TEXTURE material
        this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");


        // GRASS texture
        Texture grass = this.assetManager.loadTexture("Textures/white.png");
        grass.setWrap(WrapMode.Repeat);
        this.mat_terrain.setTexture("region1ColorMap", grass);
        this.mat_terrain.setVector3("region1", new Vector3f(-10, 0, this.grassScale));

        // DIRT texture
        Texture dirt = this.assetManager.loadTexture("Textures/white.png");
        dirt.setWrap(WrapMode.Repeat);
        this.mat_terrain.setTexture("region2ColorMap", dirt);
        this.mat_terrain.setVector3("region2", new Vector3f(0, 900, this.dirtScale));


        Texture building = this.assetManager.loadTexture("Textures/building.png");
        building.setWrap(WrapMode.Repeat);


        this.mat_terrain.setTexture("slopeColorMap", building);
        this.mat_terrain.setFloat("slopeTileFactor", 32);

        this.mat_terrain.setFloat("terrainSize", 513);
    }
}
Was it helpful?

Solution

So, I worked further on my problem and was able to achieve what I wanted to. But I still cannot understand what was the error on my first code. Below is the final code that I got by modifying the TerrainGrid example from here. Below is the final code for anyone who falls into the same situation. It is not the final thing but does answer my question above.

public class TerrainGridTest extends SimpleApplication {

    private Material mat_terrain;
    private TerrainGrid terrain;
    private float grassScale = 64;
    private float dirtScale = 16;

    public static void main(final String[] args) {
        TerrainGridTest app = new TerrainGridTest();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        this.flyCam.setMoveSpeed(100f);
        initMaterial();
        initTerrain();
        this.getCamera().setLocation(new Vector3f(0, 200, 0));
        this.getCamera().lookAt(new Vector3f(0,0,0), Vector3f.UNIT_Y);
        this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
        initLight();
    }

    @Override
    public void simpleUpdate(final float tpf) {

    }

    public void initMaterial() {
        // TERRAIN TEXTURE material
        this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");


        // GRASS texture
        Texture grass = this.assetManager.loadTexture("Textures/white.png");
        grass.setWrap(WrapMode.Repeat);
        this.mat_terrain.setTexture("region1ColorMap", grass);
        this.mat_terrain.setVector3("region1", new Vector3f(-10, 0, this.grassScale));

        // DIRT texture
        Texture dirt = this.assetManager.loadTexture("Textures/white.png");
        dirt.setWrap(WrapMode.Repeat);
        this.mat_terrain.setTexture("region2ColorMap", dirt);
        this.mat_terrain.setVector3("region2", new Vector3f(0, 900, this.dirtScale));

        // ROCK texture
        //Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
        Texture building = this.assetManager.loadTexture("Textures/building.png");
        building.setWrap(WrapMode.Repeat);


        this.mat_terrain.setTexture("slopeColorMap", building);
        this.mat_terrain.setFloat("slopeTileFactor", 32);

        this.mat_terrain.setFloat("terrainSize", 513);
    }

    private void initLight() {
        DirectionalLight light = new DirectionalLight();
        light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize());
        rootNode.addLight(light);
    }

    private void initTerrain() {
        this.terrain = new TerrainGrid("terrain", 65, 257, new ImageTileLoader(assetManager, new Namer() {

            public String getName(int x, int y) {
               //return "Interface/Scenes/TerrainMountains/terrain_" + x + "_" + y + ".png";
                return "Textures/heightmap.png";
            }
        }));

        this.terrain.setMaterial(mat_terrain);
        this.terrain.setLocalTranslation(0, 0, 0);
        this.terrain.setLocalScale(3f, 1.5f, 3f);
        this.rootNode.attachChild(this.terrain);

        TerrainLodControl control = new TerrainGridLodControl(this.terrain, getCamera());
        control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier
        this.terrain.addControl(control);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top