/************************************************************************
		ӂǂ̃t@Cf[^
		IWAMOTO CAD ̃t@Cf[^tH[}bgɕϊB
 ************************************************************************/

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

#define		Debug			0
#define		unchar			unsigned char


#define		MAXPOLY			8000
#define		MAXPOINT		8000

#define		BOTHFLAG		0

/*=======================================================================
			\̐錾
========================================================================*/

/***************** CAD OBJECT RECORD ************************************/
typedef struct {
	char	flags;			/* tbO									*/
	char	selectFlag;
	short	parentObject;	/* eIuWFNgւ̃CfbNX			*/
	short	nextBrother;	/* ̌ZIuWFNgւ̃CfbNX		*/
	short	childObject;	/* ŏ̎qIuWFNgւ̃CfbNX		*/
	short	firstPolygon;	/* ŏ̃|Sւ̃CfbNX			*/
	double	offsetx;		/* eƂ̃ItZbgw						*/
	double	offsety;		/* eƂ̃ItZbgx						*/
	double	offsetz;		/* eƂ̃ItZbgy						*/
} Object;

/***************** CAD POLYGON RECORD ***********************************/
typedef struct {
	char	flags;			/* tbO									*/
	char	selectFlag;
	short	nextPolygon;	/* O[ṽ|Sւ̃CfbNX	*/
	short	firstPoint;		/* |S\钸_ւ̃CfbNX	*/
	short   animation;		/* Aj[Vւ̃CfbNX			*/
	short	both;			/* ʃ|ŜƂ̕Бւ̃CfbNX	*/
	unchar  side;			/* |S̕\̃tbO					*/
	unchar	color;			/* |S̐F								*/
	unchar	npoints;		/* |S̒_							*/
} Polygon;

/***************** CAD POINT RECORD**************************************/
typedef struct {
	char	flags;			/* tbO									*/
	char	selectFlag;
	short	nextPoint;		/* ̃|Cgւ̃CfbNX				*/
	double	pointx;			/* wW									*/
	double	pointy;			/* xW									*/
	double	pointz;			/* yW									*/
} Point;

/***************** CAD ANIMATION INDEX RECORD ***************************/
typedef struct {			/*	Aj[ṼCfbNX			*/
	char flag;				/*	gptO							*/
	short frame[64];		/*	őUSt[܂ł̃Aj[V	*/
} IndexRecord, Index;

/***************** FUNDOSHI POINT RECORD ********************************/
typedef	struct	{
	int	pointX;				/* {fBWl	*/
	int	pointY;
	int	pointZ;
}	SHAPEPOINT;

/***************** FUNDOSHI ANIMATION POINT RECORD **********************/
typedef	struct	{
	SHAPEPOINT	shapepoint[64];	/* őAjt[Œ	*/
}	ANIMEPOINT;

/***************** FUNDOSHI FACE RECORD ********************************/
typedef	struct	{
	int		facepoint;		/* tFCX̒_			*/
	int		pointNO[16];	/* max 16ʑ				*/
	int		color;			/* J[f[^				*/
	int		equA;			/* ʂ̃̕p[^	*/
	int		equB;
	int		equC;
	int		equD;
	int		equN;			/* PʃxNg̑傫 = sqrt ( A*A + B*B + C*C )	*/
	int		distance;		/* 镽ʂ܂ł̋								*/
	int		side;			/* ̖ʂɂđɕ􂳂ʂ			*/
	int		BOTH;			/* ʃ|S`FbN	*/
	int		SIDE;			/* \`FbN			*/

} 	SHAPEFACE;

/***************** MAKE BSP RECORD *************************************/
typedef struct	nodebsp	{
	int			keyface;			
	unsigned	char	faceall[256];	
	unsigned	char	leftface[256];
	unsigned	char	rightface[256];
	struct		nodebsp	*left;
	struct		nodebsp	*right;
}	BSPTREE;

/***************** ϊp̋ʕϐ RECORD ******************************/
typedef	struct	{
	SHAPEPOINT	*shapepoint;	/* VFCv|Cg\̂ւ̃|C^	*/
	ANIMEPOINT	*animepoint;	/* VFCv|Cg\̂ւ̃|C^	*/
	SHAPEFACE	*shapeface;		/* VFCvtFCX\̂ւ̃|C^	*/
	BSPTREE		*bsptree;		/* BSPtree\̂ւ̃|C^			*/
	int			scale;			/* g嗦								*/
	int			PointTotal;		/* |Cg̃g[^ 				*/
	int 		FaceTotal;		/* tFCX̃g[^					*/
	int			AnimeTotal;		/* Aj[Ṽg[^			*/
	int			ramNO;			/* ̃f[^̃ItZbgq`laddress	*/
	char		*ramPstart;		/* VFCv̐擪AhX				*/
}	MAKESHAPE;




/************************************************************************
		 Rc-b`cvOpϐ`
 ************************************************************************/

