/* ====================================================================
 *              
 *  Elout de Kok - 2001
 */
import java.awt.*;
import java.awt.image.*;
import java.net.*;
import java.io.*;
import java.applet.*;

public class buffie04 extends Applet implements Runnable, ImageProducer
{
	private Thread runner;
	private Image image;
	private static ColorModel defaultRGB = ColorModel.getRGBdefault();
	private DirectColorModel directCM;
	private ImageConsumer consumer;
	private MediaTracker tracker;
	private int[] out;

	private int w=400;
	private int h=400;


	private long teller=0,now=0, fpsa;
	private long startTime;

	private int black[]= new int[w*h];	//black background

	private int zbuf[]= new int[w*h];		//zbuffer.
	private int zbufback[]= new int[w*h];	//zbuffer.backbuffer
	private int znear=-100000;
	private int zfar=100000;

	//----matrix
	private float mat0[]=new float[16];
	private float mat1[]=new float[16];
	private float mat2[]=new float[16];
	
	private float cubscale=4.5f;				// cube scale
	float scale2=40.0f;  // 3d scale

	private int cubes=3;					// cubes
	private int points=8*cubes;
	private int tri=12*cubes;

	private float xd[]=new float[points];	// 3d data 
	private float yd[]=new float[points];
	private float zd[]=new float[points];

	private float cxd[]=new float[points];	// 3d data after rotation
	private float cyd[]=new float[points];
	private float czd[]=new float[points];

	private int xxd[]=new int[points];		// 3d data to 2D points
	private int yyd[]=new int[points];
	private int zzd[]=new int[points];		// for z-buffering

	private int cr[]=new int[points];	// colour points
	private int cg[]=new int[points];	// colour points
	private int cb[]=new int[points];	// colour points

	private boolean bor[]=new boolean[points];	// colour points
	private boolean bog[]=new boolean[points];	// colour points
	private boolean bob[]=new boolean[points];	// colour points


	int dp[]= new int[cubes*36];

	int dporg[]= // tri - points cube
	{
	3,0,1,
	1,2,3,
	4,0,3,
	3,7,4,
	5,4,7,
	7,6,5,
	5,6,2,
	2,1,5,
	1,0,4,
	4,5,1,
	2,6,7,
	7,3,2
	};

	private float backsort[]=new float[tri];
	private int dpzsort[]=new int[tri];
	private float backzsort[]=new float[tri];

	private int ledge[]=new int[h]; // left edge
	private int redge[]=new int[h]; // right edge
	private int ledgebuf[]=new int[h]; // left edge
	private int redgebuf[]=new int[h]; // right edge

	private int ledgecolr[]=new int[h]; // red left edge colour gouraudshading
	private int redgecolr[]=new int[h]; // red right edge colour gouraudshading
	private int ledgecolg[]=new int[h]; // green left edge colour gouraudshading
	private int redgecolg[]=new int[h]; // green right edge colour gouraudshading
	private int ledgecolb[]=new int[h]; // blue left edge colour gouraudshading
	private int redgecolb[]=new int[h]; // blue right edge colour gouraudshading

	private int ledgez[]=new int[h]; // left edge for zbuffer
	private int redgez[]=new int[h]; // right edge for zbuffer


	//------mouse & stuff
	private int mx,my,sx=20,sy=30, middenx,middeny;

	// cos/sin table
	private int maxdegrees=4096;
	private float cosi[]=new float[maxdegrees];	// cosine lookup table
	private float sine[]=new float[maxdegrees]; // sine lookup table

	private int xangle,yangle,zangle; // angles of rotation
	private int ytable[]=new int[h]; // y*width table

	private int xcub=20,ycub=400,zcub=800; // cube angles of rotation

