
#define		ZCLIP		40

/************************************************************************

		<< TEST GAME >>		++ 3D draw screen ++

 ************************************************************************/

#include	<stdio.h>
#include	<string.h>
#include	<ctype.h>
#include	<math.h>

#include 	"ToolBox.h"
#include 	"map.h"
#include 	"External.h"
#include 	"Prototype.h"
#include 	"WindowSize.h"


int		POLYGON;

/************************************************************************
		Rc[`p̃[N
 ************************************************************************/

typedef	struct	anode	{

	struct	anode	*next;			/* \Ǘp̑oXg|C^		*/
	struct	anode	*prev;
	GroundInfo		*map;			/* }bvf[^ւ̃|C^				*/
	double			rotateX;		/* [h[eV̍Wl	*/
	double			rotateY;
	double			rotateZ;
	double			angleX;			/*  map Ăpxf[^		*/
	double			angleY;
	double			angleZ;
W	double			sortZ;			/* \[gp	*/

}	MAPLIST;

/************************************************************************
		s̃p[^
 ************************************************************************/

#define	M11		0				
#define	M12		1
#define	M13		2
#define	M21		3
#define	M22		4
#define	M23		5
#define	M31		6
#define	M32		7
#define	M33		8

/************************************************************************
		Rc[`p̃[N
 ************************************************************************/

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
#define	maplistmax	256							/* `惊Xgől					*/
DRAWPACK			GameDraw;					/* `p[^					*/
MAPLIST  			MapList[maplistmax];		/* }bvXgf[^				*/
double				CameraMatrix[10];			/* J̉]s					*/
double				ObjectMatrix[10];			/* IuWFNg̉]s			*/
double				RotateMatrix[10];			/* ]s							*/
double				LightMatrix[3];				/* xNg쐬					*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
#define	MAXPoint	512							/* VFCṽ|Cgő吔			*/
#define	MAXFace		256							/* VFCṽtFCXő吔			*/
ShapePoints			shapepoint[MAXPoint];		/* {fB[Wñ|Cgf[^	*/
RotatePoints		rotatepoint[MAXPoint];		/* ϊ̃|Cgf[^		*/
DisplayPoints		displaypoint[MAXPoint];		/* ϊ̃|Cgf[^		*/
int					overflag[MAXPoint];
int					vizflag[MAXFace];

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/


/************************************************************************
		ʕ`惁C[`
 ************************************************************************/

extern	void	DrawScreen(camera,drawlist)
CameraInfo	*camera;
DrawList	*drawlist;
{

	MAPLIST		*maplist;
	DRAWPACK	*draw;
	double		unitZ;

	draw = &GameDraw;
	News3DdrawInit(draw,camera);		/* `p[^̏ݒ			*/

#if	1

	MakeCameraMatrix(draw);				/* [h[e[V			*/
	MakeLightMatrix(draw);				/* CgxNgvZ				*/

	UnitRotate(draw,&unitZ);			/* n{tmhs̉]vZ		*/

	MakeMapList(draw,MapList,drawlist,&unitZ);	
										/* }bvXg쐬				*/
										/* ( SW̉]Ɠo^ )			*/
	MapZsort(MapList);					/* 	SŴysort				*/

	POLYGON = 0;
	maplist = MapList[0].next;


	while( maplist != MapList ){
		MakeObjMatrix(draw,maplist);	/* OBJECT-ROTATION ̌vZ			*/
		ReadPoint(draw,maplist);		/* |Cgf[^̓ǂݍݓo^		*/
		Rotation(draw,maplist);			/* |Cgf[^̉]ϊ			*/
		rojection(draw);				/* |Cgf[^̓ϊ			*/
		MakeVIZtable(draw,maplist);		/* VIZtable̍쐬					*/
		DrawPolygon(draw,maplist);		/* |SDRAW					*/	
		maplist = maplist->next;
	}

#endif	


}

/************************************************************************
		eXgtB
 ************************************************************************/