Object	DATAObject[10];
Polygon	DATAPolygon[MAXPOLY];
Point	DATAPoint[MAXPOINT];
Point 	animPoint[4096];		/* Aj[Vp̃|Cgf[^				*/
Index 	animIndex[256];			/* ōQTU|S̃Aj[V܂		*/

int		TOTALObject;
int		TOTALPolygon;
int		TOTALPoint;
int		TOTALAnimeTBL;
int		TOTALAnimePNT;

int		ANIMEflag;				/* Aj[VtO		*/
int		ANIMEcount;				/* Aj[VJE^	*/

MAKESHAPE	MSPtr;					/* C|C^						*/
SHAPEFACE	ShapeFace[MAXPOLY];		/* VFCvtFCXf[^				*/
SHAPEPOINT	ShapePoint[MAXPOINT];	/* |Cgf[^̃obt@ 			*/
BSPTREE		BSPtree[256];			/* BSPTREEp̃obt@					*/
ANIMEPOINT	AnimePoint[256];



/************************************************************************
			C[`
 ************************************************************************/

void main ( argc,argv )

int 	argc;
char	*argv[];

{
	FILE	*inputFP;		/* ӂǂ(sws)f[^̃t@C|C^ */
	FILE	*outputFP;		/* b`c(mdvr)f[^̃t@C|C^		*/

	int		fcount;			/* t@CJE^		*/

	char	txtname[100];
	char	cadname[100];
	int		count;

/*----------------------------------------------------------------------*/
/*		CtH[V												*/
/*----------------------------------------------------------------------*/
	if (argc < 2){
		fprintf(stderr, "***********************************************\n");
		fprintf(stderr, "*                                       *\n");
		fprintf(stderr, "*         funcad (*.txt)  => (*.cad)          *\n");
		fprintf(stderr, "*         funcad (*.anm)  => (*.nca)          *\n");
		fprintf(stderr, "*                                             *\n");
		fprintf(stderr, "*            ++ Version 3.0 ++                *\n");
		fprintf(stderr, "*                                             *\n");
		fprintf(stderr, "*                                             *\n");
		fprintf(stderr, "*      Programed By H.Yajima  1994.4.13       *\n");
		fprintf(stderr, "*                                             *\n");
		fprintf(stderr, "***********************************************\n");
		exit( 1 ) ;
	}
	printf( "(ST) ***** funcad ϊJn܂B*****\n");
/*----------------------------------------------------------------------*/
/*		ӂǂN̂̂swsf[^ǂݍ						*/
/*----------------------------------------------------------------------*/

	fcount = 1;								/* t@C̃X^[gn_	*/
	argc--;

	while ( argc-- ){
		
		strcpy (txtname,argv[fcount]);		/* t@CORs[	*/
		fcount++;							
		strcpy (cadname,txtname);
		count = strlen (cadname);

		if ( count < 4 ){
			fprintf(stderr, "==== ӂǂt@Cł͂܂(%s) ====\n",txtname); 
			exit(1);
		}
		if ( strcmp(&txtname[count-4],".txt")==0  ){
				ANIMEflag = 0;
				cadname[count-3]='c';
				cadname[count-2]='a';
				cadname[count-1]='d';
		} else {
			if ( strcmp(&txtname[count-4],".anm")==0 ){
				ANIMEflag = 1;
				cadname[count-3]='n';
				cadname[count-2]='c';
				cadname[count-1]='a';
			} else {
				fprintf(stderr, "==== ӂǂt@Cł͂܂(%s) ====\n",txtname); 
				exit(1);
			}
		}
			

		if ((inputFP = fopen(txtname,"r")) == NULL ){
			fprintf(stderr, "==== ̓t@CG[ (%s) ====\n",txtname); 
			continue;		/* !!!!!!!!!!!!!!!!!!!!()!!!!!!!!!!!!!!!!!!!!!!!! ƂÂI	*/
		}

/*----------------------------------------------------------------------*/
/*		f[^ϊ@!!													*/
/*----------------------------------------------------------------------*/

		if (ANIMEflag == 0){
			ReadFundoshi(inputFP,txtname);		/* ӂǂf[^ǂݍ 			*/
			ConvertCADdata();					/* b`ctH[}bg֕ϊ			*/	
		} else {
			InitAnimation();					/* p[^ݒ				*/
			ReadAnimation(inputFP,txtname);		/* ӂǂf[^ǂݍ 			*/
			ConvertANMdata();					/* b`ctH[}bg֕ϊ			*/	
		}


/*----------------------------------------------------------------------*/
/*		f[^Z[u													*/
/*----------------------------------------------------------------------*/

		if ((outputFP = fopen(cadname,"w")) == NULL ){
			fprintf(stderr, "==== o̓t@CG[ (%s) ====\n",cadname); 
			continue;		/* !!!!!!!!!!!!!!!!!!!!()!!!!!!!!!!!!!!!!!!!!!!!! ƂÂI	*/
		}
		printf( "(->) read %-12s file ",txtname);
		ConvertSaveData(outputFP);	/* b`cZ[utH[}bg֕ϊ	*/
		fclose(outputFP);
		fclose(inputFP);

/*----------------------------------------------------------------------*/
/*		fobOp														*/
/*----------------------------------------------------------------------*/
#if	Debug
		if ((inputFP = fopen(cadname,"r")) == NULL ){
			fprintf(stderr, "==== CADt@CG[ (%s) ====\n",cadname); 
			exit( 1 ) ;
		}
		DispSaveData(inputFP);		/* Z[uf[^mF */
		fclose(inputFP);
#endif

	}

/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
	printf( "(ED) ***** funcad ϊI܂B*****\n");

}