	//---------------------
	public void init()
	{
		image = createImage(this);
		prepareImage(image, null);
		out = new int[w * h];

		middenx=w/2;
		middeny=h/2;

		// init ytable
		for (int y=0;y<h;y++ ){ ytable[y]=y*w;}

		// black backbuffer
		for (int i=0;i<(w*h);i++){black[i]=((0<<16) | (0<<8) | 0);}

		for (int i=0;i<(w*h);i++){zbufback[i]=zfar;}

		resetcube(0,0.0f,0.0f,0.0f,cubscale,cubscale,cubscale);
		resetcube(1,0.0f,0.0f,0.0f,cubscale,cubscale,cubscale);
		resetcube(2,0.0f,0.0f,0.0f,cubscale,cubscale,cubscale);

		for (int j=0;j<cubes ;j++ )
		{
			for (int i=0;i<36 ;i++ )
			{
				dp[i+(j*36)]=dporg[i]+(j*8);
			}
		}


		for (int i=0;i<points;i++)
		{
			cr[i]=Randomize(255);
			cg[i]=Randomize(255);
			cb[i]=Randomize(255);
			bor[i]=true;
			bog[i]=true;
			bob[i]=true;
		}


		for(int i=0;i<h;i++) // create clear edge buffer
		{
			ledgebuf[i]=w;  //w
			redgebuf[i]=0;  //0
		}

		// rotation object // set up cos/sin table
		for(int i=0; i<maxdegrees; i++) 
		{
			cosi[i]=(float)( Math.cos ( (float)i*360/maxdegrees * 3.14159265 / 180.0));
			sine[i]=(float)( Math.sin ( (float)i*360/maxdegrees * 3.14159265 / 180.0));
		}

		// screen stuff
		directCM = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
		tracker = new MediaTracker(this);
	}


	//---------------------
	public void run()
	{
        // set priority low so the rest won`t slow down terrible
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
		Graphics g = getGraphics();

		while(true)
		{
			// clear screen
			copyar(black, out,w,h);

			for (int i=0;i<points;i++)
			{
				if (bor[i]==true){cr[i]=cr[i]+1;}
				else { cr[i]=cr[i]-1;}
				if (cr[i]>255){cr[i]=255;bor[i]=false;}
				if (cr[i]<0){cr[i]=0;bor[i]=true;}

				if (bog[i]==true){cg[i]=cg[i]+2;}
				else { cg[i]=cg[i]-2;}
				if (cg[i]>255){cg[i]=255;bog[i]=false;}
				if (cg[i]<0){cg[i]=0;bog[i]=true;}

				if (bob[i]==true){cb[i]=cb[i]+3;}
				else { cb[i]=cb[i]-3;}
				if (cb[i]>255){cb[i]=255;bob[i]=false;}
				if (cb[i]<0){cb[i]=0;bob[i]=true;}
			}


			//start doing calculations  rotation
			xangle= xangle+(sy/4);
			yangle= yangle+((sx-sy)/4);
			zangle= zangle+(sx/4);
			if (xangle>=maxdegrees){xangle=xangle-maxdegrees;}
			if (yangle>=maxdegrees){yangle=yangle-maxdegrees;}
			if (zangle>=maxdegrees){zangle=zangle-maxdegrees;}
			if (xangle<0){xangle=maxdegrees+xangle;}
			if (yangle<0){yangle=maxdegrees+yangle;}
			if (zangle<0){zangle=maxdegrees+zangle;}

			xcub=xcub+1;
			ycub=ycub+2;
			zcub=zcub+3;
			if (xcub>=maxdegrees){xcub=xcub-maxdegrees;}
			if (ycub>=maxdegrees){ycub=ycub-maxdegrees;}
			if (zcub>=maxdegrees){zcub=zcub-maxdegrees;}
			if (xcub<0){xcub=maxdegrees+xcub;}
			if (ycub<0){ycub=maxdegrees+ycub;}
			if (zcub<0){zcub=maxdegrees+zcub;}


			copyar(zbufback, zbuf,w,h);	// clear zbuffer

			// calculate matrix
			doedemat();

			doedemat1(0,xcub,0,0);
			doedemat1(1,0,ycub,0);
			doedemat1(2,0,0,zcub);
			//doedemat1(int cube,int xrot,int yrot,int zrot);

			// calculate 3d to 2d
			calc3d2d3(0,points);

			// calc zbuffer
			for (int p=0;p<points;p++ )
			{
				zzd[p]=(int) (czd[p]*1200.0f);
			}

			zzbacksort(backsort, backzsort, dpzsort, 0,tri);
			zqsort(backzsort,dpzsort, 0, tri-1);
			zdrawhidden4(out,dpzsort,backsort,0,tri);

			//for (int p=0;p<points;p++ )
			//{
		//		point1(out,xxd[p],yyd[p], 20, 255, 255);
		//	}
			

			// draw picture...
			if(consumer != null)
			{
				consumer.setHints(2);
				consumer.setPixels(0, 0, w, h, directCM, out, 0, w);
				consumer.imageComplete(2);
			}


			g.drawImage(image, 0, 0, null);

			// fps check
			teller++;
			now=System.currentTimeMillis();
	        fpsa = (now-startTime);
			if (fpsa>1000)
			{
				showStatus("fps: "+teller + " - clean v. 0.1 - ©2001 Elout de Kok - www.xs4all.nl/~elout/");
				startTime=now;
				teller=0;
			}

			try { Thread.sleep(15); }
			catch (InterruptedException e) { }
		}
	}

