Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

fireking

fault line formation generation method

This topic is 5386 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

void aperfil_01(float *band, int stride, int icount, float filter)
{
	float v=band[0];
	int j = stride;
	int i;
	for(i=0;i < icount-1;i++)
	{
		band[j]=((filter*v)+((1-filter)*band[j]));
		v=band[j];
		j+=stride;
	}
}
float **fault_formation_f(int width,int height,int low,int high,int iterations,float filter)
{
	float **points=new float*[width];
	for(int i=0;i < width;i++)
	{
		points[ i ]=new float[height];
	}
	for(int ax=0;ax < width;ax++)
	{
		for(int ay=0;ay 0)
	{
		int ttheight=high-((high-low)*iterations)/totiterations;
		int randx1,randy1,randx2,randy2;
		randx1=rangerand(0,width);
		randx2=rangerand(0,width);
		randy1=rangerand(0,height);
		randy2=rangerand(0,height);

		int dirx1,diry1,dirx2,diry2;
		dirx1=randx2-randx1;
		diry1=randy2-randy1;

		for(ix=0;ix < width;ix++)
		{
			for(iy=0;iy < height;iy++)
			{
				dirx2=ix-randx1;
				diry2=iy-randy1;
				if((dirx2*diry1 - dirx1*diry2) > 0)
				{
					points[ix][iy]=ttheight+points[ix][iy];
				}
			}
		}
		iterations--;
	}
	return points;
}
  
basically, the above is an implementation of the fault line formation method of generation terrain. That first function there is the erosion function... Supposedly, after each fault is placed, you're supposed to filter the entire map 4 times, one per direction (north, south, east, west) thats top to bottom, bottom to top, left to right, right to left im not sure on how to do this, i think ive got top to bottom and bottom to top correct, it goes something like aperfil_01(points[ix],1,128,0.4f); aperfil_01(points[width-1-ix],1,128,0.4f); where ix is a number going from 0 to 127, and width is 128 it doesnt like me guys, im telling you, i dont know how to go left to right or right to left... could someone help me who's tried implementing this before? [edited by - fireking on November 15, 2003 8:53:05 AM] [edited by - fireking on November 15, 2003 8:53:45 AM]

Share this post


Link to post
Share on other sites
Advertisement
possibly telling whats wrong could be a great help, not? memory access errors? wrong results? i''ve read carefully your text, not the source as its uncommented anyways (so there is no // <-- crash here anywhere:D).

what shall we do? help you? sure we like to. just tell us your problem.




If that''s not the help you''re after then you''re going to have to explain the problem better than what you have. - joanusdmentia

davepermen.net

Share this post


Link to post
Share on other sites
Like this?



void FilterBand(float *band,int stride,int count,float filter)
{
int i,j=stride;
float v = band[0];
for (i=0;i<count-1;i++)
{
band[j] = (filter*v + (1-filter)*band[j]);
v = band[j];
j+=stride;
}
}

/*
Erosion filter -
Erodes a height field in all 4 directions
*/

void FilterHeightField(float *field,int size,float filter)
{
int i;
/*
Erode rows left to right
*/

for (i=0;i<size;i++)
{
FilterBand(&field[size*i],1,size,filter);
}

/*
Erode rows right to left
*/

for (i=0;i<size;i++)
{
FilterBand(&field[size*i+size-1],-1,size,filter);
}

/*
Erode columns top to bottom
*/

for (i=0;i<size;i++)
{
FilterBand(&field[i],size,size,filter);
}

/*
Erode columns bottom to top
*/

for (i=0;i<size;i++)
{
FilterBand(&field[size*(size-1)+i],-size,size,filter);
}
}


EDIT: Assumes a square height map.
EDIT AGAIN: Change ints to floats.

Josh
vertexnormal AT linuxmail DOT org


Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

[edited by - VertexNormal on November 17, 2003 8:04:01 PM]

[edited by - VertexNormal on November 17, 2003 8:07:37 PM]

Share this post


Link to post
Share on other sites
@ VertexNormal

The terrain is in the form of a 2 dimensional array...

@ everyone else

the problem is, i dont know how to pass terrain[x][y] into FilterStuff(somepointer,...)

basically, i have a function without the documentation, and since i know erosion is a common topic in terrain generation, i was hoping someone has seen this function somewhere, and would know how to use it...

i need to pass some sort of 1d array to the function, several times, in order to erode the fractal generated terrain...

Share this post


Link to post
Share on other sites
It's basically the same as what I posted, except you have to index the beginning of a band differently, and modify your stride.

Basically, the filter takes a pointer to an array of floats. It knows nothing of how the array is set up, or how the array is indexed. Stride tells it how to increment the current position in the array to get the next position in the band being filtered.

In an array that is indexed such as HeightMap[width][height], then the stride for a row is equal to 1 or -1 (depending on left to right or right to left) and the stride for a column is height or -height (depending on top to bottom or bottom to top). In this case, rows are indexed [ i ][ 0 ] to [ i ][height-1] and columns are indexed [ 0 ][ i ] to [ width-1 ][ i ]. In this context, a row is of length height and is enumerated on the first subscript, while a column is of length width and is enumerated on the second subscript.

(Note: This is why I prefer to index a 2D array like this as HeightMap[ height ][ width ]. That way, the width subscript enumerates columns, and the height subscript enumerates rows; ie, rows are indexed with y and columns are indexed with x. Just a personal preference, but it is the reason for any mistakes in the coming code, as I am having to turn my thinking sideways to think in terms of indexing [ width ][ height ]. So please, forgive me if I made any errors.)

So, to filter all rows from left to right, we need to iterate through all of the rows (0..width), and take the address of the element at the beginning of each row ( [ i ][ 0 ] ). The stride in this case will be +1, as the elements in the row are organized: [ i ][ 0 ], [ i ][ 1 ], [ i ][ 2 ] etc...

for(i=0; i< width; i++)
{
FilterBand((float *)&HeightMap[ i ][ 0 ], 1, height, filter);
}


To filter right to left, we need to take the address of the element at the END of each row(height-1), and apply a stride of -1 (as the elements in this band are ordered [ i ][ height-1 ], [ i ][ height-2 ], etc...).

for(i=0; i< width; i++)
{
FilterBand((float *)&HeightMap[ i ][ height-1 ], -1, height, filter);
}


To filter from top to bottom, we need to iterate on columns (0..height) and take the address at the beginning of each column. In this case, stride will be equal to height (which is the width in sequential elements of each row of your 2D array.) Adding this moves us down a row, to the next element in the band.

for(i=0; i< height; i++)
{
FilterBand((float *)&HeightMap[ 0 ][ i ], height, width, filter);
}


And conversely, filtering from bottom to top we take the address at the end of each column, and a stride of -height.

for(i=0; i< height; i++)
{
FilterBand((float *)&HeightMap[ width-1 ][ i ], -height, width, filter);
}


These snippets should work for your height map. If not, forgive me for any errors.

Good luck, and if you still need help or if I confused you further, don't hesitate to ask.

EDIT: Fix some code mangled by forum/HTML tag interpretation.

Josh
vertexnormal AT linuxmail DOT org


Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

[edited by - VertexNormal on November 18, 2003 2:41:41 PM]

Share this post


Link to post
Share on other sites
damnit, that doesnt work either...


Unhandled exception at 0x77e73887 in createworld.exe: Microsoft C++ exception: std::bad_alloc @ 0x0012fb58.


im just going to buy the freaking book, thanks for the help anyways...

Share this post


Link to post
Share on other sites
Hmmm... I tested it, and it worked fine. Are you sure the problem isn't somewhere else?

EDIT: Looking more closely at your heightmap generator, it looks like the problem is probably coming from the way you are allocating your height map. You are allocating as an array of separate arrays; the code I posted expects the heightmap to be a single block.

If you want to allocate as an array of arrays, you will have to change the filtering function completely, as you can not expect the arrays to be allocated sequentially. This filtering method (and any algorithm that works with a striding parameter) expects all of the data to be allocated sequentially in memory, rather than as an array of arrays, whose separate arrays could be located just about anywhere.

Modify your heightmap allocation to ensure that the entire map is allocated sequentially in a predictable fashion, and it should work.

Josh
vertexnormal AT linuxmail DOT org


Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

[edited by - VertexNormal on November 18, 2003 7:37:36 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!