/************************************************************************
		b`ctH[}bg֕ϊ
 ************************************************************************/
InitAnimation()
{
	int	i,j;

	for(i=0;i<256;i++){
		for(j=0;j<64;j++){
			animIndex[i].frame[j] = -1;
		}
	}

}

/************************************************************************
		b`ctH[}bg֕ϊ
 ************************************************************************/

ConvertCADdata()

{
	int	object_counter;
	int	polygon_counter;
	int	point_counter;
	int	face_counter;
	int	i;
	int	face_number;
	int	facect;

	int			facetotal	= MSPtr.FaceTotal;
	SHAPEFACE	*faceP		= MSPtr.shapeface;
	SHAPEPOINT	*pointP		= MSPtr.shapepoint;
	
	object_counter = 0;


	/*- - - - ROOT OBJECT  - - - - -*/

	DATAObject[0].flags			= 1;
	DATAObject[0].parentObject 	= -1;
	DATAObject[0].nextBrother 	= -1;
	DATAObject[0].childObject 	= -1;
	DATAObject[0].firstPolygon 	= 0;
	DATAObject[0].offsetx	 	= 0;
	DATAObject[0].offsety	 	= 0;
	DATAObject[0].offsetz	 	= 0;

	object_counter++;

	/*- - - - POLYGON DATA  - - - - -*/

	polygon_counter = 0;
	point_counter = 0;

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

		face_counter = (faceP+facect)->facepoint;		/* _	*/

		DATAPolygon[polygon_counter].flags 		= 1;
		DATAPolygon[polygon_counter].selectFlag = 0;
		DATAPolygon[polygon_counter].nextPolygon = polygon_counter+1;
		DATAPolygon[polygon_counter].firstPoint = point_counter;
		DATAPolygon[polygon_counter].animation 	= -1;
		DATAPolygon[polygon_counter].both 		= (faceP+polygon_counter)-> BOTH;
		DATAPolygon[polygon_counter].side 		= (faceP+polygon_counter)-> SIDE;
		DATAPolygon[polygon_counter].color 		= (faceP+polygon_counter)->color;
		DATAPolygon[polygon_counter].npoints 	= face_counter;

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

			face_number = (faceP+facect)->pointNO[i];

			DATAPoint[point_counter].flags 		= 2;
			DATAPoint[point_counter].selectFlag = 0;
			DATAPoint[point_counter].nextPoint 	= point_counter+1;
			DATAPoint[point_counter].pointx 	= (pointP+face_number)->pointX;
			DATAPoint[point_counter].pointy 	= (pointP+face_number)->pointY;
			DATAPoint[point_counter].pointz 	= (pointP+face_number)->pointZ;
			point_counter++;							/* |CgJE^̑	*/

		}

		DATAPoint[point_counter-1].nextPoint = -1;		/* |Cgf[^͏I 	*/
		polygon_counter++;								/* |SJE^̑	*/

	}

	DATAPolygon[polygon_counter-1].nextPolygon = -1;	/* |Sf[^͏I 	*/

	TOTALObject 	= object_counter;
	TOTALPolygon	= polygon_counter;
	TOTALPoint		= point_counter;

}


/************************************************************************
		b`ctH[}bg֕ϊ
 ************************************************************************/

ConvertANMdata()