TestFill(draw)
DRAWPACK	*draw;
{
	int		toptotal = 4;
	XPoint			fillpoint[20];			/* |Cg	*/

	fillpoint[0].x = 0;
	fillpoint[0].y = 0;
	fillpoint[1].x = 120;
	fillpoint[1].y = 0;
	fillpoint[2].x = 120;
	fillpoint[2].y = 120;
	fillpoint[3].x = 0;
	fillpoint[3].y = 120;

	for(POLYGON=0;POLYGON<1000;POLYGON++){
		XSetForeground(display,draw->gc,15);
		XFillPolygon  (display,draw->pixmap,draw->gc,fillpoint,toptotal,Convex,CoordModeOrigin);
	}
}

/************************************************************************
		\p}bvXgւ̘A
 ************************************************************************/

int	MAPCOUNT;

MakeMapList(draw,maplist,drawlist,unitZ)
DRAWPACK	*draw;
MAPLIST		*maplist;
DrawList	*drawlist;
double		*unitZ;
{
	MAPLIST	*root = maplist;		/* vfO[g|C^Ƃ	*/
	ObjectPtr	object;
	double	rx,ry,rz;				/* S_̌vZ	*/

	root->next = maplist+1;			/* [g̏ݒ				*/
	root->prev = root;
	maplist++;						/* f[^͂PX^[g	*/

	MAPCOUNT = 0;

	while(	drawlist->ground != NULL ){
		object = (ObjectPtr)(drawlist->ground);
		if	(CenterRot(draw,drawlist->ground,&rx,&ry,&rz) == TRUE){

			maplist->map  = drawlist->ground;
			maplist->next = maplist+1;
			maplist->prev = maplist-1;
			maplist->rotateX = rx;	/* ]̍W̒S	x,y,z	*/
			maplist->rotateY = ry;
			maplist->rotateZ = rz;
									/* yŃ\[gƂ̒l ((y)) */
			switch (maplist->map->flags){
				case	SHAPE_GROUND:
					maplist->angleX = 0;
					maplist->angleY = 0;
					maplist->angleZ = 0;
					break;
				case	SHAPE_OBJECT:
					maplist->angleX =(float)(object->angleX);
					maplist->angleY =(float)(object->angleY);
					maplist->angleZ =(float)(object->angleZ);
					break;
			}
			

			if (maplist->map->shape->radius >= 0x400){
				maplist->sortZ = rz + *unitZ;
			} else {
				maplist->sortZ = rz;
			}

			maplist++;
		}

		drawlist++;
		MAPCOUNT++;
	}

	(maplist-1)->next = root;		/* I̓[g֕Ԃ	*/

}

/************************************************************************
		S_̉]sȂ 
 ************************************************************************/

CenterRot(draw,map,rx,ry,rz)
DRAWPACK	*draw;
GroundInfo	*map;
double		*rx,*ry,*rz;
{
	double		*matrixP = draw->worldmatrix;		/* J]s		*/
	double		px,py,pz;
	ObjectInfo	*object = (ObjectPtr)map;

	switch (map->flags){
		case	SHAPE_GROUND:
			px = (map->posX)*mapzoom-(draw->wx);
			py = 0-(draw->wy);
			pz = (map->posZ)*mapzoom-(draw->wz);
			break;
		case	SHAPE_OBJECT:
			px = (object->positionX)-(draw->wx);
			py = (object->positionY)-(draw->wy);
			pz = (object->positionZ)-(draw->wz);
			break;
	}
												/* _J	*/
	*rx = (px * *(matrixP+M11)+py * *(matrixP+M21)+pz * *(matrixP+M31))+(draw->cx);	
	*ry = (px * *(matrixP+M12)+py * *(matrixP+M22)+pz * *(matrixP+M32))+(draw->cy);	
	*rz = (px * *(matrixP+M13)+py * *(matrixP+M23)+pz * *(matrixP+M33))+(draw->cz);	

	/* printf("*** %lf ***\n",*rz); */

	if ( *rz < -128*mapzoom  )	return(FALSE);	/* VFCvaȏ͌̕Ȃ	*/
	if ( *rz > 0x180*mapzoom )	return(FALSE);	/* ̂͌Ȃ				*/
												/* PGAzp[c͌Ȃ	*/
	return(TRUE);

}

/************************************************************************
		Z̒lɂD揇ʃ\[g(S_ɂP\[g)
************************************************************************/

