Heightmap terrain

Started by Fencer, April 05, 2009, 07:43:14 PM

Previous topic - Next topic

Fencer

Is there a simple way how to create a terrain based on a heightmap, using jPCT API? Ideally something that would take an int[][] grid (or similar) containing height values and generate a terrain with some kind of interpolation (to make it smooth) and using provided textures and/or alpha maps to make it look nice?

I hope my request is not too confusing. :-)  But I would like to make a simple "run and fight" game and it would be great if a broken terrain makes it more strategic etc.

Thanks for any tips.

EgonOlsen

Back in the good old days, a jPCT sample application called "terrain" existed. It's long gone, but this is the terrain generation code from it:


/**
* 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);
}
}


It's really nothing special but maybe it's something to start with...

Fencer

Thank you Egon, I will make some experiments with it. :-)

Another question: What would be the best approach to create a "continuous terrain"? I mean a situation when the world terrain grid would be too big to make a simple Object3D object out of it (because it would probably cause an OutOfMemoryError issue), which means that some kind of loading and replacing on the fly (depending on the camera position) would be necessary. I am not sure if the given sample code would be the best option for it, regarding the note "this is why building objects this way isn't blazing fast".

I never created an application of this kind, so this is just a theoretical speculation. How about to generate a set of terrain maps, convert them to Object3D, save to disk (serialize?) and load only the visible ones when the camera is close enough?

EgonOlsen

Another option would be to create flat blue prints of the terrain parts and apply the height map afterwards using an IVertexController. That should be faster than the solution posted in the code...however, the comments are quite old. Performance of addTriangle() has improved since then, so it may not be that slow anymore.

fireside

Is there a way to level of detail?  So, the area closest has more poly's that can be later subtracted again and added to new areas as the character moves?
click here->Fireside 7 Games<-

EgonOlsen

Continuous level of detail is bad for modern GPUs. Doing it in some static way should be possible though. I think raft did something like that a long time ago but i could be wrong.

raft

right, i did implement some kind of primitive LoD algorithm. it was basicly replacing the object with a simpler one. i can say, it definitely didnt worth the effort. it helped fps for sw renderer, but wasnt looking good. trying to configure it to look smooth/good resulted in less efficiency.

in karga, most of polygons are in avatars and applying LoD to them makes things more complicated because of animations. leaving low LoD models un-animated makes them look ugly too.

Fencer, for terrain generation you may want to look at Oddlabs' GPL'ed terrain generation tool. they use that tool in their famous game Tribal Trouble. but it comes without the rendering engine.

r a f t