/***************************************************************************** * * sa2dkb.c * * from DKBTrace (c) 1990 David Buck * * This program reads a Sculpt-Animate 3D format scene file and generates an * output file that may be read in to DKBTrace. * * * This software is freely distributable. The source and/or object code may be * copied or uploaded to communications services so long as this notice remains * at the top of each file. If any changes are made to the program, you must * clearly indicate in the documentation and in the programs startup message * who it was who made the changes. The documentation should also describe what * those changes were. This software may not be included in whole or in * part into any commercial package without the express written consent of the * author. It may, however, be included in other public domain or freely * distributed software so long as the proper credit for the software is given. * * This software is provided as is without any guarantees or warranty. Although * the author has attempted to find and correct any bugs in the software, he * is not responsible for any damage caused by the use of the software. The * author is under no obligation to provide service, corrections, or upgrades * to this package. * * Despite all the legal stuff above, if you do find bugs, I would like to hear * about them. Also, if you have any comments or questions, you may contact me * at the following address: * * David Buck * 22C Sonnet Cres. * Nepean Ontario * Canada, K2H 8W7 * * I can also be reached on the following bulleton boards: * * OMX (613) 731-3419 * Mystic (613) 596-4249 or (613) 596-4772 * * Fidonet: 1:163/109.9 * Internet: dbuck@ccs.carleton.ca * The "You Can Call Me RAY" BBS (708) 358-5611 * * IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: * * The "You Can Call Me RAY" BBS (708) 358-5611 * The Information Exchange BBS (708) 945-5575 * *****************************************************************************/ #include #include /* contains "malloc" and "exit" prototypes */ #include #define DBL double typedef struct { unsigned short Red, Green, Blue, Alpha; } IMAGE_COLOUR; IMAGE_COLOUR *iff_colour_map; int colourmap_size; FILE *f, *out, *out2, *texture_file; struct Chunk_Header_Struct { long name; long size; }; typedef struct Chunk_Header_Struct CHUNK_HEADER; static CHUNK_HEADER Chunk_Header; /* function prototypes */ /* char *malloc(unsigned int size); (defined in stdlib.h) */ void read_iff_file(void); void close_all(void); void add_texture(unsigned int, unsigned int, unsigned int, unsigned int); void iff_error (void); int read_byte (FILE *); int read_word (FILE *); long read_long (FILE *); void Read_Chunk_Header (FILE *, CHUNK_HEADER *); DBL *vertices_x, *vertices_y, *vertices_z; DBL max_x, max_y, max_z, min_x, min_y, min_z; #define FABS(x) ((x<0.0)?-x:x) #define FORM 0x464f524dL #define SC3D 0x53433344L #define VERT 0x56455254L #define FACE 0x46414345L #define CMPNONE 0 char *Textures[7] = {"Dull", "Shiny", "Mirror", "Luminous", "Glass", "Metal", "Glass2"}; #define TEXTURE_TABLE_SIZE 16300 unsigned long *texture_table; unsigned int texture_table_size = 0; char outfile[80]; void close_all() { if (out != NULL) { fclose (out); unlink ("triangle.tmp"); } if (out2 != NULL) { fclose (out2); unlink (outfile); } if (texture_file != NULL) { fclose (texture_file); unlink ("textures.tmp"); } if (f != NULL) { fclose (f); } } void add_texture (texture, red, green, blue) unsigned int texture, red, green, blue; { unsigned long texture_id; int i; texture_id = ((unsigned long)texture << 24) | ((unsigned long)red << 16) | (green << 8) | blue; for (i = 0; (unsigned) i < texture_table_size; i++) if (texture_id == texture_table[i]) return; texture_table[texture_table_size++] = texture_id; if (texture_table_size >= TEXTURE_TABLE_SIZE) { fprintf (stderr, "Colour table overflow\n"); close_all(); exit(1); } fprintf (texture_file, "DECLARE %s_%d_%d_%d = TEXTURE %s COLOUR RED %f GREEN %f BLUE %f END_TEXTURE\n", Textures[texture], red, green, blue, Textures[texture], red/255.0, green/255.0, blue/255.0); } void iff_error () { fprintf (stderr, "Invalid iff file\n"); close_all(); exit(1); } int read_byte(f) FILE *f; { int c; if ((c = getc(f)) == EOF) iff_error(); return (c); } int read_word(f) FILE *f; { int result; result = read_byte(f)*256; result += read_byte(f); return (result); } long read_long(f) FILE *f; { int i; long result; result = 0; for (i = 0 ; i < 4 ; i++) result = result * 256 + read_byte(f); return (result); } void Read_Chunk_Header (f, dest) FILE *f; CHUNK_HEADER *dest; { dest->name = read_long(f); dest->size = (int) read_long(f); } void read_iff_file() { int i; int vert1, vert2, vert3; unsigned int texture; unsigned int red_int, green_int, blue_int; max_x = max_y = max_z = -10000000.0; min_x = min_y = min_z = 10000000.0; while (1) { Read_Chunk_Header(f, &Chunk_Header); switch ((int) Chunk_Header.name) { case FORM: if (read_long(f) != SC3D) iff_error(); break; case VERT: if ((vertices_x = (DBL *) malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) { fprintf (stderr, "Cannot allocate memory for vertices_x array\n"); close_all(); exit(1); } if ((vertices_y = (DBL *) malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) { fprintf (stderr, "Cannot allocate memory for vertices_y array\n"); close_all(); exit(1); } if ((vertices_z = (DBL *) malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) { fprintf (stderr, "Cannot allocate memory for vertices_z array\n"); close_all(); exit(1); } for (i = 0 ; (long) i < Chunk_Header.size/12L ; i++) { vertices_x[i] = read_long(f) / 10000.0; if (vertices_x[i] < min_x) min_x = vertices_x[i]; if (vertices_x[i] > max_x) max_x = vertices_x[i]; vertices_y[i] = read_long(f) / 10000.0; if (vertices_y[i] < min_y) min_y = vertices_y[i]; if (vertices_y[i] > max_y) max_y = vertices_y[i]; vertices_z[i] = read_long(f) / 10000.0; if (vertices_z[i] < min_z) min_z = vertices_z[i]; if (vertices_z[i] > max_z) max_z = vertices_z[i]; } break; case FACE: for (i = 0 ; (long) i < Chunk_Header.size/16L ; i++) { vert1 = (int) read_long(f); vert2 = (int) read_long(f); vert3 = (int) read_long(f); red_int = read_byte(f); green_int = read_byte(f); blue_int = read_byte(f); texture = read_byte(f); texture &= 0x07; /* mask upper bits */ add_texture (texture, red_int, green_int, blue_int); fprintf (out, "TRIANGLE <%f %f %f> <%f %f %f> <%f %f %f> TEXTURE %s_%d_%d_%d END_TEXTURE END_TRIANGLE\n", vertices_x[vert1], vertices_y[vert1], vertices_z[vert1], vertices_x[vert2], vertices_y[vert2], vertices_z[vert2], vertices_x[vert3], vertices_y[vert3], vertices_z[vert3], Textures[texture], red_int, green_int, blue_int); } return; default: for (i = 0 ; (long) i < Chunk_Header.size ; i++) if (getc(f) == EOF) iff_error(); break; } } } void main (argc, argv) int argc; char **argv; { int c; if (argc != 3) { fprintf (stderr, "Usage: %s \n", argv[0]); exit (1); } f = out = out2 = texture_file = NULL; strcpy(outfile, argv[2]); if ((texture_table = (unsigned long *) malloc((unsigned int)TEXTURE_TABLE_SIZE * sizeof (unsigned long))) == NULL) { fprintf (stderr, "Cannot allocate memory for texture table\n"); exit(1); } if ((f = fopen(argv[1], "rb")) == NULL) { fprintf (stderr, "Cannot open IFF file %s\n", argv[1]); exit(1); } if ((out = fopen("triangle.tmp", "w")) == NULL) { fprintf (stderr, "Cannot open temporary file triangle.tmp\n"); close_all(); exit(1); } if ((texture_file = fopen("textures.tmp", "w")) == NULL) { fprintf (stderr, "Cannot open temporary file textures.tmp\n"); close_all(); exit(1); } fprintf(out, "\nOBJECT\n UNION\n"); read_iff_file(); fprintf(out, " END_UNION\n"); fprintf(out, " BOUNDED_BY\n INTERSECTION\n"); fprintf(out, " PLANE <1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(max_x) * 1.01); fprintf(out, " PLANE <-1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(min_x) * 1.01); fprintf(out, " PLANE <0.0 1.0 0.0> %1.02f END_PLANE\n", FABS(max_y) * 1.01); fprintf(out, " PLANE <0.0 -1.0 0.0> %1.02f END_PLANE\n", FABS(min_y) * 1.01); fprintf(out, " PLANE <0.0 0.0 1.0> %1.02f END_PLANE\n", FABS(max_z) * 1.01); fprintf(out, " PLANE <0.0 0.0 -1.0> %1.02f END_PLANE\n", FABS(min_z) * 1.01); fprintf(out, " END_INTERSECTION\n END_BOUND\n \nEND_OBJECT\n"); printf ("X values range from %f to %f\n", min_x, max_x); printf ("Y values range from %f to %f\n", min_y, max_y); printf ("Z values range from %f to %f\n", min_z, max_z); fclose(f); fflush(out); fclose(out); fflush(texture_file); fclose(texture_file); if ((out2 = fopen (argv[2], "w")) == NULL) { fprintf (stderr, "Cannot open output file %s\n", argv[2]); exit(1); } if ((out = fopen("triangle.tmp", "r")) == NULL) { fprintf (stderr, "Cannot open temporary file triangle.tmp\n"); close_all(); exit(1); } if ((texture_file = fopen("textures.tmp", "r")) == NULL) { fprintf (stderr, "Cannot open temporary file textures.tmp\n"); close_all(); exit(1); } while ((c = getc(texture_file)) != EOF) putc (c, out2); while ((c = getc(out)) != EOF) putc (c, out2); fflush(out2); fclose(out2); out2 = NULL; /* make sure close_all doesn't delete out2 file */ close_all(); exit(0); }