MapZsort(root)
MAPLIST		*root;
{

	MAPLIST		*pwork,*pnext;			/* }bvXgւ̃|C^	*/
	int			sortflag;
	double		r1,r2;

	sortflag = 1;
	while (sortflag){
		sortflag = 0;					/* 	ȂΏI	*/
		pwork = root -> next;
		while ( (pnext = pwork->next) != root ){
				r1 = pwork -> sortZ;
				r2 = pnext -> sortZ;
			if ( r1 < r2 ){
										/* |C^̂Ȃ	*/
				(pwork -> prev)->next 	= pnext;
				(pnext -> next)->prev 	= pwork;
				pnext -> prev 			= pwork -> prev;
				pwork -> prev 			= pnext; 
				pwork -> next 			= pnext -> next;
				pnext -> next 			= pwork;
				sortflag = 1;			/* tO	*/
			} else {
				pwork = pnext;			/* |C^i߂			*/
			}
		}
	}
}


/************************************************************************
 		]s
************************************************************************/
MakeObjMatrix(draw,maplist)
DRAWPACK	*draw;
MAPLIST		*maplist;
{
	double	ax,ay,az;
	double	pai = 3.141592;

	switch	(maplist->map->flags){
		case	SHAPE_GROUND:
			break;
		case	SHAPE_OBJECT:
			ax = (draw->ax)/AngleParam*2*pai;
			ay = (draw->ay)/AngleParam*2*pai;
			az = (draw->az)/AngleParam*2*pai;
			Make3DMatrix(ObjectMatrix,ax,ay,az);
			CalcMatrix(RotateMatrix,ObjectMatrix,CameraMatrix);
			draw->worldmatrix = RotateMatrix;
			break;
	}



}

/************************************************************************
		|Cgf[^̓ǂݍ
		VFCv char^ 	ROM-DATA 	ǂݍ
				   double^	RAM-BUFFER	֓o^
 ************************************************************************/

ReadPoint(draw,maplist)
DRAWPACK	*draw;
MAPLIST		*maplist;
{

	ShapePoints	*shapeP 	= draw->shapeP;					/* |Cgf[^i[AhX		*/
	PointData	*pointP 	= maplist->map->shape->point;	/* VFCṽ|Cgf[^ւ̃|C^	*/
	int			pointtotal 	= maplist->map->shape->npoints;	/* |Cg̑						*/
	int			x,y,z;

	draw->pointtotal = pointtotal;			/* |Cg̑								*/

	while(pointtotal--){
		shapeP->shapeX = pointP->pointX;
		shapeP->shapeY = pointP->pointY;
		shapeP->shapeZ = pointP->pointZ;
		shapeP++;
		pointP++;
	}

}


/************************************************************************
		]ϊsȂ
 ************************************************************************/

Rotation(draw,maplist)
DRAWPACK	*draw;
MAPLIST		*maplist;
{
	double			*matrixP;						/* ]ϊ}gNX̃|C^	*/
	ShapePoints		*shapeP;						/* ϊO̍\̂ւ̃|C^			*/
	RotatePoints	*rotateP;						/* ϊ̍\̂ւ̃|C^			*/
	int				*overflagP;						/* ỹI[o[t[ւ̃|C^	*/
	int				total = draw->pointtotal;		/* |Cg̃g[^					*/
	int				scale = draw->scale;			/* VFCv̑傫						*/
	double			cx = maplist->rotateX;			/* [hWSl					*/
	double			cy = maplist->rotateY;			/* [hWSl					*/
	double			cz = maplist->rotateZ;			/* [hWSl					*/

	double			px,py,pz;						/* VFCṽ{fBW					*/

	matrixP	 	= draw->worldmatrix;				/* J]s						*/
	shapeP		= draw->shapeP;						/* bodyW̃|Cgf[^				*/
	rotateP 	= draw->rotateP;					/* worldrotation|Cgf[^		*/
	overflagP	= draw->overflagP;					/* ỹI[o[t[flag			*/

	scale	= 1;

	while( total-- ){

		px = (shapeP->shapeX);
		py = (shapeP->shapeY);
		pz = (shapeP->shapeZ);

		rotateP -> rotateX = (px * *(matrixP+M11)
			  			     +py * *(matrixP+M21)
						     +pz * *(matrixP+M31))*scale
					  	     + cx;	/* [h]̒S̒l(w) */
		rotateP -> rotateY = (px * *(matrixP+M12)
						     +py * *(matrixP+M22)
					  	     +pz * *(matrixP+M32))*scale
					  	     + cy;	/* [h]̒S̒l(x)	*/
		rotateP -> rotateZ  =(px * *(matrixP+M13)
					  	     +py * *(matrixP+M23)
					  	     +pz * *(matrixP+M33))*scale
					  	     + cz;	/* [h]̒S̒l(y)	*/
		if ( rotateP->rotateZ > ZCLIP )	*overflagP = 0;
		else 							*overflagP = 1;

		*overflagP++;
		*rotateP++;
		*shapeP++;

		/* printf ("%lf,%lf,%lf\n",rotateP->rotateX,rotateP->rotateY,rotateP->rotateZ); */

	}



}

