NEW PAINT FUNCTION:
void Terrain_Paint(int x, int y)
{
ENTITY* Terr = Terrain[x][y];
CONTACT* c1;
int i; //vertex info for terrain
BMAP* Source_BM;
BMAP* OldSkin;
VECTOR Pixel_pos; //pixel coordinates for skin bmap
var height;
var pixel_source; var pixel_dest;
//var t_format1; var t_format2;
COLOR* t_color; var t_alpha;
BMAP* NewSkin = bmap_create("Terrain_Sand.tga");
t_format1=bmap_lock(NewSkin,0);
c1 = ent_getvertex(Terr,NULL,1);
for(Pixel_pos.y=0;Pixel_pos.y<512;Pixel_pos.y++)
{
for(Pixel_pos.x=0;Pixel_pos.x<512;Pixel_pos.x++)
{
i = (integer((Pixel_pos.x)/16)+1) + (((integer((Pixel_pos.y)/16)+1)*33));
height = get_height(Pixel_pos.x,Pixel_pos.y,i,c1);
if(height>16)
{
if(height<=16)//sand
{
Source_BM=Sand_BM;
}
else if(height<75)//grass
{
Source_BM=Grass_BM;
}
else if(height<150)//stone
{
Source_BM=Rock_BM;
}
else//snow
{
Source_BM=Snow_BM;
}
pixel_source = pixel_for_bmap(Source_BM,Pixel_pos.x,Pixel_pos.y);
t_color = pixel_to_vec(NULL, t_alpha ,t_format2,pixel_source);
//paint pixel on selected terrain's texture
pixel_dest=pixel_for_vec(t_color,t_alpha,t_format1);
pixel_to_bmap(NewSkin,Pixel_pos.x,Pixel_pos.y,pixel_dest);
}
}
}
bmap_unlock(NewSkin);
OldSkin=ent_getskin(Terr,1);
ptr_remove(OldSkin);
ent_setskin(Terr,NewSkin,1);
}
NEW HEIGHT FUNCTION:
var get_height(var Px, var Py, int SW, CONTACT* c1)
{
//P = point that we want the height of (x,y,0)
//SW = vertex number of terrain ent closest towards the lower left corner of the square
//c1 = pointer to our terrain vertex info
VECTOR P;
//TRANSFORM SKIN PIXEL COORDS TO LOCAL ENT COORD SYSTEM
vec_set(P,vector(Px,Py,0));
P.x-= 256;
P.y = 256-P.y;
VECTOR Triangle[3];
VECTOR temp_vec;
ANGLE temp_ang;
VECTOR Director[2];
VECTOR formula;
var ind_term;
//retrieve first point of containing triangle (base corner)
Triangle[0].x=(c1.v)[SW].x;
Triangle[0].y=(c1.v)[SW].z;
Triangle[0].z=(c1.v)[SW].y;
//retrieve second point of containing triangle (diagonal to base)
Triangle[1].x=(c1.v)[SW-32].x;
Triangle[1].y=(c1.v)[SW-32].z;
Triangle[1].z=(c1.v)[SW-32].y;
//determine third point of containing triangle (varying point)
vec_set (temp_vec, P);
vec_sub (temp_vec,Triangle[0].x);
vec_to_angle (temp_ang.pan,temp_vec);
//retrieve third point of containing triangle (varying point)
if(temp_ang.pan>45)
{
Triangle[2].x = (c1.v)[SW-33].x;
Triangle[2].y = (c1.v)[SW-33].z;
Triangle[2].z = (c1.v)[SW-33].y;
}
else
{
Triangle[2].x = (c1.v)[SW+1].x;
Triangle[2].y = (c1.v)[SW+1].z;
Triangle[2].z = (c1.v)[SW+1].y;
}
//calculate the triangle's plane normal for the formula coeficients
vec_set(Director[0],Triangle[1]);
vec_sub(Director[0],Triangle[0]);
vec_set(Director[1],Triangle[2]);
vec_sub(Director[1],Triangle[0]);
vec_cross(formula,Director[0],Director[1]);
//set the independant term of the formula
ind_term=(-1*formula.x*Triangle[0].x)+(-1*formula.y*Triangle[0].y)+(-1*formula.z*Triangle[0].z);
//calculate our point's height plugging our values into the formula
P.z=(-1*((formula.x*P.x)+(formula.y*P.y)+ind_term))/formula.z;
return(P.z);
}
EDIT:relevant changes are:
-CONTACT* now being declared in paint function
-c1 = ent_getvertex(Terr,NULL,1);
being called only once in the paint function before the loops
-paint function now passes a contact pointer to the height function instead of a entity pointer
height = get_height(Pixel_pos.x,Pixel_pos.y,i,c1);
-height function now recieves a contact pointer instead of a ent pointer
var get_height(var Px, var Py, int SW, CONTACT* c1)
-removed all ent_getvertex calls from the height function
(adittional speed tests will be posted soon)