Script to create Voronoi Heightmaps. These are used to create realistic terrain erosion heightmaps (in combination with Perlin Noise or Diamond Square)

Code:
//Voronoi Heightmap Generator
//recommended default values:
// size_ 			= 512
// points_			= 32
var* voronoi_map_tmp_pixels=NULL;
var* voronoi_map_tmp_points=NULL;
///////////////////////////////
BMAP* voronoi_map(double size_,var points_)
{
	//create data
	voronoi_map_tmp_pixels=(var*)sys_malloc(sizeof(var) * size_*size_);
	voronoi_map_tmp_points=(var*)sys_malloc(sizeof(var) * points_*2);
	
	//create random points
	int i; for(i=0;i<points_;i++)
	{
		voronoi_map_tmp_points[i*2+0]=integer(random(size_));//px
		voronoi_map_tmp_points[i*2+1]=integer(random(size_));//py
	}
	
	//fill empty pixels
	var pmax=0;
	int py; for(py=0;py<size_;py++)
	{
		int px; for(px=0;px<size_;px++)
		{
			var fmax=999999;
			var closest_p=fmax;
			var second_closest_p=fmax;
			
			int i; for(i=0;i<points_;i++)
			{
				VECTOR vec_from_,vec_to_;
				vec_set(vec_from_,vector(px,py,0));
				vec_set(vec_to_,vector(voronoi_map_tmp_points[i*2+0],voronoi_map_tmp_points[i*2+1],0));
				var distance=vec_dist(vec_from_,vec_to_);
				
				if(distance<closest_p)
				{
					second_closest_p=closest_p;
					closest_p=distance;
				}
				else if(distance<second_closest_p)
				{
					second_closest_p=distance;
				}
			}
			
			var c1=1;
			var c2=-1;
			var d1=255-closest_p;
			var d2=255-second_closest_p;
			
			voronoi_map_tmp_pixels[px*size_+py]=c1*d1 + c2*d2;
			
			//find brightest pixel to prepare normalizing
			if(voronoi_map_tmp_pixels[px*size_+py]>pmax){pmax=voronoi_map_tmp_pixels[px*size_+py];}
		}
	}
	
	//normalize heightmap (range 0-255)
	if(pmax!=0)
	{
		var factor=255/pmax;
		int py; for(py=0;py<size_;py++)
		{
			int px; for(px=0;px<size_;px++)
			{
				voronoi_map_tmp_pixels[px*size_+py]*=factor;
				voronoi_map_tmp_pixels[px*size_+py]=clamp(integer(voronoi_map_tmp_pixels[px*size_+py]),0,255);
			}
		}
	}

	//create bmap
	BMAP* bmp_tmp=bmap_createblack(size_,size_,24);
	
	//fill bmap
	int py; for(py=0;py<size_;py++)
	{
		int px; for(px=0;px<size_;px++)
		{
			//get heightmap color
			var grey=voronoi_map_tmp_pixels[px*size_+py];
			
			VECTOR bmp_color_;
			bmp_color_.x=grey;
			bmp_color_.y=grey;
			bmp_color_.z=grey;
			
			//add to heightmap
			var format=bmap_lock(bmp_tmp,0);
			var pixel=pixel_for_vec(bmp_color_,100,format);
			pixel_to_bmap(bmp_tmp, px, py, pixel);
			bmap_unlock(bmp_tmp);
		}
	}
	
	//free pixels and bmaps
	sys_free(voronoi_map_tmp_pixels);
	sys_free(voronoi_map_tmp_points);
	
	return bmp_tmp;
}



Example:
Code:
void main()
{
	video_mode=9;
	
	wait(1);
	
	BMAP* bmp=voronoi_map(512,32);
	
	while(1)
	{
		DEBUG_BMAP(bmp,0,1);
		
		wait(1);
	}
}



Further reading:
http://oddlabs.com/download/terrain_generation.pdf


Last edited by oliver2s; 01/15/14 12:45. Reason: Code Update / Bug Fix