BMAP* bmap_heightmap_to_normalmap(BMAP* bmap_hmap_,BMAP* bmap_nmap_,var factor_);
//Make Blendmap from Heightmap on slopes
///////////////////////////////
// bmap_hmap_ -> heightmap
// bmap_blendmap_ -> blendmap which will be painted or NULL for creating new blendmap
// color_ -> color which will be painted in blendmap on slopes
// gradientMin_ -> angle of slopes where painting should begin (range 0-90)
// gradientMax_ -> angle of slopes where painting should stop (range 0-90)
///////////////////////////////
BMAP* bmap_heightmap_to_blendmap_slopes(BMAP* bmap_hmap_,BMAP* bmap_blmap_,COLOR* color_,var gradientMin_,var gradientMax_)
{
//clear up gradients
var gradient_min_=gradientMin_;
var gradient_max_=gradientMax_;
if(gradient_max_<gradient_min_)
{
gradient_max_=gradientMin_;
gradient_min_=gradientMax_;
}
gradient_min_=clamp(gradient_min_,0,90);
gradient_max_=clamp(gradient_max_,0,90);
if(gradient_min_==gradient_max_){ return NULL; }
//store color
COLOR c1_;
c1_.red=color_.red;
c1_.green=color_.green;
c1_.blue=color_.blue;
//get size
var size_x_=bmap_width(bmap_hmap_);
var size_y_=bmap_height(bmap_hmap_);
//create tmp normalmap bmap
BMAP* normalmap_=bmap_heightmap_to_normalmap(bmap_hmap_,NULL,1);
//create temp bitmap for blendmap
BMAP* blendmap_=bmap_createblack(size_x_,size_y_,24);
//search slopes within the given range on normalmap
int py; for(py=0;py<size_y_;py++)
{
int px; for(px=0;px<size_x_;px++)
{
//get normalmap pixel
COLOR c_;
var format=bmap_lock(normalmap_,0);var alpha_;
var pixel=pixel_for_bmap(normalmap_, px, py);
pixel_to_vec(c_,alpha_,format,pixel);
bmap_unlock(normalmap_);
//convert normalmap pixel to normal vector
VECTOR n;
n.x = 2.0*(c_.red-128);
n.y = 2.0*(c_.green-128);
n.z = 2.0*(c_.blue-128);
//normalize to 0-1
vec_normalize(n,1);
//get Euler angle
var angle = 90-asinv(abs(n.z));
//if angle is between given angles, paint blendmap
if(angle>=gradient_min_ && angle<=gradient_max_)
{
//paint given color to blendmap
var format=bmap_lock(blendmap_,0);
var pixel=pixel_for_vec(c1_,100,format);
pixel_to_bmap(blendmap_, px, py, pixel);
bmap_unlock(blendmap_);
}
}
}
//remove tmp normalmap
bmap_purge(normalmap_);
bmap_remove(normalmap_);
//return new created blendmap if no target bitmap was passed to function
if(bmap_blmap_==NULL){return blendmap_;}
else
{
//otherwise copy created blendmap to target bitmap
bmap_blit(bmap_blmap_,blendmap_,NULL,vector(bmap_width(bmap_blmap_),bmap_height(bmap_blmap_),0));
//delete temp bitmap
bmap_purge(blendmap_);
bmap_remove(blendmap_);
//return
return bmap_blmap_;
}
}
BMAP* bmap_heightmap_to_normalmap(BMAP* bmap_hmap_,BMAP* bmap_nmap_,var factor_)
{
//get size
var size_x_=bmap_width(bmap_hmap_);
var size_y_=bmap_height(bmap_hmap_);
BMAP* normalmap_=bmap_createblack(size_x_,size_y_,24);
int py; for(py=0;py<size_y_;py++)
{
int px; for(px=0;px<size_x_;px++)
{
//get height of 3 neighbor pixels
COLOR color_;
var c1,c2,c3;
var format=bmap_lock(bmap_hmap_,0);var alpha_;
var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py-1,0,size_y_));
pixel_to_vec(color_,alpha_,format,pixel); c1=color_.red;
var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py-1,0,size_y_));
pixel_to_vec(color_,alpha_,format,pixel); c2=color_.red;
var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py+1,0,size_y_));
pixel_to_vec(color_,alpha_,format,pixel); c3=color_.red;
bmap_unlock(bmap_hmap_);
//build temporary points that makes a triangle
VECTOR v1,v2,p1,p2,p3;
p1.x=0;p1.y=0;p1.z=c1*factor_;
p2.x=32;p2.y=0;p2.z=c2*factor_;
p3.x=0;p3.y=32;p3.z=c3*factor_;
//get first vector for cross product (p2-p1)
v1.x=p2.x-p1.x;
v1.y=p2.y-p1.y;
v1.z=p2.z-p1.z;
//get second vector for cross product (p3-p1)
v2.x=p3.x-p1.x;
v2.y=p3.y-p1.y;
v2.z=p3.z-p1.z;
//calculate cross product of v1 and v2
VECTOR n;
vec_cross(n,v1,v2);
//normalize to color range 0-255
vec_normalize(n,255);
//convert vector into normalmap color
n.x=n.x/2 + 128;
n.y=n.y/2 + 128;
n.z=n.z/2 + 128;
//copy color
COLOR color1_;
color1_.red=n.x;
color1_.green=n.y;
color1_.blue=n.z;
//get height of another 3 neighbor pixels
COLOR color_;
var c1,c2,c3;
var format=bmap_lock(bmap_hmap_,0);var alpha_;
var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py+1,0,size_y_));
pixel_to_vec(color_,alpha_,format,pixel); c1=color_.red;
var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py+1,0,size_y_));
pixel_to_vec(color_,alpha_,format,pixel); c2=color_.red;
var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py-1,0,size_y_));
pixel_to_vec(color_,alpha_,format,pixel); c3=color_.red;
bmap_unlock(bmap_hmap_);
//build temporary points that makes a triangle
VECTOR v1,v2,p1,p2,p3;
p1.x=32;p1.y=32;p1.z=c1*factor_;
p2.x=0;p2.y=32;p2.z=c2*factor_;
p3.x=32;p3.y=0;p3.z=c3*factor_;
//get first vector for cross product (p2-p1)
v1.x=p2.x-p1.x;
v1.y=p2.y-p1.y;
v1.z=p2.z-p1.z;
//get second vector for cross product (p3-p1)
v2.x=p3.x-p1.x;
v2.y=p3.y-p1.y;
v2.z=p3.z-p1.z;
//calculate cross product of v1 and v2
VECTOR n;
vec_cross(n,v1,v2);
//normalize to color range 0-255
vec_normalize(n,255);
//convert vector into normalmap color
n.x=n.x/2 + 128;
n.y=n.y/2 + 128;
n.z=n.z/2 + 128;
//copy color
COLOR color2_;
color2_.red=n.x;
color2_.green=n.y;
color2_.blue=n.z;
COLOR color_;
color_.red=(color1_.red+color2_.red)/2;
color_.green=(color1_.green+color2_.green)/2;
color_.blue=(color1_.blue+color2_.blue)/2;
//add to pixels
var format=bmap_lock(normalmap_,0);
var pixel=pixel_for_vec(color_,100,format);
pixel_to_bmap(normalmap_, px, py, pixel);
bmap_unlock(normalmap_);
}
}
//return new created Normalmap if no target bitmap was passed to function
if(bmap_nmap_==NULL){return normalmap_;}
else
{
//otherwise copy created Normalmap to target bitmap
bmap_blit(bmap_nmap_,normalmap_,NULL,vector(bmap_width(bmap_nmap_),bmap_height(bmap_nmap_),0));
//delete temp bitmap
bmap_purge(normalmap_);
bmap_remove(normalmap_);
//return
return bmap_nmap_;
}
}