
/////////////////////////////////////////////////////////////////////
// cubes part



#define GRID 4
FVector campos(2,2,-10);
FMatrix cammat;
#define SCALEZ 400
#define MINZ 1


class PVector : public FVector
{
public:
	int x,y;
	void project() {if (Z>MINZ) {float f=SCALEZ/Z;x=X*f+160;y=Y*f+100;/*putpixel(x,y,255);*/}};
	PVector (const FVector &f) {X=f.X;Y=f.Y;Z=f.Z;};
	PVector () {};
};

struct SQUARE
{
	float h;	// height
	float dh;	// dest height
	PVector p[4];	// rotated points
	int zord;
	float cx,cy;
};


#define GRD2 (GRID+2)
SQUARE grid[GRD2][GRD2];


void drawquad3d(const PVector *a, const PVector *b, const PVector *c, const PVector *d, int col)
{
	static PVector b1[8];
	PVector *out=b1;

#define CLIPMAC(aa,bb) 										\
	if (bb->Z>=MINZ) {                                      \
		if (aa->Z<MINZ) {*out++=*aa+(*bb-*aa)*((aa->Z-MINZ)/(bb->Z-aa->Z));};            \
		*out++=*bb;                                         \
	} else if (aa->Z>=MINZ) {*out++=*aa+(*bb-*aa)*((aa->Z-MINZ)/(bb->Z-aa->Z));};


	CLIPMAC(a,b);
	CLIPMAC(b,c);
	CLIPMAC(c,d);
	CLIPMAC(d,a);

	int i=out-b1;
	int j,k;
	if (i<3) return;

	k=i-1;
	resetedges();
	for (j=0;j<i;j++)
	{
		//addedge(b1[j].x,b1[j].y,b1[k].x,b1[k].y);
		addedge(b1[k].x,b1[k].y,b1[j].x,b1[j].y);
		k=j;
	}
	flatfill(screenbuf,col);


}

void drawgrid()
{
	//cammat.MakeID();
	// work out the rotated coords
	SQUARE *sq=&grid[1][1];
	int cx,cy,x,y,i,j;
	float f;
	FVector p,xp,yp;
	cx=campos.X;
	cy=campos.Y;
	yp=cammat*(campos*-1);
	for (y=0;y<GRID;y++)
	{
		xp=yp;
		yp+=cammat.Row[1];
		for (x=0;x<GRID;x++)
		{
			sq->h+=(sq->dh-sq->h)*0.03f;
			if (rand()<255)
			{
				sq->dh=rand()*16/32767.f;
			}

			p=xp+cammat.Row[2]*sq->h;
			sq->p[0]=p;
			sq->p[1]=p+cammat.Row[0];
			sq->p[2]=p+cammat.Row[1];
			sq->p[3]=sq->p[1]+cammat.Row[1];
			sq->cx=x-campos.X;
			sq->cy=y-campos.Y;
			sq->zord=abs(x-cx)+(abs(y-cy)<<8);
			for (i=0;i<4;i++) sq->p[i].project();
			xp+=cammat.Row[0];
			sq++;
		}
		sq+=2;
	}
	// bubble sort the indices by the zord field
	static SQUARE *idx[GRID*GRID];
	static int first=1;
	if (first)
	{
		first=0;
		for (j=0;j<GRID;j++)
		for (i=0;i<GRID;i++)
		{
			sq=idx[j*GRID+i]=&grid[j+1][i+1];
			sq->h=rand()*8/32767.f;
			sq->dh=rand()*8/32767.f;
		}

	}
	do
	{
		j=0;
		for (i=0;i<GRID*GRID-1;i++)
		{
			if (idx[i]->zord<idx[i+1]->zord)
			{
				j=1;
				sq=idx[i];idx[i]=idx[i+1];idx[i+1]=sq;
			}
		}
	} while (j);

	for (i=0;i<GRID*GRID;i++)
	{
		sq=idx[i];
		// build a vector to this point...
		p=FVector(sq->cx,sq->cy,sq->h-campos.Z);
		if (p.Z>=0)	drawquad3d(&sq->p[0],&sq->p[1],&sq->p[3],&sq->p[2],i*4+5);
		if (p.X>=0 && sq->h<sq[-1].h)
			drawquad3d(&sq[0].p[0],&sq[0].p[2],&sq[-1].p[3],&sq[-1].p[1],i*4-15);
		if (p.X<=0 && sq->h<sq[+1].h)
			drawquad3d(&sq[0].p[3],&sq[0].p[1],&sq[+1].p[0],&sq[+1].p[2],i*4-5);
		if (p.Y>=0 && sq->h<sq[-GRD2].h)
			drawquad3d(&sq[0].p[1],&sq[0].p[0],&sq[-GRD2].p[2],&sq[-GRD2].p[3],i*4+10);
		if (p.Y<=0 && sq->h<sq[+GRD2].h)
			drawquad3d(&sq[0].p[2],&sq[0].p[3],&sq[+GRD2].p[1],&sq[+GRD2].p[0],i*4-10);
	}
}

*/