/************************************************************************

 ************************************************************************/
#define		ZOOMCAMERA	512.0

Projection(draw)
DRAWPACK	*draw;
{

	RotatePoints	*rotateP;
	DisplayPoints	*displayP;
	int				total 		= draw->pointtotal;
	double			displayCX	= draw->dispCY;
	double			displayCY	= draw->dispCY;

	rotateP 	= draw->rotateP;
	displayP 	= draw->displayP;

	while ( total-- ){

		if (rotateP -> rotateZ == 0.0){
			rotateP -> rotateZ = 1;
		}

		displayP -> displayX = rotateP -> rotateX/(rotateP -> rotateZ)*ZOOMCAMERA 	 + displayCX;
		displayP -> displayY = -(rotateP -> rotateY/(rotateP -> rotateZ)*ZOOMCAMERA) + displayCY;

		*displayP++;
		*rotateP++;

		}

}

/**************	Zclip p-c ϊ ***************/

ZclipProjection(draw,rx,ry,rz,displayP)
DRAWPACK		*draw;
double			rx,ry,rz;
DisplayPoints	*displayP;
{
	double	displayCX	= draw->dispCY;
	double	displayCY	= draw->dispCY;
	displayP -> displayX =  rx/rz * ZOOMCAMERA  + displayCX;
	displayP -> displayY = -ry/rz * ZOOMCAMERA  + displayCY;
}

/************************************************************************
		uhye[u쐬
 ************************************************************************/

MakeVIZtable(draw,maplist)
DRAWPACK	*draw;
MAPLIST		*maplist;
{

	DisplayPoints	*displayP;			/* ϊ̍Wl				*/
	FaceData		*faceP;				/* tFCXf[^(ROM)̃|C^	*/
	int				facect;				/* tFCX̌					*/
	int				*viztableP;			/* VIZ tablẽ|C^				*/
	int				x1,x2,x3,y1,y2,y3;	/* OόvZp	*/
	int				i;
	int				toptotal;
	int				facetotal 	= maplist->map->shape->nfaces;
	double			displayCX	= draw->dispCY;
	double			displayCY	= draw->dispCY;


	viztableP	= vizflag;
	displayP 	= draw->displayP;				/* projection |Cgf[^	*/
	faceP 		= maplist->map->shape->face;	/* tFCXf[^̃|C^			*/

	for (facect=0;facect<facetotal;facect++){
		toptotal = faceP->nvertexes;	/* _̐	*/
		if(toptotal<3){
			*viztableP++ = 1;
		} else {
			x1 = (displayP + (faceP->points[0]) ) -> displayX;
			y1 = (displayP + (faceP->points[0]) ) -> displayY;
			x2 = (displayP + (faceP->points[1]) ) -> displayX;
			y2 = (displayP + (faceP->points[1]) ) -> displayY;
			x3 = (displayP + (faceP->points[2]) ) -> displayX;
			y3 = (displayP + (faceP->points[2]) ) -> displayY;
			*viztableP++ =  (( x2 - x1 ) * ( y3 - y2 ))  -  (( y2 - y1 ) * ( x3 - x2 ));
		}
		faceP++;
	}


}

