From: curt Date: Mon, 8 Jun 1998 17:11:44 +0000 (+0000) Subject: Renamed *.[ch] to *.[ch]xx X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=f7a80a9de3b3d1380cb23dbdbb6db4feea9d34c6;p=flightgear.git Renamed *.[ch] to *.[ch]xx --- diff --git a/FixObj/Makefile.am b/FixObj/Makefile.am index 2ee3159b4..0f7f16710 100644 --- a/FixObj/Makefile.am +++ b/FixObj/Makefile.am @@ -26,7 +26,7 @@ bin_PROGRAMS = fixobj -fixobj_SOURCES = main.c obj.c obj.h +fixobj_SOURCES = main.cxx obj.cxx obj.hxx fixobj_LDADD = \ $(top_builddir)/Lib/Math/libMath.la \ @@ -38,6 +38,9 @@ INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib #--------------------------------------------------------------------------- # $Log$ +# Revision 1.5 1998/06/08 17:11:44 curt +# Renamed *.[ch] to *.[ch]xx +# # Revision 1.4 1998/04/24 00:44:05 curt # Added zlib support. # diff --git a/FixObj/main.c b/FixObj/main.c deleted file mode 100644 index bb20a0e37..000000000 --- a/FixObj/main.c +++ /dev/null @@ -1,55 +0,0 @@ -/* main.c -- read and fix the stripping order of a .obj file - * - * Written by Curtis Olson, started December 1997. - * - * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id$ - * (Log is kept at end of this file) - */ - - -#include - -#include "obj.h" - - -int main(int argc, char **argv) { - char infile[256], outfile[256]; - - if ( argc != 3 ) { - printf("Usage %s: infile outfile\n", argv[0]); - } - - strcpy(infile, argv[1]); - strcpy(outfile, argv[2]); - - /* load the input data files */ - obj_fix(infile, outfile); - - return(0); -} - - -/* $Log$ -/* Revision 1.2 1998/01/09 23:03:12 curt -/* Restructured to split 1deg x 1deg dem's into 64 subsections. -/* - * Revision 1.1 1997/12/08 19:28:54 curt - * Initial revision. - * - */ diff --git a/FixObj/main.cxx b/FixObj/main.cxx new file mode 100644 index 000000000..bf117a10c --- /dev/null +++ b/FixObj/main.cxx @@ -0,0 +1,57 @@ +// main.cxx -- read and fix the stripping order of a .obj file +// +// Written by Curtis Olson, started December 1997. +// +// Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + + +#include + +#include "obj.hxx" + + +int main(int argc, char **argv) { + char infile[256], outfile[256]; + + if ( argc != 3 ) { + printf("Usage %s: infile outfile\n", argv[0]); + } + + strcpy(infile, argv[1]); + strcpy(outfile, argv[2]); + + // load the input data files + obj_fix(infile, outfile); + + return(0); +} + + +// $Log$ +// Revision 1.1 1998/06/08 17:11:45 curt +// Renamed *.[ch] to *.[ch]xx +// +// Revision 1.2 1998/01/09 23:03:12 curt +// Restructured to split 1deg x 1deg dem's into 64 subsections. +// +// Revision 1.1 1997/12/08 19:28:54 curt +// Initial revision. +// + diff --git a/FixObj/obj.c b/FixObj/obj.c deleted file mode 100644 index 31942ea61..000000000 --- a/FixObj/obj.c +++ /dev/null @@ -1,617 +0,0 @@ -/************************************************************************** - * obj.c -- routines to handle WaveFront .obj format files. - * - * Written by Curtis Olson, started October 1997. - * - * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id$ - * (Log is kept at end of this file) - **************************************************************************/ - - -#include -#include - -#include "obj.h" - -#include - - -/* 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; - -static int cw_list[MAXNODES]; -int cw_list_ptr; - -FILE *in, *out; - -double refx, refy, refz; - - -/* some simple list routines */ - -/* reset the list */ -void list_init(int *list_ptr) { - *list_ptr = 0; -} - - -/* add to list */ -void list_add(int *list, int *list_ptr, int node) { - if ( *list_ptr >= MAXNODES ) { - printf("ERROR: list overflow in list_add()\n"); - exit(-1); - } - - list[*list_ptr] = node; - *list_ptr += 1; - - /* printf("list pointer = %d adding %d\n", *list_ptr, node); */ -} - - -/* 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, "gbs %.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, n1, n2, n3; - double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin, dist, radius; - - fprintf(out, "\n"); - for ( i = 1; i < fcount; i++ ) { - n1 = faces[i][0]; - n2 = faces[i][1]; - n3 = faces[i][2]; - - /* calc center of face */ - xmin = xmax = nodes[n1][0]; - ymin = ymax = nodes[n1][1]; - zmin = zmax = nodes[n1][2]; - - if ( nodes[n2][0] < xmin ) { xmin = nodes[n2][0]; } - if ( nodes[n2][0] > xmax ) { xmax = nodes[n2][0]; } - if ( nodes[n2][1] < ymin ) { ymin = nodes[n2][1]; } - if ( nodes[n2][1] > ymax ) { ymax = nodes[n2][1]; } - if ( nodes[n2][2] < zmin ) { zmin = nodes[n2][2]; } - if ( nodes[n2][2] > zmax ) { zmax = nodes[n2][2]; } - - if ( nodes[n3][0] < xmin ) { xmin = nodes[n3][0]; } - if ( nodes[n3][0] > xmax ) { xmax = nodes[n3][0]; } - if ( nodes[n3][1] < ymin ) { ymin = nodes[n3][1]; } - if ( nodes[n3][1] > ymax ) { ymax = nodes[n3][1]; } - if ( nodes[n3][2] < zmin ) { zmin = nodes[n3][2]; } - if ( nodes[n3][2] > zmax ) { zmax = nodes[n3][2]; } - - x = (xmin + xmax) / 2.0; - y = (ymin + ymax) / 2.0; - z = (zmin + zmax) / 2.0; - - /* calc bounding radius */ - radius = calc_dist(nodes[n1][0] - x, nodes[n1][1] - y, - nodes[n1][2] - z); - - dist = calc_dist(nodes[n2][0] - x, nodes[n2][1] - y, nodes[n2][2] - z); - if ( dist > radius ) { radius = dist; } - - dist = calc_dist(nodes[n3][0] - x, nodes[n3][1] - y, nodes[n3][2] - z); - if ( dist > radius ) { radius = dist; } - - /* output data */ - fprintf(out, "bs %.2f %.2f %.2f %.2f\n", x, y, z, radius); - fprintf(out, "f %d %d %d\n", n1, n2, n3); - } -} - - -/* dump list */ -void dump_list(int *list, int list_ptr) { - double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin, dist, radius; - int i, j, len, n; - - if ( list_ptr < 3 ) { - printf("List is empty ... skipping\n"); - return; - } - - printf("Dumping list, size = %d\n", list_ptr); - - i = 0; - while ( i < list_ptr ) { - /* do next strip */ - - if ( (i % 2) == 0 ) { - fprintf(out, "\nusemtl desert1\n"); - } else { - fprintf(out, "\nusemtl desert2\n"); - } - - /* find length of next tri strip */ - 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("strip length = %d\n", len); - - /* calc center of face */ - n = list[i]; - xmin = xmax = nodes[n][0]; - ymin = ymax = nodes[n][1]; - zmin = zmax = nodes[n][2]; - // printf("%.2f %.2f %.2f\n", nodes[n][0], nodes[n][1], nodes[n][2]); - - for ( j = i + 1; j < i + len; j++ ) { - // printf("j = %d\n", j); - n = list[j]; - if ( nodes[n][0] < xmin ) { xmin = nodes[n][0]; } - if ( nodes[n][0] > xmax ) { xmax = nodes[n][0]; } - if ( nodes[n][1] < ymin ) { ymin = nodes[n][1]; } - if ( nodes[n][1] > ymax ) { ymax = nodes[n][1]; } - if ( nodes[n][2] < zmin ) { zmin = nodes[n][2]; } - if ( nodes[n][2] > zmax ) { zmax = nodes[n][2]; } - // printf("%.2f %.2f %.2f\n", nodes[n][0], nodes[n][1], nodes[n][2]); - } - x = (xmin + xmax) / 2.0; - y = (ymin + ymax) / 2.0; - z = (zmin + zmax) / 2.0; - // printf("center = %.2f %.2f %.2f\n", x, y, z); - - /* calc bounding radius */ - n = list[i]; - radius = calc_dist(nodes[n][0] - x, nodes[n][1] - y, nodes[n][2] - z); - - for ( j = i + 1; j < i + len; j++ ) { - n = list[j]; - dist = calc_dist(nodes[n][0] - x, nodes[n][1] - y, - nodes[n][2] - z); - if ( dist > radius ) { radius = dist; } - } - // printf("radius = %.2f\n", radius); - - /* dump bounding sphere and header */ - fprintf(out, "bs %.2f %.2f %.2f %.2f\n", x, y, z, radius); - 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]); */ - i += 3; - - /* dump rest of strip (until -1) */ - while ( (i < list_ptr) && (list[i] != -1) ) { - fprintf(out, "q %d", list[i]); - i++; - if ( (i < list_ptr) && (list[i] != -1) ) { - fprintf(out, " %d", list[i]); - i++; - } - fprintf(out, "\n"); - } - - i++; - } -} - - -/* Check the direction the current triangle faces, compared to it's - * pregenerated normal. Returns the dot product between the target - * normal and actual normal. If the dot product is close to 1.0, they - * nearly match. If the are close to -1.0, the are nearly - * opposite. */ -double check_cur_face(int n1, int n2, int n3) { - double v1[3], v2[3], approx_normal[3], dot_prod, temp; - - /* check for the proper rotation by calculating an approximate - * normal and seeing if it is close to the precalculated normal */ - v1[0] = nodes[n2][0] - nodes[n1][0]; - v1[1] = nodes[n2][1] - nodes[n1][1]; - v1[2] = nodes[n2][2] - nodes[n1][2]; - v2[0] = nodes[n3][0] - nodes[n1][0]; - v2[1] = nodes[n3][1] - nodes[n1][1]; - v2[2] = nodes[n3][2] - nodes[n1][2]; - - MAT3cross_product(approx_normal, v1, v2); - MAT3_NORMALIZE_VEC(approx_normal,temp); - dot_prod = MAT3_DOT_PRODUCT(normals[n1], approx_normal); - - /* not first triangle */ - /* if ( ((dot_prod < -0.5) && !is_backwards) || - ((dot_prod > 0.5) && is_backwards) ) { - printf(" Approx normal = %.2f %.2f %.2f\n", approx_normal[0], - approx_normal[1], approx_normal[2]); - printf(" Dot product = %.4f\n", dot_prod); - } */ - /* angle = acos(dot_prod); */ - /* printf("Normal ANGLE = %.3f rads.\n", angle); */ - - return(dot_prod); -} - - -/* Load a .obj file */ -void obj_fix(char *infile, char *outfile) { - char line[256]; - double dot_prod; - 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 ) { - printf("Cannot open file: %s\n", infile); - exit(-1); - } - - if ( (out = fopen(outfile, "w")) == NULL ) { - printf("Cannot open file: %s\n", outfile); - exit(-1); - } - - 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); - - while ( fgets(line, 250, in) != NULL ) { - if ( line[0] == '#' ) { - /* pass along the comments verbatim */ - fprintf(out, "%s", line); - } else if ( strlen(line) <= 1 ) { - /* 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", &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"); - exit(-1); - } - } else if ( strncmp(line, "vn ", 3) == 0 ) { - /* save vertex normals to memory and output to file */ - if ( vncount < MAXNODES ) { - /* printf("vertex normal = %s", line); */ - 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]); - vncount++; - } else { - printf("Read too many vertex normals ... dying :-(\n"); - exit(-1); - } - } else if ( line[0] == 't' ) { - /* starting a new triangle strip */ - - printf("Starting a new triangle strip\n"); - - n1 = n2 = n3 = n4 = 0; - - printf("new tri strip = %s", line); - sscanf(line, "t %d %d %d %d\n", &n1, &n2, &n3, &n4); - - /* special cases to handle bugs in our beloved tri striper */ - if ( (n1 == 4) && (n2 == 2) && (n3 == 2) && (n4 == 1) ) { - n2 = 3; - } - if ( (n1 == 3) && (n2 == 1) && (n3 == 1) && (n4 == 0) ) { - n3 = 4; - } - - dot_prod = check_cur_face(n1, n2, n3); - if ( dot_prod < 0.0 ) { - /* this stripe is backwards (CW) */ - is_ccw = 0; - printf(" -> Starting a backwards stripe\n"); - } else { - /* this stripe is normal (CCW) */ - is_ccw = 1; - } - - if ( is_ccw ) { - if ( ccw_list_ptr ) { - list_add(ccw_list, &ccw_list_ptr, -1); - } - - list_add(ccw_list, &ccw_list_ptr, n1); - list_add(ccw_list, &ccw_list_ptr, n2); - list_add(ccw_list, &ccw_list_ptr, n3); - } else { - if ( cw_list_ptr ) { - list_add(cw_list, &cw_list_ptr, -1); - } - - list_add(cw_list, &cw_list_ptr, n1); - list_add(cw_list, &cw_list_ptr, n2); - list_add(cw_list, &cw_list_ptr, n3); - } - - if ( n4 > 0 ) { - if ( is_ccw ) { - list_add(ccw_list, &ccw_list_ptr, n4); - } else { - list_add(cw_list, &cw_list_ptr, n4); - } - } - } else if ( line[0] == 'f' ) { - 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; - - /* printf("continued tri strip = %s ", line); */ - sscanf(line, "q %d %d\n", &n1, &n2); - - if ( is_ccw ) { - list_add(ccw_list, &ccw_list_ptr, n1); - } else { - list_add(cw_list, &cw_list_ptr, n1); - } - - if ( n2 > 0 ) { - if ( is_ccw ) { - list_add(ccw_list, &ccw_list_ptr, n2); - } else { - list_add(cw_list, &cw_list_ptr, n2); - } - } - } else { - printf("Unknown line in %s = %s\n", infile, line); - } - } - - /* reference point is the "center" */ - refx = (xmin + xmax) / 2.0; - refy = (ymin + ymax) / 2.0; - refz = (zmin + zmax) / 2.0; - - /* 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.16 1998/05/27 02:27:22 curt -/* Commented out a couple of debugging messages. -/* - * Revision 1.15 1998/05/24 02:47:47 curt - * For each strip, specify a default material property and calculate a center - * and bounding sphere. - * - * 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. - * - * Revision 1.7 1998/03/19 02:51:41 curt - * Added special case handling to compensate for bugs in our beloved tri striper - * - * Revision 1.6 1998/03/03 15:36:12 curt - * Tweaks for compiling with g++ - * - * Revision 1.5 1998/03/03 03:37:03 curt - * Cumulative tweaks. - * - * Revision 1.4 1998/01/31 00:41:25 curt - * Made a few changes converting floats to doubles. - * - * Revision 1.3 1998/01/19 19:51:07 curt - * A couple final pre-release tweaks. - * - * Revision 1.2 1998/01/09 23:03:12 curt - * Restructured to split 1deg x 1deg dem's into 64 subsections. - * - * Revision 1.1 1997/12/08 19:28:54 curt - * Initial revision. - * - */ diff --git a/FixObj/obj.cxx b/FixObj/obj.cxx new file mode 100644 index 000000000..25690d5b4 --- /dev/null +++ b/FixObj/obj.cxx @@ -0,0 +1,619 @@ +// obj.cxx -- routines to handle WaveFront .obj format files. +// +// Written by Curtis Olson, started October 1997. +// +// Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + + +#include +#include + +#include "obj.hxx" + +#include + + + + +// 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; + +static int cw_list[MAXNODES]; +int cw_list_ptr; + +FILE *in, *out; + +double refx, refy, refz; + + +// some simple list routines + +// reset the list +void list_init(int *list_ptr) { + *list_ptr = 0; +} + + +// add to list +void list_add(int *list, int *list_ptr, int node) { + if ( *list_ptr >= MAXNODES ) { + printf("ERROR: list overflow in list_add()\n"); + exit(-1); + } + + list[*list_ptr] = node; + *list_ptr += 1; + + // printf("list pointer = %d adding %d\n", *list_ptr, node); +} + + +// 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, "gbs %.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, n1, n2, n3; + double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin, dist, radius; + + fprintf(out, "\n"); + for ( i = 1; i < fcount; i++ ) { + n1 = faces[i][0]; + n2 = faces[i][1]; + n3 = faces[i][2]; + + // calc center of face + xmin = xmax = nodes[n1][0]; + ymin = ymax = nodes[n1][1]; + zmin = zmax = nodes[n1][2]; + + if ( nodes[n2][0] < xmin ) { xmin = nodes[n2][0]; } + if ( nodes[n2][0] > xmax ) { xmax = nodes[n2][0]; } + if ( nodes[n2][1] < ymin ) { ymin = nodes[n2][1]; } + if ( nodes[n2][1] > ymax ) { ymax = nodes[n2][1]; } + if ( nodes[n2][2] < zmin ) { zmin = nodes[n2][2]; } + if ( nodes[n2][2] > zmax ) { zmax = nodes[n2][2]; } + + if ( nodes[n3][0] < xmin ) { xmin = nodes[n3][0]; } + if ( nodes[n3][0] > xmax ) { xmax = nodes[n3][0]; } + if ( nodes[n3][1] < ymin ) { ymin = nodes[n3][1]; } + if ( nodes[n3][1] > ymax ) { ymax = nodes[n3][1]; } + if ( nodes[n3][2] < zmin ) { zmin = nodes[n3][2]; } + if ( nodes[n3][2] > zmax ) { zmax = nodes[n3][2]; } + + x = (xmin + xmax) / 2.0; + y = (ymin + ymax) / 2.0; + z = (zmin + zmax) / 2.0; + + // calc bounding radius + radius = calc_dist(nodes[n1][0] - x, nodes[n1][1] - y, + nodes[n1][2] - z); + + dist = calc_dist(nodes[n2][0] - x, nodes[n2][1] - y, nodes[n2][2] - z); + if ( dist > radius ) { radius = dist; } + + dist = calc_dist(nodes[n3][0] - x, nodes[n3][1] - y, nodes[n3][2] - z); + if ( dist > radius ) { radius = dist; } + + // output data + fprintf(out, "bs %.2f %.2f %.2f %.2f\n", x, y, z, radius); + fprintf(out, "f %d %d %d\n", n1, n2, n3); + } +} + + +// dump list +void dump_list(int *list, int list_ptr) { + double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin, dist, radius; + int i, j, len, n; + + if ( list_ptr < 3 ) { + printf("List is empty ... skipping\n"); + return; + } + + printf("Dumping list, size = %d\n", list_ptr); + + i = 0; + while ( i < list_ptr ) { + // do next strip + + if ( (i % 2) == 0 ) { + fprintf(out, "\nusemtl desert1\n"); + } else { + fprintf(out, "\nusemtl desert2\n"); + } + + // find length of next tri strip + 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("strip length = %d\n", len); + + // calc center of face + n = list[i]; + xmin = xmax = nodes[n][0]; + ymin = ymax = nodes[n][1]; + zmin = zmax = nodes[n][2]; + // printf("%.2f %.2f %.2f\n", nodes[n][0], nodes[n][1], nodes[n][2]); + + for ( j = i + 1; j < i + len; j++ ) { + // printf("j = %d\n", j); + n = list[j]; + if ( nodes[n][0] < xmin ) { xmin = nodes[n][0]; } + if ( nodes[n][0] > xmax ) { xmax = nodes[n][0]; } + if ( nodes[n][1] < ymin ) { ymin = nodes[n][1]; } + if ( nodes[n][1] > ymax ) { ymax = nodes[n][1]; } + if ( nodes[n][2] < zmin ) { zmin = nodes[n][2]; } + if ( nodes[n][2] > zmax ) { zmax = nodes[n][2]; } + // printf("%.2f %.2f %.2f\n", nodes[n][0], nodes[n][1], nodes[n][2]); + } + x = (xmin + xmax) / 2.0; + y = (ymin + ymax) / 2.0; + z = (zmin + zmax) / 2.0; + // printf("center = %.2f %.2f %.2f\n", x, y, z); + + // calc bounding radius + n = list[i]; + radius = calc_dist(nodes[n][0] - x, nodes[n][1] - y, nodes[n][2] - z); + + for ( j = i + 1; j < i + len; j++ ) { + n = list[j]; + dist = calc_dist(nodes[n][0] - x, nodes[n][1] - y, + nodes[n][2] - z); + if ( dist > radius ) { radius = dist; } + } + // printf("radius = %.2f\n", radius); + + // dump bounding sphere and header + fprintf(out, "bs %.2f %.2f %.2f %.2f\n", x, y, z, radius); + 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]); + i += 3; + + // dump rest of strip (until -1) + while ( (i < list_ptr) && (list[i] != -1) ) { + fprintf(out, "q %d", list[i]); + i++; + if ( (i < list_ptr) && (list[i] != -1) ) { + fprintf(out, " %d", list[i]); + i++; + } + fprintf(out, "\n"); + } + + i++; + } +} + + +// Check the direction the current triangle faces, compared to it's +// pregenerated normal. Returns the dot product between the target +// normal and actual normal. If the dot product is close to 1.0, they +// nearly match. If the are close to -1.0, the are nearly opposite. +double check_cur_face(int n1, int n2, int n3) { + double v1[3], v2[3], approx_normal[3], dot_prod, temp; + + // check for the proper rotation by calculating an approximate + // normal and seeing if it is close to the precalculated normal + v1[0] = nodes[n2][0] - nodes[n1][0]; + v1[1] = nodes[n2][1] - nodes[n1][1]; + v1[2] = nodes[n2][2] - nodes[n1][2]; + v2[0] = nodes[n3][0] - nodes[n1][0]; + v2[1] = nodes[n3][1] - nodes[n1][1]; + v2[2] = nodes[n3][2] - nodes[n1][2]; + + MAT3cross_product(approx_normal, v1, v2); + MAT3_NORMALIZE_VEC(approx_normal,temp); + dot_prod = MAT3_DOT_PRODUCT(normals[n1], approx_normal); + + // not first triangle + // if ( ((dot_prod < -0.5) && !is_backwards) || + // ((dot_prod > 0.5) && is_backwards) ) { + // printf(" Approx normal = %.2f %.2f %.2f\n", approx_normal[0], + // approx_normal[1], approx_normal[2]); + // printf(" Dot product = %.4f\n", dot_prod); + // } + // angle = acos(dot_prod); + // printf("Normal ANGLE = %.3f rads.\n", angle); + + return(dot_prod); +} + + +// Load a .obj file +void obj_fix(char *infile, char *outfile) { + char line[256]; + double dot_prod; + 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 ) { + printf("Cannot open file: %s\n", infile); + exit(-1); + } + + if ( (out = fopen(outfile, "w")) == NULL ) { + printf("Cannot open file: %s\n", outfile); + exit(-1); + } + + 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); + + while ( fgets(line, 250, in) != NULL ) { + if ( line[0] == '#' ) { + // pass along the comments verbatim + fprintf(out, "%s", line); + } else if ( strlen(line) <= 1 ) { + // 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", &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"); + exit(-1); + } + } else if ( strncmp(line, "vn ", 3) == 0 ) { + // save vertex normals to memory and output to file + if ( vncount < MAXNODES ) { + // printf("vertex normal = %s", line); + 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]); + vncount++; + } else { + printf("Read too many vertex normals ... dying :-(\n"); + exit(-1); + } + } else if ( line[0] == 't' ) { + // starting a new triangle strip + + printf("Starting a new triangle strip\n"); + + n1 = n2 = n3 = n4 = 0; + + printf("new tri strip = %s", line); + sscanf(line, "t %d %d %d %d\n", &n1, &n2, &n3, &n4); + + // special cases to handle bugs in our beloved tri striper + if ( (n1 == 4) && (n2 == 2) && (n3 == 2) && (n4 == 1) ) { + n2 = 3; + } + if ( (n1 == 3) && (n2 == 1) && (n3 == 1) && (n4 == 0) ) { + n3 = 4; + } + + dot_prod = check_cur_face(n1, n2, n3); + if ( dot_prod < 0.0 ) { + // this stripe is backwards (CW) + is_ccw = 0; + printf(" -> Starting a backwards stripe\n"); + } else { + // this stripe is normal (CCW) + is_ccw = 1; + } + + if ( is_ccw ) { + if ( ccw_list_ptr ) { + list_add(ccw_list, &ccw_list_ptr, -1); + } + + list_add(ccw_list, &ccw_list_ptr, n1); + list_add(ccw_list, &ccw_list_ptr, n2); + list_add(ccw_list, &ccw_list_ptr, n3); + } else { + if ( cw_list_ptr ) { + list_add(cw_list, &cw_list_ptr, -1); + } + + list_add(cw_list, &cw_list_ptr, n1); + list_add(cw_list, &cw_list_ptr, n2); + list_add(cw_list, &cw_list_ptr, n3); + } + + if ( n4 > 0 ) { + if ( is_ccw ) { + list_add(ccw_list, &ccw_list_ptr, n4); + } else { + list_add(cw_list, &cw_list_ptr, n4); + } + } + } else if ( line[0] == 'f' ) { + 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; + + // printf("continued tri strip = %s ", line); + sscanf(line, "q %d %d\n", &n1, &n2); + + if ( is_ccw ) { + list_add(ccw_list, &ccw_list_ptr, n1); + } else { + list_add(cw_list, &cw_list_ptr, n1); + } + + if ( n2 > 0 ) { + if ( is_ccw ) { + list_add(ccw_list, &ccw_list_ptr, n2); + } else { + list_add(cw_list, &cw_list_ptr, n2); + } + } + } else { + printf("Unknown line in %s = %s\n", infile, line); + } + } + + // reference point is the "center" + refx = (xmin + xmax) / 2.0; + refy = (ymin + ymax) / 2.0; + refz = (zmin + zmax) / 2.0; + + // 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.1 1998/06/08 17:11:46 curt +// Renamed *.[ch] to *.[ch]xx +// +// Revision 1.16 1998/05/27 02:27:22 curt +// Commented out a couple of debugging messages. +// +// Revision 1.15 1998/05/24 02:47:47 curt +// For each strip, specify a default material property and calculate a center +// and bounding sphere. +// +// 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. +// +// Revision 1.7 1998/03/19 02:51:41 curt +// Added special case handling to compensate for bugs in our beloved tri striper +// +// Revision 1.6 1998/03/03 15:36:12 curt +// Tweaks for compiling with g++ +// +// Revision 1.5 1998/03/03 03:37:03 curt +// Cumulative tweaks. +// +// Revision 1.4 1998/01/31 00:41:25 curt +// Made a few changes converting floats to doubles. +// +// Revision 1.3 1998/01/19 19:51:07 curt +// A couple final pre-release tweaks. +// +// Revision 1.2 1998/01/09 23:03:12 curt +// Restructured to split 1deg x 1deg dem's into 64 subsections. +// +// Revision 1.1 1997/12/08 19:28:54 curt +// Initial revision. +// + diff --git a/FixObj/obj.h b/FixObj/obj.h deleted file mode 100644 index 4fd07f42f..000000000 --- a/FixObj/obj.h +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************************** - * obj.h -- routines to handle WaveFront .obj format files. - * - * Written by Curtis Olson, started October 1997. - * - * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id$ - * (Log is kept at end of this file) - **************************************************************************/ - - -#ifndef OBJ_H -#define OBJ_H - - -#define MAXNODES 100000 - - -/* Load a .obj file */ -void obj_fix(char *infile, char *outfile); - - -#endif /* OBJ_H */ - - -/* $Log$ -/* Revision 1.4 1998/03/03 15:36:13 curt -/* Tweaks for compiling with g++ -/* - * Revision 1.3 1998/01/31 00:41:25 curt - * Made a few changes converting floats to doubles. - * - * Revision 1.2 1998/01/09 23:03:13 curt - * Restructured to split 1deg x 1deg dem's into 64 subsections. - * - * Revision 1.1 1997/12/08 19:28:55 curt - * Initial revision. - * - */ diff --git a/FixObj/obj.hxx b/FixObj/obj.hxx new file mode 100644 index 000000000..59a362c8d --- /dev/null +++ b/FixObj/obj.hxx @@ -0,0 +1,60 @@ +// obj.hxx -- routines to handle WaveFront .obj format files. +// +// Written by Curtis Olson, started October 1997. +// +// Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + + +#ifndef OBJ_HXX +#define OBJ_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + + +#define MAXNODES 100000 + + +// Load a .obj file +void obj_fix(char *infile, char *outfile); + + +#endif // OBJ_HXX + + +// $Log$ +// Revision 1.1 1998/06/08 17:11:46 curt +// Renamed *.[ch] to *.[ch]xx +// +// Revision 1.4 1998/03/03 15:36:13 curt +// Tweaks for compiling with g++ +// +// Revision 1.3 1998/01/31 00:41:25 curt +// Made a few changes converting floats to doubles. +// +// Revision 1.2 1998/01/09 23:03:13 curt +// Restructured to split 1deg x 1deg dem's into 64 subsections. +// +// Revision 1.1 1997/12/08 19:28:55 curt +// Initial revision. +// +