	public void start()
	{
		if (runner == null);
		{ 
			runner = new Thread(this);
			runner.start();	
		}
	}

	public void stop()
	{
		if (runner != null)
		{
			runner.stop();
			runner = null;
		}
	}

	public void addConsumer(ImageConsumer imageconsumer) { }
	public boolean isConsumer(ImageConsumer imageconsumer) { return false; }
	public void removeConsumer(ImageConsumer imageconsumer) { }
	public void requestTopDownLeftRightResend(ImageConsumer imageconsumer) { }
	public void startProduction(ImageConsumer imageconsumer)
	{
		consumer = imageconsumer;
		consumer.setDimensions(w, h);
		consumer.setColorModel(directCM);
	}


	//------------------Check mouse~--------------------------------
	public synchronized boolean mouseMove(Event evt, int x, int y)
	{
		mx=x;
		my=y;
		if ( mx > middenx){sx=0-((middenx-mx)/2);}
		else{sx=((mx-middenx)/2);}
		if ( my > middeny){sy=0-((middeny-my)/2);}
		else{sy=((my-middeny)/2);}

		return true;
	}

	public synchronized  boolean mouseEnter(Event evt, int x, int y) 
	{
		requestFocus();
		showStatus("©2001 Elout de Kok - www.xs4all.nl/~elout/");

		return true;
	}
	

	public String getAppletInfo()
	{
		return ("elout@xs4all.nl");
	}

	public void destroy() {}

	//------------Randomizer--------
	private final int Randomize(int range)
	{
		double  rawResult;
		rawResult = Math.random();
		return (int) (rawResult * range);
	}

	public final void drawpoint2(int background[],int xpos, int ypos, int softr0, int softg0, int softb0)
	{
		//int offset,cr1,cg1,cb1;

		if (xpos > 0 && ypos > 0 && xpos < w && ypos < h)
		{
			background[ytable[ypos] + xpos] =  ((softr0<<16) | (softg0<<8) | softb0);
		}
	}

	//--------------------------copy arrays--------------------------------------------
	public final void copyar(int fpix1[], int fpix2[],int w,int h) // source, destination
	{	
		System.arraycopy(fpix1, 0, fpix2, 0, w*h);
	}


	//---------------------doe de Mat thing-------------------------------
	public final void doedemat()
	{
		matbasic(mat1);
		matbasic(mat2);
		matrotx(mat1,xangle);
		matroty(mat2,yangle);
		addmat(mat0,mat1,mat2);
		matcopy(mat1, mat0);
		matbasic(mat2);
		matrotz(mat2,zangle);
		addmat(mat0,mat1,mat2);
		finmat(mat0,0,points);
	}

