Homegrown Tile-Loader Making Heightmaps weird

I've been writing my own Tile loader for my game. The basic idea is that there is a text file with a square of numbers like



1 2 3

4 5 6

7 8 9



where the numbers represent filenames (i.e. 1.raw, 2.raw, 3.raw) and the square tells my program how to order them in local translation by multiplying their coordinate in the text file (i.e. 1 is at 0,0 while 2 is at 0,1 and 5 is at 1,1) by the size of the heightmap. I started out with 512x512 heightmaps, but got memory errors when I tried to load it. So I scaled down to a single 64x64 heightmap to see if it loads properly, and the heightmap is loading above the camera's head and is completely smooth.



Here is my code, it's a bit complicated. The Tile class is simply a HeightMap with two more variables that hold the coordinate in which it was found. I'm using a factory-method to scan through the text file and then put all of the Tiles into an ArrayList which is passed to the main program, which in turn turns all of the Heightmaps into TerrainPages and sets their local translation according to the method described above.



See if you get the same results using your own heightmaps or if you can see something wrong with the code here.



Tile.java:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package mappingexperiment2;

import com.jmex.terrain.util.RawHeightMap;

/**
 *
 * @author Tyler
 */
public class Tile
{
    int x; //coordinates in the index file
    int y;
    RawHeightMap myMap;
   
    public Tile(RawHeightMap map, int x, int y)
    {
        myMap = map;
        this.x = x;
        this.y = y;
    }
   
    public int getX()
    {
        return x;
    }
   
    public int getY()
    {
        return y;
    }
   
    public RawHeightMap getMap()
    {
        return myMap;
    }
}



MapLoader.java (the Factory):


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package mappingexperiment2;

import com.jmex.terrain.util.RawHeightMap;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Tyler
 */
public class MapLoader
{
    static final File mapIndex = new File("index.dat");
    static Scanner sn;
   
    public static ArrayList<Tile> getTilesFromFile()
    {
        try
        {
            sn = new Scanner(mapIndex);
            ArrayList<Tile> tiles = new ArrayList();
            int rows = 0;
            int columns = 0;
            while (sn.hasNextLine())
            {
                sn.nextLine();
                rows += 1;
            }
            sn = new Scanner(mapIndex);
            String rowFinder = sn.nextLine();
            StringTokenizer st = new StringTokenizer(rowFinder, " ");
            columns = st.countTokens();
           
            sn = new Scanner(mapIndex);
            for (int i = 0; i < rows; i++)
            {
                String line = sn.nextLine();
                st = new StringTokenizer(line, " ");
                for (int n = 0; n < columns; n++)
                {
                    String fileName = st.nextToken();
                    tiles.add(new Tile(new RawHeightMap(fileName + ".raw", 513, RawHeightMap.FORMAT_16BITLE, false), i, n));
                    System.out.println(fileName + ".raw");
                }
            }
           
            return tiles;
        }
        catch (FileNotFoundException ex)
        {
            Logger.getLogger(MapLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
       
        return null;
       
    }
   
}



MapLoaderTest.java:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package mappingexperiment2;

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.scene.state.TextureState;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.RawHeightMap;
import java.util.ArrayList;

/**
 *
 * @author Tyler
 */
public class MapLoaderTest extends SimpleGame
{
    public static void main(String args[])
    {
        MapLoaderTest app = new MapLoaderTest();
        app.setDialogBehaviour(SimpleGame.FIRSTRUN_OR_NOCONFIGFILE_SHOW_PROPS_DIALOG);
        app.start();
    }

    protected void simpleInitGame()
    {
        Vector3f terrainScale = new Vector3f(5f, .003f, 6f);
       
        ArrayList<Tile> myMaps = MapLoader.getTilesFromFile();
        ArrayList<TerrainPage> myPages = new ArrayList();
       
        for(Tile t : myMaps)
        {
            t.getMap().setHeightScale(.001f);
            myPages.add(new TerrainPage("" + t.getX() + t.getY(), 65, t.getMap().getSize(), terrainScale, t.getMap().getHeightMap(), false));
            myPages.get(myPages.size() - 1).setLocalTranslation(new Vector3f(64f * t.getX(), 0f, 64f * t.getY()));
            myPages.get(myPages.size() - 1).setDetailTexture(1, 1);
            myPages.get(myPages.size() - 1).setModelBound(new BoundingBox());
            myPages.get(myPages.size() - 1).updateModelBound();
        }
       
        for(TerrainPage tp : myPages)
        {
            rootNode.attachChild(tp);
        }
        rootNode.updateGeometricState(0.0f, true);
        rootNode.updateRenderState();
    }
}




Thanks!

I don't see your issue right away, but one thing to be aware of; TerrainPage is CENTERED at (0,0,0) while the TerrainBlock STARTS at (0,0,0);



Also, try updating the geometric state of each terrain page, rather than the root node.

Have a look at Terra

theprism said:

Have a look at Terra


Dunno what that means or how I'm supposed to look at it.

basixs said:

I don't see your issue right away, but one thing to be aware of; TerrainPage is CENTERED at (0,0,0) while the TerrainBlock STARTS at (0,0,0);

Also, try updating the geometric state of each terrain page, rather than the root node.


I'll try that--but what does the above thing matter. If I am using TerrainPage for all of them, and I use the same method for all of them, shouldn't the outcome be the same?

I'll post back on if the geometric state worked.

Geometric state didn't work.

Terra = http://www.jmonkeyengine.com/jmeforum/index.php?topic=5170.0

Actually since I posted that I wrote my own dynamic tile loader without looking at Terra, and it works with one exception. see other post…