/************************************************************************
	|Scq`v
	(ʖʑ̐p̂cq`v[`)
	(BSPp̂cq`v)
 ************************************************************************/

DisplayPoints		Zclipdisplay[30];	/* ϊ̃|Cgf[^		*/

DrawPolygon(draw,maplist)
DRAWPACK	*draw;
MAPLIST		*maplist;
{

	DisplayPoints	*displayP;
	RotatePoints	*rotateP;
	XPoint			fillpoint[20];			/* |Cg							*/
	FaceData		*faceP;				/* tFCXf[^̃|C^			*/
	int				facetotal;			/* tFCX̃g[^				*/
	int				toptotal;			/* _̐							*/
	int				color;				/* tFCX(|S)̐F			*/
	double			nx,ny,nz;			/* m[}xNg					*/	
	int				facect,topct,i;
	int				facepoint[50];		/* tFCX\|Cgԍ	*/
	double			clipX,clipY;
	int				Lcolor;				/* 16iK̃Cg\[XR[h		*/
	double			*lightP;
	int				*viztableP;

	int				flag,flag2;

	facetotal	= maplist->map->shape->nfaces;		/* tFCX̃g[^				*/
	faceP 		= maplist->map->shape->face;		/* tFCXf[^̃|C^			*/
	rotateP		= draw->rotateP;
	displayP 	= draw->displayP;					/* projection |Cgf[^	*/
	lightP 		= draw->lightvector;				/* xNgւ̃|C^			*/
	viztableP	= vizflag;

	for (facect=0;facect<facetotal;facect++){

		toptotal = faceP->nvertexes;	/* _̐			*/
		color	 = faceP->color;		/* tFCX̐F		*/
		nx		 = faceP->planeA;		/* @xNg		*/
		ny		 = faceP->planeB;
		nz		 = faceP->planeC;

		if (toptotal<3){
			DrawLine();
		} else {

		/*===== ZւClippingKvǂ`FbN =======*/

			flag = 0;
			flag2 = 0;
			for(i=0;i<toptotal;i++){
				flag = flag+overflag[(faceP->points[i])];
			}
			if (flag!=0){
				if (flag==toptotal)	goto nextface;	/* ׂĂ̓_ overĂNbvȂ */

				toptotal = EntryZclip(draw,faceP,toptotal,facect);	/* ZclipsȂ */
				for	(i=0;i<toptotal;i++){
					clipX = Zclipdisplay[i].displayX;
					clipY = Zclipdisplay[i].displayY;
					   if ( (clipX<-30000) || (30000<clipX) ) flag2=1;
					/* if (clipX<-30000)	clipX = -30000;	*/
					/* if (clipX>30000) 	clipX =  30000;	*/
					fillpoint[i].x = clipX;
					fillpoint[i].y = clipY;
				}
			} else {
				for	(i=0;i<toptotal;i++){
					clipX = (displayP + (faceP->points[i]) ) -> displayX;
					clipY = (displayP + (faceP->points[i]) ) -> displayY;
					   if ( (clipX<-30000) || (30000<clipX) ) flag2=1; 
					/* if (clipX<-30000)	clipX = -30000; 			*/
					/* if (clipX>30000) 	clipX =  30000; 			*/
					fillpoint[i].x = clipX;
					fillpoint[i].y = clipY;
				}
			}


			if (flag2==1){
				/* printf("ϊI[o[t[܂B\n");	*/
				goto	nextface;	/* ϊI[o[t[ */
			} else {
				if (viztableP[facect]>=0){
					Lcolor = (nx*lightP[0]+ny*lightP[1]+nz*lightP[2])*-16;
					if (Lcolor <  0) Lcolor = 0;
					if (Lcolor > 15) Lcolor = 15;

					color = CalcColor(color,Lcolor,0);				/* Cg\[XvZ	*/
#if	1
					XSetForeground(display,draw->gc,color);	
					XFillPolygon  (display,draw->pixmap,draw->gc,fillpoint,toptotal,Convex,CoordModeOrigin);
#endif
					POLYGON++;
				}	/* tFCX\̕		*/

			}		/* ϊ~X`FbN		*/
		} 			/* Cƃ|S̕	*/
	nextface:
	faceP++;
	}				/* tFCX[v			*/

}