{

	int	object_counter;
	int	polygon_counter;
	int	point_counter;
	int	face_counter;
	int	anime_table,anime_point;
	int	i,j,k;
	int POINTNO;
	int	facect;

	int			animetotal	= MSPtr.AnimeTotal;
	int			facetotal	= MSPtr.FaceTotal;
	SHAPEFACE	*faceP		= MSPtr.shapeface;
	SHAPEPOINT	*pointP		= MSPtr.shapepoint;
	ANIMEPOINT	*animeP		= MSPtr.animepoint;	


	object_counter = 0;


	/*- - - - ROOT OBJECT  - - - - -*/

	DATAObject[0].flags			= 1;
	DATAObject[0].parentObject 	= -1;
	DATAObject[0].nextBrother 	= -1;
	DATAObject[0].childObject 	= -1;
	DATAObject[0].firstPolygon 	= 0;
	DATAObject[0].offsetx	 	= 0;
	DATAObject[0].offsety	 	= 0;
	DATAObject[0].offsetz	 	= 0;

	object_counter++;

	/*- - - - POLYGON DATA  - - - - -*/

	polygon_counter = 0;
	point_counter = 0;
	anime_table = 0;
	anime_point	  = 0;

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

		face_counter = (faceP+facect)->facepoint;		/* _	*/

		DATAPolygon[polygon_counter].flags 		= 1;
		DATAPolygon[polygon_counter].selectFlag = 0;
		DATAPolygon[polygon_counter].nextPolygon = polygon_counter+1;
		DATAPolygon[polygon_counter].firstPoint =  point_counter;
		DATAPolygon[polygon_counter].animation 	= anime_table;		/* Aj[Vւ̃|C^ */
		DATAPolygon[polygon_counter].both 		= (faceP+polygon_counter)-> BOTH;
		DATAPolygon[polygon_counter].side 		= (faceP+polygon_counter)-> SIDE;
		DATAPolygon[polygon_counter].color 		= (faceP+polygon_counter)->color;
		DATAPolygon[polygon_counter].npoints 	= face_counter;

		for (k=0;k<face_counter;k++){
			POINTNO = (faceP+facect)->pointNO[k];
			DATAPoint[point_counter].flags 		= 2;
			DATAPoint[point_counter].selectFlag = 0;
			DATAPoint[point_counter].nextPoint 	= point_counter+1;
			DATAPoint[point_counter].pointx 	= (animeP+POINTNO)->shapepoint[0].pointX;
			DATAPoint[point_counter].pointy 	= (animeP+POINTNO)->shapepoint[0].pointY;
			DATAPoint[point_counter].pointz 	= (animeP+POINTNO)->shapepoint[0].pointZ;
			point_counter++;							/* |CgJE^̑	*/
		}
		DATAPoint[point_counter-1].nextPoint = -1;		/* |Cgf[^͏I 	*/


		/* Aj */
		for(j=0;j<animetotal;j++){

			animIndex[anime_table].flag			= 1;				/* gp 	*/
			animIndex[anime_table].frame[j]		= anime_point;

			/* _ */
			for(k=0;k<face_counter;k++){

				POINTNO = (faceP+facect)->pointNO[k];				/* tFCX\P_	*/

				animPoint[anime_point].flags 		= 2;
				animPoint[anime_point].selectFlag 	= 0;
				animPoint[anime_point].nextPoint 	= anime_point+1;
				animPoint[anime_point].pointx 		= (animeP+POINTNO)->shapepoint[j].pointX;
				animPoint[anime_point].pointy 		= (animeP+POINTNO)->shapepoint[j].pointY;
				animPoint[anime_point].pointz 		= (animeP+POINTNO)->shapepoint[j].pointZ;
				anime_point++;

			}

			animPoint[anime_point-1].nextPoint = -1;		/* |Cgf[^͏I 		*/

		}

		polygon_counter++;								/* |SJE^̑		*/
		anime_table++;									/* Aj[Ve[ȗ	*/

	}

	DATAPolygon[polygon_counter-1].nextPolygon = -1;	/* |Sf[^͏I 		*/

	TOTALObject 	= object_counter;
	TOTALPolygon	= polygon_counter;
	TOTALPoint		= point_counter;
	TOTALAnimeTBL	= anime_table;
	TOTALAnimePNT	= anime_point;

}


/************************************************************************
		Z[uf[^tH[}bg֕ϊ
 ************************************************************************/

ConvertSaveData(outputFP)
FILE	*outputFP;
{

	int		animetotal	= MSPtr.AnimeTotal;
	char	headder;
	short	i;

	printf( " objects (%d)",TOTALObject	);
	printf( " polygons(%d)",TOTALPolygon);
	printf( " points  (%d)",TOTALPoint );

	if (ANIMEflag == 0)	printf("\n");
	else {
		printf (" animeframe(%d) animepoint(%d)\n",animetotal,TOTALAnimePNT);
	}

	/*- - - - OBJECT Z[u  - - - - - -*/

	i = 0;			
	headder = 0;
	fwrite (&headder,sizeof(char),1,outputFP);
	fwrite (&i,sizeof(short),1,outputFP);			
	fwrite (&DATAObject[0],sizeof(Object),1,outputFP);

	/*- - - - POLYGON Z[u - - - - - -*/

	for (i=0;i<TOTALPolygon;i++){
		headder = 1;
		fwrite (&headder,sizeof(char),1,outputFP);
		fwrite (&i,sizeof(short),1,outputFP);
		fwrite (&DATAPolygon[i],sizeof(Polygon),1,outputFP);
	}

	/*- - - - POINT Z[u - - - - - - -*/

	for (i=0;i<TOTALPoint;i++){
		headder = 2;
		fwrite (&headder,sizeof(char),1,outputFP);
		fwrite (&i,sizeof(short),1,outputFP);			
		fwrite (&DATAPoint[i],sizeof(Point),1,outputFP);
	}

	/*- - - - Aj[Ve[uZ[u - - -*/

	for (i=0;i<TOTALAnimeTBL;i++){
		headder = 3;
		fwrite (&headder,sizeof(char),1,outputFP);
		fwrite (&i,sizeof(short),1,outputFP);			
		fwrite (&animIndex[i],sizeof(Index),1,outputFP);
	}

	/*- - - - Aj[V|CgZ[u - - -*/

	for (i=0;i<TOTALAnimePNT;i++){
		headder = 4;
		fwrite (&headder,sizeof(char),1,outputFP);
		fwrite (&i,sizeof(short),1,outputFP);
		fwrite (&animPoint[i],sizeof(Point),1,outputFP);
	}

}