	public final void doedemat1(int cuber,int xrot,int yrot,int zrot)
	{
		matbasic(mat1);
		matbasic(mat2);
		matrotx(mat1,xrot);
		matroty(mat2,yrot);
		addmat(mat0,mat1,mat2);
		matcopy(mat1, mat0);
		matbasic(mat2);
		matrotz(mat2,zrot);
		addmat(mat0,mat1,mat2);
		finmat1(mat0,cuber*8,(cuber*8)+8);
	}

	//---------------------Mat nothin-------------------------------
	public final void matbasic(float matrix[])
	{
		for (int i=0; i<16; i++){matrix[i]=0.0f;}
		matrix[0]=1.0f;
		matrix[5]=1.0f;
		matrix[10]=1.0f;
		matrix[15]=1.0f;
	}
	//---------------------copy Mat -------------------------------
	public final void matcopy(float matrix1[], float matrix2[])
	{
		for (int i=0; i<16; i++){matrix1[i]=matrix2[i];}
	}
	//---------------------Mat translate-------------------------------
	public final void mattranslate(float matrix[], float x, float y,float z)
	{
		matrix[3]=x;
		matrix[7]=y;
		matrix[11]=z;
	}
	//---------------------Mat scale-------------------------------
	public final void matscale(float matrix[], float x, float y,float z)
	{
		matrix[0]=x;
		matrix[5]=y;
		matrix[10]=z;
	}
	//---------------------Mat rotate X-------------------------------
	public final void matrotx(float matrix[], int rotation)
	{
		matrix[5]= cosi[rotation];
		matrix[6]= -sine[rotation];
		matrix[9]= sine[rotation];
		matrix[10]= cosi[rotation];
	}
	//---------------------Mat rotate Y-------------------------------
	public final void matroty(float matrix[], int rotation)
	{
		matrix[0]=cosi[rotation];
		matrix[2]= sine[rotation];
		matrix[8]= -sine[rotation];
		matrix[10]=cosi[rotation];
	}
	//---------------------Mat rotate Z-------------------------------
	public final void matrotz(float matrix[], int rotation)
	{
		matrix[0]= cosi[rotation];
		matrix[1]= -sine[rotation];
		matrix[4]= sine[rotation];
		matrix[5]= cosi[rotation];
	}

	public final static void addmat(float matrixf[], float matrixa[], float matrixb[])
	{
		for (int i = 0; i < 4; i++)
		{
			float a0 = matrixa[i];
			float a1 = matrixa[i+4];
			float a2 = matrixa[i+8];
			float a3 = matrixa[i+12];
			matrixf[i] = a0 * matrixb[0] + a1 * matrixb[1] + a2 * matrixb[2] + a3 * matrixb[3];
			matrixf[i+4] = a0 * matrixb[4] + a1 * matrixb[5] + a2 * matrixb[6] + a3 * matrixb[7];
			matrixf[i+8] = a0 * matrixb[8] + a1 * matrixb[9] + a2 * matrixb[10] + a3 * matrixb[11];
			matrixf[i+12] = a0 * matrixb[12] + a1 * matrixb[13] + a2 * matrixb[14] + a3 * matrixb[15];
         }
	}

