//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;
}