/************************************************************************
	yւ̃NbsO
 ************************************************************************/


EntryZclip(draw,faceP,toptotal,ct)
DRAWPACK		*draw;
FaceData		*faceP;				/* tFCXf[^̃|C^			*/
int				toptotal;			/* _̐							*/
int				ct;					/* ݃tFCXԍ					*/
{

	RotatePoints	*rotateP		= draw->rotateP;
	DisplayPoints	*displayP		= draw->displayP;
	int				clipvertex;		/* Zclip̒_	*/
	int				i,j;
	int				work;
	double			x1,y1,z1,x2,y2,z2,x3,y3,z3;
	double			cx,cy;				/* ZNbvꂽrotateW */

	clipvertex = 0;

	/*-------------	̒_Ƃ̃`FbN(ӂ̃NbsO) -------------------*/

	for(i=0;i<toptotal;i++){

		if	(i != toptotal-1)	j = i+1;
		else					j = 0;
		work = overflag[(faceP->points[i])]+overflag[(faceP->points[j])];
	
		switch(work){
		case 0:
			Zclipdisplay[clipvertex].displayX = (displayP + (faceP->points[i]) ) -> displayX;
			Zclipdisplay[clipvertex].displayY = (displayP + (faceP->points[i]) ) -> displayY;
			clipvertex++;
			break;
		case 1:

			if (overflag[(faceP->points[i])]==1){	/* Jn_łyNbv	*/

				x1 = (rotateP + (faceP->points[i])) ->rotateX;
				y1 = (rotateP + (faceP->points[i])) ->rotateY;
				z1 = (rotateP + (faceP->points[i])) ->rotateZ;
				x2 = (rotateP + (faceP->points[j])) ->rotateX;
				y2 = (rotateP + (faceP->points[j])) ->rotateY;
				z2 = (rotateP + (faceP->points[j])) ->rotateZ;
				if (z1 == z2) break;
				cx = ((x2-x1)/(z2-z1))*(ZCLIP-z1)+x1;
				cy = ((y2-y1)/(z2-z1))*(ZCLIP-z1)+y1;

				ZclipProjection(draw,cx,cy,(double)ZCLIP,Zclipdisplay+clipvertex);
				clipvertex++;

			} else {								/* I_łyNbv	*/

				x1 = (rotateP + (faceP->points[i])) ->rotateX;
				y1 = (rotateP + (faceP->points[i])) ->rotateY;
				z1 = (rotateP + (faceP->points[i])) ->rotateZ;
				x2 = (rotateP + (faceP->points[j])) ->rotateX;
				y2 = (rotateP + (faceP->points[j])) ->rotateY;
				z2 = (rotateP + (faceP->points[j])) ->rotateZ;
				if (z1 == z2) break;
				cx = ((x2-x1)/(z2-z1))*(ZCLIP-z1)+x1;
				cy = ((y2-y1)/(z2-z1))*(ZCLIP-z1)+y1;

				Zclipdisplay[clipvertex].displayX = (displayP + (faceP->points[i]) ) -> displayX;
				Zclipdisplay[clipvertex].displayY = (displayP + (faceP->points[i]) ) -> displayY;
				clipvertex++;
				ZclipProjection(draw,cx,cy,(double)ZCLIP,Zclipdisplay+clipvertex);
				clipvertex++;

			}
			
			break;
		default:
			break;
		}

	}


	/* VIZ XgČvZ	*/

	x1 = Zclipdisplay[0].displayX;
	y1 = Zclipdisplay[0].displayY;
	x2 = Zclipdisplay[1].displayX;
	y2 = Zclipdisplay[1].displayY;
	x3 = Zclipdisplay[2].displayX;
	y3 = Zclipdisplay[2].displayY;

	vizflag[ct] =  (( x2 - x1 ) * ( y3 - y2 ))  -  (( y2 - y1 ) * ( x3 - x2 ));

#if	0
	printf ("_ %d łB\n",clipvertex);
	for (i=0;i<clipvertex;i++){
		printf ("<< %d >>,<%lf>,<%lf>\n",i,Zclipdisplay[i].displayX,Zclipdisplay[i].displayY);
	}
#endif

	return(clipvertex);

}