	//---------------------fin mat-------------------------------
	public final void finmat(float matrix[], int start, int number)
	{
		float xo,yo,zo;
		for (int i=start; i<number; i++)
		{
			xo=xd[i];
			yo=yd[i];
			zo=zd[i];
			cxd[i]=xo*matrix[0]+yo*matrix[1]+zo*matrix[2]+matrix[3];
			cyd[i]=xo*matrix[4]+yo*matrix[5]+zo*matrix[6]+matrix[7];
			czd[i]=xo*matrix[8]+yo*matrix[9]+zo*matrix[10]+matrix[11];
		}
	}
	//---------------------fin mat-------------------------------
	public final void finmat1(float matrix[], int start, int number)
	{
		float xo,yo,zo;
		for (int i=start; i<number; i++)
		{
			xo=cxd[i];
			yo=cyd[i];
			zo=czd[i];
			cxd[i]=xo*matrix[0]+yo*matrix[1]+zo*matrix[2]+matrix[3];
			cyd[i]=xo*matrix[4]+yo*matrix[5]+zo*matrix[6]+matrix[7];
			czd[i]=xo*matrix[8]+yo*matrix[9]+zo*matrix[10]+matrix[11];
		}
	}

	public void calc3d2d3(int start, int tot)
	{
		for (int i=start; i<tot; i++)
		{
			//xxd[i]=(int) (cxd[i]*(1.0f/(2.5f+czd[i]))*middeny+middenx);
			//yyd[i]=(int) (cyd[i]*(1.0f/(2.5f+czd[i]))*middeny+middeny);

			xxd[i]=(int) (cxd[i]*(5.0/(scale2+czd[i]))*middeny+middenx);
			yyd[i]=(int) (cyd[i]*(5.0/(scale2+czd[i]))*middeny+middeny);

		}
	}

	//----draw point--------------------------
	public void point1(int dimage[],int xpoint,int ypoint, int r, int g, int b)
	{
		if (xpoint>=0 && ypoint>=0 && xpoint<w && ypoint<h)
		{
			dimage[ ytable[ypoint] + xpoint ] = ((r<<16) | (g<<8) | b);
		}
	}

