home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************/
- /* */
- /* VP2RAW.C Viewpoint to Raw triangle converter */
- /* */
- /* Takes the 3 numbers following the delimiter v, stores */
- /* them in an array, then reads the connection table and */
- /* generates a polygon data file that's converted into */
- /* triangles */
- /* */
- /* Written to get Viewpoint files into anything else. */
- /* */
- /* Jeff Bowermaster & Steve Anger */
- /* Splat! Graphics */
- /* 1/11/93 */
- /* */
- /* Syntax: VP2RAW filename.ext [outfile] */
- /* */
- /* Input: A Viewpoint object file */
- /* */
- /* g */
- /* v 3.660927 0.002173 -0.738231 */
- /* v 3.719482 0.346536 -0.832918 */
- /* v ... */
- /* */
- /* Output: filename.RAW (or a specified filename) */
- /* */
- /* in the form: */
- /* */
- /* texture */
- /* vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3 */
- /* vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3 */
- /* vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3 */
- /* vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3 */
- /* ... */
- /* */
- /* Some cluze: */
- /* */
- /* vn 0.332949 -0.705421 0.625720 */
- /* vn -0.260047 -0.789584 0.555817 */
- /* vn 0.532304 -0.547688 0.645515 */
- /* vn -0.440163 0.835449 -0.329062 */
- /* */
- /* vn Viewpoint files can contain vn (vertex normal) information, and */
- /* based on the fact that there are usually more vertex normals than */
- /* vertex's (vertii?) I assume they are normal to the center of the */
- /* polygon, but I get really vague about the reason. I don't use them. */
- /* */
- /* Folowing the vn's, there is a connection table in the form: */
- /* */
- /* g coat */
- /* s 1 */
- /* f 66//52 67//53 68//54 69//55 */
- /* f 69//55 68//54 70//56 71//57 */
- /* f 71//57 70//56 72//58 73//59 */
- /* f 73//59 72//58 74//60 75//61 */
- /* f 75//61 74//60 76//62 77//63 */
- /* f 77//63 76//62 78//64 79//65 */
- /* f 79//65 78//64 80//66 81//67 */
- /* ... */
- /* */
- /* g I parse the name (coat) and define a texture block with the color */
- /* gray. Go in and edit these textures to whatever you like. */
- /* */
- /* s May be a smoothing group. I just ignore it too. */
- /* */
- /* f The first number (before the //) is the vertex, the second number */
- /* is the normal. Lines denote individual polygons, thus these are */
- /* all squares. I've seen 13gons (tridecagons), but they are generally */
- /* 3-4-5 gons. */
- /* */
- /* Some Viewpoint files do not contain vertex normals so the connection */
- /* table can be used directly. I'm also leaving that one up to you. */
- /* */
- /* Thank you Viewpoint for allowing these files to be distributed so */
- /* freely. Awfully decent of you people. */
- /* */
- /***************************************************************************/
-
- #include <math.h>
- #include <string.h>
- #include <alloc.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- typedef struct
- {
- float x, y, z;
- }
- Vector;
-
- int remove_triangle (Vector *poly, int *polysize, Vector *v1, Vector *v2,
- Vector *v3);
- int poly_inside (Vector *poly, int polysize, Vector *v);
- void vect_init (Vector *v, float x, float y, float z);
- void vect_copy (Vector *v1, Vector *v2);
- void vect_add (Vector *v1, Vector *v2, Vector *v3);
- void vect_sub (Vector *v1, Vector *v2, Vector *v3);
- void vect_scale (Vector *v, float k);
- float vect_mag (Vector *v);
- float dot_prod (Vector *v1, Vector *v2);
- void cross_prod (Vector *v1, Vector *v2, Vector *v3);
- float vect_angle (Vector *v1, Vector *v2);
- void add_ext (char *fname, char *ext, int force);
- int polyread (int argc, char *argv[]);
-
-
- void main(int argc, char *argv[])
- {
- char *ptr, *infile, *outfile, *string, buffer[5];
- char parse0, parse1,*texture,tex[50][20];
- FILE *in, *out;
- int a,count,i,n,t,textures,x,done,length,pos,point1,point2,vertexnum[15],have;
- Vector vertex;
- Vector huge *coords = NULL;
- Vector huge *keep;
-
-
- printf("(V)iew(P)oint 2 (RAW) Triangle Translator\n");
- printf(" (c) 1993 Jeff Bowermaster & Steve Anger,\n Splat! Graphics\n");
-
- if (argc < 2)
- {
- printf("\nUsage: VP2RAW filename[.obj] [outfile]\n");
- printf(" outfile defaults to filename.raw\n");
- exit(1);
- }
-
- string=(char *)malloc(256);
- texture=(char *)malloc(80);
-
- infile=(char *)calloc(80,sizeof(char));
- outfile=(char *)calloc(80,sizeof(char));
-
- strcpy (infile, argv[1]);
-
- if (argc > 2)
- strcpy (outfile, argv[2]);
- else {
- strcpy (outfile, infile);
- add_ext (outfile, "pol", 1);
- }
-
- add_ext (infile, "obj", 1);
- add_ext (outfile, "pol", 0);
-
- if ((in = fopen (infile, "r")) == NULL) {
- printf ("Cannot open input file %s!\n", infile);
- exit (1);
- }
-
- if((out = fopen(outfile,"wt"))==NULL) {
- printf ("Cannot open output file %s!\n", outfile);
- exit (1);
- }
-
- printf("\nReading %s for vertex count...\n",argv[1]);
- count=0;
- n=0;
- while (fgets(string,256,in) != NULL) { // get a line
- parse0 = string[0];
- parse1 = string[1];
- switch (parse0) {
- case 'v':
- // v 3.660927 0.002173 -0.738231
- if(parse1==' ') {
- count++;
- }
- break;
-
- case 'g':
- /* g skin */
- if(parse1==' ') {
- sscanf(string,"%*s %s",texture);
- have=0;
- for(x=0;x<n;x++)
- if(!strcmp(texture,tex[x])) have=1;
- if(!have)
- strcpy(tex[n++],texture);
- }
- break;
-
- default: /* Blank lines, page numbers... */
- break;
- }
- }
-
- for(x=0;x<n;x++) {
- for(a=0;a<strlen(tex[x]);a++) {
- if(tex[x][a]==' ') tex[x][a] = '_';
- }
- printf(" %d %s\n",x,tex[x]);
- }
-
- if ((coords = farmalloc ((long)count * sizeof(Vector)))==NULL) {
- printf("Insufficient memory for vertices.\n");
- exit(1);
- }
- else
- printf("Allocating memory for %d vertices.\n",count);
-
- keep=coords;
- printf("Writing data to %s. Please wait...\n",outfile);
-
- textures=n;
-
- for(t=0;t<textures;t++) {
- printf("Working on %s\n",tex[t]);
- fprintf(out,"%s\n",tex[t]);
- rewind(in);
-
- while (fgets(string,256,in) != NULL) { // get a line
- parse0 = string[0];
- parse1 = string[1];
- switch (parse0) {
- case 'v':
- // v 3.660927 0.002173 -0.738231
- if(parse1==' ' && !t) {
- sscanf(string,"%*s %f %f %f\n",
- &vertex.x,&vertex.y,&vertex.z);
- coords->x=vertex.x;
- coords->y=vertex.y;
- coords->z=vertex.z;
- coords++;
- // fprintf(out,"%f %f %f\n",vertex.x,vertex.y,vertex.z);
- }
- break;
-
- case 'g':
- /* g skin */
- sscanf(string,"%*s %s\n",texture);
- if(strcmp(tex[t],texture))
- break;
- break;
-
- case 'f':
- /* f 2576//2175 2732//2331 2721//2320
-
- 1) get the numbers before the //
- 2) save the first one
- 3) repeat it at the end of the line
-
- */
- if(strcmp(tex[t],texture))
- break;
-
- coords=keep;
- length=strlen(string);
-
- buffer[0]='\0';
- buffer[1]='\0';
- buffer[2]='\0';
- buffer[3]='\0';
- buffer[4]='\0';
-
- pos = 0;
- n = 0;
-
- for(x=2;x<length;x++){
- switch (string[x]) {
-
- case '/':
- vertexnum[n++]=atoi(buffer);
- buffer[0]='\0';
- buffer[1]='\0';
- buffer[2]='\0';
- buffer[3]='\0';
- buffer[4]='\0';
- pos=0;
- while(string[x++]!=' ');
- x--;
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- buffer[pos++]=string[x];
- break;
-
- default:
- break;
- }
- }
-
- fprintf(out,"%d ",n);
-
- for(i=0;i<n;i++)
- fprintf(out,"%f %f %f ",
- (coords+vertexnum[i]-1)->x,
- (coords+vertexnum[i]-1)->y,
- (coords+vertexnum[i]-1)->z);
- fprintf(out,"\n");
-
- break;
-
- default: /* Blank lines, page numbers... */
- break;
- }
- }
- }
- fclose(in);
- fclose(out);
-
- polyread(argc,argv);
- }
-
- /*----------------------------------------------------------------------
-
- Polygon to triangle converter
- by Steve Anger Jan 1993
-
- This program is commited to the public domain. Feel free to use all or part
- of this code in your own programs.
-
-
- This is a utility that breaks polygon shapes down into individual
- triangles. The polygons are assumed to be planar however the program
- should be able to tolerate slightly non-planar shapes.
-
- The input file consists of one line per polygon in the following format:
-
- n x1 y1 z1 x2 y2 z2 ..... xn yn zn
-
- where n is the number of vertices in the polygon and xi, yi, and zi are the
- coordinates of the polygon's vertices.
-
-
- The output file consists of one triangle per line in the following format:
-
- x1 y1 z1 x2 y2 z2 x3 y3 z3
-
-
- -----------------------------------------------------------------------*/
-
-
- #define POLYMAX 17
- #define BUFSIZ 512
-
- int polyread (int argc, char *argv[])
- {
- FILE *f, *g;
- Vector poly[POLYMAX], v1, v2, v3;
- int polysize, cnt, i, j, start;
- char infile[80] = "", outfile[80] = "",parse,*string,texture[20];
-
- if (argc < 2) {
- printf ("Usage: infile[.pol] [outfile[.raw]]\n");
- exit(1);
- }
- string=malloc(BUFSIZ);
-
- strcpy (infile, argv[1]);
-
- if (argc > 2)
- strcpy (outfile, argv[2]);
- else {
- strcpy (outfile, infile);
- add_ext (outfile, "raw", 1);
- }
-
- add_ext (infile, "pol", 1);
- add_ext (outfile, "raw", 0);
-
- f = fopen (infile, "r");
- if (f == NULL) {
- printf ("Unable to open input file '%s'\n", infile);
- exit(1);
- }
-
- g = fopen (outfile, "w");
- if (g == NULL) {
- printf ("Unable to open output file '%s'\n", outfile);
- exit(1);
- }
-
- printf("Converting polygons to triangles...\n");
- cnt = 0;
-
- while (fgets(string,BUFSIZ,f) != NULL) { // get a line
- parse = string[0];
-
- switch (parse) {
-
- case '\x0A':
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- polysize = 0;
- start=1;
-
- sscanf (string, "%d", &polysize);
-
- if (polysize > POLYMAX) {
- printf ("Polygon %d too large (%d), skipping.\n",cnt,polysize);
- fgets(string,BUFSIZ,f); //read to the end of this one
- break;
- }
- if(polysize>9)
- start=2;
-
- for (i=0;i<polysize; i++) {
- sscanf (&string[start], "%f %f %f", &poly[i].x, &poly[i].y, &poly[i].z);
- for(j=0;j<3;j++){
- start=strchr(&string[start+1],' ')-string;
- }
- }
-
- /* Remove triangles from the polygon until there's nothing left */
- while (remove_triangle (poly, &polysize, &v1, &v2, &v3)) {
- fprintf (g, "%f %f %f %f %f %f %f %f %f \n",
- v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z);
- }
-
- cnt++;
-
- if (cnt % 10 == 0)
- printf ("%d\r", cnt);
- break;
-
- default:
- sscanf(string,"%s",&texture);
- fprintf(g,"%s\n",texture);
- break;
- }
-
- }
-
- fclose (f);
- fclose (g);
-
- return (0);
- }
-
-
- /* Removes a triangle from the specified polygon. */
- /* The size of the polygon is reduced */
- int remove_triangle (Vector *poly, int *polysize,Vector *v1, Vector *v2, Vector *v3)
- {
- Vector tri[3], center;
- int i, j, a, b, c;
-
- if (*polysize < 3)
- return 0; /* No triangle found */
-
- /* This simplest case */
- if (*polysize == 3) {
- vect_copy (v1, &poly[0]);
- vect_copy (v2, &poly[1]);
- vect_copy (v3, &poly[2]);
-
- *polysize = 0;
-
- return 1; /* Ok */
- }
-
- for (i = 0; i < *polysize; i++) {
- a = i;
- b = (i + 1) % *polysize;
- c = (i + 2) % *polysize;
-
- /* Select a candidate triangle */
- vect_copy (&tri[0], &poly[a]);
- vect_copy (&tri[1], &poly[b]);
- vect_copy (&tri[2], &poly[c]);
-
- /* Calculate the center of the triangle */
- vect_init (¢er, 0.0, 0.0, 0.0);
- vect_add (¢er, ¢er, &tri[0]);
- vect_add (¢er, ¢er, &tri[1]);
- vect_add (¢er, ¢er, &tri[2]);
- vect_scale (¢er, 1.0/3.0);
-
- /* Is the center of the triangle inside the original polygon? */
- /* If not skip this triangle */
- if (!poly_inside (poly, *polysize, ¢er))
- continue;
-
- /* Are any of the polygons other vertices inside the triangle */
- /* If so skip this triangle */
- for (j = 0; j < *polysize; j++) {
- if (j != a && j != b && j != c && poly_inside (tri, 3, &poly[j]))
- break;
- }
-
- if (j < *polysize)
- continue;
-
- /* This is the one */
- vect_copy (v1, &tri[0]);
- vect_copy (v2, &tri[1]);
- vect_copy (v3, &tri[2]);
-
- /* Remove this triangle from the polygon */
- (*polysize)--;
- for (j = b; j < *polysize; j++)
- vect_copy (&poly[j], &poly[j+1]);
-
- return 1; /* Ok */
- }
- return 0; /* No triangle found */
- }
-
-
- /* Determines if the specified point 'v' is inside the polygon. */
- /* Uses a convoluted version of the sum of angles approach */
- int poly_inside (Vector *poly, int polysize, Vector *v)
- {
- Vector sum, cross, v1, v2;
- float magcross;
- int i;
-
- vect_init (&sum, 0.0, 0.0, 0.0);
-
- for (i = 0; i < polysize; i++) {
- vect_sub (&v1, v, &poly[i]);
- vect_sub (&v2, v, &poly[(i+1) % polysize]);
-
- cross_prod (&cross, &v1, &v2);
- magcross = vect_mag (&cross);
-
- if (magcross > 0.0)
- vect_scale (&cross, 1.0/magcross);
-
- vect_scale (&cross, vect_angle (&v1, &v2));
- vect_add (&sum, &sum, &cross);
- }
- return (vect_mag (&sum) > M_PI);
- }
-
-
- void vect_init (Vector *v, float x, float y, float z)
- {
- v->x = x;
- v->y = y;
- v->z = z;
- }
-
-
- void vect_copy (Vector *v1, Vector *v2)
- {
- v1->x = v2->x;
- v1->y = v2->y;
- v1->z = v2->z;
- }
-
-
- void vect_add (Vector *v1, Vector *v2, Vector *v3)
- {
- v1->x = v2->x + v3->x;
- v1->y = v2->y + v3->y;
- v1->z = v2->z + v3->z;
- }
-
-
- void vect_sub (Vector *v1, Vector *v2, Vector *v3)
- {
- v1->x = v2->x - v3->x;
- v1->y = v2->y - v3->y;
- v1->z = v2->z - v3->z;
- }
-
-
- void vect_scale (Vector *v, float k)
- {
- v->x = k * v->x;
- v->y = k * v->y;
- v->z = k * v->z;
- }
-
-
- float vect_mag (Vector *v)
- {
- float mag = sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
-
- return mag;
- }
-
-
- float dot_prod (Vector *v1, Vector *v2)
- {
- return (v1->x*v2->x + v1->y*v2->y + v1->z*v2->z);
- }
-
-
- void cross_prod (Vector *v1, Vector *v2, Vector *v3)
- {
- v1->x = (v2->y * v3->z) - (v2->z * v3->y);
- v1->y = (v2->z * v3->x) - (v2->x * v3->z);
- v1->z = (v2->x * v3->y) - (v2->y * v3->x);
- }
-
-
- /* Return the angle (rads) between two vectors */
- float vect_angle (Vector *v1, Vector *v2)
- {
- float mag1, mag2, angle, cos_theta;
-
- mag1 = vect_mag(v1);
- mag2 = vect_mag(v2);
-
- if (mag1 * mag2 == 0.0)
- angle = 0.0;
- else {
- cos_theta = dot_prod(v1,v2) / (mag1 * mag2);
-
- if (cos_theta <= -1.0)
- angle = M_PI;
- else if (cos_theta >= +1.0)
- angle = 0.0;
- else
- angle = acos(cos_theta);
- }
-
- return angle;
- }
-
-
- void add_ext (char *fname, char *ext, int force)
- {
- int i;
-
- for (i = 0; i < strlen(fname); i++)
- if (fname[i] == '.') break;
-
- if (fname[i] == '\0' || force) {
- if (strlen(ext) > 0)
- fname[i++] = '.';
-
- strcpy (&fname[i], ext);
- }
- }
-