fault line formation generation method

Started by
13 comments, last by fireking 20 years, 5 months ago

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=new float[height];
	}
	for(int ax=0;ax < width;ax++)
	{
		for(int ay=0;ay<height;ay++)
		{
			points[ax][ay]=0;
		}
	}

	int ix;
	int iy;
	int totiterations=iterations;
	
	while(iterations > 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;
}
  </pre>  

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, &#111;ne per direction (north, south, east, west)

thats top to bottom, bottom to top, left to right, right to left

im not sure &#111;n 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?   

<SPAN CLASS=editedby>[edited by - fireking &#111;n November 15, 2003 8:53:05 AM]</SPAN>

<SPAN CLASS=editedby>[edited by - fireking &#111;n November 15, 2003 8:53:45 AM]</SPAN>   
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
Advertisement
anyone?
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
bump
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
surely someone knows a little something about erosion formulas
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
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
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

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

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]
@ 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...
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
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 [ 0 ] to [height-1] and columns are indexed [ 0 ] to [ width-1 ]. In this context, a row is of length <b>height </b> and is enumerated &#111;n the first subscript, while a column is of length <b>width </b> and is enumerated &#111;n the second subscript.<br><br>(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.)<br><br>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 ( [ 0 ] ). The stride in this case will be +1, as the elements in the row are organized: [ 0 ], [ 1 ], [ 2 ] etc…<br><pre><br>for(i=0; i< width; i++)<br>{<br> FilterBand((float *)&HeightMap[ 0 ], 1, height, filter);<br>}<br> </pre> <br><br>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 [ height-1 ], [ height-2 ], etc…).<br><pre><br>for(i=0; i< width; i++)<br>{<br> FilterBand((float *)&HeightMap[ height-1 ], -1, height, filter);<br>}<br> </pre> <br><br>To filter from top to bottom, we need to iterate &#111;n 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.<br><pre><br>for(i=0; i< height; i++)<br>{<br> FilterBand((float *)&HeightMap[ 0 ], height, width, filter);<br>}<br> </pre> <br><br>And conversely, filtering from bottom to top we take the address at the end of each column, and a stride of -height.<br><pre><br>for(i=0; i< height; i++)<br>{<br> FilterBand((float *)&HeightMap[ width-1 ], -height, width, filter);<br>}<br> </pre> <br><br>These snippets <i>should </i> work for your height map. If not, forgive me for any errors.<br><br>Good luck, and if you still need help or if I confused you further, don't hesitate to ask.<br> <br>EDIT: Fix some code mangled by forum/HTML tag interpretation.<br><br>Josh<br>vertexnormal AT linuxmail DOT org<br><hr><br>Check out <a href="http://www.angelfire.com/rpg2/vertexnormal">Golem: Lands of Shadow</a>, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo. <br><br><SPAN CLASS=editedby>[edited by - VertexNormal on November 18, 2003 2:41:41 PM]</SPAN>
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...
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
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]

This topic is closed to new replies.

Advertisement