/************************************************************************
		Z[uf[^mF
 ************************************************************************/

Object	objectData[10];
Polygon	polygonData[500];
Point	pointData[1000];



DispSaveData(testFP)
FILE *testFP;
{
	
	int		Acount = 0;
	char	headder;
	short	pt;
	int		ct = 0;

	while ( fread(&headder,sizeof(char),1,testFP) != NULL ){


		switch 	(headder){

			case	0:
				fread (&pt,sizeof(short),1,testFP);
				fread (&objectData[pt],sizeof(Object),1,testFP);
				printf (" IuWFNg\ ======================== \n");
				break;
			case	1:
				fread (&pt,sizeof(short),1,testFP);
				fread (&polygonData[pt],sizeof(Polygon),1,testFP);
				printf (" |S\ ************************** \n");
				printf (" io[         %d\n",pt);
				printf (" flags       ---> %d\n",polygonData[pt].flags);
				printf (" selectFlag  ---> %d\n",polygonData[pt].selectFlag);
				printf (" nextPolygon ---> %d\n",polygonData[pt].nextPolygon);
				printf (" firstPoint  ---> %d\n",polygonData[pt].firstPoint);
				printf (" animation   ---> %d\n",polygonData[pt].animation);
				printf (" both        ---> %d\n",polygonData[pt].both);
				printf (" side        ---> %d\n",polygonData[pt].side);
				printf (" color       ---> %d\n",polygonData[pt].color);
				printf (" npoints     ---> %d\n",polygonData[pt].npoints);
				break;
			case	2:
				fread (&pt,sizeof(short),1,testFP);
				fread (&pointData[pt],sizeof(Point),1,testFP);
#if	0
				printf (" |Cg\ --------------------------- \n");
				printf (" io[         %d\n",pt);
				printf (" flags       ---> %d\n",pointData[pt].flags);
				printf (" selectFlag  ---> %d\n",pointData[pt].selectFlag);
				printf (" nextPoint   ---> %d\n",pointData[pt].nextPoint);
				printf (" pointx      ---> %lf\n",pointData[pt].pointx);
				printf (" pointy      ---> %lf\n",pointData[pt].pointy);
				printf (" pointz      ---> %lf\n",pointData[pt].pointz);
#endif
				break;
			case	3:
				fread (&pt,sizeof(short),1,testFP);
				fread (&animIndex[pt],sizeof(Index),1,testFP);
				while (animIndex[pt].frame[Acount]!= -1){
					Acount++;
				}
				break;
			case	4:
				fread (&pt,sizeof(short),1,testFP);
				fread (&animPoint[pt],sizeof(Point),1,testFP);
				printf (" Aj̓_f[^ %d,%d,%d,%d\n",ct,
						(int)(animPoint[pt].pointx),
						(int)(animPoint[pt].pointy),
						(int)(animPoint[pt].pointz) );
				ct++;
				break;
		}
	}

	printf ("animation(%d)(%d)(%d)\n",Acount,ct/8);



}




/************************************************************************
		ӂǂf[^̓ǂݍ
 ************************************************************************/

