#include "MadMap.h"
void MadMap::XMLRead(vcg::Xml &xml)
{
char buffer[200];
int i,a;
const char *s;
assert(xml.id == "MadMap");
//Dimensione della Mappa
Dim.X = (int)atoi(xml["SizeX"].c_str());
Dim.Z = (int)atoi(xml["SizeZ"].c_str());
numtex = (int)atoi(xml["numtex"].c_str());
for (i=0;i<numtex;i++)
{
sprintf(buffer,"Tex_%d",i);
s=xml[buffer].c_str();
a=strlen(s);
strncpy(Tex[i],s,a);
Tex[i][a]='\0';
}
sprintf(buffer,"Enemys_Tex");
TexEnemy=(int) atoi(xml[buffer].c_str());
for(i=0;i<Dim.X;++i)
{
for(int j=0;j<Dim.Z;++j)
{
//Costruisce la MadTile nella posizione (i,j) nella mappa
sprintf(buffer,"NO_%d_%d",i,j);
Map[i][j].NE = (double) atof(xml[buffer].c_str());
sprintf(buffer,"NE_%d_%d",i,j);
Map[i][j].NW = (double) atof(xml[buffer].c_str());
sprintf(buffer,"SO_%d_%d",i,j);
Map[i][j].SE = (double) atof(xml[buffer].c_str());
sprintf(buffer,"SE_%d_%d",i,j);
Map[i][j].SW = (double) atof(xml[buffer].c_str());
sprintf(buffer,"C_%d_%d",i,j);
Map[i][j].C = (double) atof(xml[buffer].c_str());
sprintf(buffer,"typet_%d_%d",i,j);
Map[i][j].typet = (int) atoi(xml[buffer].c_str());
sprintf(buffer,"typew_%d_%d",i,j);
Map[i][j].typew = (int) atoi(xml[buffer].c_str());
sprintf(buffer,"goal_%d_%d",i,j);
Map[i][j].goal = (int) atoi(xml[buffer].c_str());
sprintf(buffer,"grav_%d_%d",i,j);
Map[i][j].grav = (double) atof(xml[buffer].c_str());
sprintf(buffer,"artr_%d_%d",i,j);
Map[i][j].attr = (double) atof(xml[buffer].c_str());
}
}
int x,z;
//Start
x =(int) atoi(xml["X_S"].c_str());
z =(int) atoi(xml["Z_S"].c_str());
Start.first.X=x;
Start.first.Z=z;
Start.last.X=x;
Start.last.Z=z;
//Goal
for (i=0;i<MAXENEMY;i++) {
sprintf(buffer,"Enemy_%d_X",i);
x =(int) atoi(xml[buffer].c_str());
sprintf(buffer,"Enemy_%d_Z",i);
z =(int) atoi(xml[buffer].c_str());
Enemys[i].first.X=x; Enemys[i].first.Z=z;
Enemys[i].last.X=x; Enemys[i].last.Z=z;
}
}
MadMap::MadMap(int SizeX,int SizeZ)
{
//Lo Start non è presenta nella Mappa
Start.first.X=NOMAP;
Start.first.Z=NOMAP;
Start.last.X=NOMAP;
Start.last.Z=NOMAP;
//Dimenzione della Mappa
Dim.X = SizeX;
Dim.Z = SizeZ;
//Mappa Valida
Meaningful=true;
strncpy(Tex[0],"tile.jpg\0",9);
strncpy(Tex[1],"wall.jpg\0",9);
strncpy(Tex[2],"enemy.jpg\0",16);
TexEnemy=2;
for (int i=0;i<Dim.Z;i++)
{
for (int j=0;j<Dim.X;j++)
{
//Tile nella posizione (i,j) altezza DEFAULT!
Map[i][j].C = DEFAULT_Y;
Map[i][j].NE = DEFAULT_Y;
Map[i][j].NW = DEFAULT_Y;
Map[i][j].SE = DEFAULT_Y;
Map[i][j].SW = DEFAULT_Y;
Map[i][j].typet=TILE;
Map[i][j].typew=WALL;
Map[i][j].goal=0;
Map[i][j].grav=-160;
Map[i][j].attr=7;
}
}
numtex=3;
CalcNorm();
}
void MadMap::CalcNorm()
{
//con area colorata
Point3f nw;
Point3f ne;
Point3f sw;
Point3f se;
Point3f c;
c[XX]=0;
c[ZZ]=0;
nw[XX]=-1;
nw[ZZ]=-1;
ne[XX]=1;
ne[ZZ]=-1;
sw[XX]=-1;
sw[ZZ]=1;
se[XX]=1;
se[ZZ]=1;
for (int i=0;i<Dim.Z;i++)
for (int j=0;j<Dim.X;j++)
{
c[YY]=Map[j][i].C;
nw[YY]=Map[j][i].NW;
ne[YY]=Map[j][i].NE;
sw[YY]=Map[j][i].SW;
se[YY]=Map[j][i].SE;
Nl[j][i][STH]=Normal(c,sw,se);
Nl[j][i][EST]=Normal(ne,c,se);
Nl[j][i][NTH]=-Normal(ne,c,nw);
Nl[j][i][WST]=-Normal(nw,c,sw);
}
}
MadMap::MadMap(){Meaningful=false;}
void MadMap::Draw (int option)
{
glMatrixMode(GL_MODELVIEW);
for (int i=0;i<Dim.Z;i++)
for (int j=0;j<Dim.X;j++)
{DrawTile(j,i,option);
if ((i+1)<Dim.Z)
{if ((Map[j][i].SW!=Map[j][i+1].NW)||
((Map[j][i].SE!=Map[j][i+1].NE)))
DrawWall(j,i,NORTH,option);}
else DrawWall(j,i,NORTH,option);
if ((i-1)>=0) {
if ((Map[j][i].NE!=Map[j][i-1].SE)||
(Map[j][i].NW!=Map[j][i-1].SW))
DrawWall(j,i,SOUTH,option);}
else DrawWall(j,i,SOUTH,option);
if ((j-1)>=0) {
if ((Map[j][i].NW!=Map[j-1][i].NE)||
(Map[j][i].SW!=Map[j-1][i].SE))
DrawWall(j,i,EAST,option);}
else DrawWall(j,i,EAST,option);
if ((j+1)<Dim.X){
if ((Map[j][i].SE!=Map[j+1][i].SW)||
(Map[j][i].NE!=Map[j+1][i].NW))
DrawWall(j,i,WEST,option);}
else DrawWall(j,i,WEST,option);
}
}
void MadMap::XMLWrite(FILE *fp)
{
fprintf(fp,"<MadMap\n");
//Dimensione
fprintf(fp," SizeX=\"%d\" \n", Dim.X);
fprintf(fp," SizeZ=\"%d\" \n", Dim.Z);
int i,j;
fprintf(fp," numtex=\"%d\" \n",numtex);
for (i=0;i<numtex;i++)
{
fprintf(fp," Tex_%d=\"%s\"\n",i,Tex[i]);
}
fprintf(fp," Enemys_Tex=\"%i\" \n",TexEnemy);
for(i=0;i<Dim.X;++i) {
for(j=0;j<Dim.Z;++j)
{
//Tile
fprintf(fp," NO_%d_%d =\"%f\"\n",i,j, Map[i][j].NE);
fprintf(fp," NE_%d_%d =\"%f\"\n",i,j, Map[i][j].NW);
fprintf(fp," SO_%d_%d =\"%f\" \n",i,j, Map[i][j].SE);
fprintf(fp," SE_%d_%d =\"%f\" \n",i,j, Map[i][j].SW);
fprintf(fp," C_%d_%d =\"%f\" \n",i,j, Map[i][j].C);
fprintf(fp," typet_%d_%d =\"%d\" \n",i,j, Map[i][j].typet);
fprintf(fp," typew_%d_%d =\"%d\" \n",i,j, Map[i][j].typew);
fprintf(fp," goal_%d_%d =\"%d\" \n",i,j, Map[i][j].goal);
fprintf(fp," grav_%d_%d =\"%f\" \n",i,j, Map[i][j].grav);
fprintf(fp," artr_%d_%d =\"%f\" \n",i,j, Map[i][j].attr);
}
}
//Start
fprintf(fp," X_S=\"%d\"\n", Start.last.X);
fprintf(fp," Z_S=\"%d\"\n", Start.last.Z);
for (i=0;i<MAXENEMY;i++) {
fprintf(fp," Enemy_%d_X=\"%d\" \n",i,Enemys[i].first.X);
fprintf(fp," Enemy_%d_Z=\"%d\" \n",i,Enemys[i].first.Z);
}
fprintf(fp,"/>\n");
}
int MadMap::PickElement(int x, int y, int option)
{
long hits;
static unsigned int selectBuf[16384];
glSelectBuffer(16384, selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
/* Because LoadName() won't work with no names on the stack */
glPushName(-1);
double mp[16];
int viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
glMatrixMode(GL_PROJECTION);
glGetDoublev(GL_PROJECTION_MATRIX ,mp);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(x, viewport[3]-y, 7, 7, viewport);
glMultMatrixd(mp);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
Draw(option); //disegno della mappa
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
hits = glRenderMode(GL_RENDER);
if (hits <= 0) return -1;
vector< pair<double,unsigned int> > H;
for(int ii=0;ii<hits;ii++)
H.push_back( make_pair(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3]));
sort(H.begin(),H.end());
return H[0].second;
}
void MadMap::upTile(int X,int Z,double Y)
{
Map[X][Z].C=Map[X][Z].C+Y;
Map[X][Z].NW=Map[X][Z].NW+Y;
Map[X][Z].SE=Map[X][Z].SE+Y;
Map[X][Z].SW=Map[X][Z].SW+Y;
Map[X][Z].NE=Map[X][Z].NE+Y;
}
void MadMap::zeroTile(int X,int Z,double k)
{
Map[X][Z].C=0+k;
Map[X][Z].NW=0+k;
Map[X][Z].SE=0+k;
Map[X][Z].SW=0+k;
Map[X][Z].NE=0+k;
}
double MadMap::getY(double X, double Z)
{
double hB,hC,dB,dC,ret;
if ((X<0)||(Z<0)) return -200;
int iX=(int)X; //parte intera X
int iZ=(int)Z; //parte intera Z
double dX=X -iX; //parte decimale X
double dZ=Z-iZ; //parte decimale Z
if ((iX>=0) && (iZ>=0) && (iX<Dim.X) && ( iZ<Dim.Z))
//se le coordinate sono nella mappa
{
double hA= Map[iX][iZ].C; //altezza A = altezza Centro Tile
double dA=sqrt(pow((dX-0.5),2)+pow((dZ-0.5),2));
//Distanza A = Distanza punto (X,Z) dal Centro Tile
/*
SE
+--+ quale è il punto B?
|\ |
| \|
+--+
NW */
if (dZ>(1-dX)){
hB=Map[iX][iZ].SE; //altezza B = altezza Nord-Ovest della tile
dB=sqrt(pow((1-dX),2)+pow((1-dZ),2));
//Distanza B= distanza punto(X,Z) dal punto + a Nord-Ovest Tile
}
else {
hB=Map[iX][iZ].NW; //altezza B = altezza Sud Est della tile
dB=sqrt(pow((dX),2)+pow((dZ),2));
//Distanza B= distanza punto(X,Z) dal punto + a Sud-Est Tile
}
/*
SW
+--+ quale è il punto C?
| /|
|/ |
+--+
NE */
if (dZ>dX){ hC=Map[iX][iZ].SW; //altezza C = altezza Nord-Est della tile
dC=sqrt(pow((dX),2)+pow((1-dZ),2));
//Distanza C= distanza punto(X,Z) dal punto + a Nord-Est Tile
}
else {hC=Map[iX][iZ].NE; //altezza C = altezza Sud-Ovest della tile
dC=sqrt(pow((1-dX),2)+pow((dZ),2));
//Distanza C= distanza punto(X,Z) dal punto + a Sud-Ovest Tile
}
double maxdA=sqrt(pow(0.5,2)+pow(0.5,2));
//distanza massima di un punto (dX,dZ) dal centro della tile
ret= hA*(1-dA/maxdA)+ (hB*(1-dB)+hC*(dB))*(dA/maxdA);
//calcolo dell'altezza del punto (dX,dZ) in base alle altezze conosciute della tile
}
else ret=-200;
return ret;
}
void MadMap::getTriangle(double X, double Z,MarbleTriangle *currentTriangle )
{
Point3f p1,p2,p3;
int iX=(int)X; //parte intera X
int iZ=(int)Z; //parte intera Z
int ch=0;
double dX=X -iX; //parte decimale X
double dZ=Z-iZ; //parte decimale Z
if ((iX>=0) && (iZ>=0) && (iX<Dim.X) && ( iZ<Dim.Z))
//se le coordinate sono nella mappa
{
p1= vcg::Point3f(iX+0.5,Map[iX][iZ].C,iZ+0.5);
/*
SE
+--+ quale è il punto B?
|\ |
| \|
+--+
NW */
if (dZ>=(1-dX)) {
p2= vcg::Point3f(iX+1,Map[iX][iZ].SE,iZ+1);
ch=SOUTH+EAST;
}
else {
p2= vcg::Point3f(iX,Map[iX][iZ].NW,iZ);
ch=NORTH+WEST;
}
/*
SW
+--+ quale è il punto C?
| /|
|/ |
+--+
NE */
if (dZ>=dX) {
p3= vcg::Point3f(iX,Map[iX][iZ].SW,iZ+1);
ch=(ch+SOUTH+WEST)/2;
}
else {
p3= vcg::Point3f(iX+1,Map[iX][iZ].NE,iZ);
ch=(ch+NORTH+EAST)/2;
}
switch(ch)
{
case NORTH: currentTriangle->a=p3;
currentTriangle->b=p2;
currentTriangle->c=p1;
break;
case SOUTH: currentTriangle->a=p3;
currentTriangle->b=p2;
currentTriangle->c=p1;
break;
case EAST: currentTriangle->a=p1;
currentTriangle->b=p2;
currentTriangle->c=p3;
break;
case WEST: currentTriangle->a=p1;
currentTriangle->b=p2;
currentTriangle->c=p3;
break;
default:break;
}
}
return ;
}
void MadMap::setY(double X,double Z, double Y)
{
double max,min;
int iX=(int)X;
int iZ=(int)Z;
int ch,ch1,ch2;
double dX= X -iX;
double dZ=Z-iZ;
if ((iX>=0) && (iZ>=0) && (iX<Dim.X) && ( iZ<Dim.Z))
{
double hA= Map[iX][iZ].C;
double hB,hC,dB,dC;
double dA=sqrt(pow((dX-0.5),2)+pow((dZ-0.5),2));
if ((dZ>(1-dX))){ hB=Map[iX][iZ].SE; ch1=SOUTH+EAST;
dB=sqrt(pow((1-dX),2)+pow((1-dZ),2));}
else
{ hB=Map[iX][iZ].NW; ch1=NORTH+WEST;
dB=sqrt(pow((dX),2)+pow((dZ),2)); }
if (dZ>dX){ hC=Map[iX][iZ].SW; ch2=SOUTH+WEST;
dC=sqrt(pow((dX),2)+pow((1-dZ),2));
}
else {hC=Map[iX][iZ].NE;
ch2=NORTH+EAST;
dC=sqrt(pow((1-dX),2)+pow((dZ),2));
}
if ((dA<dB) & (dA<dC)) Map[iX][iZ].C=Y;
else {
if (dB<dC) ch=ch1;
else ch=ch2;
switch(ch) {
case NORTH+EAST: Map[iX][iZ].NE=Y;break;
case SOUTH+WEST: Map[iX][iZ].SW=Y;break;
case NORTH+WEST: Map[iX][iZ].NW=Y;break;
case SOUTH+EAST: Map[iX][iZ].SE=Y;break;
default: break;}
if (Map[iX][iZ].NE>Map[iX][iZ].SW)
{max=Map[iX][iZ].NE; min= Map[iX][iZ].SW;}
else {min=Map[iX][iZ].NE; max= Map[iX][iZ].SW;}
if (Map[iX][iZ].SE>=max) max=Map[iX][iZ].SE;
if (Map[iX][iZ].SE<=min) min=Map[iX][iZ].SE;
if (Map[iX][iZ].NW>=max) max=Map[iX][iZ].NW;
if (Map[iX][iZ].NW<=min) min=Map[iX][iZ].NW;
//Map[iX][iZ].C= (Map[iX][iZ].NW+Map[iX][iZ].SE+
// Map[iX][iZ].NE+Map[iX][iZ].SW)/4;
Map[iX][iZ].C = (max+min)/2;
}
}
}
void MadMap::InitTexture(void)
{
ilInit();
iluInit();
ilutRenderer(ILUT_OPENGL);
for (int i=0;i<numtex;i++)
{
ti[i]=ilutGLLoadImage(Tex[i]);
printf("Texture %d:%s\n",i,Tex[i]);
ilutGLBuildMipmaps();
}
Start.InitTexture("start.jpg");
Wall.InitTexture("wall.jpg");
}
void MadMap::setColoredArea(coord a, coord b)
{
Colored.first.X=a.X;
Colored.first.Z=a.Z;
Colored.last.X=b.X;
Colored.last.Z=b.Z;
}
bool MadMap::isColored(double x, double z)
{ bool ret=FALSE;
if ((x >= Colored.first.X) && (x <= Colored.last.X) &&
(z >= Colored.first.Z) && ( z<= Colored.last.Z) )
ret = TRUE;
return ret;
}
void MadMap::copy ( MadMap *map_copy , coord first , coord last)
{
int x1,z1;
int k=Map[first.X][first.Z].C;
for (x1 = first.X ; x1 <= last.X; x1++)
for ( z1 = first.Z ; z1 <= last.Z ; z1++)
{
map_copy->Map[x1 -first.X ][z1 -first.Z].C = Map[x1][z1].C-k;
map_copy->Map[x1 -first.X ][z1 -first.Z].NE = Map[x1][z1].NE-k;
map_copy->Map[x1 -first.X ][z1 -first.Z].NW = Map[x1][z1].NW-k;
map_copy->Map[x1 -first.X ][z1 -first.Z].SE = Map[x1][z1].SE-k;
map_copy->Map[x1 -first.X ][z1 -first.Z].SW = Map[x1][z1].SW-k;
}
map_copy->Dim.X=(last.X-first.X)+1;
map_copy->Dim.Z=(last.Z-first.Z)+1;
map_copy->Meaningful=true;
}
void MadMap::copy ( MadMap *map_copy)
{ coord F;
coord L;
F.X=0;
F.Z=0;
L.X=Dim.X-1;
L.Z=Dim.Z-1;
copy(map_copy,F,L);
Meaningful=false;
}
void MadMap::paste ( MadMap *map_paste , coord first , coord last )
{
int x1,x2,z1,z2;
int k=Map[first.X][first.Z].C;
if ((map_paste->Dim.X-1) > ( (Dim.X-1) -first.X) )
x1=Dim.X ;
else x1=(first.X + map_paste->Dim.X)-1;
if (map_paste->Dim.Z-1 > ( (Dim.Z-1) -first.Z) )
x2=Dim.Z ;
else x2=(first.Z + map_paste->Dim.Z)-1 ;
for (z1 = first.X ; z1 <= x1; z1++)
for ( z2 = first.Z ; z2 <= x2 ; z2++)
{
Map[z1][z2].C = map_paste->Map[z1-first.X][z2-first.Z].C +k;
Map[z1][z2].NE = map_paste->Map[z1-first.X][z2-first.Z].NE +k;
Map[z1][z2].NW = map_paste->Map[z1-first.X][z2-first.Z].NW +k ;
Map[z1][z2].SE = map_paste->Map[z1-first.X][z2-first.Z].SE +k;
Map[z1][z2].SW = map_paste->Map[z1-first.X][z2-first.Z].SW +k;
}
Colored.last.X = x1;
Colored.last.Z = x2;
}
void MadMap::merge ( MadMap *map_paste , coord first , coord last )
{
int x1,x2,z1,z2;
int k=Map[first.X][first.Z].C;
if ((map_paste->Dim.X-1) > ( (Dim.X-1) -first.X) )
x1=Dim.X ;
else x1=(first.X + map_paste->Dim.X)-1;
if (map_paste->Dim.Z-1 > ( (Dim.Z-1) -first.Z) )
x2=Dim.Z ;
else x2=(first.Z + map_paste->Dim.Z)-1 ;
for (z1 = first.X ; z1 <= x1; z1++)
for ( z2 = first.Z ; z2 <= x2 ; z2++)
{
Map[z1][z2].C = map_paste->Map[z1-first.X][z2-first.Z].C +Map[z1][z2].C;
Map[z1][z2].SE = map_paste->Map[z1-first.X][z2-first.Z].SE +Map[z1][z2].SE;
Map[z1][z2].SW = map_paste->Map[z1-first.X][z2-first.Z].SW +Map[z1][z2].SW ;
Map[z1][z2].NE = map_paste->Map[z1-first.X][z2-first.Z].NE +Map[z1][z2].NE;
Map[z1][z2].NW = map_paste->Map[z1-first.X][z2-first.Z].NW +Map[z1][z2].NW;
}
}
void MadMap::DrawTile(int x,int z,int option)
{ double a=0;
glLoadName(z*100+x);
if (Map[x][z].goal==1) a=0.2;
else a=0;
if (!Colored.isArea(x,z)) glColor3f(1-a,1-a,1-a);
else glColor3f(0.4-a,0.5-a,0.7-a);
switch (option)
{
case WIREFRAME: //Caso "Fildiferro"
glDisable(GL_TEXTURE_2D);
//nome per la pick!
glBegin(GL_LINE_LOOP); //disegno dei 4 triangoli della tile
glVertex3f( x+1 ,Map[x][z].SE,z+1); //in wireframe
glVertex3f( x+1 ,Map[x][z].NE,z);
glVertex3f( x+0.5 ,Map[x][z].C,z+0.5);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f( x+1 ,Map[x][z].SE,z+1);
glVertex3f( x ,Map[x][z].SW,z+1);
glVertex3f( x+0.5 ,Map[x][z].C,z+0.5);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f( x ,Map[x][z].SW,z+1);
glVertex3f( x ,Map[x][z].NW,z);
glVertex3f( x+0.5 ,Map[x][z].C,z+0.5);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f( x+1 ,Map[x][z].NE,z);
glVertex3f( x ,Map[x][z].NW,z);
glVertex3f( x+0.5 ,Map[x][z].C,z+0.5);
glEnd();
break;
case SOLID:
glDisable(GL_TEXTURE_2D);
if(Colored.isArea(x,z)) glColor3f(0,0,1); //Blu
else glColor3f(1,1,1);
glBegin(GL_TRIANGLES); //disegno dei triangli pieni delle tile
glNormal(Nl[x][z][STH]);
glVertex3f( x ,Map[x][z].SW,z+1);
glVertex3f( x+0.5,Map[x][z].C,z+0.5); //con area colorata
glVertex3f( x+1 ,Map[x][z].SE,z+1);
glNormal(Nl[x][z][WST]);
glVertex3f( x,Map[x][z].NW,z);
glVertex3f( x+0.5,Map[x][z].C,z+0.5);
glVertex3f( x ,Map[x][z].SW,z+1);
glNormal(Nl[x][z][EST]);
glVertex3f( x+1 ,Map[x][z].NE,z);
glVertex3f( x+0.5,Map[x][z].C,z+0.5);
glVertex3f( x+1 ,Map[x][z].SE,z+1);
glNormal(Nl[x][z][NTH]);
glVertex3f( x+1 ,Map[x][z].NE,z);
glVertex3f( x+0.5,Map[x][z].C,z+0.5);
glVertex3f( x,Map[x][z].NW,z);
glEnd();
break;
case TEXTURED:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,ti[Map[x][z].typet]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
Start.setTexture(Start.isArea(x,z),Colored.isArea(x,z));
glBegin(GL_TRIANGLES); //disegno dei triangli pieni delle tile
glNormal(Nl[x][z][STH]);
glTexCoord2f(1.0, 1.0); glVertex3f( x ,Map[x][z].SW,z+1);
glTexCoord2f(0.5, 0.5); glVertex3f( x+0.5,Map[x][z].C,z+0.5); //con area colorata
glTexCoord2f(0.0, 1.0); glVertex3f( x+1 ,Map[x][z].SE,z+1);
glNormal(Nl[x][z][WST]);
glTexCoord2f(1.0, 0.0); glVertex3f( x,Map[x][z].NW,z);
glTexCoord2f(0.5, 0.5); glVertex3f( x+0.5,Map[x][z].C,z+0.5);
glTexCoord2f(1.0, 1.0); glVertex3f( x ,Map[x][z].SW,z+1);
glNormal(Nl[x][z][EST]);
glTexCoord2f(0.0, 0.0); glVertex3f( x+1 ,Map[x][z].NE,z);
glTexCoord2f(0.5, 0.5); glVertex3f( x+0.5,Map[x][z].C,z+0.5);
glTexCoord2f(0.0, 1.0); glVertex3f( x+1 ,Map[x][z].SE,z+1);
glNormal(Nl[x][z][NTH]);
glTexCoord2f(0.0, 0.0); glVertex3f( x+1 ,Map[x][z].NE,z);
glTexCoord2f(0.5, 0.5); glVertex3f( x+0.5,Map[x][z].C,z+0.5);
glTexCoord2f(1.0, 0.0); glVertex3f( x,Map[x][z].NW,z);
glEnd();
break;
default: break;
}
}
void MadMap::DrawWall(int x,int z,int side,int option)
{
vcg::Point3f wall[4];
Point3f nl;
nl[YY]=0;
switch (side){
case NORTH:
nl[XX]=0;
nl[ZZ]=1;
wall[0]=vcg::Point3f(x,Map[x][z].SW,z+1);
wall[1]=vcg::Point3f(x+1,Map[x][z].SE,z+1);
if ((z+1)<(Dim.Z)) {
wall[2]=vcg::Point3f(x+1,Map[x][z+1].NE,z+1);
wall[3]=vcg::Point3f(x,Map[x][z+1].NW,z+1);
}
else {wall[2]=vcg::Point3f(x+1,0,z+1);
wall[3]=vcg::Point3f(x,0,z+1);}
break;
case SOUTH:
nl[XX]=0;
nl[ZZ]=-1;
wall[0]=vcg::Point3f(x,Map[x][z].NW,z);
wall[1]=vcg::Point3f(x+1,Map[x][z].NE,z);
if ((z-1)>=0) {
wall[2]=vcg::Point3f(x+1,Map[x][z-1].SE,z);
wall[3]=vcg::Point3f(x,Map[x][z-1].SW,z);
}
else {wall[2]=vcg::Point3f(x+1,0,z);
wall[3]=vcg::Point3f(x,0,z);}
break;
case EAST:
nl[XX]=-1;
nl[ZZ]=0;
wall[0]=vcg::Point3f(x,Map[x][z].NW,z);
wall[1]=vcg::Point3f(x,Map[x][z].SW,z+1);
if ((x-1)>=0) {
wall[2]=vcg::Point3f(x,Map[x-1][z].SE,z+1);
wall[3]=vcg::Point3f(x,Map[x-1][z].NE,z);
}
else {wall[2]=vcg::Point3f(x,0,z+1);
wall[3]=vcg::Point3f(x,0,z);}
break;
case WEST:
nl[XX]=1;
nl[ZZ]=0;
wall[0]=vcg::Point3f(x+1,Map[x][z].NE,z);
wall[1]=vcg::Point3f(x+1,Map[x][z].SE,z+1);
if ((x+1)<Dim.Z) {
wall[2]=vcg::Point3f(x+1,Map[x+1][z].SW,z+1);
wall[3]=vcg::Point3f(x+1,Map[x+1][z].NW,z);
}
else {wall[2]=vcg::Point3f(x+1,0,z+1);
wall[3]=vcg::Point3f(x+1,0,z);}
break;
default: break;
}
if (( (wall[0].y()+wall[1].y())/2) >=( (wall[2].y()+wall[3].y())/2) )
{
glLoadName(z*100+x);
switch (option) {
case SOLID:
glDisable(GL_TEXTURE_2D);
if (Colored.isArea(x,z)) glColor3f(0,0,1);
else glColor3f(1,1,1);
glBegin(GL_POLYGON);
glNormal(nl);
glVertex3f(wall[0].x(),wall[0].y(),wall[0].z());
glVertex3f(wall[1].x(),wall[1].y(),wall[1].z());
glVertex3f(wall[2].x(),wall[2].y(),wall[2].z());
glVertex3f(wall[3].x(),wall[3].y(),wall[3].z());
glEnd();
break;
case TEXTURED:
Wall.setTexture(true,Colored.isArea(x,z));
glBindTexture(GL_TEXTURE_2D,ti[Map[x][z].typew]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glBegin(GL_POLYGON);
glNormal(nl);
glTexCoord2f(1, 0); glVertex3f(wall[0].x(),wall[0].y(),wall[0].z());
glTexCoord2f(0, 0); glVertex3f(wall[1].x(),wall[1].y(),wall[1].z());
glTexCoord2f(0, (wall[2].y()-wall[1].y()));glVertex3f(wall[2].x(),wall[2].y(),wall[2].z());
glTexCoord2f(1, (wall[3].y()-wall[0].y())); glVertex3f(wall[3].x(),wall[3].y(),wall[3].z());
glEnd();
break;
case WIREFRAME:
if (Colored.isArea(x,z)) glColor3f(0,0,1);
else glColor3f(1,1,1);
glBegin(GL_LINE_LOOP);
glVertex3f( wall[0].x(),wall[0].y(),wall[0].z());
glVertex3f( wall[1].x(),wall[1].y(),wall[1].z());
glVertex3f( wall[2].x(),wall[2].y(),wall[2].z());
glVertex3f( wall[3].x(),wall[3].y(),wall[3].z());
glEnd();
break;
default: break;
}
}
}
bool MadMap::intersect(float x1,float y1,float z1,float x2, float y2,float z2)
{
int j;
int n=sqrt(pow(x2-x1,2)+pow(z2-z1,2));
//n=n*n;
for (j=0;j<=n;j++)
{ if (getY((x2*j+x1*(n-j))/n,(z2*j+z1*(n-j))/n)>((y2*j+y1*(n-j))/n))
return false;
if (getY((x2*j+(x1-1)*(n-j))/n,(z2*j+z1*(n-j))/n)>((y2*j+y1*(n-j))/n))
return false;
if (getY((x2*j+(x1+1)*(n-j))/n,(z2*j+z1*(n-j))/n)>((y2*j+y1*(n-j))/n))
return false;
if (getY((x2*j+(x1)*(n-j))/n,(z2*j+(z1-1)*(n-j))/n)>((y2*j+y1*(n-j))/n))
return false;
if (getY((x2*j+(x1)*(n-j))/n,(z2*j+(z1+1)*(n-j))/n)>((y2*j+y1*(n-j))/n))
return false;
}
return true;
}
int MadMap::getColoredGravity()
{
if (Colored.first.X==-1) return -1;
int ret=Map[Colored.first.X][Colored.first.Z].grav;
for (int i=Colored.first.X; i<=Colored.last.X;i++)
for (int j=Colored.first.Z; j<=Colored.last.Z;j++)
if (ret!=Map[i][j].grav) return -1;
return ret;
}
int MadMap::getColoredTexTile()
{
if (Colored.first.X==-1) return -1;
int ret=Map[Colored.first.X][Colored.first.Z].typet;
for (int i=Colored.first.X; i<=Colored.last.X;i++)
for (int j=Colored.first.Z; j<=Colored.last.Z;j++)
if (ret!=Map[i][j].typet) return -1;
return ret;
}
int MadMap::getColoredAttrito()
{
if (Colored.first.X==-1) return -1;
int ret=Map[Colored.first.X][Colored.first.Z].attr;
for (int i=Colored.first.X; i<=Colored.last.X;i++)
for (int j=Colored.first.Z; j<=Colored.last.Z;j++)
if (ret!=Map[i][j].attr) return -1;
return ret;
}
int MadMap::getColoredTexWall()
{
if (Colored.first.X==-1) return -1;
int ret=Map[Colored.first.X][Colored.first.Z].typew;
for (int i=Colored.first.X; i<=Colored.last.X;i++)
for (int j=Colored.first.Z; j<=Colored.last.Z;j++)
if (ret!=Map[i][j].typew) return -1;
return ret;
}