/* what do ya' know, here's some global variables */
static double nodes[MAXNODES][3];
static double normals[MAXNODES][3];
+static int faces[MAXNODES][3];
+int ncount, vncount, fcount;
static int ccw_list[MAXNODES];
int ccw_list_ptr;
FILE *in, *out;
+double refx, refy, refz;
+
/* some simple list routines */
}
+/* fix the cw list and append to ccw_list */
+void fix_cw_list(int *list, int list_ptr) {
+ int i, j, len;
+
+ if ( list_ptr < 3 ) {
+ printf("List is empty ... skipping\n");
+ return;
+ }
+
+ printf("Fixing cw list, size = %d\n", list_ptr);
+
+ i = 0;
+ while ( i < list_ptr ) {
+ /* do next strip */
+
+ /* find length */
+ len = 0;
+ /* scan rest of strip (until -1) */
+ while ( ((i+len) < list_ptr) && (list[i+len] != -1) ) {
+ // printf("len = %d item = %d\n", len, list[i+len] );
+ len++;
+ }
+ // printf(" Final length = %d\n", len);
+
+ if ( (len % 2) != 0 ) {
+ /* if length is odd, just reverse order of nodes to reverse
+ winding */
+ if ( ccw_list_ptr ) {
+ list_add(ccw_list, &ccw_list_ptr, -1);
+ }
+ for ( j = i + len - 1; j >= i; j-- ) {
+ // printf(" odd -> item = %d\n", list[j] );
+ list_add(ccw_list, &ccw_list_ptr, list[j]);
+ }
+ } else {
+ /* if length is even, reverse order of (n-1) nodes to
+ reverse winding, and create an orphan triangle for the
+ last "nth" node */
+ if ( ccw_list_ptr ) {
+ list_add(ccw_list, &ccw_list_ptr, -1);
+ }
+ for ( j = i + len - 2; j >= i; j-- ) {
+ // printf(" even -> item = %d\n", list[j] );
+ list_add(ccw_list, &ccw_list_ptr, list[j]);
+ }
+
+ // printf(" even bonus -> item = %d\n", list[i + len - 1] );
+ // printf(" even bonus -> item = %d\n", list[i + len - 2] );
+ // printf(" even bonus -> item = %d\n", list[i + len - 3] );
+ list_add(ccw_list, &ccw_list_ptr, -1);
+ list_add(ccw_list, &ccw_list_ptr, list[i + len - 3]);
+ list_add(ccw_list, &ccw_list_ptr, list[i + len - 2]);
+ list_add(ccw_list, &ccw_list_ptr, list[i + len - 1]);
+ }
+
+ i += len + 1;
+ }
+}
+
+
+// Calculate distance between (0,0,0) and the specified point
+static double calc_dist(double x, double y, double z) {
+ return ( sqrt(x*x + y*y + z*z) );
+}
+
+
+void dump_global_bounds( void ) {
+ double dist, radius;
+ int i;
+
+ radius = 0.0;
+
+ fprintf(out, "\n");
+
+ for ( i = 1; i < ncount; i++ ) {
+
+ dist = calc_dist(nodes[i][0] - refx, nodes[i][1] - refy,
+ nodes[i][2] - refz);
+ // printf("node = %.2f %.2f %.2f dist = %.2f\n",
+ // nodes[i][0], nodes[i][1], nodes[i][2],
+ // dist);
+
+ if ( dist > radius ) {
+ radius = dist;
+ }
+
+ }
+
+ fprintf(out, "gb %.5f %.5f %.5f %.2f\n", refx, refy, refz, radius);
+}
+
+
+/* dump nodes */
+void dump_nodes( void ) {
+ int i;
+
+ fprintf(out, "\n");
+ for ( i = 1; i < ncount; i++ ) {
+ fprintf(out, "v %.5f %.5f %.5f\n",
+ nodes[i][0] - refx, nodes[i][1] - refy, nodes[i][2] - refz);
+ }
+}
+
+
+/* dump normals */
+void dump_normals( void ) {
+ int i;
+
+ fprintf(out, "\n");
+ for ( i = 1; i < vncount; i++ ) {
+ fprintf(out, "vn %.5f %.5f %.5f\n",
+ normals[i][0], normals[i][1], normals[i][2]);
+ }
+}
+
+
+/* dump faces */
+void dump_faces( void ) {
+ int i;
+
+ fprintf(out, "\n");
+ for ( i = 1; i < fcount; i++ ) {
+ fprintf(out, "f %d %d %d\n",
+ faces[i][0], faces[i][1], faces[i][2]);
+ }
+}
+
+
/* dump list */
void dump_list(int *list, int list_ptr) {
int i;
while ( i < list_ptr ) {
/* do next strip */
+ if ( (i % 2) == 0 ) {
+ fprintf(out, "\nusemtl desert1\n");
+ } else {
+ fprintf(out, "\nusemtl desert2\n");
+ }
+
/* dump header */
fprintf(out, "t %d %d %d\n", list[i], list[i+1], list[i+2]);
/* printf("t %d %d %d\n", list[i], list[i+1], list[i+2]); */
void obj_fix(char *infile, char *outfile) {
char line[256];
double dot_prod;
- int first, ncount, vncount, n1, n2, n3, n4;
+ int first, n1, n2, n3, n4;
+ double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin;
int is_ccw;
if ( (in = fopen(infile, "r")) == NULL ) {
list_init(&ccw_list_ptr);
list_init(&cw_list_ptr);
+ /* I start counting at one because that is how the triangle
+ program refers to nodes and normals */
first = 1;
ncount = 1;
vncount = 1;
+ fcount = 1;
printf("Reading file: %s\n", infile);
/* pass along the comments verbatim */
fprintf(out, "%s", line);
} else if ( strlen(line) <= 1 ) {
- /* pass along empty lines */
- fprintf(out, "%s", line);
+ /* don't pass along empty lines */
+ // fprintf(out, "%s", line);
} else if ( strncmp(line, "v ", 2) == 0 ) {
/* save vertex to memory and output to file */
if ( ncount < MAXNODES ) {
/* printf("vertex = %s", line); */
- sscanf(line, "v %lf %lf %lf\n",
- &nodes[ncount][0], &nodes[ncount][1], &nodes[ncount][2]);
- fprintf(out, "v %.2f %.2f %.2f\n",
- nodes[ncount][0], nodes[ncount][1], nodes[ncount][2]);
+ sscanf(line, "v %lf %lf %lf\n", &x, &y, &z);
+ nodes[ncount][0] = x;
+ nodes[ncount][1] = y;
+ nodes[ncount][2] = z;
+
+ /* first time through set min's and max'es */
+ if ( ncount == 1 ) {
+ xmin = x;
+ xmax = x;
+ ymin = y;
+ ymax = y;
+ zmin = z;
+ zmax = z;
+ }
+
+ /* keep track of min/max vertex values */
+ if ( x < xmin ) xmin = x;
+ if ( x > xmax ) xmax = x;
+ if ( y < ymin ) ymin = y;
+ if ( y > ymax ) ymax = y;
+ if ( z < zmin ) zmin = z;
+ if ( z > zmax ) zmax = z;
+
+ // fprintf(out, "v %.2f %.2f %.2f\n",
+ // nodes[ncount][0], nodes[ncount][1], nodes[ncount][2]);
ncount++;
} else {
printf("Read too many nodes ... dying :-(\n");
sscanf(line, "vn %lf %lf %lf\n",
&normals[vncount][0], &normals[vncount][1],
&normals[vncount][2]);
- fprintf(out, "vn %.4f %.4f %.4f\n", normals[vncount][0],
- normals[vncount][1], normals[vncount][2]);
+ // fprintf(out, "vn %.4f %.4f %.4f\n", normals[vncount][0],
+ // normals[vncount][1], normals[vncount][2]);
vncount++;
} else {
printf("Read too many vertex normals ... dying :-(\n");
}
}
} else if ( line[0] == 'f' ) {
- /* pass along the unoptimized faces verbatim */
- fprintf(out, "%s", line);
+ if ( fcount < MAXNODES ) {
+ /* pass along the unoptimized faces verbatim */
+ sscanf(line, "f %d %d %d\n", &n1, &n2, &n3);
+ faces[fcount][0] = n1;
+ faces[fcount][1] = n2;
+ faces[fcount][2] = n3;
+
+ fcount++;
+ } else {
+ printf("Read too many unoptimized faces ... dying :-(\n");
+ exit(-1);
+ }
+
+ // fprintf(out, "%s", line);
} else if ( line[0] == 'q' ) {
/* continue a triangle strip */
n1 = n2 = 0;
}
}
- fprintf(out, "winding ccw\n");
- dump_list(ccw_list, ccw_list_ptr);
+ /* reference point is the "center" */
+ refx = (xmin + xmax) / 2.0;
+ refy = (ymin + ymax) / 2.0;
+ refz = (zmin + zmax) / 2.0;
- fprintf(out, "winding cw\n");
- dump_list(cw_list, cw_list_ptr);
+ /* convert the cw_list to ccw add append to ccw_list */
+ fix_cw_list(cw_list, cw_list_ptr);
+
+ dump_global_bounds();
+ dump_nodes();
+ dump_normals();
+ if ( fcount > 1 ) {
+ dump_faces();
+ }
+
+ dump_list(ccw_list, ccw_list_ptr);
fclose(in);
fclose(out);
/* $Log$
-/* Revision 1.9 1998/04/18 04:01:03 curt
-/* Now use libMath rather than having local copies of math routines.
+/* Revision 1.14 1998/05/23 15:19:49 curt
+/* Output more digits after the decimal place.
/*
+ * Revision 1.13 1998/05/20 20:55:19 curt
+ * Fixed arbitrary polygon winding problem here so all tristrips are passed
+ * to runtime simulator with a consistant counter clockwise winding.
+ *
+ * Revision 1.12 1998/05/16 13:11:26 curt
+ * Fixed an off by one error in node, normal, and face counters.
+ *
+ * Revision 1.11 1998/04/27 15:59:24 curt
+ * Fixed an off by one error.
+ *
+ * Revision 1.10 1998/04/27 03:33:11 curt
+ * Code now calculates a center reference points and outputs everything
+ * relative to that. This is useful in the rendering engine to keep everything
+ * close to (0, 0, 0) where we can avoid many GLfloat precision problems.
+ *
+ * Revision 1.9 1998/04/18 04:01:03 curt
+ * Now use libMath rather than having local copies of math routines.
+ *
* Revision 1.8 1998/04/08 23:19:37 curt
* Adopted Gnu automake/autoconf system.
*