/************************************************************************
		դɤΥեǡ
		IWAMOTO CAD ΥեǡեޥåȤѴ롣
 ************************************************************************/

#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;			/* եå									*/
	char	selectFlag;
	short	parentObject;	/* ƥ֥ȤؤΥǥå			*/
	short	nextBrother;	/* η索֥ȤؤΥǥå		*/
	short	childObject;	/* ǽλҥ֥ȤؤΥǥå		*/
	short	firstPolygon;	/* ǽΥݥꥴؤΥǥå			*/
	double	offsetx;		/* ƤȤΥեåȣ						*/
	double	offsety;		/* ƤȤΥեåȣ						*/
	double	offsetz;		/* ƤȤΥեåȣ						*/
} Object;

/***************** CAD POLYGON RECORD ***********************************/
typedef struct {
	char	flags;			/* եå									*/
	char	selectFlag;
	short	nextPolygon;	/* Ʊ쥰롼ΥݥꥴؤΥǥå	*/
	short	firstPoint;		/* ݥꥴĺؤΥǥå	*/
	short   animation;		/* ˥᡼ؤΥǥå			*/
	short	both;			/* ξ̥ݥꥴΤȤ¦ؤΥǥå	*/
	unchar  side;			/* ݥꥴɽ΢Υեå					*/
	unchar	color;			/* ݥꥴο								*/
	unchar	npoints;		/* ݥꥴĺ							*/
} Polygon;

/***************** CAD POINT RECORD**************************************/
typedef struct {
	char	flags;			/* եå									*/
	char	selectFlag;
	short	nextPoint;		/* ΥݥȤؤΥǥå				*/
	double	pointx;			/* غɸ									*/
	double	pointy;			/* ٺɸ									*/
	double	pointz;			/* ںɸ									*/
} Point;

/***************** CAD ANIMATION INDEX RECORD ***************************/
typedef struct {			/*	˥᡼Υǥå			*/
	char flag;				/*	ե饰							*/
	short frame[64];		/*	磶ե졼ޤǤΥ˥᡼	*/
} IndexRecord, Index;

/***************** FUNDOSHI POINT RECORD ********************************/
typedef	struct	{
	int	pointX;				/* ܥǥɸ	*/
	int	pointY;
	int	pointZ;
}	SHAPEPOINT;

/***************** FUNDOSHI ANIMATION POINT RECORD **********************/
typedef	struct	{
	SHAPEPOINT	shapepoint[64];	/* 祢˥ե졼	*/
}	ANIMEPOINT;

/***************** FUNDOSHI FACE RECORD ********************************/
typedef	struct	{
	int		facepoint;		/* եĺ			*/
	int		pointNO[16];	/* max 16				*/
	int		color;			/* 顼ǡ				*/
	int		equA;			/* ʿ̤Υѥ᡼	*/
	int		equB;
	int		equC;
	int		equD;
	int		equN;			/* ñ̥٥ȥ礭 = sqrt ( A*A + B*B + C*C )	*/
	int		distance;		/* ʿ̤ޤǤεΥ								*/
	int		side;			/* ̤ˤä¾ʬ̤			*/
	int		BOTH;			/* ξ̥ݥꥴå	*/
	int		SIDE;			/* ɽ΢å			*/

} 	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;

/***************** ѴѤζѿ RECORD ******************************/
typedef	struct	{
	SHAPEPOINT	*shapepoint;	/* ץݥȹ¤ΤؤΥݥ	*/
	ANIMEPOINT	*animepoint;	/* ץݥȹ¤ΤؤΥݥ	*/
	SHAPEFACE	*shapeface;		/* ץե¤ΤؤΥݥ	*/
	BSPTREE		*bsptree;		/* BSPtree¤ΤؤΥݥ			*/
	int			scale;			/* Ψ								*/
	int			PointTotal;		/* ݥȤΥȡ 				*/
	int 		FaceTotal;		/* եΥȡ					*/
	int			AnimeTotal;		/* ˥᡼Υȡ			*/
	int			ramNO;			/* ΥǡΥեåȣңaddress	*/
	char		*ramPstart;		/* פƬɥ쥹				*/
}	MAKESHAPE;




/************************************************************************
		 -ãĥץѿ
 ************************************************************************/

Object	DATAObject[10];
Polygon	DATAPolygon[MAXPOLY];
Point	DATAPoint[MAXPOINT];
Point 	animPoint[4096];		/* ˥᡼ѤΥݥȥǡ				*/
Index 	animIndex[256];			/* ǹ⣲ݥꥴΥ˥᡼ޤ		*/

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

int		ANIMEflag;				/* ˥᡼ե饰		*/
int		ANIMEcount;				/* ˥᡼󥫥	*/

MAKESHAPE	MSPtr;					/* ᥤݥ						*/
SHAPEFACE	ShapeFace[MAXPOLY];		/* ץեǡ				*/
SHAPEPOINT	ShapePoint[MAXPOINT];	/* ݥȥǡΥХåե 			*/
BSPTREE		BSPtree[256];			/* BSPTREEѤΥХåե					*/
ANIMEPOINT	AnimePoint[256];



/************************************************************************
			ᥤ롼
 ************************************************************************/

void main ( argc,argv )

int 	argc;
char	*argv[];

{
	FILE	*inputFP;		/* դɤ(ԣأ)ǡΥեݥ */
	FILE	*outputFP;		/* ã(Σţף)ǡΥեݥ		*/

	int		fcount;			/* ե륫		*/

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

/*----------------------------------------------------------------------*/
/*		ե᡼												*/
/*----------------------------------------------------------------------*/
	if (argc < 2){
		fprintf(stderr, "***********************************************\n");
		fprintf(stderr, "*                                             *\n");
		fprintf(stderr, "*    դɤΣԣأ/Σͥǡ      *\n");
		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 Ѵ򳫻Ϥޤ*****\n");
/*----------------------------------------------------------------------*/
/*		դɤΤΣԣأԥǡɤ߹						*/
/*----------------------------------------------------------------------*/

	fcount = 1;								/* եΥ	*/
	argc--;

	while ( argc-- ){
		
		strcpy (txtname,argv[fcount]);		/* ե̾򥳥ԡ	*/
		fcount++;							
		strcpy (cadname,txtname);
		count = strlen (cadname);

		if ( count < 4 ){
			fprintf(stderr, "==== դɤեǤϤޤ(%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, "==== դɤեǤϤޤ(%s) ====\n",txtname); 
				exit(1);
			}
		}
			

		if ((inputFP = fopen(txtname,"r")) == NULL ){
			fprintf(stderr, "==== ϥե륨顼 (%s) ====\n",txtname); 
			continue;		/* !!!!!!!!!!!!!!!!!!!!()!!!!!!!!!!!!!!!!!!!!!!!! ȤĤŤ롪	*/
		}

/*----------------------------------------------------------------------*/
/*		ǡѴ!!													*/
/*----------------------------------------------------------------------*/

		if (ANIMEflag == 0){
			ReadFundoshi(inputFP,txtname);		/* դɤǡɤ߹ 			*/
			ConvertCADdata();					/* ãĥեޥåȤѴ			*/	
		} else {
			InitAnimation();					/* ѥ᡼				*/
			ReadAnimation(inputFP,txtname);		/* դɤǡɤ߹ 			*/
			ConvertANMdata();					/* ãĥեޥåȤѴ			*/	
		}


/*----------------------------------------------------------------------*/
/*		ǡ													*/
/*----------------------------------------------------------------------*/

		if ((outputFP = fopen(cadname,"w")) == NULL ){
			fprintf(stderr, "==== ϥե륨顼 (%s) ====\n",cadname); 
			continue;		/* !!!!!!!!!!!!!!!!!!!!()!!!!!!!!!!!!!!!!!!!!!!!! ȤĤŤ롪	*/
		}
		printf( "(->) read %-12s file ",txtname);
		ConvertSaveData(outputFP);	/* ãĥ֥եޥåȤѴ	*/
		fclose(outputFP);
		fclose(inputFP);

/*----------------------------------------------------------------------*/
/*		ǥХå														*/
/*----------------------------------------------------------------------*/
#if	Debug
		if ((inputFP = fopen(cadname,"r")) == NULL ){
			fprintf(stderr, "==== CADե륨顼 (%s) ====\n",cadname); 
			exit( 1 ) ;
		}
		DispSaveData(inputFP);		/* ֥ǡǧ */
		fclose(inputFP);
#endif

	}

/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
	printf( "(ED) ***** funcad Ѵλޤ*****\n");

}


/************************************************************************
		ãĥեޥåȤѴ
 ************************************************************************/
InitAnimation()
{
	int	i,j;

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

}

/************************************************************************
		ãĥեޥåȤѴ
 ************************************************************************/

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++;							/* ݥȥ󥿤	*/

		}

		DATAPoint[point_counter-1].nextPoint = -1;		/* ݥȥǡϽλ 	*/
		polygon_counter++;								/* ݥꥴ󥫥󥿤	*/

	}

	DATAPolygon[polygon_counter-1].nextPolygon = -1;	/* ݥꥴǡϽλ 	*/

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

}


/************************************************************************
		ãĥեޥåȤѴ
 ************************************************************************/

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;		/* ˥᡼ؤΥݥ */
		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++;							/* ݥȥ󥿤	*/
		}
		DATAPoint[point_counter-1].nextPoint = -1;		/* ݥȥǡϽλ 	*/


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

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

			/* ĺĿ */
			for(k=0;k<face_counter;k++){

				POINTNO = (faceP+facect)->pointNO[k];				/* ե룱	*/

				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;		/* ݥȥǡϽλ 		*/

		}

		polygon_counter++;								/* ݥꥴ󥫥󥿤		*/
		anime_table++;									/* ˥᡼ơ֥	*/

	}

	DATAPolygon[polygon_counter-1].nextPolygon = -1;	/* ݥꥴǡϽλ 		*/

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

}


/************************************************************************
		֥ǡեޥåȤѴ
 ************************************************************************/

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 򥻡  - - - - - -*/

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

	/*- - - - POLYGON 򥻡 - - - - - -*/

	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 򥻡 - - - - - - -*/

	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);
	}

	/*- - - - ˥᡼ơ֥򥻡 - - -*/

	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);
	}

	/*- - - - ˥᡼ݥȤ򥻡 - - -*/

	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);
	}

}

/************************************************************************
		֥ǡǧ
 ************************************************************************/

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 (" ֥ȹ¤ ======================== \n");
				break;
			case	1:
				fread (&pt,sizeof(short),1,testFP);
				fread (&polygonData[pt],sizeof(Polygon),1,testFP);
				printf (" ݥꥴ¤ ************************** \n");
				printf (" ʥС         %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 (" ݥȹ¤ --------------------------- \n");
				printf (" ʥС         %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 (" ˥ǡ %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);



}




/************************************************************************
		դɤǡɤ߹
 ************************************************************************/

ReadFundoshi(inputFP,nameP)
FILE	*inputFP;				/* դɤ(ԣأ)ǡΥեݥ */
char	*nameP;
{

	char	lineword[101]; 					/* ơ֥ե룱ԤǤκʸ */

	int		total;							/* ݥȥȡο */
	int		ix,iy,iz;						/* ݥȺɸ x1,x2,x3 */
	int 	facecount;						/* եǡ */
	int		facepointer;	
	int		color;
	int		i,counter;						/* ѥ */

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

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*		ץǡɤߤ										*/
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

	ReadHead(inputFP,lineword,nameP);		/*	إåå				*/
	ReadTotalPoint(inputFP,lineword);		/*	ݥȥȡɤ߹	*/
	ReadPointData(inputFP,lineword);		/*	ݥȥǡɤ߹	*/
	ReadFaceData(inputFP,lineword);			/*	եǡɤ߹	*/
	SetBOTH();								/*  ξ̥å					*/
	SetSIDE();								/*  ɽ΢󥻥å				*/

/*- - - - - - - - - - - - - - - - - - - */
/*	ɤ߹߽λ						*/
/*- - - - - - - - - - - - - - - - - - - */

}

/************************************************************************
		դɤ˥᡼ǡɤ߹
 ************************************************************************/

ReadAnimation(inputFP,nameP)
FILE	*inputFP;				/* դɤ(ԣأ)ǡΥեݥ */
char	*nameP;
{

	char	lineword[101]; 					/* ơ֥ե룱ԤǤκʸ */

	int		total;							/* ݥȥȡο */
	int		ix,iy,iz;						/* ݥȺɸ x1,x2,x3 */
	int 	facecount;						/* եǡ */
	int		facepointer;
	int		color;
	int		i,counter;						/* ѥ */

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

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*		ץǡɤߤ										*/
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

	ReadAnimeHead(inputFP,lineword,nameP);	/*	إåå				*/
	ReadTotalPoint(inputFP,lineword);		/*	ݥȥȡɤ߹	*/
	ReadAnimeTotal(inputFP,lineword);		/*	˥᡼ɤ߹	*/
	ReadAnimePoint(inputFP,lineword);		/*	ݥȥǡɤ߹	*/
	ReadFaceData(inputFP,lineword);			/*	եǡɤ߹	*/
	SetBOTH();								/*  ξ̥å					*/
	SetSIDE();								/*  ɽ΢󥻥å				*/

/*- - - - - - - - - - - - - - - - - - - */
/*	ɤ߹߽λ						*/
/*- - - - - - - - - - - - - - - - - - - */

}

/*=====================================================================*/
/*																		*/
/*		դɤեɤ߹ߥ롼								*/
/*																		*/
/*======================================================================*/

/************************************************************************
		ݥꥴξ̥å
 ************************************************************************/






/************************************************************************
		إåΥå
 ************************************************************************/

ReadAnimeHead(fp,lineword,nameP)
FILE	*fp;
char	*lineword;
char	*nameP;
{
	fgets(lineword,128,fp);
	if (strncmp(lineword,"3DAN",4) !=0 ){
		fprintf(stderr,"ΥեϤդɤANMեޥåȤǤϤޤ(%s)\n",nameP);		
		exit(1);
	}
}

/************************************************************************
		ȡݥȿɤ߹
 ************************************************************************/

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

	int		total;
	if ( fgets( lineword,100,fp ) == NULL ){
		fputs ("˥᡼ȡߤߥ顼\n",stderr );
		exit(1);
	}
	GetNumber( &lineword,&total);

	MSPtr.AnimeTotal =	total;

}


/************************************************************************
		ݥȥǡɤ߹
 ************************************************************************/

ReadAnimePoint(fp,linewordS)
FILE		*fp;
char		*linewordS;			/* ɤ߹ߥݥ		*/
{
	int			i,j;
	int			ix,iy,iz;
	char 		*lineword;
	int		animetotal	= MSPtr.AnimeTotal;	/* ˥᡼ȡ	*/
	int			total   = MSPtr.PointTotal;	/* ɤ߹ߥݥȿ		*/
	ANIMEPOINT	*animeP = MSPtr.animepoint;	/* ˥ݥȹ¤		*/

	for(j=0;j<animetotal;j++){
		for (i=0;i<total;i++){
			lineword = linewordS;		/* ɤ߹ߥХåեΥݥ󥿤Ȥ᤹	*/
			if ( fgets( lineword,100,fp ) == NULL ){
				fputs ("ɸǡߤߥ顼\n",stderr );
				exit(1);
			}
			GetNumber ( &lineword,&ix );	*lineword++;
			GetNumber ( &lineword,&iy );	*lineword++;
			GetNumber ( &lineword,&iz );
			(animeP+i)->shapepoint[j].pointX = ix;		/* i=ݥֹФƤѲ	*/
			(animeP+i)->shapepoint[j].pointY = iy;		/* j=ե졼ֹФƤѲ	*/
			(animeP+i)->shapepoint[j].pointZ = iz;
		}
	}

}





/************************************************************************
		إåΥå
 ************************************************************************/

ReadHead(fp,lineword,nameP)
FILE	*fp;
char	*lineword;
char	*nameP;
{
	fgets(lineword,128,fp);
	if (strncmp(lineword,"3DG1",4) !=0 ){
		fprintf(stderr,"ΥեϤդɤTXTեޥåȤǤϤޤ(%s)\n",nameP);		
		exit(1);
	}
}

/************************************************************************
		ȡݥȿɤ߹
 ************************************************************************/

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

	int		total;

	if ( fgets( lineword,100,fp ) == NULL ){
		fputs ("ݥȥȡߤߥ顼\n",stderr );
		exit(1);
	}
	GetNumber( &lineword,&total);

	MSPtr.PointTotal =	total;

}

/************************************************************************
		ݥȥǡɤ߹
 ************************************************************************/

ReadPointData(fp,linewordS)
FILE		*fp;
char		*linewordS;			/* ɤ߹ߥݥ		*/
{
	int			i;
	int			ix,iy,iz;
	char 		*lineword;
	int			total   = MSPtr.PointTotal;	/* ɤ߹ߥݥȿ		*/
	SHAPEPOINT	*shapeP = MSPtr.shapepoint; /* ץݥȹ¤	*/

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

		lineword = linewordS;		/* ɤ߹ߥХåեΥݥ󥿤Ȥ᤹	*/
		if ( fgets( lineword,100,fp ) == NULL ){
			fputs ("ɸǡߤߥ顼\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++;

	}

}

/************************************************************************
		եǡɤ߹
 ************************************************************************/

ReadFaceData(fp,linewordS)
FILE		*fp;
char		*linewordS;			/* ɤ߹ߥݥ				*/
{

	char	*lineword;	
	int		total;				/* եΥȡ				*/
	int		pointNO;			/* եݥֹ	*/
	int		topcount;			/* եĺο				*/
	int		color;				/* եΥ顼					*/
	int		i,counter;

	int			facecount	= 0;					/* եο򥫥Ȥ		*/
	SHAPEFACE	*face		= MSPtr.shapeface;		/* ե¤ΤؤΥݥ	*/

	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++){					/* եǡɤ߹	*/
			GetNumber( &lineword,&pointNO );
			*lineword++;
			face->pointNO[i] = pointNO;
		}

		GetNumber( &lineword,&color );				/* 顼ǡɤ߹		*/
		face->color = color;

		facecount++;								/* եο򣱤䤹 */
		face++;										/* եݥ󥿤ʤ	*/
		lineword = linewordS;						/* ʸݥ󥿤ꥻå	*/

	} 

	MSPtr.FaceTotal = facecount;					/* եȡ	*/

}

/************************************************************************
		̤ɽ΢å(CAD)ˡ٥ȥη׻	
 ************************************************************************/
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++;

	}

}

/************************************************************************
		ξ̥ݥꥴΥå
 ************************************************************************/
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;			/* ̥ݥꥴȤƥå	*/
	}


#if	BOTHFLAG

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

		vertex = (face+key)->facepoint;	/* keyĺݥȤ	*/

										/* keyʹߤΥݥꥴƱΤ뤫ɤå */
		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];						/* ܤ̤Υݥ */
					for(j=0;j<vertex;j++){
						if ( pointNO == (face+sub)->pointNO[j] ) flag++;	/* ̤Υݥ */
					}
				}
			}

													/* פ!!	*/
			if (flag == vertex){
													/* ݥꥴȿиɤå */

				(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

/************************************************************************
		ƥȷοǡ(10դ)
		INT ǡѴ
 ************************************************************************/

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

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

		pt = *dt ;	/* Ԥʸݥ󥿤Ȥ */

					/* ޥʥǡΤȤ */
		if ( *pt == '-' ){
			*pt++;
			sign_flag++;
		}

		while ( isdigit( *pt )) {
			nn = nn * 10 + (*pt++ - '0');
			ct++;	/* åݥ */
		}

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

		*dt = pt ;	/* Ԥʸݥ󥿤Ϥ */
		*nm = nn ;	/* ǡϤ */

		return ( ct ) ;

}

/*----------------------------------------------------------------------*/
/*	ˡ٥ȥη׻
/*----------------------------------------------------------------------*/

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;			/* ʿ̾Σ		*/
		y1 = (sp+point1)->pointY;
		z1 = (sp+point1)->pointZ;

											/* Ѥη׻				*/

		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;		/* ʿ̤ˡ٥ȥ	*/
		face -> equB = nomal_y;
		face -> equC = nomal_z;

								/* ʿ̤ ax+by+cz+D=0 ((D))	*/
		face -> equD = -( nomal_x*x1 + nomal_y*y1 + nomal_z*z1 );
								/* Υ뤿η׻				*/
		face -> equN = nomal;

}


