--- ray/src/cv/mgflib/3ds2mgf.c 1996/02/08 11:08:03 1.1 +++ ray/src/cv/mgflib/3ds2mgf.c 2008/11/10 19:08:18 1.10 @@ -1,5 +1,8 @@ +#ifndef lint +static const char RCSid[] = "$Id: 3ds2mgf.c,v 1.10 2008/11/10 19:08:18 greg Exp $"; +#endif /* - 3DS2POV.C Copyright (c) 1996 Steve Anger and Jeff Bowermaster + 3DS2POV.C by Steve Anger and Jeff Bowermaster MGF output added by Greg Ward Reads a 3D Studio .3DS file and writes a POV-Ray, Vivid, @@ -10,10 +13,6 @@ Compiled with MSDOS GNU C++ 2.4.1 or generic ANSI-C compiler */ -#ifndef lint -static char SCCSid[] = "$SunId$ LBL"; -#endif - #include #include #include @@ -47,8 +46,8 @@ extern unsigned _stklen = 16384; #define MGF 4 #define RAW 99 -#define DEG(x) ((180.0/M_PI)*(x)) -#define RAD(x) ((M_PI/180.0)*(x)) +#define DEG(x) ((double)(180.0/M_PI)*(x)) +#define RAD(x) ((double)(M_PI/180.0)*(x)) #ifndef M_PI #define M_PI (3.14159265358979323846) @@ -270,6 +269,8 @@ int cameras = 0; int libs = 0; float vue_version = 1.0; Matrix *ani_matrix = NULL; +int no_opt = FALSE; +FILE *meshf = NULL; void process_args (int argc, char *argv[]); @@ -349,21 +350,35 @@ char *read_string (void); float findfov (float lens); int read_mgfmatname (char *s, int n, FILE *f); +char *progname; + int main (int argc, char *argv[]) { + char meshfname[128]; Material *m; int i; process_args (argc, argv); - if (format != RAW) { + if (!no_opt) { opt_set_format (format); opt_set_dec (4); opt_set_bound (bound); opt_set_smooth (smooth); opt_set_quiet (!verbose); opt_set_fname (outname, ""); + } else if (format == MGF) { + strcpy(meshfname, outname); + add_ext(meshfname, "inc", 1); + if (!strcmp(meshfname, outname)) { + printf ("Output and mesh file names are identical!\n"); + exit (1); + } + if ((meshf = fopen (meshfname, "w")) == NULL) { + printf ("Cannot open mesh output file %s!\n", meshfname); + exit (1); + } } if ((in = fopen (inname, "rb")) == NULL) { @@ -407,11 +422,14 @@ int main (int argc, char *argv[]) if (frame >= 0) save_animation(); - if (format != RAW) { + if (!no_opt) { write_summary (out); fflush (out); opt_finish(); + } else if (meshf != NULL) { + fclose(meshf); + fprintf (out, "i %s\n", meshfname); } fclose (out); @@ -436,14 +454,10 @@ int main (int argc, char *argv[]) void process_args (int argc, char *argv[]) { int i; - char *progname; char *env_opt, *option; printf("\n\nAutodesk 3D Studio to Raytracer file Translator. Feb/96\n"); - printf("Version 2.0 Copyright (c) 1996 Steve Anger and Jeff Bowermaster\n"); -#ifdef __GNUC__ - printf ("32 bit version. DOS extender Copyright (c) 1991 DJ Delorie\n"); -#endif + printf("Version 2.0 by Steve Anger and Jeff Bowermaster 1996\n"); printf ("\n"); if (argc < 2) { @@ -456,7 +470,7 @@ void process_args (int argc, char *argv[]) printf (" -b - Convert this object as a box\n"); printf (" +i, -i - Turn internal bounding on or off\n"); printf (" +v, -v - Turn verbose status messages on or off\n"); - printf (" -op - Output to POV-Ray 2.0 format (default)\n"); + printf (" -op - Output to POV-Ray 2.0 format\n"); printf (" -op1 - Output to POV-Ray 1.0 format\n"); printf (" -ov - Output to Vivid format\n"); printf (" -ol - Output to poLyray format\n"); @@ -480,7 +494,7 @@ void process_args (int argc, char *argv[]) else if (!strcmp(progname, "3ds2raw")) format = RAW; else - format = MGF; /* default if program name strange */ + format = POV20; /* default if program name strange */ strcpy (inname, ""); strcpy (outname, ""); @@ -536,6 +550,9 @@ void process_args (int argc, char *argv[]) if ((strlen(vuename) > 0) != (frame >= 0)) abortmsg ("The -a and -f parameters must be used together", 1); + + if (format == RAW || (format == MGF && smooth < 0.1)) + no_opt = TRUE; } @@ -906,6 +923,9 @@ void write_summary (FILE *f) case MGF: comstr = "# "; break; + default: + printf ("Illegal format in write_summary() '%c'\n", format); + exit(1); } fprintf (f, "%s Object CenterX CenterY CenterZ LengthX LengthY LengthZ\n", comstr); fprintf (f, "%s ---------- ---------- ---------- ---------- ---------- ---------- ----------\n", comstr); @@ -991,7 +1011,7 @@ void write_light (FILE *f, char *name, Vector pos, Col if (name[0]) fprintf (f, "o %s\n", name); fprintf (f, "m\n\tsides 1\n\tc\n\t\t\tcmix %.3f R %.3f G %.3f B\n\ted %e\n", CIE_Y_r*col.red, CIE_Y_g*col.green, CIE_Y_b*col.blue, - 10000.0*(CIE_Y_r*col.red + CIE_Y_g*col.green + CIE_Y_b*col.blue)); + 100000.0*(CIE_Y_r*col.red + CIE_Y_g*col.green + CIE_Y_b*col.blue)); fprintf (f, "v c =\n\tp %.4f %.4f %.4f\nsph c .01\n", pos[X], pos[Y], pos[Z]); if (name[0]) fprintf (f, "o\n"); @@ -1066,7 +1086,7 @@ void write_spot (FILE *f, char *name, Vector pos, Vect fprintf (f, "# hotspot: %.2f\n# falloff: %.2f\n", hotspot, falloff); fprintf (f, "m\n\tsides 1\n\tc\n\t\t\tcmix %.3f R %.3f G %.3f B\n\ted %e\n", CIE_Y_r*col.red, CIE_Y_g*col.green, CIE_Y_b*col.blue, - 10000.0*(CIE_Y_r*col.red + CIE_Y_g*col.green + CIE_Y_b*col.blue)); + 100000.0*(CIE_Y_r*col.red + CIE_Y_g*col.green + CIE_Y_b*col.blue)); fprintf (f, "v c =\n\tp %.4f %.4f %.4f\n\tn %.4f %.4f %.4f\n", pos[X], pos[Y], pos[Z], target[X]-pos[X], target[Y]-pos[Y], target[Z]-pos[Z]); @@ -1581,6 +1601,7 @@ void write_mgf_material (FILE *f, MatProp *m) void write_mesh (FILE *f, Mesh *mesh) { int i; + char curmat[80]; Vector va, vb, vc; Summary *new_summary; Matrix obj_matrix; @@ -1607,11 +1628,33 @@ void write_mesh (FILE *f, Mesh *mesh) } switch (format) { + case MGF: + if (no_opt) { + if (mesh->name[0]) fprintf (meshf, "o %s\n", mesh->name); + for (i = 0; i < mesh->vertices; i++) { + vect_copy(va, mesh->vertex[i]); + if (ani_matrix != NULL) + vect_transform (va, va, obj_matrix); + fprintf (meshf, "v v%d =\n\tp %.5f %.5f %.5f\n", + i, va[X], va[Y], va[Z]); + } + curmat[0] = '\0'; + for (i = 0; i < mesh->faces; i++) { + if (strcmp(mesh->mtl[i]->name, curmat)) { + strcpy(curmat, mesh->mtl[i]->name); + fprintf (meshf, "m %s\n", curmat); + } + fprintf (meshf, "f v%d v%d v%d\n", mesh->face[i].a, + mesh->face[i].b, mesh->face[i].c); + } + if (mesh->name[0]) fprintf (meshf, "o\n"); + break; + } + /*FALL THROUGH*/ case POV10: case POV20: case VIVID: case POLYRAY: - case MGF: opt_set_vert (mesh->vertices); for (i = 0; i < mesh->faces; i++) { @@ -2332,7 +2375,10 @@ void parse_3ds (Chunk *mainchunk) do { start_chunk (&chunk); - + if (feof(in)) { + fprintf(stderr, "%s: unexpected EOF\n", progname); + break; + } if (chunk.end <= mainchunk->end) { switch (chunk.tag) { case 0x3D3D: parse_mdata (&chunk); @@ -2904,11 +2950,24 @@ dword read_dword() float read_float() { + union { dword i; char c[8]; } u; dword data; data = read_dword(); - return *(float *)&data; + if (sizeof(dword) == sizeof(float)) + return *(float *)&data; + + u.i = 1; + if (u.c[0] == 0) + return *(float *)&data; /* assume big-endian */ + + if (sizeof(dword) != 2*sizeof(float)) { + fputs("Unsupported word length\n", stderr); + exit(1); + } + u.i = data; + return *(float *)&u.c[4]; }