/************************************************************************
	khmd̂cq`v
 ************************************************************************/
DrawLine()
{
	int	i;
	i = 0;

}

/*======================================================================*/
/*======================================================================*/
/*					RcvZCu									*/
/*======================================================================*/
/*======================================================================*/

/************************************************************************
		{jbg(naf)̍W]vZ
 ************************************************************************/
static	double	unitp[] = { -1056,-1056, 1056,-1056, -1056, 1056, 1056, 1056 };
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

UnitRotate(draw,unitZ)
DRAWPACK	*draw;
double		*unitZ;		/* worldrot̍łyWl	*/
{
	double	*p		 = unitp;					/* nUNITtextyl	*/
	double	*matrixP = draw->worldmatrix;		/* J]s		*/
	double	cz[4];
	int	i;
	*unitZ = 0;									/* ł_̂yl	*/

	for(i=0;i<4;i++){
		cz[i] = (p[i*2+0] * *(matrixP+M13) + p[i*2+1] * *(matrixP+M33));
		if	( *unitZ < cz[i] ) *unitZ = cz[i];
	}

}

/************************************************************************
		J̉]s쐬
 ************************************************************************/
MakeCameraMatrix(draw)
DRAWPACK	*draw;
{
	double	ax,ay,az;
	double	pai = 3.141592;
	ax = (draw->ax)/AngleParam*2*pai;
	ay = (draw->ay)/AngleParam*2*pai;
	az = (draw->az)/AngleParam*2*pai;
	Make3DMatrix(draw->worldmatrix,ax,ay,az);
}
/************************************************************************
		Cg̉]s쐬
 ************************************************************************/
MakeLightMatrix(draw)
DRAWPACK	*draw;
{
	double		lx = draw->lx;
	double		ly = draw->ly;
	double		lz = draw->lz;
	double		*matrix,*light;
	matrix 		= draw->worldmatrix;
	light		= draw->lightvector;
	*light++	= lx* *(matrix+M11) + ly* *(matrix+M12) + lz* *(matrix+M13);
	*light++	= lx* *(matrix+M21) + ly* *(matrix+M22) + lz* *(matrix+M23);
	*light++	= lx* *(matrix+M31) + ly* *(matrix+M32) + lz* *(matrix+M33);
	/* printf ("light -> %lf,%lf,%lf \n",vector -> vectorX,vector -> vectorY,vector -> vectorZ);	*/
}
/************************************************************************
		RcvZCu
 ************************************************************************/


/* === s@WnʍWւ̕ϊ ===*/

extern	void	CalcUVWXYZ(matrix,dU,dV,dW,dX,dY,dZ)
double	*matrix;
double	dU,dV,dW;
double	*dX,*dY,*dZ;
{
		*dX = (*(matrix+M11) * dU ) + (*(matrix+M12) * dV) + (*(matrix+M13) * dW);
		*dY = (*(matrix+M21) * dU ) + (*(matrix+M22) * dV) + (*(matrix+M23) * dW);
		*dZ = (*(matrix+M31) * dU ) + (*(matrix+M32) * dV) + (*(matrix+M33) * dW);
}

/* === ]ssps쐬 ====*/

extern	void	Make3DMatrix(matrix,aX,aY,aZ)
double	*matrix;
double	aX,aY,aZ;
{

		*matrix++	=  cos(aY)*cos(aZ)+sin(aX)*sin(aY)*sin(aZ);
		*matrix++	= -cos(aY)*sin(aZ)+sin(aX)*sin(aY)*cos(aZ);
		*matrix++	=  cos(aX)*sin(aY);

		*matrix++	=  cos(aX)*sin(aZ);
		*matrix++	=  cos(aX)*cos(aZ);
		*matrix++	= -sin(aX);

		*matrix++	= -sin(aY)*cos(aZ)+sin(aX)*cos(aY)*sin(aZ);
		*matrix++	=  sin(aY)*sin(aZ)+sin(aX)*cos(aY)*cos(aZ);
		*matrix		=  cos(aX)*cos(aY);

}


/* === s񓯎m̊|Z ====*/