ReadFundoshi(inputFP,nameP)
FILE	*inputFP;				/* ӂǂ(sws)f[^̃t@C|C^ */
char	*nameP;
{

	char	lineword[101]; 					/* e[ut@CPsł̍ő啶 */

	int		total;							/* |Cgg[^̐ */
	int		ix,iy,iz;						/* |CgW x1,x2,x3 */
	int 	facecount;						/* tFCXf[^JE^ */
	int		facepointer;	
	int		color;
	int		i,counter;						/* ėp[N */

	MSPtr.shapepoint 	= ShapePoint;
	MSPtr.shapeface 	= ShapeFace;

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*		VFCvf[^̓ǂ݂										*/
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

	ReadHead(inputFP,lineword,nameP);		/*	wb_`FbN				*/
	ReadTotalPoint(inputFP,lineword);		/*	|Cgg[^ǂݍ	*/
	ReadPointData(inputFP,lineword);		/*	|Cgf[^̓ǂݍ	*/
	ReadFaceData(inputFP,lineword);			/*	tFCXf[^̓ǂݍ	*/
	SetBOTH();								/*  ʃZbg					*/
	SetSIDE();								/*  \Zbg				*/

/*- - - - - - - - - - - - - - - - - - - */
/*	ǂݍݏI						*/
/*- - - - - - - - - - - - - - - - - - - */

}

/************************************************************************
		ӂǂAj[Vf[^̓ǂݍ
 ************************************************************************/

ReadAnimation(inputFP,nameP)
FILE	*inputFP;				/* ӂǂ(sws)f[^̃t@C|C^ */
char	*nameP;
{

	char	lineword[101]; 					/* e[ut@CPsł̍ő啶 */

	int		total;							/* |Cgg[^̐ */
	int		ix,iy,iz;						/* |CgW x1,x2,x3 */
	int 	facecount;						/* tFCXf[^JE^ */
	int		facepointer;
	int		color;
	int		i,counter;						/* ėp[N */

	MSPtr.animepoint 	= AnimePoint;
	MSPtr.shapepoint 	= ShapePoint;
	MSPtr.shapeface 	= ShapeFace;

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*		VFCvf[^̓ǂ݂										*/
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

	ReadAnimeHead(inputFP,lineword,nameP);	/*	wb_`FbN				*/
	ReadTotalPoint(inputFP,lineword);		/*	|Cgg[^ǂݍ	*/
	ReadAnimeTotal(inputFP,lineword);		/*	Aj[V̓ǂݍ	*/
	ReadAnimePoint(inputFP,lineword);		/*	|Cgf[^̓ǂݍ	*/
	ReadFaceData(inputFP,lineword);			/*	tFCXf[^̓ǂݍ	*/
	SetBOTH();								/*  ʃZbg					*/
	SetSIDE();								/*  \Zbg				*/

/*- - - - - - - - - - - - - - - - - - - */
/*	ǂݍݏI						*/
/*- - - - - - - - - - - - - - - - - - - */

}

/*=====================================================================*/
/*																		*/
/*		ӂǂt@Cǂݍ݃[`								*/
/*																		*/
/*======================================================================*/

/************************************************************************
		|Sʃ`FbN
 ************************************************************************/






/************************************************************************
		wb_̃`FbN
 ************************************************************************/

ReadAnimeHead(fp,lineword,nameP)
FILE	*fp;
char	*lineword;
char	*nameP;
{
	fgets(lineword,128,fp);
	if (strncmp(lineword,"3DAN",4) !=0 ){
		fprintf(stderr,"̃t@C͂ӂǂANMtH[}bgł͂܂(%s)B\n",nameP);		
		exit(1);
	}
}

/************************************************************************
		g[^|Cg̓ǂݍ
 ************************************************************************/

ReadAnimeTotal(fp,lineword)
FILE		*fp;
char		*lineword;
{

	int		total;
	if ( fgets( lineword,100,fp ) == NULL ){
		fputs ("Aj[Vg[^݂݃G[\n",stderr );
		exit(1);
	}
	GetNumber( &lineword,&total);

	MSPtr.AnimeTotal =	total;

}


/************************************************************************
		|Cgf[^̓ǂݍ
 ************************************************************************/

ReadAnimePoint(fp,linewordS)
FILE		*fp;
char		*linewordS;			/* Psǂݍ݃|C^		*/
{
	int			i,j;
	int			ix,iy,iz;
	char 		*lineword;
	int		animetotal	= MSPtr.AnimeTotal;	/* Aj[Vg[^	*/
	int			total   = MSPtr.PointTotal;	/* ǂݍ݃|Cg		*/
	ANIMEPOINT	*animeP = MSPtr.animepoint;	/* Aj|Cg\		*/

	for(j=0;j<animetotal;j++){
		for (i=0;i<total;i++){
			lineword = linewordS;		/* ǂݍ݃obt@̃|C^Ƃ֖߂	*/
			if ( fgets( lineword,100,fp ) == NULL ){
				fputs ("Wf[^݂݃G[\n",stderr );
				exit(1);
			}
			GetNumber ( &lineword,&ix );	*lineword++;
			GetNumber ( &lineword,&iy );	*lineword++;
			GetNumber ( &lineword,&iz );
			(animeP+i)->shapepoint[j].pointX = ix;		/* i=|Cgԍɑ΂Ă̕ω	*/
			(animeP+i)->shapepoint[j].pointY = iy;		/* j=t[ԍɑ΂Ă̕ω	*/
			(animeP+i)->shapepoint[j].pointZ = iz;
		}
	}

}





/************************************************************************
		wb_̃`FbN
 ************************************************************************/

ReadHead(fp,lineword,nameP)
FILE	*fp;
char	*lineword;
char	*nameP;
{
	fgets(lineword,128,fp);
	if (strncmp(lineword,"3DG1",4) !=0 ){
		fprintf(stderr,"̃t@C͂ӂǂTXTtH[}bgł͂܂(%s)B\n",nameP);		
		exit(1);
	}
}

/************************************************************************
		g[^|Cg̓ǂݍ
 ************************************************************************/

int	ReadTotalPoint(fp,lineword)
FILE		*fp;
char		*lineword;
{

	int		total;

	if ( fgets( lineword,100,fp ) == NULL ){
		fputs ("|Cgg[^݂݃G[\n",stderr );
		exit(1);
	}
	GetNumber( &lineword,&total);

	MSPtr.PointTotal =	total;

}

/************************************************************************
		|Cgf[^̓ǂݍ
 ************************************************************************/

ReadPointData(fp,linewordS)
FILE		*fp;
char		*linewordS;			/* Psǂݍ݃|C^		*/
{
	int			i;
	int			ix,iy,iz;
	char 		*lineword;
	int			total   = MSPtr.PointTotal;	/* ǂݍ݃|Cg		*/
	SHAPEPOINT	*shapeP = MSPtr.shapepoint; /* VFCv|Cg\	*/

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

		lineword = linewordS;		/* ǂݍ݃obt@̃|C^Ƃ֖߂	*/
		if ( fgets( lineword,100,fp ) == NULL ){
			fputs ("Wf[^݂݃G[\n",stderr );
			exit(1);
		}

		GetNumber ( &lineword,&ix );	*lineword++;
		GetNumber ( &lineword,&iy );	*lineword++;
		GetNumber ( &lineword,&iz );
		shapeP->pointX = ix;
		shapeP->pointY = iy;
		shapeP->pointZ = iz;
		shapeP++;

	}

}

/************************************************************************
		tFCXf[^̓ǂݍ
 ************************************************************************/

ReadFaceData(fp,linewordS)
FILE		*fp;
char		*linewordS;			/* Psǂݍ݃|C^				*/
{

	char	*lineword;	
	int		total;				/* tFCX̃g[^				*/
	int		pointNO;			/* tFCX\|Cgԍ	*/
	int		topcount;			/* tFCX̒_̐				*/
	int		color;				/* tFCX̃J[					*/
	int		i,counter;

	int			facecount	= 0;					/* tFCX̐JEg		*/
	SHAPEFACE	*face		= MSPtr.shapeface;		/* tFCX\̂ւ̃|C^	*/

	lineword = linewordS;

	while ( fgets( lineword,100,fp ) != NULL ){

		GetNumber( &lineword,&topcount  );			/* _̓ǂݍ			*/

		if ( topcount== 0 )	break;					/* MSDOS FILE ΍			*/

		*lineword++;
		face->facepoint = topcount;


		for (i=0;i<topcount;i++){					/* tFCXf[^ǂݍ	*/
			GetNumber( &lineword,&pointNO );
			*lineword++;
			face->pointNO[i] = pointNO;
		}

		GetNumber( &lineword,&color );				/* J[f[^ǂݍ		*/
		face->color = color;

		facecount++;								/* tFCX̐P₷ */
		face++;										/* tFCX|C^i߂	*/
		lineword = linewordS;						/* |C^Zbg	*/

	} 

	MSPtr.FaceTotal = facecount;					/* tFCXg[^̑	*/

}

/************************************************************************
		ʂ̕\`FbN(CADp)@xNǧvZ	
 ************************************************************************/
SetSIDE()
{
	int		counter;
	int		point1,point2,point3;

	SHAPEPOINT	*point 		= MSPtr.shapepoint;
	SHAPEFACE	*face  		= MSPtr.shapeface;
	int			facetotal	= MSPtr.FaceTotal;

	for (counter = 0;counter<facetotal;counter++){
		point1 = face -> pointNO[0];
		point2 = face -> pointNO[1];
		point3 = face -> pointNO[2];
		calc_vector(point1,point2,point3,counter,face,point);

		face->SIDE = 0;
		if ( face->equB <  0 ) face->SIDE += 1;
		if ( face->equC >= 0 ) face->SIDE += 2;
		if ( face->equA <  0 ) face->SIDE += 4;
		face++;

	}

}

/************************************************************************
		ʃ|S̃`FbN
 ************************************************************************/
SetBOTH()
{

	int		key,sub;
	int		point1,point2,point3;
	int		vertex;
	int		i,j;
	int		flag;
	int		pointNO;

	SHAPEPOINT	*point 		= MSPtr.shapepoint;
	SHAPEFACE	*face  		= MSPtr.shapeface;
	SHAPEFACE	*faceroot 	= MSPtr.shapeface;
	int			facetotal	= MSPtr.FaceTotal;

	for (key = 0;key<facetotal;key++){
		(face+key)->BOTH = -1;			/* Жʃ|SƂăZbg	*/
	}


#if	BOTHFLAG

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

		vertex = (face+key)->facepoint;	/* key̒_|Cg̒֓	*/

										/* keyȍ~̃|Sœ̂邩ǂ`FbN */
		for(sub=key+1;sub<facetotal;sub++){

			flag = 0;
			if ( vertex == (face+sub)->facepoint ){
				for(i=0;i<vertex;i++){
					pointNO = (face+key)->pointNO[i];						/* {̖ʂ̃|Cg */
					for(j=0;j<vertex;j++){
						if ( pointNO == (face+sub)->pointNO[j] ) flag++;	/* ʂ̃|Cg */
					}
				}
			}

													/* vꍇ!!	*/
			if (flag == vertex){
													/* |SΌǂ`FbN */

				(face+key)->BOTH =  sub;
				(face+sub)->BOTH =  key;

			}

		}

	}

#endif

}

