Android Height Mapping Imported OBJ file in OpenGL ES 2.0?

631 views Asked by At

I am working on a sample project in Java, specifically Android, with OpenGL ES 2.0. I am looking to create a terrain for a player to move across. The player needs to move up and down the terrains hieght following the heightmap. The terrain is not flat. I am using Blender to create the terrain and heightmap. The terrain is being imported as an obj file.

The import and the drawing is working fine but i am having issues making the coordinates follow the heightmap. It doesn't seem to follow it 100%. The player moves up or down too soon every so often or he drops below the terrain.

What I Have So Far:

1)What I am doing is importing the OBJ file into project. Reading the farthest point from terrain object and using this as the object length ( this value * 2 ). This tells me how many vertices are in the object along one side.

2)I then get the difference in the players position to terrain origin in world coordinates. I take the x and z values and divide each by the OBJ object length*2 to give the region of the terrain the object is in. This will give me the percentage of where the x and z position the player is in reference to the terrain.

3) I open the heightmap and multiply the percentages above to the image of the heightmap to get the x and y position on the heightmap to read the height from.

Below is what I am working with.

What I have so far... Heightmap overview

   public float getHeightOfTerrain(float worldX, float worldZ){
       // worldX and worldZ are the players position
       // Currentmatrix is the matrix used for positioning the terrain
       float terrainX = worldX - CurrentMatrix[12] + objLength;
       float terrainZ = worldZ - CurrentMatrix[14] + objLength;

       return getHeight(terrainX, terrainZ);
    }
   ................
float MAX_HEIGHT = 20;
float MAX_PIXEL_COLOR = 256*256*256;
   ................

   public float getHeight(float x, float z){
       float posX = x / (objLength*2);
       float posZ = z / (objLength*2);

       if(posX < 0 || posX > 1 || posZ < 0 || posZ > 1){ // if over 1 which is 100% of terrain then return
           return 0;
       }
       float imgX = posX * bitmapOfMap.getWidth();
       float imgZ = bitmapOfMap.getHeight() - (posZ * bitmapOfMap.getHeight()); // subtract BC bitmap y reads in reverse

       if(imgX < 0 || imgX >= bitmapOfMap.getWidth() || imgZ < 0 || imgZ >= bitmapOfMap.getHeight()){ // if over then return
           return 0;
       }
       float height = bitmapOfMap.getPixel((int)imgX, (int)imgZ);
       height += MAX_PIXEL_COLOR/2f;
       height /= MAX_PIXEL_COLOR/2f;
       height *= MAX_HEIGHT;
       return height;
   }

The smaller the terrain height, the better this setup works. The bigger change in terrain height, the worse this system works. I have tried different obj and heightmaps, recreating over and over thinking this may be the issue but the same problems exist.

Am I doing this completely wrong? Any help would be appreciated. Anyone know a better way? I really want to keep my OBJ file import and read from that for customization.

1

There are 1 answers

0
itgeek25 On

I went ahead and created the terrain just by the heightmap, no OBJ import. Then applied my code above and had the same exact issue. So I dug a bit deeper in what is exactly going on step by step. It all started from the way I was keep track of the terrains location on x, y, and z then subtract that from the players position. I was tracking the players position from a seperate array of x, y, z and then terrains position from the matrix[12], matrix[13], matrix[14] as x, y, z.

This was the issue. I can't use the floats in the matrices as positioning relative values. I had to keep a seperate x, y, z for the terrain as well.

So from.....

   float terrainX = worldX - CurrentMatrix[12] + objLength;
   float terrainZ = worldZ - CurrentMatrix[14] + objLength;

to

   float x, y, z = 0; 

   .....

   float terrainX = z;
   float terrainZ = x;

Now the model works perfect! .... moves up and down the terrain appropriately following the heightmap. I hope this helps anyone that may be having the same issue.