	//---------------------------------
	public void scanedgegou(int x1,int y1,int z1,int x2,int y2,int z2,int r1,int g1,int b1,int r2,int g2,int b2)
	{
		int mx,mc; // slopes of x and color
		int mcg; // slopes of x and color
		int mcb; // slopes of x and color
		int mz; // slopes z
		int temp; // for swapping
		int x,y,r,g,b,z; // source x and y screen coordinates, and color (all in 16.16)
		int tempx;

		// make sure that edge goes from top to bottom
		if(y1 > y2)
		{
			temp=x1;
			x1=x2;
			x2=temp;
			temp=y1;
			y1=y2;
			y2=temp;
			temp=z1;
			z1=z2;
			z2=temp;
			temp=r1;
			r1=r2;
			r2=temp;
			temp=g1;
			g1=g2;
			g2=temp;
			temp=b1;
			b1=b2;
			b2=temp;
		}

		// initialize the slopes for stepping the edges
		if((y2-y1) != 0)
		{
			mx = ((x2-x1) << 16) / (y2-y1); // dx/dy
			mc =  ((r2-r1) << 16) / (y2-y1); // dc/dy
			mcg = ((g2-g1) << 16) / (y2-y1); // dc/dy
			mcb = ((b2-b1) << 16) / (y2-y1); // dc/dy
			mz = ((z2-z1) << 16) / (y2-y1); // dc/dy
		}
		else
		{
			mx = ((x2-x1) << 16); // dx
			mc =  ((r2-r1) << 16); // dc
			mcg = ((g2-g1) << 16); // dc
			mcb = ((b2-b1) << 16); // dc
			mz = ((z2-z1) << 16); // dc
		}

		// initialize first coordinates
		x=x1<<16;
		r=r1<<16;
		g=g1<<16;
		b=b1<<16;
		z=z1<<16;

		// step through edge and record coordinates along the way
		for(y=y1;y<y2;y++)
		{
		// update left edge information

			if( y>=0 && y<h)
			{
				if( ((x>>16)<ledge[y]) && (ledge[y]>=0))
				{
					ledge[y]=(x>>16);
					ledgecolr[y]=(r>>16);
					ledgecolg[y]=(g>>16);
					ledgecolb[y]=(b>>16);
					ledgez[y]=(z>>16);
				}

				if( ((x>>16)>redge[y]) && (redge[y]<w))
				{
					redge[y]=(x>>16);
					redgecolr[y]=(r>>16);
					redgecolg[y]=(g>>16);
					redgecolb[y]=(b>>16);
					redgez[y]=(z>>16);
				}
			}
			// increment the coordinates by their respective slopes
			x+=mx;
			r+=mc;
			g+=mcg;
			b+=mcb;
			z+=mz;
		}
	}
	//-------------------------
	public void scanlinegou(int dimage[])
	{
		int ky,kx,numz;
		int sizler=w*h;

		int dc,dcg,dcb,dz;
		int mc,mcg,mcb,mz;
		int cr1,cg1,cb1,cz1;

		for (ky=0;ky<h ;ky++)
		{
			if (redge[ky]!=0)
			{
				// find the slope of the color
				if( (redge[ky] - ledge[ky]) != 0)
				{
					mc =  ((redgecolr[ky] - ledgecolr[ky]) << 16) /(redge[ky] - ledge[ky]);
					mcg = ((redgecolg[ky] - ledgecolg[ky]) << 16) /(redge[ky] - ledge[ky]);
					mcb = ((redgecolb[ky] - ledgecolb[ky]) << 16) /(redge[ky] - ledge[ky]);
					mz =  ((redgez[ky] - ledgez[ky]) << 16) /(redge[ky] - ledge[ky]);
				}
				else
				{
					mc =  (redgecolr[ky] - ledgecolr[ky])<<16;
					mcg = (redgecolg[ky] - ledgecolg[ky])<<16;
					mcb = (redgecolb[ky] - ledgecolb[ky])<<16;
					mz = (redgez[ky] - ledgez[ky])<<16;
				}
				// initialize color
				dc=ledgecolr[ky]<<16;
				dcg=ledgecolg[ky]<<16;
				dcb=ledgecolb[ky]<<16;
				dz=ledgez[ky]<<16;

				for (kx=ledge[ky];kx<=redge[ky] ;kx++ )
				{	
					cr1=(dc>>16);
					cg1=(dcg>>16);
					cb1=(dcb>>16);
					cz1=(dz>>16);
					numz=ytable[ky] + kx;
					if (numz<sizler)
					{
						if (cz1<zbuf[numz]) // check if zbuffer within range
						{
							zbuf[numz]=cz1;
							dimage[numz] = ((cr1<<16) | (cg1<<8) | cb1);
						}
					}
					dc+=mc;
					dcg+=mcg;
					dcb+=mcb;
					dz+=mz;
				}
			}
		}
	}