CalcMatrix(matrixC,matrixA,matrixB)
double	*matrixC,*matrixA,*matrixB;
{
	int	i;

		*matrixC++ = matrixA[M11]*matrixB[M11]+matrixA[M21]*matrixB[M21]+matrixA[M31]*matrixB[M31];
		*matrixC++ = matrixA[M11]*matrixB[M12]+matrixA[M21]*matrixB[M22]+matrixA[M31]*matrixB[M32];
		*matrixC++ = matrixA[M11]*matrixB[M13]+matrixA[M21]*matrixB[M23]+matrixA[M31]*matrixB[M33];

		*matrixC++ = matrixA[M12]*matrixB[M11]+matrixA[M22]*matrixB[M21]+matrixA[M32]*matrixB[M31];
		*matrixC++ = matrixA[M12]*matrixB[M12]+matrixA[M22]*matrixB[M22]+matrixA[M32]*matrixB[M32];
		*matrixC++ = matrixA[M12]*matrixB[M13]+matrixA[M22]*matrixB[M23]+matrixA[M32]*matrixB[M33];

		*matrixC++ = matrixA[M13]*matrixB[M11]+matrixA[M23]*matrixB[M21]+matrixA[M33]*matrixB[M31];
		*matrixC++ = matrixA[M13]*matrixB[M12]+matrixA[M23]*matrixB[M22]+matrixA[M33]*matrixB[M32];
		*matrixC   = matrixA[M13]*matrixB[M13]+matrixA[M23]*matrixB[M23]+matrixA[M33]*matrixB[M33];

}


/*======================================================================*/
/*======================================================================*/
/*			ݒ													*/
/*======================================================================*/
/*======================================================================*/
/************************************************************************
		ʕ`惁C[`
 ************************************************************************/
News3DdrawInit(draw,camera)
CameraInfo	*camera;
DRAWPACK	*draw;
{

	extern	GC		GameGC;						/* }bvEBhEł GC		*/
	extern	Pixmap	GamePixmap;					/* }bvEBhE PIXMAP		*/

	InitDrawParameter(draw,GameGC,GamePixmap,camera,
					  (double)GamePixmapWidth/2,	/* \ʂ̒SW				*/
					  (double)GamePixmapHeight/2,
					  camera->offsetX,
					  camera->offsetY,
					  camera->offsetZ,
					  shapepoint,rotatepoint,displaypoint);

}

/************************************************************************
		POLYGON DRAW PACKAGE ̏ݒ
************************************************************************/

InitDrawParameter(draw,gc,pixmap,camera,dispCX,dispCY,cx,cy,cz,shapeP,rotateP,displayP)
DRAWPACK 		*draw;				/* `p[^ւ̃|C^		*/
GC				gc;					/* GC 								*/
Pixmap			pixmap;				/* PIXMAP							*/
CameraInfo		*camera;			/* J̍Wpx					*/
double			dispCX,dispCY;		/* XN[̒Sl				*/
double			cx,cy,cz;			/* [hWItZbgl			*/
ShapePoints		*shapeP;			/* {fB[Wñ|Cgf[^	*/
RotatePoints	*rotateP;			/* ϊ̃|Cgf[^		*/
DisplayPoints	*displayP;			/* ϊ̃|Cgf[^		*/
{

		draw->wx			= camera->positionX;
		draw->wy			= camera->positionY;
		draw->wz			= camera->positionZ;
		draw->ax			= camera->angleX;
		draw->ay			= camera->angleY;
		draw->az			= camera->angleZ;

		draw->lx			= 0;
		draw->ly			= -1.7320508/2;
		draw->lz			= 0.5;

		draw->worldmatrix	= CameraMatrix;		
		draw->lightvector	= LightMatrix;

		draw->gc			= gc;
		draw->pixmap		= pixmap;
		draw->dispCX 		= dispCX;
		draw->dispCY 		= dispCY;
		draw->cx			= cx;
		draw->cy			= cy;
		draw->cz			= cz;
		draw->scale			= 1;
		draw->shapeP		= shapepoint;
		draw->rotateP		= rotatepoint;
		draw->displayP		= displaypoint;
		draw->overflagP		= overflag;

}

