Stitching server generated terrain blocks - advice welcomed

So, I have a server, I use routines on the server side to generate a heightmap for the whole of my world in one shot (lets say 4096x4096). This allows me to not worry about having to raise and lower terrain when stiching terrain blocks together.

I then write a routine to split my generated height map into 128x128 blocks so they are of a size I can send to a client app in pieces (sending all blocks adjacent to the client location every time he moves from block to block).

On the jMonkey client when I load in the game character it pulls in all adjacents 128x128 terrain blocks and attaches them to the root node each as an individual terrain quad. Everything working fine so far.

The one problem though. Each terrain block is obviously not stitiched to the adjacent terrain block creating a gap (one heightmap point in width) between each 128x128 slab. Now I obviously need to eliminate the gaps somehow and would appreciate opinions from people more experienced with terrain than myself (this is my first outing). The way I see it I have the following options:-

  1. Alter the TerrainQuad in some way to stitch between blocks using terrain splating somehow - not even sure this is possible and have no idea how to do it as it will probably involve implementing #2 below to get the terrain splat to work.
  2. Take the current 128x128 heightmaps and extend each of them 1 point to the x and z axis with the exact same vertices as the terrain block they are stitching too. Is this the normal methodology for stitching something? Do graphics cards have any performance problems with rendering against vertices that are connected to 2 different meshes and have the same vector? - as you can see my low level knowledge of resolving the problem isn’t the best at present.
  3. My least favourite solution, load a massive amount of terrain into the client in a single block and when they move close to being able to see the edge of the terrain, remove the terrainquad node containing the large amount of terrain and add a new one centering on where the game character is at the time. This one is my final option as it will more than double the amount of memory taken up by the client for heightmaps, not to mention maybe causing the client render to stutter.

    Anyway, thoughts welcome from anyone. Or maybe I am missing some basic functionality of TerraMonkey and someone can point me in the right direction.


1 Like

This is actually one of the Google Summer of Code tasks that I hope someone picks up :slight_smile:

Here is how the stitching works:

Every terrain patch finds out what its LOD level is from the LodCalculator that re-calculates LOD levels whenever the camera moves.

It then looks at its neighbour’s LOD levels on all four sides. If a neighbour on one of the sides has a higher LOD, then this terrain patch will stitch that side to the neighbour’s LOD level. If the LOD level of the neighbour is lower than this terrain patch, then there is no stitching and it is up to the neighbour to do the stitching.

To change the geometry based on LOD, it just changes the indexes, not the actual points of the geometry.

There are two stitching algorithms that the Terrain Patches can use. The method names are a little crummy and I need to rename them, but they are:

writeIndexArrayLodDiff() and writeIndexArrayLodVariable() in the LODGeomap class.

The will stitch patches that are at most 1 LOD different, while writeIndexArrayLodVariable will stitch between several LOD differences.

So, with that down, what you need is to extend the TerrainQuad to be able to have neighbour quads that aren’t part of the same quad tree. There are several methods that perform lookups that you will need to modify so they can venture off to the other neighbours that are in a different TerrainQuad tree. Some of these methods are: findRightPatch, findRightQuad, findLeftPatch, findLeftQuad, etc.

These are used for seaming together the indexes for LOD, the normal vectors, and the tangents.

If you overwrite those ‘find’ methods to look at other terrain quad trees, much of the same code should still work.

Some other methods such as getHeight, adjustHeight, collideWith, findPick, getAllTerrainPatches(for physics), might need to be implemented above the collection of TerrainQuads and delegate to whatever quad tree they intersect with below.

Let me know how you progress, this is a feature that I would like to have with TerraMonkey. And if there is anything I can do to help you along the way feel free to ask.

Thanks Sploreg. You’ve given me the direction to head in. When I get it working I will post the code.

  • Physi

Cool! If you run into any stumbling blocks (private methods you need made protected etc., or questions) don’t hesitate to ask.

Good luck :slight_smile: