/*
 * off2ray.c
 *
 * Convert OFF format objects to rayshade format.
 *
 * Warning!  Hastily thrown-together code follows.
 *
 * usage:
 * off2ray objname > objname.ray	(default vertex order)
 * or
 * off2ray objnamne yes > objname.ray	(reverse vertex order)
 *
 * Reads 'objname.geom', as well as 'objname.vnorm' and 'objname.pcol'
 * if they exist, and writes a rayshade-compatible object description
 * to the standard output.
 *
 * Note that you'll want to hand-tweak the surface definitions.
 *
 * Craig Kolb 12/89
 *
 * Indexed polygon color changes by Tom Friedel, 1/90
 */
#include <stdio.h>

#define TRUE	1
#define FALSE	0
#define usage()		fprintf(stderr,"usage: off2ray basename\n")

typedef struct {
	float x, y, z;
} Vertex;

FILE *fgeom, *fnorm, *fpcol;
Vertex *vertices, *normals, *surfaces;
int Nvert, Nnorm, Npoly, Nsurface, *surfindex, Ncols;
int NoNormals, NoPcol, ReverseOrder;

main(argc, argv)
int argc;
char **argv;
{
	char buf[BUFSIZ];
	int porder, norder, pnum, nnum, junk, i, j;
	float red, green, blue;

	if (argc != 2 && argc != 3) {
		usage();
		exit(2);
	}

	if (argc == 3)
		ReverseOrder = TRUE;

	sprintf(buf,"%s.geom",argv[1]);
#ifdef __WATCOMC__
	fgeom = fopen(buf, "rb");
#else
	fgeom = fopen(buf, "r");
#endif
	if (fgeom == (FILE *)NULL) {
		fprintf(stderr,"Cannot open geometry file %s\n",buf);
		exit(3);
	}
	/*
	 * Read geometry file header and read in vertices.
	 */
	fscanf(fgeom,"%d %d %d",&Nvert, &Npoly, &junk);
	vertices = (Vertex *)malloc(Nvert * sizeof(Vertex));
	for (i = 0; i < Nvert; i++)
		fscanf(fgeom,"%f %f %f",&vertices[i].x, &vertices[i].y,
					&vertices[i].z);

	sprintf(buf,"%s.vnorm",argv[1]);
#ifdef __WATCOMC__
	fnorm = fopen(buf, "rb");
#else
	fnorm = fopen(buf, "r");
#endif
	if (fnorm == (FILE *)NULL)
		NoNormals = TRUE;
	else {
		/*
		 * Read normal file header and normals.
		 */
		fscanf(fnorm,"%d %d %d",&Nnorm, &Npoly, &junk);
		normals = (Vertex *)malloc(Nnorm * sizeof(Vertex));
		for (i = 0; i < Nnorm; i++)
			fscanf(fnorm,"%f %f %f",&normals[i].x,
						&normals[i].y,
						&normals[i].z);
	}

	sprintf(buf,"%s.ipcol",argv[1]);
#ifdef __WATCOMC__
	fpcol = fopen(buf, "rb");
#else
	fpcol = fopen(buf, "r");
#endif
	if (fpcol == (FILE *)NULL)
		NoPcol = TRUE;
	else {
		fscanf(fpcol,"%d %d",&Ncols, &Npoly);
		surfaces = (Vertex *)malloc(Npoly * sizeof(Vertex));
		surfindex = (int *)malloc(Npoly * sizeof(int));
		for (i = 0; i < Ncols; i++) {
			fscanf(fpcol,"%f %f %f", &red, &green, &blue);
			find_surface(red, green, blue);
		}
		for (i = 0; i < Npoly; i++) {
			fscanf(fpcol,"%d", & surfindex[ i ] ) ;
			surfindex[ i ] -- ;
		}
		print_surfaces();
	}

	for (i = 0; i < Npoly; i++) {
		fscanf(fgeom,"%d",&porder);
		if (!NoNormals) {
			fscanf(fnorm, "%d",&porder);
			if (porder != 3) {
				fprintf(stderr,"%d-sided poly!\n",porder);
				exit(10);
			}
		}
		if (porder == 3)
			printf("triangle ");
		else
			printf("poly ");
		if (NoPcol)
			printf("poly_surf ");
		else
			printf("poly_surf%d ",surfindex[i]);
		print_poly(porder);
	}
}

print_poly(order)
int order;
{
	int pnum, nnum;

	if (order == 0)
		return;

	fscanf(fgeom,"%d",&pnum);
	pnum--;
	if (!NoNormals) {
		fscanf(fnorm,"%d",&nnum);
		nnum--;
	}
	if (ReverseOrder)
		print_poly(order -1);
	printf("%f %f %f",vertices[pnum].x, vertices[pnum].y,
					vertices[pnum].z);
	if (NoNormals)
		printf("\n");
	else if (!ReverseOrder)
		printf(" %f %f %f\n",-normals[nnum].x, -normals[nnum].y,
					-normals[nnum].z);
	else
		printf(" %f %f %f\n",normals[nnum].x, normals[nnum].y,
					normals[nnum].z);
	if (!ReverseOrder)
		print_poly(order -1);
} 

find_surface(r, g, b)
float r, g, b;
{
	surfaces[Nsurface].x = r;
	surfaces[Nsurface].y = g;
	surfaces[Nsurface].z = b;
	Nsurface++;

}

print_surfaces()
{
	int i;

	for (i = 0; i < Nsurface; i++)
		printf("surface poly_surf%d 0 0 0  %f %f %f  0 0 0 0 0 0 0\n",
			i, surfaces[i].x, surfaces[i].y, surfaces[i].z);
}
