# Difference between revisions of "Heightmap"

From JPCT

Line 129: | Line 129: | ||

Kind regards, | Kind regards, | ||

Kaiidyn. | Kaiidyn. | ||

+ | |||

+ | [[Category:jPCT]] | ||

+ | [[Category:jPCT-AE]] |

## Latest revision as of 00:37, 2 February 2013

A Heightmap class I wrote (more like edited Egon's random terrain)

Egon's Terrain script that randomly generates terrain heights.

/** * This is where the terrain-array is filled with some data, i.e. the * terrain is build. Keep in mind that this approach to build a terrain * is quite simple and slow. But it's easy to understand and the results * are not that bad, so.... */ for (int x = 0; x < X_SIZE; x++) { for (int z = 0; z < Z_SIZE; z++) { terrain[x][z] = -20 + (float) Math.random() * 40f; // Very // simple.... } } /** * We are now smoothing the terrain heights. This looks better because * it removes sharp edges from the terrain. */ for (int x = 0; x < X_SIZE - 1; x++) { for (int z = 0; z < Z_SIZE - 1; z++) { terrain[x][z] = (terrain[x][z] + terrain[x + 1][z] + terrain[x][z + 1] + terrain[x + 1][z + 1]) / 4; } } /** * The terrain heights are calculated now. Now we have to build an * Object3D from them. */ ground = new Object3D(X_SIZE * Z_SIZE * 2); /** * We have 50 tiles in x and z direction and 2 polygons per tile. */ float xSizeF = (float) X_SIZE; float zSizeF = (float) Z_SIZE; int id = texMan.getTextureID("base"); for (int x = 0; x < X_SIZE - 1; x++) { for (int z = 0; z < Z_SIZE - 1; z++) { /** * We are now taking the heights calculated above and build the * actual triangles using this data. The terrain's grid is fixed * in x and z direction and so are the texture coordinates. The * only part that varies is the height, represented by the data * in terrain[][]. jPCT automatically takes care of vertex * sharing and mesh optimizations (this is why building objects * this way isn't blazing fast...but it pays out in the * end...:-)) The Mesh is build with triangle strips in mind * here. The format for these strips is equal to that of * OpenGL's triangle strips. */ TextureInfo ti = new TextureInfo(id, (x / xSizeF), (z / zSizeF), ((x + 1) / xSizeF), (z / zSizeF), (x / xSizeF), ((z + 1) / zSizeF)); ground.addTriangle(new SimpleVector(x * 10, terrain[x][z], z * 10), new SimpleVector((x + 1) * 10, terrain[x + 1][z], z * 10), new SimpleVector(x * 10, terrain[x][z + 1], (z + 1) * 10), ti); ti = new TextureInfo(id, (x / xSizeF), ((z + 1) / zSizeF), ((x + 1) / xSizeF), (z / zSizeF), ((x + 1) / xSizeF), ((z + 1) / zSizeF)); ground.addTriangle(new SimpleVector(x * 10, terrain[x][z + 1], (z + 1) * 10), new SimpleVector((x + 1) * 10, terrain[x + 1][z], z * 10), new SimpleVector((x + 1) * 10, terrain[x + 1][z + 1], (z + 1) * 10), ti); } }

My terrain class that uses a bitmap.

When using it make sure you have a Texture Manager with a TextureID ready, (I used a flat gray 128x128 image for this)

public class Terrain { public static float HighestPoint = 0; static Bitmap bmp = null; static String pixel = null; public static Object3D Generate(int X_SIZE, int Z_SIZE, TextureManager tm, String TextureID){ bmp = BitmapFactory.decodeResource(SpaceGrabber.resources, R.drawable.terrain); // the heightmap texture (128x128 due to memory limitations?) float[][] terrain = new float[X_SIZE][Z_SIZE]; for (int x = 0; x < X_SIZE-1; x++) { for (int z = 0; z < Z_SIZE-1; z++) { pixel = Integer.toString(bmp.getPixel(x, z), 16); terrain[x][z] = Integer.parseInt(pixel.charAt(1) + "" + pixel.charAt(2), 16); if(terrain[x][z] > HighestPoint){ HighestPoint = terrain[x][z]; } } } for (int x = 0; x < X_SIZE - 1; x++) { for (int z = 0; z < Z_SIZE - 1; z++) { terrain[x][z] = (terrain[x][z] + terrain[x + 1][z] + terrain[x][z + 1] + terrain[x + 1][z + 1]) / 4; } } Object3D ground = new Object3D(X_SIZE * Z_SIZE * 2); float xSizeF = (float) X_SIZE; float zSizeF = (float) Z_SIZE; int id = tm.getTextureID(TextureID); // I used a gray 128x128 texture for (int x = 0; x < X_SIZE - 1; x++) { for (int z = 0; z < Z_SIZE - 1; z++) { TextureInfo ti = new TextureInfo(id, (x / xSizeF), (z / zSizeF), ((x + 1) / xSizeF), (z / zSizeF), (x / xSizeF), ((z + 1) / zSizeF)); ground.addTriangle(new SimpleVector(x * 10, terrain[x][z], z * 10), new SimpleVector((x + 1) * 10, terrain[x + 1][z], z * 10), new SimpleVector(x * 10, terrain[x][z + 1], (z + 1) * 10), ti); ti = new TextureInfo(id, (x / xSizeF), ((z + 1) / zSizeF), ((x + 1) / xSizeF), (z / zSizeF), ((x + 1) / xSizeF), ((z + 1) / zSizeF)); ground.addTriangle(new SimpleVector(x * 10, terrain[x][z + 1], (z + 1) * 10), new SimpleVector((x + 1) * 10, terrain[x + 1][z], z * 10), new SimpleVector((x + 1) * 10, terrain[x + 1][z + 1], (z + 1) * 10), ti); } } return ground; } }

Note that this is originally written for jPCT-ae so it might need editing to work on pc version.

It might need some modification to work in your application, but it's something to start with :)

Kind regards, Kaiidyn.