home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK2 / MULTI_04 / 3DSDKB.ZIP / 3DS2DKB.C next >
C/C++ Source or Header  |  1991-09-04  |  19KB  |  665 lines

  1. /* 3DS2DKB.C      Sep 1991              (c) Jeff Bowermaster
  2.  
  3.     Reads a 3DS ascii save file and writes a DKB DATa file
  4.  
  5.     Version 1.1                        Written 9/03/91
  6.  
  7.     Compiled with Borland C++ ver. 2.0
  8.  
  9. */
  10. #define BUFSIZE 128
  11.  
  12. #include <stdio.h>
  13. #include <conio.h>
  14. #include <math.h>
  15. #include <alloc.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. typedef struct
  20. {
  21.     float x, y, z;
  22. } Vector;
  23.  
  24. typedef struct
  25. {
  26.     int    A;
  27.     int    B;
  28.     int    C;
  29. } Triangle;
  30.  
  31. Vector huge * coords, huge * face_normals, huge * vertex_normals;
  32. Triangle huge * tiplist;
  33. char * matlist;
  34.  
  35. FILE *in,*out,*ext,*txtdkb;
  36.  
  37. /* globals */
  38. float max_x, max_y, max_z, min_x, min_y, min_z;
  39. int faces,vertices,materials=0,listed=0,internal=0,debug=1,txt=1;
  40. char mtl[17],catmtl[17],material[50][17],object[12];
  41.  
  42. /* protos */
  43. void Abort(char*,int);
  44. void Process();
  45. void FaceNorm (int, Vector, Vector, Vector);
  46. void Txt_Out();
  47.  
  48. void main(argc, argv)
  49. int argc;
  50. char *argv[];
  51. {
  52.     int face_number,vertex_number,d,e,f,l,m,yesno;
  53.     char parse,string[81],mp;
  54.     char inname[80],outname[80],extname[80],txtname[80],*index;
  55.     float a,b,c,x,y,z,tx,ty,tz,red,green,blue,mag;
  56.  
  57.     max_x = max_y = max_z = -10000000.0;    /* init bounding limits */
  58.     min_x = min_y = min_z =  10000000.0;
  59.  
  60.     clrscr();
  61.  
  62.     printf("\n\nAutoDesk 3D Studio to DKB .Data file Translator\n");
  63.     printf("Version 1.1   (c) Jeff Bowermaster, 9/03/91\n\n");
  64.     if (argc < 2)
  65.     {
  66.         printf("Usage:  %s infile[.ASC] [outfile[.DAT]]\n", argv[0]);
  67.         exit(1);
  68.     }
  69.  
  70.     /* Handle the input file */
  71.  
  72.     strcpy(inname, argv[1]);    /* make copy we can mess with */
  73.     if (!strchr(inname, '.'))    /* no dot present in filename? */
  74.         strcat(inname, ".asc");
  75.  
  76.     if (!(in = fopen(inname, "rt"))) {
  77.         printf("Cannot open input file %s!\n", inname);
  78.         exit(1);
  79.     }
  80.  
  81.     /* Handle the output file */
  82.  
  83.     switch (argc){
  84.  
  85.         case(2):         /* no output file name supplied... */
  86.             if (!strchr(inname, '\\'))    /* no subdirectory stuff? */
  87.                 strcpy(outname,inname);
  88.             else {
  89.                 index = strrchr(inname, '\\'); /* break out directory info */
  90.                 strcpy(outname,index+1);
  91.             }
  92.             strcpy(extname, outname);    /* make copy just in case */
  93.             strcpy(txtname, outname);    /* make copy just in case */
  94.  
  95.             if (!strchr(outname, '.'))    /* no dot in filename? */
  96.                 strcat(outname, ".dat");        /* make new ext. .DAT... */
  97.             else {
  98.                 index = strchr(outname, '.');    /* find the dot */
  99.                 strcpy(index, ".dat");      /* make the new ext. .DAT... */
  100.             }
  101.  
  102.             if(!internal) {
  103.                 if (!strchr(extname, '.'))    /* no dot in filename? */
  104.                     strcat(extname, ".inc");    /* make new ext. .INC... */
  105.                 else {
  106.                     index = strchr(extname, '.');    /* find the dot */
  107.                     strcpy(index, ".inc"); /* make the new ext. .INC... */
  108.                 }
  109.             }
  110.             if(txt) {
  111.                 if (!strchr(txtname, '.'))    /* no dot in filename? */
  112.                     strcat(extname, ".txt");    /* make new ext. .TXT... */
  113.                 else {
  114.                     index = strchr(txtname, '.');    /* find the dot */
  115.                     strcpy(index, ".txt"); /* make the new ext. .TXT... */
  116.                 }
  117.             }
  118.             break;
  119.  
  120.         case(3):         /* output file name or options supplied */
  121.  
  122.             switch(argv[2][0]){
  123.  
  124.                 case '/':
  125.                 case '-':
  126.                     switch(argv[2][1]){
  127.                         case 'i':
  128.                         case 'I':
  129.                             internal=1;
  130.                             if(internal)
  131.                                 printf("internal material definition selected\n");
  132.                             break;
  133.                         default:       /*  Add options here...  */
  134.                             break;
  135.                     }
  136.  
  137.                     /* Now go make the input into the output */
  138.  
  139.                     if (!strchr(inname, '\\'))    /* no subdirectory stuff? */
  140.                          strcpy(outname,inname);
  141.                     else {
  142.                         index = strrchr(inname, '\\'); /* break out directory info */
  143.                         strcpy(outname,index+1);
  144.                     }
  145.  
  146.                     strcpy(extname, outname);    /* make copy just in case */
  147.                     strcpy(txtname, outname);    /* make copy just in case */
  148.  
  149.                     if (!strchr(outname, '.'))    /* no dot in filename? */
  150.                         strcat(outname, ".dat");        /* make new ext. .DAT... */
  151.                     else {
  152.                         index = strchr(outname, '.');    /* find the dot */
  153.                         strcpy(index, ".dat");      /* make the new ext. .DAT... */
  154.                     }
  155.  
  156.                     if(!internal) {
  157.                         if (!strchr(extname, '.'))    /* no dot in filename? */
  158.                             strcat(extname, ".inc");    /* make new ext. .INC... */
  159.                         else {
  160.                             index = strchr(extname, '.');    /* find the dot */
  161.                             strcpy(index, ".inc"); /* make the new ext. .INC... */
  162.                         }
  163.                     }
  164.                     if(txt) {
  165.                         if (!strchr(txtname, '.'))    /* no dot in filename? */
  166.                             strcat(txtname, ".txt");    /* make new ext. .TXT... */
  167.                         else {
  168.                             index = strchr(txtname, '.');    /* find the dot */
  169.                             strcpy(index, ".txt"); /* make the new ext. .TXT... */
  170.                         }
  171.                     }
  172.  
  173.                     break;
  174.                 default:                /*    output name supplied */
  175.                     strcpy(outname, argv[2]);
  176.                     if (!strchr(outname, '.'))    /* no dot in filename? */
  177.                         strcat(outname, ".dat");    /* add .DAT extension */
  178.                     break;
  179.             }
  180.             break;
  181.  
  182.         case(4):         /* output file name AND options supplied */
  183.             switch(argv[3][0]){
  184.                 case '/':
  185.                 case '-':
  186.                     switch(argv[3][1]){
  187.                         case 'i':
  188.                         case 'I':
  189.                             internal=1;
  190.                             if(internal)
  191.                                 printf("internal material definition selected\n");
  192.                             break;
  193.                         default:       /*  Add more options here...  */
  194.                             break;
  195.                     }
  196.  
  197.                     strcpy(outname, argv[2]);
  198.                     strcpy(extname, outname);    /* make copy just in case */
  199.                     strcpy(txtname, outname);    /* make copy just in case */
  200.  
  201.                     if (!strchr(outname, '.'))    /* no dot in filename? */
  202.                         strcat(outname, ".dat");    /* add .DAT extension */
  203.  
  204.                     if(!internal) {
  205.                         if (!strchr(extname, '.'))    /* no dot in filename? */
  206.                             strcat(extname, ".inc");        /* make new ext. .INC... */
  207.                         else {
  208.                             index = strchr(extname, '.');    /* find the dot */
  209.                             strcpy(index, ".inc");        /* make the new ext. .INC... */
  210.                         }
  211.                     }
  212.                     if(txt) {
  213.                         if (!strchr(txtname, '.'))    /* no dot in filename? */
  214.                             strcat(txtname, ".txt");    /* make new ext. .TXT... */
  215.                         else {
  216.                             index = strchr(txtname, '.');    /* find the dot */
  217.                             strcpy(index, ".txt"); /* make the new ext. .TXT... */
  218.                         }
  219.                     }
  220.                 default:
  221.                     break;
  222.             }
  223.         default:
  224.             break;
  225.     }
  226.  
  227.     if (!(out = fopen(outname, "wt"))) {
  228.         printf("Cannot create output file %s!\n", outname);
  229.         fclose(in);
  230.         exit(1);
  231.     }
  232.  
  233.     if (!internal) {
  234.         if (!(ext = fopen(extname, "wt"))) {
  235.             printf("Cannot create include output file %s!\n", extname);
  236.             fclose(in);
  237.             exit(1);
  238.         }
  239.     }
  240.  
  241.     if(txt) {
  242.         if (!(txtdkb = fopen(txtname,"wt"))){
  243.             printf("Can't open text output file\n");
  244.             exit(1);
  245.         }
  246.     }
  247.  
  248.  
  249.     printf("Input from:  %s\n",inname);
  250.     printf("Output to:   %s\n",outname);
  251.     if(!internal)
  252.     printf("External to: %s\n",extname);
  253.     if(txt)
  254.     printf("Text Output: %s\n",txtname);
  255.     printf("\nPlease wait; Processing...\n");
  256.  
  257.     fprintf(out,"INCLUDE \"colors.dat\"\n");
  258.     fprintf(out,"INCLUDE \"shapes.dat\"\n");
  259.     fprintf(out,"INCLUDE \"textures.dat\"\n");
  260.     if(!internal)
  261.         fprintf(out,"INCLUDE \"%s\"\n",extname);
  262.  
  263.  
  264.     while(fgets(string,BUFSIZ,in)!=NULL) {
  265.         parse=string[0];
  266.  
  267.     switch(parse){
  268.  
  269.         case 'A':    /*   Ambient light color: Red=0.3 Green=0.3 Blue=0.3 */
  270.             sscanf(string,"%*s %*s %*s %*4s %f %*6s %f %*5s %f",
  271.                 &red,&green,&blue);
  272.             /* Ignore for now */
  273.             break;
  274.  
  275.         case 'B':    /*   Bank angle: 0.00 degrees */
  276.                   /*   Background solid color: Red=0 Green=0.105882 Blue=0.32549 */
  277.  
  278.             /* Ignore for now */
  279.             break;
  280.  
  281.         case 'C':    /*   Camera (50.000000mm) */
  282.             fprintf(out,"VIEW_POINT\n");
  283.             fprintf(out,"   LOCATION <0.0 0.0 0.0>\n");
  284.             break;
  285.  
  286.         case 'D':    /*   Direct light     */
  287.             fprintf(out,"OBJECT  \n");
  288.             fprintf(out,"   SPHERE <0.0  0.0  0.0>  1.0 END_SPHERE\n");
  289.             break;
  290.  
  291.         case 'F':   /*   Face list: */
  292.             if(strstr(string,"list:"))
  293.                 break;
  294.  
  295.                         /*  Falloff size: 18.25 degrees */
  296.             if(strstr(string,"Fall"))
  297.                 break;
  298.  
  299.                         /*   Face 0:    A:0 B:1 C:109 Mtl:CHROME */
  300.             sscanf(string,"%*s %d %*s %2*s %d %2*s %d %2*s %d %4*s %17c",
  301.                 &face_number,&d,&e,&f,&mtl);
  302.  
  303.             tiplist[face_number].A=d;
  304.             tiplist[face_number].B=e;
  305.             tiplist[face_number].C=f;
  306.  
  307.             /* get material names */
  308.  
  309.             for(l=0;l<17;l++){
  310.                 mp=mtl[l];
  311.  
  312.                 switch(mp) {
  313.                     case ' ':
  314.                         catmtl[l]='_';       /* glue separate words together */
  315.                         break;
  316.                     case '\n':
  317.                         catmtl[l]='\0';    /* convert cr to end of string */
  318.                         l=17;                    /* done (does this work?) */
  319.                         break;
  320.                     default :
  321.                         catmtl[l]=mp;       /* pass everything else */
  322.                 }
  323.             }
  324.  
  325.             /* is this different from any material we have so far? */
  326.  
  327.             yesno=1;  /*set to yes */
  328.  
  329.             for(m=0;m<materials;m++){
  330.                 yesno=strcmp(&material[m][0],catmtl);
  331.                 if(!yesno) {
  332.                     matlist[face_number]=(char)m;
  333.                     break;
  334.                 }
  335.             }
  336.  
  337.             if(yesno) {
  338.                 strcpy(&material[materials++][0],catmtl);
  339.                 matlist[face_number]=(char)materials-1;
  340.             }
  341.  
  342.             if(face_number==faces-1) {  /* done with this object */
  343.  
  344.                 if(internal){
  345.                     fprintf(out,"\n{New materials: }\n");
  346.                     for(m=listed;m<materials;m++){
  347.                         fprintf(out,"   DECLARE %s = TEXTURE\n",material[m]);
  348.                         fprintf(out,"      COLOUR White\n");
  349.                         fprintf(out,"      PHONG 1.0\n");
  350.                         fprintf(out,"   END_TEXTURE\n\n");
  351.                     }
  352.                     listed=materials;      /* only new materials */
  353.                 }
  354.                 Process();
  355.             }
  356.             break;
  357.  
  358.  
  359.  
  360.         case 'L':    /*   Light color: Red=0.32 Green=0.9 Blue=0.72 */
  361.  
  362.             sscanf(string,"%*s %*s %*4s %f %*6s %f %*5s %f",
  363.                 &red,&green,&blue);
  364.             fprintf(out,"   COLOUR RED %4.2f GREEN %4.2f BLUE %4.2f\n",red,green,blue);
  365.             fprintf(out,"   TEXTURE\n");
  366.             fprintf(out,"       AMBIENT 1.0\n");
  367.             fprintf(out,"       DIFFUSE 0.0\n");
  368.             fprintf(out,"       COLOUR RED %4.2f GREEN %4.2f BLUE %4.2f\n",red,green,blue);
  369.             fprintf(out,"   END_TEXTURE\n");
  370.             fprintf(out,"   LIGHT_SOURCE\n");
  371.             fprintf(out,"END_OBJECT\n\n");
  372.  
  373.             break;
  374.  
  375.         case 'N':    /*   Named object: teacup   */
  376.             sscanf(string,"%*s %*s %s",&object);
  377.             fprintf(out,"{ %s }\n",object);
  378.             printf("Working on: %s\n",object);
  379.             break;
  380.  
  381.         case 'P':    /*   Position:  X:298.177734 Y:-314.924225 Z:182.459198 */
  382.             sscanf(string,"%*s %2*s %f %2*s %f %2*s %f",
  383.                 &x,&y,&z);
  384.             fprintf(out,"   TRANSLATE <%11.6f %11.6f %11.6f>\n",x,y,z);
  385.             break;
  386.  
  387.         case 'S':    /*   Smoothing:  1, 10 */
  388.                         /*   Smoothing:  17 */
  389.             /* don't know what it means */
  390.  
  391.                      /*  Spotlight to:  X:-98.558777 Y:-176.971039 Z:-363.822357 */
  392.             break;
  393.             /* Could be synthesized, flaming terror */
  394.  
  395.         case 'T':    /*   Target:  X:79.31871 Y:-11.135715 Z:27.661964 */
  396.             if(strstr(string,"Target:")){
  397.                 sscanf(string,"%*s %2*s %f %2*s %f %2*s %f",&tx,&ty,&tz);
  398.                 x-=tx; y-=ty;    z-=tz;
  399.                 mag=(float)sqrt((double)(x*x+y*y+z*z));
  400.                 x/=mag; y/=mag; z/=mag;
  401.                 fprintf(out,"   DIRECTION <%4.2f %4.2f %4.2f>\n",x,y,z);
  402.                 fprintf(out,"   SKY  <0.0  0.0  1.0>\n");
  403.                 fprintf(out,"   RIGHT <-1.33 0.0 0.0>\n");
  404.                 fprintf(out,"   LOOK_AT <%11.6f %11.6f %11.6f>\n",tx,ty,tz);
  405.                 fprintf(out,"END_VIEW_POINT\n\n");
  406.                 break;
  407.             }
  408.                         /*   Tri-mesh, Vertices: 3240     Faces: 6480 */
  409.             sscanf(string,"%*s %*s %d %*s %d",&vertices,&faces);
  410.  
  411.             if((coords = farmalloc ((long)vertices * sizeof(Vector)))==NULL)
  412.                 Abort ("Insufficient memory for coordinates.", 1);
  413.             if((face_normals = farmalloc ((long)faces * sizeof(Vector)))==NULL)
  414.                 Abort ("Insufficient memory for face normals.", 2);
  415.             if((vertex_normals = farmalloc ((long)vertices * sizeof(Vector)))==NULL)
  416.                 Abort ("Insufficient memory for vertex normals.", 3);
  417.             if((tiplist = farmalloc ((long)faces * sizeof(Triangle)))==NULL)
  418.                 Abort ("Insufficient memory for face list.", 4);
  419.             if((matlist = farmalloc ((long)faces * sizeof(char)))==NULL)
  420.                 Abort ("Insufficient memory for materials list.", 5);
  421.  
  422.             break;
  423.  
  424.         case 'V':    /*   Vertex list: */
  425.             if(strstr(string,"list:"))
  426.                 break;
  427.                         /*   Vertex 0:  X: 82.320801     Y: -15.238132     Z: 28.071295 */
  428.             sscanf(string,"%*s %d %*s %2*s %f %2*s %f %2*s %f",
  429.                 &vertex_number,&a,&b,&c);
  430.  
  431.             coords[vertex_number].x=a;
  432.             coords[vertex_number].y=b;
  433.             coords[vertex_number].z=c;
  434.  
  435.             max_x = (a > max_x) ? a : max_x;
  436.             min_x = (a < min_x) ? a : min_x;
  437.             max_y = (b > max_y) ? b : max_y;
  438.             min_y = (b < min_y) ? b : min_y;
  439.             max_z = (c > max_z) ? c : max_z;
  440.             min_z = (c < min_z) ? c : min_z;
  441.  
  442.             break;
  443.  
  444.         default:        /*   Blank lines, page numbers...  */
  445.             break;
  446.         }
  447.     }
  448.  
  449.     fprintf(out,"\n{Deal with the following materials: }\n");
  450.     for(m=0;m<materials;m++)
  451.         if(!internal) {
  452.             fprintf(ext,"   DECLARE %s = TEXTURE\n",material[m]);
  453.             fprintf(ext,"      COLOUR White\n");
  454.             fprintf(ext,"      PHONG 1.0\n");
  455.             fprintf(ext,"   END_TEXTURE\n\n");
  456.         }
  457.         else
  458.             fprintf(out," { %s }\n",material[m]);
  459.  
  460.     fclose(in);
  461.     fclose(out);
  462.     if(!internal)
  463.         fclose(ext);
  464.     if(txt) 
  465.         fclose(txtdkb); 
  466. }
  467.  
  468. void Process()
  469. {
  470.  
  471.     int face_number,vertex_number;
  472.     float m2,magnitude;
  473.  
  474.     fprintf(out,"COMPOSITE\n");
  475.  
  476.     /* Calculate the face normals */
  477.  
  478.     if(debug) printf("face normals\n");
  479.  
  480.     for(face_number=0;face_number<faces;face_number++) {
  481.         FaceNorm(face_number,
  482.             coords[tiplist[face_number].A],
  483.             coords[tiplist[face_number].B],
  484.             coords[tiplist[face_number].C]);
  485.     }
  486.  
  487.     /* normalize to unit vectors */
  488.  
  489.     if(debug) printf("unit vector1\n");
  490.  
  491.     for(face_number=0;face_number<faces;face_number++) {
  492.         m2=face_normals[face_number].x*face_normals[face_number].x+
  493.             face_normals[face_number].y*face_normals[face_number].y+
  494.             face_normals[face_number].z*face_normals[face_number].z;
  495.  
  496.         magnitude=(float)sqrt((double)m2);
  497.  
  498.         if (magnitude==0.0) {
  499.             printf("Face expected; vector encountered\n");
  500.             magnitude=1;
  501.         }
  502.  
  503.         face_normals[face_number].x/=magnitude;
  504.         face_normals[face_number].y/=magnitude;
  505.         face_normals[face_number].z/=magnitude;
  506.     }
  507.  
  508.     /* Clear out the memory for the averages */
  509.  
  510.     for(vertex_number=0;vertex_number<vertices;vertex_number++) {
  511.         vertex_normals[vertex_number].x=0.0;
  512.         vertex_normals[vertex_number].y=0.0;
  513.         vertex_normals[vertex_number].z=0.0;
  514.     }
  515.  
  516.     /* add all the normals for faces touching each vertex */
  517.  
  518.     if (debug) printf("average face normals\n");
  519.  
  520.     for(face_number=0;face_number<faces;face_number++) {
  521.  
  522.         vertex_normals[tiplist[face_number].A].x+=face_normals[face_number].x;
  523.         vertex_normals[tiplist[face_number].A].y+=face_normals[face_number].y;
  524.         vertex_normals[tiplist[face_number].A].z+=face_normals[face_number].z;
  525.  
  526.         vertex_normals[tiplist[face_number].B].x+=face_normals[face_number].x;
  527.         vertex_normals[tiplist[face_number].B].y+=face_normals[face_number].y;
  528.         vertex_normals[tiplist[face_number].B].z+=face_normals[face_number].z;
  529.  
  530.         vertex_normals[tiplist[face_number].C].x+=face_normals[face_number].x;
  531.         vertex_normals[tiplist[face_number].C].y+=face_normals[face_number].y;
  532.         vertex_normals[tiplist[face_number].C].z+=face_normals[face_number].z;
  533.     }
  534.  
  535.     /* normalize to unit vectors */
  536.  
  537.     if(debug) printf("normalize #2\n");
  538.  
  539.     for(vertex_number=0;vertex_number<vertices;vertex_number++) {
  540.         m2=(vertex_normals[vertex_number].x*vertex_normals[vertex_number].x)+
  541.             (vertex_normals[vertex_number].y*vertex_normals[vertex_number].y)+
  542.             (vertex_normals[vertex_number].z*vertex_normals[vertex_number].z);
  543.  
  544.         magnitude=(float)sqrt((double)m2);
  545.  
  546.         if (magnitude==0.0) {
  547.             printf("Normals all cancel (?)\n");
  548.             magnitude=1;
  549.         }
  550.  
  551.         vertex_normals[vertex_number].x/=magnitude;
  552.         vertex_normals[vertex_number].y/=magnitude;
  553.         vertex_normals[vertex_number].z/=magnitude;
  554.     }
  555.  
  556.     /* print out the results */
  557.  
  558.     for(face_number=0;face_number<faces;face_number++) {
  559.         fprintf(out,"OBJECT\n");
  560.         fprintf(out,"   SMOOTH_TRIANGLE \n");
  561.         fprintf(out,"   <%8.4f %8.4f %8.4f> <%8.4f %8.4f %8.4f>\n",
  562.             coords[tiplist[face_number].A].x,
  563.             coords[tiplist[face_number].A].y,
  564.             coords[tiplist[face_number].A].z,
  565.             vertex_normals[tiplist[face_number].A].x,
  566.             vertex_normals[tiplist[face_number].A].y,
  567.             vertex_normals[tiplist[face_number].A].z);
  568.         fprintf(out,"   <%8.4f %8.4f %8.4f> <%8.4f %8.4f %8.4f>\n",
  569.             coords[tiplist[face_number].B].x,
  570.             coords[tiplist[face_number].B].y,
  571.             coords[tiplist[face_number].B].z,
  572.             vertex_normals[tiplist[face_number].B].x,
  573.             vertex_normals[tiplist[face_number].B].y,
  574.             vertex_normals[tiplist[face_number].B].z);
  575.         fprintf(out,"   <%8.4f %8.4f %8.4f> <%8.4f %8.4f %8.4f>\n",
  576.             coords[tiplist[face_number].C].x,
  577.             coords[tiplist[face_number].C].y,
  578.             coords[tiplist[face_number].C].z,
  579.             vertex_normals[tiplist[face_number].C].x,
  580.             vertex_normals[tiplist[face_number].C].y,
  581.             vertex_normals[tiplist[face_number].C].z);
  582.         fprintf(out,"   END_SMOOTH_TRIANGLE\n");
  583.         fprintf(out,"   TEXTURE \n");
  584.         fprintf(out,"      %s\n",material[matlist[face_number]]);
  585.         fprintf(out,"   END_TEXTURE\n");
  586.         fprintf(out,"END_OBJECT\n\n");
  587.     }
  588.  
  589.     fprintf(out,"BOUNDED_BY\n");
  590.     fprintf(out,"   INTERSECTION\n");
  591.     fprintf(out,"      PLANE < 1.0  0.0  0.0> %f END_PLANE\n",max_x);
  592.     fprintf(out,"      PLANE <-1.0  0.0  0.0> %f END_PLANE\n",-1*min_x);
  593.     fprintf(out,"      PLANE < 0.0  1.0  0.0> %f END_PLANE\n",max_y);
  594.     fprintf(out,"      PLANE < 0.0 -1.0  0.0> %f END_PLANE\n",-1*min_y);
  595.     fprintf(out,"      PLANE < 0.0  0.0  1.0> %f END_PLANE\n",max_z);
  596.     fprintf(out,"      PLANE < 0.0  0.0 -1.0> %f END_PLANE\n",-1*min_z);
  597.     fprintf(out,"   END_INTERSECTION\n");
  598.     fprintf(out,"END_BOUND\n\n");
  599.     fprintf(out,"END_COMPOSITE\n\n");
  600.  
  601.     /* free up the memory for the next object */
  602.  
  603.     /* if you want a text list of the points */
  604.     if(txt)
  605.         Txt_Out();
  606.  
  607.     farfree((void far *)coords);
  608.     farfree((void far *)vertex_normals);
  609.     farfree((void far *)face_normals);
  610.     farfree((void far *)tiplist);
  611.     farfree((void far *)matlist);
  612.  
  613.     max_x = max_y = max_z = -10000000.0;    /* reset bounding limits */
  614.     min_x = min_y = min_z =  10000000.0;
  615.  
  616. }
  617.  
  618. void FaceNorm (int face_number,Vector V1, Vector V2, Vector V3)
  619. {
  620.     Vector V4, V5;
  621.  
  622.     V4.x = V1.x - V2.x;
  623.     V4.y = V1.y - V2.y;
  624.     V4.z = V1.z - V2.z;
  625.  
  626.     V5.x = V1.x - V3.x;
  627.     V5.y = V1.y - V3.y;
  628.     V5.z = V1.z - V3.z;
  629.  
  630.     face_normals[face_number].x = (V4.y * V5.z) - (V4.z * V5.y);
  631.     face_normals[face_number].y = (V4.z * V5.x) - (V4.x * V5.z);
  632.     face_normals[face_number].z = (V4.x * V5.y) - (V4.y * V5.x);
  633. }
  634.  
  635. void Abort (char *Msg, int ExitCode)
  636. {
  637.     puts (Msg);
  638.     exit (ExitCode);
  639. }
  640.  
  641. void Txt_Out() {
  642.  
  643.     /* Modify this routine to get lists of whatever you need */
  644.  
  645.     int vertex_number,face_number;
  646.  
  647.     fprintf(txtdkb,"%s\n",object);  /* delimits objects */
  648.  
  649.     for(face_number=0;face_number<faces;face_number++) {
  650.         fprintf(txtdkb,"%f %f %f ",
  651.             coords[tiplist[face_number].A].x,
  652.             coords[tiplist[face_number].A].y,
  653.             coords[tiplist[face_number].A].z);
  654.         fprintf(txtdkb,"%f %f %f ",
  655.             coords[tiplist[face_number].B].x,
  656.             coords[tiplist[face_number].B].y,
  657.             coords[tiplist[face_number].B].z);
  658.         fprintf(txtdkb,"%f %f %f\n",
  659.             coords[tiplist[face_number].C].x,
  660.             coords[tiplist[face_number].C].y,
  661.             coords[tiplist[face_number].C].z);
  662.     }
  663. }
  664.  
  665.