#if	0
				if ( (face+key)->equA > 0 ){
					if ( (face+sub)->equA > 0 ) )	break;
				}
				if ( (face+key)->equB > 0 ){
					if ( (face+sub)->equB > 0 ) )	break;
				}
				if ( (face+key)->equC > 0 ){
					if ( (face+sub)->equC > 0 ) )	break;
				}
#endif

/************************************************************************
		eLXg`̐f[^(10it)@
		INT^ f[^֕ϊ
 ************************************************************************/

GetNumber( dt,nm )
char	**dt;
int		*nm;
{

	char	*pt;
	int	ct=0, nn=0 ;
	int	sign_flag = 0;

		pt = *dt ;	/* s̕|C^󂯂Ƃ */

					/* }CiXf[^̂Ƃ */
		if ( *pt == '-' ){
			*pt++;
			sign_flag++;
		}

		while ( isdigit( *pt )) {
			nn = nn * 10 + (*pt++ - '0');
			ct++;	/* `FbN|C^ */
		}

		if ( sign_flag != 0 ){
			nn = -nn;
		}

		*dt = pt ;	/* s̕|C^󂯓n */
		*nm = nn ;	/* f[^󂯓n */

		return ( ct ) ;

}

/*----------------------------------------------------------------------*/
/*	@xNǧvZ
/*----------------------------------------------------------------------*/