	public void resetcube(int cub,float xs,float ys,float zs,float scalex,float scaley,float scalez)
	{
		cub=cub*8;	
		xd[cub+0]=(-1.0f+xs)*scalex;
		yd[cub+0]=(1.0f+ys)*scaley;
		zd[cub+0]=(-1.0f+zs)*scalez;

		xd[cub+1]=(-1.0f+xs)*scalex;
		yd[cub+1]=(-1.0f+ys)*scaley;
		zd[cub+1]=(-1.0f+zs)*scalez;

		xd[cub+2]=(1.0f+xs)*scalex;
		yd[cub+2]=(-1.0f+ys)*scaley;
		zd[cub+2]=(-1.0f+zs)*scalez;

		xd[cub+3]=(1.0f+xs)*scalex;
		yd[cub+3]=(1.0f+ys)*scaley;
		zd[cub+3]=(-1.0f+zs)*scalez;

		xd[cub+4]=(-1.0f+xs)*scalex;
		yd[cub+4]=(1.0f+ys)*scaley;
		zd[cub+4]=(1.0f+zs)*scalez;

		xd[cub+5]=(-1.0f+xs)*scalex;
		yd[cub+5]=(-1.0f+ys)*scaley;
		zd[cub+5]=(1.0f+zs)*scalez;

		xd[cub+6]=(1.0f+xs)*scalex;
		yd[cub+6]=(-1.0f+ys)*scaley;
		zd[cub+6]=(1.0f+zs)*scalez;

		xd[cub+7]=(1.0f+xs)*scalex;
		yd[cub+7]=(1.0f+ys)*scaley;
		zd[cub+7]=(1.0f+zs)*scalez;
	}
	///-------------------zdepth check
	public void zzbacksort(float sort[],float sort2[],int sort3[],int start, int tot)
	{		//  zzbacksort(backsort, backzsort, dpzsort, 0,tri);
		int p1,p2,p3;
		float ax,ay,bx,by,cx,cy;

		for (int i=start; i<tot; i++)
		{
			p1=dp[(i*3)];
			p2=dp[(i*3)+1];
			p3=dp[(i*3)+2];
			sort2[i]=(float) (czd[p1]+czd[p3])/(-2.0f); // calculate z of triangle (painters)
			sort3[i]=i;
			ax=cxd[p1];
			ay=cyd[p1];
			bx=cxd[p2];
			by=cyd[p2];
			cx=cxd[p3];
			cy=cyd[p3];
			sort[i]=((bx-ax)*(cy-ay)-(by-ay)*(cx-ax));
		}
	}
	//---------------quicksort..
	public void zqsort(float sort[], int sort2[],int low, int high)
	{		//	zqsort(backzsort,dpzsort, 0, tri-1);
		int tomp;
		float temp;
		int i = low;
		int j = high;
		float x;

		if (high > low)
		{
			x = (float) sort[(low+high) / 2];;
			do
			{
				while (sort[i] < x) i++;
				while (sort[j] > x) j--;
				if ( i<=j )
				{
					tomp=sort2[i];
					sort2[i]=sort2[j];
					sort2[j]=tomp;
					temp=sort[i];
					sort[i]=sort[j];
					sort[j]=temp;
					i++;
					j--;
				}
			} 
			while (i <= j);
		    if (low < j)  zqsort(sort, sort2, low, j);
			if (i < high )  zqsort(sort, sort2, i, high);
		}
	}
	//---------------------gourard shading--
	public void zdrawhidden4(int dimage[], int sort[],float sort2[],int start, int tot)
	{		//  zdrawhidden3(out,dpzsort,backsort,0,tri);
		int p1,p2,p3,cor,cog,cob,dope;

		for (int i=start; i<tot; i++)
		{	
			dope=sort[i];
			if (sort2[dope]<0.2){	}// dont draw then
			else
			{
				p1=dp[(dope*3)];
				p2=dp[(dope*3)+1];
				p3=dp[(dope*3)+2];

				copyar(ledgebuf, ledge,1,h); // clear edge buffer
				copyar(redgebuf, redge,1,h);

				scanedgegou(xxd[p1],yyd[p1],zzd[p1],xxd[p2],yyd[p2],zzd[p2], cr[p1],cg[p1],cb[p1],cr[p2],cg[p2],cb[p2]);
				scanedgegou(xxd[p1],yyd[p1],zzd[p1],xxd[p3],yyd[p3],zzd[p3], cr[p1],cg[p1],cb[p1],cr[p3],cg[p3],cb[p3]);
				scanedgegou(xxd[p3],yyd[p3],zzd[p3],xxd[p2],yyd[p2],zzd[p2], cr[p3],cg[p3],cb[p3],cr[p2],cg[p2],cb[p2]);
					
				for (int ot=0;ot<h ;ot++ )
				{
					if (ledge[ot]<0){ledge[ot]=0;}
					if (redge[ot]<0){redge[ot]=0;}
					if (ledge[ot]>w){ledge[ot]=w-1;}
					if (redge[ot]>w){redge[ot]=w-1;}
				}
				scanlinegou(dimage);
			}
		}
	}

//-----------------------------------------
} // end



