This is archived copy of currently unavailable Nem's Tools website, restored from Web Archive.
Download section now provides links to both Web Archive and to this unofficial Github mirror.
Terrain Generator Map Files - NemPosted: Jul 1st, 2003 - 3:38:42 pm
Data Types:

Type
Description
int 32 Bit Integer
float 32 Bit IEEE Floating Point Number
bool 8 Bit Boolean
string Variable Length String. (An int followed by an ASCII char array, no null terminator.)


Structures:

Header:

typedef struct Header300 { int XSize; // Number of vertices on the X axis. int YSize; // Number of vertices on the Y axis. float QuadSize; // Length of each quad. } Header300;

Vertex3f:

typedef struct Vertex3f { float X; float Y; float Z; } Vertex3f;

Vertex2f:

typedef struct Vertex2f { float U; float V; } Vertex2f;

TG Vertex:

typedef struct TGVertex { Vertex3f Vertex; // X,Y,Z coordinates of vertex. bool Locked; // Vertex locked. } TGVertex;

TG Face:

typedef struct TGFace { string Texture; // Texture name. Vertex2f Shift; // Texture shift. Vertex2f Scale; // Texture Scale. float Rotation; // Texture rotation in degrees. } TGFace;


File Layout:

TGM File:

{ string Version; // TGM Version ('TGM300'). Header300 Header; // Header information. TGVertex Vertices[]; // Array of Vertices. TGFace Faces[]; // Array of Faces. }
Modified: Jul 1st, 2003 - 3:55:46 pm[ 26548 Views ]

1. tonfPosted: Jul 18th, 2007 - 1:26:51 pm
hi nem,
how do implement your string type? Is it in a library or #include somewhere already?
I did typedef char* string; and my prog compiled but I suspect that isn't how it is supposed to be done.
When you say "An int followed by an ASCII char array, no null terminator." do you mean the int stores the length of the char array, maybe like:
struct string
{
int length;
char[] txt;
};

Thx for your help

2. NemPosted: Jul 18th, 2007 - 2:12:12 pm
They'd appear as the struct you declared in the file, but they're variable length, so you can't read them directly as a struct. This should work:

Code:
int iLength = 0;
fread(&iLength, sizeof(int), 1, pFile);
char *lpString = new char[iLength + 1];
fread(lpString, sizeof(char), iLength, pFile);
lpString[iLength] = '\0';

3. tonfPosted: Jul 19th, 2007 - 1:36:41 pm
hey nem, thanks for the info.

4. tonfPosted: Jul 19th, 2007 - 5:40:55 pm
hey nem, i got another question:
i was reading the texture area of a file and there seems to be a lot more TGFace items than i thought. I was assuming that there were 2 TGFace items in the array for every square created by the grid of points. I kept reading more and more than that trying to find the end of the file and there was way more than I expected. Thanks for your help.

5. NemPosted: Jul 19th, 2007 - 6:47:18 pm
Not sure if you're asking a question, but to clarify, there are Header300.XSize * Header300.YSize vertices and (Header300.XSize - 1) * (Header300.YSize - 1) faces. If you only want the height data, then you only need to read the first vertex section, if you want the texture data, you have to read the second face section. To interpret the second section, think of the terrain consisting of strips of quads; there is one face per quad.

6. tonfPosted: Jul 19th, 2007 - 7:33:47 pm
here's the code when i assumed the faces were triangles, 2 per quad, which is twice as many as what you are saying:

[code]
int numtriangles = 2 * (m_Header->XSize-1) * (m_Header->YSize-1);
m_Faces = new TGFace[numtriangles];
for (i=0; i < numtriangles; i++)
{
fread(&iStrLength, sizeof(int), 1, pFile);
m_Faces[i].Texture.length = iStrLength;
m_Faces[i].Texture.txt = new char[iStrLength];
fread(&m_Faces[i].Texture.txt, sizeof(char), iStrLength, pFile);
//m_Faces[i].Texture.txt[iStrLength+1] = "\0";
fread(&m_Faces[i].Shift, sizeof(Vertex2f), 1, pFile);
fread(&m_Faces[i].Scale, sizeof(Vertex2f), 1, pFile);
fread(&m_Faces[i].Rotation, sizeof(float), 1, pFile);
printf ("%f %f\n",m_Faces[i].Rotation,m_Faces[i].Rotation);
printf ("%s\n",m_Faces[i].Texture.txt);
}
printf ("%d %d",numverts, i);
[/code]
I'm testing with a 121 point (11 x 11) file, and the value of "i" at the end prints 200.

I should have definitely faulted or reached EOF, but it doesn't. I even went higher than numtriangles iterations, and it still didn't fault.

This code is from right after reading the vertex info which i verified was read correctly and completely.
The values printed by the printf for Shift,Scale, and Rotation are all zero's (as opposed to random garbage).
The texture printf prints a blank.

Also, i never assigned a texture to my test file (or even loaded a wad)., which may have something to do with it.

I'm basically confused how come the file seems to be so much bigger than it should be.

thanks

7. tonfPosted: Jul 20th, 2007 - 1:55:33 pm
sorry for the hassle, i just discovered that you can read past the end of the file and not throw an exception. Very un c/c++ like. Twas like you said of course.

This may have been discussed elsewhere on the site, but does TG have the ability to increase/decrease number of points while keeping height info intact? And also, can TG clip parts of a terrain (and/or paste or save them somewhere)?

I played with TG a little, but not completely and i didn't see anything like this.


8. NemPosted: Jul 21st, 2007 - 8:09:58 pm
Each quad (pair of triangles) has one face, so you're reading in twice as many faces as you need to.

You cannot adjust the number of vertices per axis after you've created your terrain in TG. I'm not sure what you mean by clipping the terrain.

9. tonfModified: Aug 13th, 2007 - 6:51:51 pm
i wrote a console program which does things to the terrain files. Here's the README. Let me know if you want it posted here and/or if you want the code posted here. The repointing part isn't perfect, but it's not bad.

here's the readme:
readme:

This program splits, scales, and/or adds/subtracts points from files created by Nem's excellent terrain generator.

You should back up any files you don't want modified/lost and/or read this whole thing before you use this.

This program is written in c++ and currently only runs properly on linux, bsd, etc but not on windows, I believe because of different implementations of "strtok". It builds on windows, and is so close to running, but alas I got fed up with it, and it dogged me. It needs to run on windows bad because that is where the actual terrain generator made by Nem runs. If anybody can fix this and get it to run on windows, that would be so freaking awesome. It should be simple for anybody familiar with processing strings in c++ (which I ain't). The bug is in main.cpp in the function LoadConfigFile where the config file is being read to load the commands.

Also, this program isn't super user-friendly, as in if you specify the wrong file on the command line or don't pass in the correct number or type of parameters in the config file, it will simply crash without telling you anything in most cases (sometimes writing a giant core dump file, if you have core dumps turned on). So if that happens, you need to go back and scrutinize all your spelling, number of parameters, etc.

This program is run on the command line like:
tgmanip filename
or
tgmanip filename <configfile>

"filename" is the name of your terrain file, and <configfile> is the name of the file that tells the program what to do.
If the program is run without specifying a config file, the program will look for a file in the same directory as the terrain file with the same name but with a .cfg extension instead. If it can't find a config file to use, it won't run.
If your paths have spaces in them, use quotes.

The commands in the config file are:
split <numbercolumns> [<numberrows>]
scale [sections] <factor> [<scaleZ>]
repoint [sections] <factor>
scroll <xfactor> <yfactor>
rotate <number of quarter turns in counterclockwise direction>
join <filename1> <filename2> <vertically>

Note the special word: sections.

"split" will split the terrain into <numbercolumns> * <numberrows> new files (without changing the original) which are the sections of the original. If <numberrows> is omitted, then it will be the same as <numbercolumns>.

"scale" is pretty obvious. Pass in a number. The number 1 would keep the same scale. Negative numbers will mirror it twice, which essentially just rotates it 180 degrees. If the parameter <scaleZ> is not 0 or omitted, then the heights will scale, otherwise they'll remain the same.

"repoint" multiplies the current number of quads along the x axis times <factor> to come up with the new number of quads along the x axis while maintaining the same size terrain. So again, giving it 1 will keep it the same. Specifying a number less than 1 will subtract information from the terrain. Working with rectangular (as opposed to perfectly square) grids can possibly result in a loss of information (a strip across the top of the grid) if the resulting new quad size doesn't divide perfectly into the overall height (y axis) of the grid.
The algorithm for figuring out the z values of the new points isn't very sophisticated (ie doesn't use calculus) or psychic (not sure if calculus would help), it only looks good if you repoint by a factor of 2 at a time. See below for good workaround. If somebody can figure this out, that would be awesome.

"scroll" will scroll the terrain by <xfactor> along the x axis and by <yfactor> along the y axis. A factor of 1 makes it scroll all the way around and end up where it began, essentially doing nothing, which is what should be done (instead of specifying 0) if you don't want it scrolled any in that particular direction.

"rotate" will rotate the terrain by 90 degrees in the counterclockwise direction for every quarter turn specified.

"join" takes 2 terrain files and joins them together into 1 terrain file. If <vertically> is 0, the terrains will be joined side by side, otherwise they will be one above the other (along the y axis). The resulting file does not have to exist beforehand and will be named the same as the config file except with a .tgm extension. See below.


If you put the word "sections" after a command, it does the command to all the sections (without modifying the original). Otherwise it will modify the original.
There must already be a "split" command before specifying "sections" in any commands. Also, the program doesn't support recursively splitting sections (unless you manually run it again).

Examples for a config file:
Code:

# pound sign is for comments in the config file

# simply add more detail to the original -
# Doing a repoint to add more detail with any value other than 2 makes it look wacked,
# so if you want more detail than twice as much (like 4 times as much), simply call
# "repoint 2" twice
repoint 2
repoint 2

# split the file into 16 new files, scale them all out to be bigger without scaling the height, add lots more detail to all of them
split 4 4
scale sections 2 0
repoint sections 2
repoint sections 2
repoint sections 2

# split a terrain across the center horizontally into 2 pieces
split 1 2

# scroll a terrain 30% to the right, but not at all up and down
scroll .3 1

# scroll all the newly made sections 50% in both axes (don't know why you would want this)
scroll sections .5 .5

# rotate a terrain 270 degrees (3 quarter turns to the left)
rotate 3

# join 2 files side by side
join foothills.tgm bigassmountain.tgm 0

# or vertically
join foothills.tgm bigassmountain.tgm 1

# the resulting terrain file will be named the same as the config file (with a .tgm extension) that
# the join command is in even if the terrain file doesn't exist yet. So you would make for example a config
# file named "joined.cfg" and on the command line say:
# tgmanip joined.tgm
# even though the file "joined.tgm" doesn't exist yet.

10. tonfPosted: Jul 25th, 2007 - 8:26:47 pm
lol i totally borked the page

11. tonfPosted: Jul 26th, 2007 - 12:43:42 pm
thx for fixing my ignorant formatting. I'll try to find a place to post this program for download if you don't want to host it. If you do, that would be great, but i can probably find a place in a few days or so. If you want some of the code to incorporate into TG lemme know and i'll post/send it. I'm probably going to add some more functions like scrolling and concatenating soon too.
BTW im doing all this so i can more easily make a planet, in case you're wondering why any of this is useful.

12. NemPosted: Aug 1st, 2007 - 12:28:48 pm
If you can post a link to the download, I'll put it in a more prominent spot.

The current version of TG is quite inefficient, I've meant to rewrite it for well over a year, but I haven't had much of a chance.

13. tonfPosted: Aug 6th, 2007 - 4:51:38 pm
Yeah i know how the "haven't had much of a chance" thing goes. I'm surprised I managed to get as far as I did.

There is a problem with my program. I developed it on linux, where it works fine, but the part that parses the config file for instructions is broken on the windows build due to (I strongly suspect) different implementations of the function "strtok" between the windows version of c++ and the linux version. String manipulating/parsing in c++ for me is a frustrating bitch.

I tried to tweak it so it wouldn't seg fault on the windows build, but I started pulling my hair out real soon so i said "fuggit". I'll probably retry soon though because I'm kind of getting tired of transferring giant files all the time.

I've added scrolling, but got sidetracked from adding concatenating and rotating, so here's what I might can do:
I can post everything I have somewhere, work on rotating and concatenating, and maybe some helpful soul in the meantime will fix the string parsing thing on windows.

14. tonfPosted: Aug 6th, 2007 - 11:24:53 pm
It's at:
http://planet.insteadofwork.com

Feel free to use whatever code you want if you find it useful.

I'm adding concatenating files and rotating soon.

BTW the archives contain the source code, linux binary, and a visual studio .vcproj file and a README file.

15. tonfPosted: Aug 7th, 2007 - 11:59:54 pm
yo hang on making that more public yet. Textures were broken, but now they're fixed, and all I've got left now is rotate

Nem's Tools v2.0 © 2006 Ryan Gregg.
Execution time: 0.07963s; Queries: 14.