calc_vector(point1,point2,point3,i,face,sp)
int	point1,point2,point3,i;
SHAPEFACE		*face;
SHAPEPOINT		*sp;
{

	int	nx,ny,nz;
	int	p1,p2,p3;
	int	a1,a2,a3,a4;
	int	x1,y1,z1;

	double	nomal;
	int		nomal_x,nomal_y,nomal_z;

		x1 = (sp+point1)->pointX;			/* ʏ̂P_߂		*/
		y1 = (sp+point1)->pointY;
		z1 = (sp+point1)->pointZ;

											/* Oς̌vZ				*/

		a1 = (sp+point2)->pointY - (sp+point1)->pointY;
		a2 = (sp+point3)->pointZ - (sp+point2)->pointZ;
		a3 = (sp+point2)->pointZ - (sp+point1)->pointZ;
		a4 = (sp+point3)->pointY - (sp+point2)->pointY;

		nx = a1*a2 - a3*a4;

		a1 = (sp+point2)->pointZ - (sp+point1)->pointZ;
		a2 = (sp+point3)->pointX - (sp+point2)->pointX;
		a3 = (sp+point2)->pointX - (sp+point1)->pointX;
		a4 = (sp+point3)->pointZ - (sp+point2)->pointZ;

		ny = a1*a2 - a3*a4;

		a1 = (sp+point2)->pointX - (sp+point1)->pointX;
		a2 = (sp+point3)->pointY - (sp+point2)->pointY;
		a3 = (sp+point2)->pointY - (sp+point1)->pointY;
		a4 = (sp+point3)->pointX - (sp+point2)->pointX;

		nz = a1*a2 - a3*a4;

		nomal = nx*nx+ny*ny+nz*nz;
		nomal = sqrt ( nomal );

		if ( nomal == 0 ){
			nomal = 1;
		}

/*DB	Xprintf  ( "%lf\n",nomal);		DB*/

		nomal_x = ( nx / nomal ) * 127;
		nomal_y = ( ny / nomal ) * 127;
		nomal_z = ( nz / nomal ) * 127;

/*DB	Xprintf ( ",%4.0lf,%4.0lf,%4.0lf",nomal_x,nomal_y,nomal_z);	DB*/

		face -> equA = nomal_x;		/* ʂ̖@xNg	*/
		face -> equB = nomal_y;
		face -> equC = nomal_z;

								/* ʂ̕ ax+by+cz+D=0 ((D̒l))	*/
		face -> equD = -( nomal_x*x1 + nomal_y*y1 + nomal_z*z1 );
								/* ߂邽߂̌vZl				*/
		face -> equN = nomal;

}


