"Hangover" is the name of the "proof of concept" project for my study thesis, an all-3D 3D terrain editor which enables you to simply interactively draw and manipulate terrains in 3D space. Since this is not based on height fields, there are no problems with steep hills, overhangs or even tunnels - that is all easily doable here.

The data is stored in a hybrid data structure. The 3D space is partitioned in so-called "3D Tiles", and each 3D tile can be represented with material stacks or voxels. For editing and synthesizing the meshes (with a marching cubes algorithm), the 3D tiles are present in voxel format, and those tiles that are not in use are stored as material stacks to save a lot of memory. The material stacks are also used for saving terrains to and loading terrains from disk.
Interactive editor (963 kiB)
This thing has English and German help texts.
The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.

My study thesis, the formal foundation of all this (8.56 MiB)
Warning, this is in German!
image image image image image
.ho.dat file format
 1. "HANGOVER" (ASCII-encoded)
 2. 0 (32bit int)
 3. Terrain.TilesX (32bit int)
 4. Terrain.TilesZ (32bit int)
 5. Tile.Width (32bit float)
 6. Tile.Length (32bit float)
 7. Tile.Height (32bit float)
 8. Tile.MeshResolutionX (32bit int)
 9. Tile.MeshResolutionY (32bit int)
10. Tile.MeshResolutionZ (32bit int)
11. Tile.VoxelsX (32bit int)
12. Tile.VoxelsY (32bit int)
13. Tile.VoxelsZ (32bit int)
14. terrain data

The terrain data has the following structure.
The space that the terrain resides in is divided in the X and Z directions in so-called 3D tiles. The following pattern describes the order of tiles in the terrain and stacks in a tile (Terrain.TilesX = 3, Terrain.TilesZ = 2):
0 1 2
3 4 5

In the terrain data, there is a sequence of all tiles in the terrain, laid out according to the pattern. Each tile in the terrain data consists of only its stack data. A tile contains Tile.VoxelsX*Y*Z voxels. All voxels for a given combination of X and Z reside in a stack starting at the bottom of the tile. Each stack is made of stack elements. A stack element is a pair of two bytes (h, t): The height of the stack element and the material type of the stack element. A stack ends either when the added heights of its elements are equal to Tile.VoxelsY or when the pair (h = 0, t = *) is used to "finish" that stack (* = whatever byte, that one's ignored).
When reading such a .ho.dat file and interpreting it as voxel data, you need to do the following:
  1. read all data until you reach the terrain data; the total voxel space has these dimensions: (Terrain.TilesX*Tile.VoxelsX, Tile.VoxelsY, Terrain.TilesZ*Tile.VoxelsZ)
  2. read the voxel data as follows: for each tile (for each stack (read stack elements until either stack height Tile.VoxelsY is reached or the stack element (h = 0, t = *) is encountered))
  3. fill your voxel space according to the stack data

Do note that when you read stacks within tiles, the pattern looks like this (numbers = tile indices, letters = stack indices):
0A 0B 1A 1B 2A 2B
0C 0D 1C 1D 2C 2D
3A 3B 4A 4B 5A 5B
3C 3D 4C 4D 5C 5D

A long time after my thesis was submitted and evaluated, we figured out one problem: Contrary to how the marching cubes algorithm should be implemented, I calculated the values for the normals only after offsetting/interpolating the grid points. That calculation must be done before that interpolation is done. You may also notice that there are gaps appearing in the model: Those come from the natural ambiguities of the original marching cubes algorithm and can be alleviated by using more sample points in those situations.
Design by Hai.