home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / grafik / raytracing / magiccamera / misc / turbo2arrt.c < prev   
Encoding:
C/C++ Source or Header  |  1994-06-18  |  19.4 KB  |  816 lines

  1. /***********************************************************
  2. *
  3. *    This file is Copyright © 1990-1994 Dan Wesnor
  4. *
  5. *    This file and any executables resulting from compilation
  6. *    of this file are freely distributable so long as the
  7. *    above copyright statement is included intact.  This
  8. *    statement of distributability is limited to this file
  9. *    only, and does not include any other file in this
  10. *    archive.
  11. *
  12. *    No gaurantees of usability are made for this file or
  13. *    any executables generated from it.  Use at your own risk.
  14. *
  15. ************************************************************
  16. *
  17. *    This program generates an MC script from a 3DDD object
  18. *    file as generated by Impulse's renderers (Turbo Silver
  19. *    and Imagine).  This version show how to generate objects
  20. *    not using vertex based definitions of triangles.
  21. *
  22. *    The 3DDD parser is not all that great, and could be
  23. *    improved upon.  Someone could also use this code as
  24. *    a basis for a program which generates scripts from other 
  25. *    object formats as well.
  26. *
  27. *    NOTE: be careful using this code on machines with
  28. *    int lengths other than 32 bits!
  29. *
  30. ***********************************************************/
  31.  
  32. #include "turbo.h"
  33. #include <fcntl.h>
  34. #include <stdio.h>
  35. #include <math.h>
  36.  
  37. #define max(a,b)    (((a)>(b))?(a):(b))
  38. #define min(a,b)    (((a)<(b))?(a):(b))
  39.  
  40. typedef struct {
  41.     unsigned int    form,
  42.                     size,
  43.                     type;
  44. } Form, *FormPtr;
  45.  
  46. #define MakeName(s)    (((s)[0]<<24)+((s)[1]<<16)+((s)[2]<<8)+(s)[3])
  47.  
  48. typedef struct {
  49.     unsigned int    name,
  50.                     len;
  51. } Chunk, *ChunkPtr;
  52.  
  53.  
  54. typedef struct str_surface {
  55.     struct str_surface    *next;
  56.     int                    num;
  57.     COLOR                colr,
  58.                         refl,
  59.                         tran;
  60.     UBYTE                hard,
  61.                         spec,
  62.                         index;
  63.     char                name[32];
  64. } Surface, *SurfacePtr;
  65.     
  66.  
  67.  
  68.  
  69. #define FND_PNTS    0x1
  70. #define FND_POSI    0x2
  71. #define FND_NAME    0x4
  72. #define FND_SHAP    0x8
  73. #define FND_AXIS    0x10
  74. #define FND_SIZE    0x20
  75. #define FND_EDGE    0x40
  76. #define FND_FACE    0x80
  77. #define FND_COLR    0x100
  78. #define FND_REFL    0x200
  79. #define FND_TRAN    0x400
  80. #define FND_CLST    0x800
  81. #define FND_SPEC    0x1000
  82. #define FND_TLST    0x2000
  83. #define FND_RLST    0x4000
  84. #define FND_MTTR    0x8000
  85. #define FND_INTS    0x10000
  86. #define FND_PRP0    0x20000
  87.  
  88.  
  89. FILE *ofh=0;
  90. char *filename;
  91.  
  92. SurfacePtr surfList=NULL;
  93.  
  94. SurfacePtr MakeSurface(cr, cg, cb, rr, rg, rb, tr, tg, tb, h, s, i)
  95.     UBYTE    cr, cg, cb,
  96.             rr, rg, rb,
  97.             tr, tg, tb,
  98.             h, s,
  99.             i;
  100. {
  101.     SurfacePtr    surf;
  102.     
  103.     surf = surfList;
  104.     
  105.     while (surf) {
  106.         if ((surf->colr[0] == cr) && (surf->colr[1] == cg) && (surf->colr[2] == cb)
  107.                 && (surf->refl[0] == rr) && (surf->refl[1] == rg) 
  108.                 && (surf->refl[2] == rb)
  109.                 && (surf->tran[0] == tr) && (surf->tran[1] == tg) 
  110.                 && (surf->tran[2] == tb)
  111.                 && (surf->hard == h) && (surf->spec == s) 
  112.                 && (surf->index == i))
  113.             return surf;
  114.         surf = surf->next;
  115.     }
  116.  
  117.     if (!(surf = (SurfacePtr)calloc(1, sizeof(Surface)))) {
  118.         fprintf(stdout, "Cannot allocate new surface\n");
  119.         return surfList;
  120.     }
  121.     
  122.     surf->num = surfList ? surfList->num+1 : 0;
  123.     surf->next = surfList;
  124.     surfList = surf;
  125.     surf->colr[0] = cr;
  126.     surf->colr[1] = cg;
  127.     surf->colr[2] = cb;
  128.     surf->refl[0] = rr;
  129.     surf->refl[1] = rg;
  130.     surf->refl[2] = rb;
  131.     surf->tran[0] = tr;
  132.     surf->tran[1] = tg;
  133.     surf->tran[2] = tb;
  134.     surf->hard = h;
  135.     surf->spec = s;
  136.     surf->index = i;
  137.     sprintf(surf->name, "t2a_surf_%s_%d", filename, surf->num);
  138.     
  139.     fprintf(ofh, "surface %s {\n", surf->name);
  140.     fprintf(ofh, "\tdiff\t<%f, %f, %f>\n", cr/255.0, cg/255.0, cb/255.0);
  141.     if (tr && tg && tb)
  142.         fprintf(ofh, "\ttrans\t<%f, %f, %f>\n", tr/255.0, tg/255.0, tb/255.0);
  143.     if (rr && rg && rb)
  144.         fprintf(ofh, "\trefl\t<%f, %f, %f>\n", rr/255.0, rg/255.0, rb/255.0);
  145.     if (s) {
  146.         fprintf(ofh, "\tpcoef\t%f\n", h/5.0);
  147.         fprintf(ofh, "\tprefl\t%f\n", s/255.0);
  148.     }
  149.     if (i)
  150.         fprintf(ofh, "\tindex\t%f\n", i/100.0+1.0);
  151.     fprintf(ofh, "}\n\n");
  152.  
  153.     return surf;
  154. }
  155.  
  156.  
  157.  
  158. float imn[3]={1e6, 1e6, 1e6}, imx[3]={-1e6, -1e6, -1e6};
  159.  
  160. void GetDescChunk(int ifd, int len)
  161. {
  162.     Chunk        chunk;
  163.     int            whatami=0;
  164.     int            found=0;
  165.     int            i, p1, p2, p3;
  166.     int            degen;
  167.     SurfacePtr    surf;
  168.     PNTS         *pnts;
  169.     POSI         posi;
  170.     NAME         name;
  171.     SHAP         shap;
  172.     AXIS         axis;
  173.     SIZE         size;
  174.     EDGE         *edge;
  175.     FACE         *face;
  176.     COLR         colr;
  177.     REFL         refl;
  178.     TRAN         tran;
  179.     CLST         *clst;
  180.     SPEC         spec;
  181.     TLST         *tlst;
  182.     RLST         *rlst;
  183.     MTTR         mttr;
  184.     INTS         ints;
  185.     PRP0         prp;
  186.     
  187.     colr.col[0] = colr.col[1] = colr.col[2] = 255;
  188.     refl.col[0] = refl.col[1] = refl.col[2] = 0;
  189.     tran.col[0] = tran.col[1] = tran.col[2] = 0;
  190.  
  191.     while (len) {
  192.         len -= read(ifd, &chunk, sizeof(Chunk));
  193.         chunk.len += chunk.len % 2;
  194.  
  195.         if (chunk.name == MakeName("NAME")) {
  196.             len -= read(ifd, &name, sizeof(NAME));
  197.             fprintf(stdout, "\t\tNAME:  %s\n", name.Name);
  198.         }
  199.  
  200.         else if (chunk.name == MakeName("SHAP")) {
  201.             len -= read(ifd, &shap, sizeof(SHAP));
  202.             fprintf(stdout, "\t\tSHAP:  ");
  203.             switch (shap.Lamp) {
  204.                 case LMP_NOTALAMP:
  205.                     whatami = shap.Shape;
  206.                     switch (shap.Shape) {
  207.                         case SHP_SPHERE:
  208.                             fprintf(stdout, "sphere\n");
  209.                             break;
  210.                 
  211.                         case SHP_STENCIL:
  212.                             fprintf(stdout, "stencil\n");
  213.                             break;
  214.  
  215.                         case SHP_AXIS:
  216.                             fprintf(stdout, "axis\n");
  217.                             break;
  218.                     
  219.                         case SHP_FACETS:
  220.                             fprintf(stdout, "facets\n");
  221.                             break;
  222.                 
  223.                         case SHP_SURFACE:
  224.                             fprintf(stdout, "Surface\n");
  225.                             break;
  226.                 
  227.                         case SHP_GROUND:
  228.                             fprintf(stdout, "Ground\n");
  229.                             break;
  230.                 
  231.                         default:
  232.                             fprintf(stdout, "Unknown:  %d\n", 
  233.                                     shap.Shape);
  234.                             break;
  235.                     }
  236.                     break;
  237.  
  238.                 case LMP_SUN:
  239.                     fprintf(stdout, "Lamp (Sun)\n");
  240.                     break;
  241.                 
  242.                 case LMP_LAMP:
  243.                     fprintf(stdout, "Lamp (Lamp)\n");
  244.                     break;
  245.                     
  246.                 default:
  247.                     break;
  248.             }        
  249.         }
  250.  
  251.         else if (chunk.name == MakeName("POSI")) {
  252.             found |= FND_POSI;
  253.             len -= read(ifd, &posi, sizeof(POSI));
  254.             fprintf(stdout, "\t\tPOSI:  <%f, %f, %f>\n", 
  255.                     posi.Position.X/65536.0, 
  256.                     posi.Position.Y/65536.0, posi.Position.Z/65536.0);
  257.         }
  258.  
  259.         else if (chunk.name == MakeName("AXIS")) {
  260.             found |= FND_AXIS;
  261.             len -= read(ifd, &axis, sizeof(AXIS));
  262.             fprintf(stdout, "\t\tAXIS:  X = <%f, %f, %f>\n", 
  263.                     axis.XAxis.X/65536.0, axis.XAxis.Z/65536.0, 
  264.                     axis.XAxis.Y/65536.0);
  265.             fprintf(stdout, "\t\t       Y = <%f, %f, %f>\n", 
  266.                     axis.YAxis.X/65536.0, axis.YAxis.Z/65536.0, 
  267.                     axis.YAxis.Y/65536.0);
  268.             fprintf(stdout, "\t\t       Z = <%f, %f, %f>\n", 
  269.                     axis.ZAxis.X/65536.0, axis.ZAxis.Z/65536.0, 
  270.                     axis.ZAxis.Y/65536.0);
  271.         }
  272.  
  273.         else if (chunk.name == MakeName("SIZE")) {
  274.             found |= FND_SIZE;
  275.             len -= read(ifd, &size, sizeof(SIZE));
  276.             fprintf(stdout, "\t\tSIZE:  <%f, %f, %f>\n", 
  277.                     size.Size.X/65536.0, size.Size.Y/65536.0, 
  278.                     size.Size.Z/65536.0);
  279.         }
  280.  
  281.         else if (chunk.name == MakeName("PNTS")) {
  282.             if (pnts = (PNTS *)calloc(1, chunk.len)) {
  283.                 found |= FND_PNTS;
  284.                 len -= read(ifd, &(pnts->PCount), 2);
  285.                 len -= read(ifd, pnts->Points, chunk.len-2);
  286.                 fprintf(stdout, "\t\tPNTS:  %d\n", pnts->PCount);
  287. #ifdef COUNT_UNIQUE_POINTS
  288.                 {
  289.                     int i, j, u, uc=0;
  290.                     for (i=0; i<pnts->PCount; i++)
  291.                     {
  292.                         u = 1;
  293.                         for (j=0; j<pnts->PCount; j++)
  294.                             if ((pnts->Points[i].X == pnts->Points[j].X)
  295.                                     && (pnts->Points[i].Y == pnts->Points[j].Y)
  296.                                     && (pnts->Points[i].Z == pnts->Points[j].Z))
  297.                             if (i != j)
  298.                             {
  299.                                 u = 0;
  300.                                 break;
  301.                             }
  302.                         if (u)
  303.                             uc++;
  304.                     }
  305.                     printf("%d unique points found.\n", uc);
  306. #endif
  307.                 }
  308.             }
  309.             else
  310.                 fprintf(stdout, "PNTS found, no memory to load\n");
  311.         }
  312.  
  313.         else if (chunk.name == MakeName("EDGE")) 
  314.         {
  315.             if (edge = (EDGE *)calloc(1, chunk.len)) 
  316.             {
  317.                 found |= FND_EDGE;
  318.                 len -= read(ifd, edge, chunk.len);
  319.                 fprintf(stdout, "\t\tEDGE:  %d\n", edge->ECount);
  320.             }
  321.             else
  322.                 fprintf(stdout, "EDGE found, no memory to load\n");
  323.         }
  324.  
  325.         else if (chunk.name == MakeName("FACE")) 
  326.         {
  327.             if (face = (FACE *)calloc(1, chunk.len)) 
  328.             {
  329.                 found |= FND_FACE;
  330.                 len -= read(ifd, face, chunk.len);
  331.                 fprintf(stdout, "\t\tFACE:  %d\n", face->TCount);
  332.             }
  333.             else
  334.                 fprintf(stdout, "FACE found, no memory to load\n");
  335.         }
  336.  
  337.         else if (chunk.name == MakeName("COLR")) 
  338.         {
  339.             found |= FND_COLR;
  340.             len -= read(ifd, &colr, sizeof(COLR));
  341.             fprintf(stdout, "\t\tCOLR:  %d %d %d\n", 
  342.                     colr.col[0], colr.col[1], colr.col[2]);
  343.         }
  344.  
  345.         else if (chunk.name == MakeName("REFL")) 
  346.         {
  347.             found |= FND_REFL;
  348.             len -= read(ifd, &refl, sizeof(REFL));
  349.             fprintf(stdout, "\t\tREFL:  %d %d %d\n", 
  350.                     refl.col[0], refl.col[1], refl.col[2]);
  351.         }
  352.  
  353.         else if (chunk.name == MakeName("TRAN")) 
  354.         {
  355.             found |= FND_TRAN;
  356.             len -= read(ifd, &tran, sizeof(TRAN));
  357.             fprintf(stdout, "\t\tTRAN:  %d %d %d\n", 
  358.                     tran.col[0], tran.col[1], tran.col[2]);
  359.         }
  360.  
  361.         else if (chunk.name == MakeName("CLST")) 
  362.         {
  363.             if (clst = (CLST *)calloc(1, chunk.len)) 
  364.             {
  365.                 found |= FND_CLST;
  366.                 len -= read(ifd, clst, chunk.len);
  367.                 fprintf(stdout, "\t\tCLST:  %d\n", clst->count);
  368.             }
  369.             else
  370.                 fprintf(stdout, "CLST found, no memory to load\n");
  371.         }
  372.  
  373.         else if (chunk.name == MakeName("RLST")) 
  374.         {
  375.             if (rlst = (RLST *)calloc(1, chunk.len)) 
  376.             {
  377.                 found |= FND_RLST;
  378.                 len -= read(ifd, rlst, chunk.len);
  379.                 fprintf(stdout, "\t\tRLST:  %d\n", rlst->count);
  380.             }
  381.             else
  382.                 fprintf(stdout, "RLST found, no memory to load\n");
  383.         }
  384.  
  385.         else if (chunk.name == MakeName("TLST")) 
  386.         {
  387.             if (tlst = (TLST *)calloc(1, chunk.len)) 
  388.             {
  389.                 found |= FND_TLST;
  390.                 len -= read(ifd, tlst, chunk.len);
  391.                 fprintf(stdout, "\t\tTLST:  %d\n", tlst->count);
  392.             }
  393.             else
  394.                 fprintf(stdout, "TLST found, no memory to load\n");
  395.         }
  396.  
  397.         else if (chunk.name == MakeName("TPAR")) 
  398.         {
  399.             fprintf(stdout, "\t\tTPAR:  found\n");
  400.             lseek(ifd, chunk.len, 1);
  401.             len -= chunk.len;
  402.         }
  403.  
  404.         else if (chunk.name == MakeName("SURF")) 
  405.         {
  406.             fprintf(stdout, "\t\tSURF:  found\n");
  407.             lseek(ifd, chunk.len, 1);
  408.             len -= chunk.len;
  409.         }
  410.  
  411.         else if (chunk.name == MakeName("MTTR")) 
  412.         {
  413.             found |= FND_MTTR;
  414.             len -= read(ifd, &mttr, sizeof(MTTR));
  415.             switch (mttr.Type) 
  416.             {
  417.                 case RFR_AIR:
  418.                     fprintf(stdout, "\t\tMTTR:  %f (Air)\n", VAL_AIR);
  419.                     break;
  420.  
  421.                 case RFR_WATER:
  422.                     fprintf(stdout, "\t\tMTTR:  %f (Water)\n", 
  423.                             VAL_WATER);
  424.                     break;
  425.  
  426.                 case RFR_GLASS:
  427.                     fprintf(stdout, "\t\tMTTR:  %f (Glass)\n", 
  428.                             VAL_GLASS);
  429.                     break;
  430.  
  431.                 case RFR_CRYSTAL:
  432.                     fprintf(stdout, "\t\tMTTR:  %f (Crystal)\n", 
  433.                             VAL_CRYSTAL);
  434.                     break;
  435.  
  436.                 case RFR_CUSTOM:
  437.                     fprintf(stdout, "\t\tMTTR:  %f (Custom)\n", 
  438.                             VAL_CUSTOM(mttr.Index));
  439.                     break;
  440.  
  441.                 default:
  442.                     fprintf(stdout, "\t\tMTTR:  unknown type %d\n", 
  443.                             mttr.Type);
  444.                     break;
  445.             }
  446.         }
  447.  
  448.         else if (chunk.name == MakeName("SPEC")) 
  449.         {
  450.             found |= FND_SPEC;
  451.             len -= read(ifd, &spec, sizeof(SPEC));
  452.             fprintf(stdout, "\t\tSPEC:  Spec=%d, Hard=%d\n", 
  453.                     spec.Specularity, spec.Hardness);
  454.         }
  455.  
  456.         else if (chunk.name == MakeName("PRP0")) 
  457.         {
  458.             found |= FND_PRP0;
  459.             len -= read(ifd, &prp, sizeof(PRP0));
  460.             fprintf(stdout, "\t\tPRP0:  Blend = %d\n", prp.Props[PRP_BLEND]);
  461.             fprintf(stdout, "\t\t       Rough = %d\n", prp.Props[PRP_SMOOTH]);
  462.             fprintf(stdout, "\t\t       Shade = %s\n", 
  463.                     prp.Props[PRP_SHADE] ? "ON" : "OFF");
  464.             fprintf(stdout, "\t\t       Phong = %s\n", 
  465.                     prp.Props[PRP_PHONG] ? "OFF" : "ON");
  466.             fprintf(stdout, "\t\t       Glossy = %s\n", 
  467.                     prp.Props[PRP_GLOSSY] ? "ON" : "OFF");
  468.             fprintf(stdout, "\t\t       Quick = %s\n", 
  469.                     prp.Props[PRP_QUICK] ? "ON" : "OFF");
  470.         }
  471.  
  472.         else if (chunk.name == MakeName("INTS")) 
  473.         {
  474.             found |= FND_INTS;
  475.             len -= read(ifd, &ints, sizeof(INTS));
  476.             fprintf(stdout, "\t\tINTS:  %f\n", ints.Intensity/65536.0);
  477.         }
  478.  
  479.         else if (chunk.name == MakeName("STRY")) 
  480.         {
  481.             fprintf(stdout, "\t\tSTRY:  found\n");
  482.             lseek(ifd, chunk.len, 1);
  483.             len -= chunk.len;
  484.         }
  485.  
  486.         else 
  487.         {
  488.             fprintf(stdout, "\t\t%.4s:  Found unknown chunk, skipping\n", &chunk.name);
  489.             lseek(ifd, chunk.len, 1);
  490.             len -= chunk.len;
  491.         }
  492.     }
  493.  
  494.     if (whatami == SHP_AXIS) 
  495.     {
  496.         float mx[3]={-1e6, -1e6, -1e6}, mn[3]={1e6, 1e6, 1e6};
  497.  
  498.         degen = 0;
  499.         
  500.         fprintf(stdout, "***\tDumping axis type object\n");
  501.  
  502.         fprintf(ofh, "/* --------- %s --------- */\n", name.Name);
  503.  
  504.         if ((found & FND_PRP0) && (!(prp.Props[PRP_SMOOTH])))
  505.             fprintf(ofh, "");
  506.  
  507.         if ((found & (FND_PNTS | FND_EDGE | FND_FACE)) 
  508.                 != (FND_PNTS | FND_EDGE | FND_FACE))
  509.             fprintf(stdout, "***\tError:  One of PNTS, EDGE, or FACE not found or allocated\n");
  510.         else 
  511.         {
  512.             for (i=0; i<pnts->PCount; i++) 
  513.             {
  514.                 pnts->Points[i].X *= -1.0;
  515.                 mx[0] = max(mx[0], pnts->Points[i].X/65536.0);
  516.                 mn[0] = min(mn[0], pnts->Points[i].X/65536.0);
  517.                 imx[0] = max(imx[0], pnts->Points[i].X/65536.0);
  518.                 imn[0] = min(imn[0], pnts->Points[i].X/65536.0);
  519.                 mx[1] = max(mx[1], pnts->Points[i].Y/65536.0);
  520.                 mn[1] = min(mn[1], pnts->Points[i].Y/65536.0);
  521.                 imx[1] = max(imx[1], pnts->Points[i].Y/65536.0);
  522.                 imn[1] = min(imn[1], pnts->Points[i].Y/65536.0);
  523.                 mx[2] = max(mx[2], pnts->Points[i].Z/65536.0);
  524.                 mn[2] = min(mn[2], pnts->Points[i].Z/65536.0);
  525.                 imx[2] = max(imx[2], pnts->Points[i].Z/65536.0);
  526.                 imn[2] = min(imn[2], pnts->Points[i].Z/65536.0);
  527.             }
  528.  
  529.             for (i=0; i<face->TCount; i++) 
  530.             {
  531.                 surf = MakeSurface(
  532.                     (found & FND_CLST)? clst->colors[i][0]: colr.col[0],
  533.                     (found & FND_CLST)? clst->colors[i][1]: colr.col[1],
  534.                     (found & FND_CLST)? clst->colors[i][2]: colr.col[2],
  535.                     (found & FND_RLST)? rlst->colors[i][0]: refl.col[0],
  536.                     (found & FND_RLST)? rlst->colors[i][1]: refl.col[1],
  537.                     (found & FND_RLST)? rlst->colors[i][2]: refl.col[2],
  538.                     (found & FND_TLST)? tlst->colors[i][0]: tran.col[0],
  539.                     (found & FND_TLST)? tlst->colors[i][1]: tran.col[1],
  540.                     (found & FND_TLST)? tlst->colors[i][2]: tran.col[2],
  541.                     (found & FND_SPEC) ? spec.Hardness : 0,
  542.                     (found & FND_SPEC) ? spec.Specularity : 0,
  543.                     (found & FND_MTTR) ? mttr.Index : 0);
  544.                     
  545.                 p1 = edge->Edges[face->Connects[i][0]][0];
  546.                 p2 = edge->Edges[face->Connects[i][0]][1];
  547.                 p3 = edge->Edges[face->Connects[i][1]][0];
  548.                 p3 = ((p1 == p3) || (p2 == p3)) ? 
  549.                         edge->Edges[face->Connects[i][1]][1] : p3;
  550.  
  551.                 if ((pnts->Points[p1].X == pnts->Points[p2].X) 
  552.                         && (pnts->Points[p1].Y == pnts->Points[p2].Y) 
  553.                         && (pnts->Points[p1].Z == pnts->Points[p2].Z))
  554.                     degen++;
  555.                 else if ((pnts->Points[p1].X == pnts->Points[p3].X) 
  556.                         && (pnts->Points[p1].Y == pnts->Points[p3].Y) 
  557.                         && (pnts->Points[p1].Z == pnts->Points[p3].Z))
  558.                     degen++;
  559.                 else if ((pnts->Points[p2].X == pnts->Points[p3].X) 
  560.                         && (pnts->Points[p2].Y == pnts->Points[p3].Y) 
  561.                         && (pnts->Points[p2].Z == pnts->Points[p3].Z))
  562.                     degen++;
  563.                 else 
  564.                 {
  565.                     fprintf(ofh, "triangle {\n");
  566.                     fprintf(ofh, "\tloc\t\t<%f, %f, %f>\n", 
  567.                         pnts->Points[p1].X/65536.0,
  568.                         pnts->Points[p1].Z/65536.0, 
  569.                         pnts->Points[p1].Y/65536.0);
  570.                     fprintf(ofh, "\tv1\t\t<%f, %f, %f>\n",
  571.                         (pnts->Points[p2].X-pnts->Points[p1].X)/65536.0,
  572.                         (pnts->Points[p2].Z-pnts->Points[p1].Z)/65536.0,
  573.                         (pnts->Points[p2].Y-pnts->Points[p1].Y)/65536.0);
  574.                     fprintf(ofh, "\tv2\t\t<%f, %f, %f>\n",
  575.                         (pnts->Points[p3].X-pnts->Points[p1].X)/65536.0,
  576.                         (pnts->Points[p3].Z-pnts->Points[p1].Z)/65536.0,
  577.                         (pnts->Points[p3].Y-pnts->Points[p1].Y)/65536.0);
  578.                     fprintf(ofh, "\tsurface\t%s\n", surf->name);
  579.                     fprintf(ofh, "}\n\n");
  580.                 }
  581.             }
  582.             fprintf(stdout, "%d of %d triangle degenerative\n", degen, face->TCount);
  583.             fprintf(stdout, "***\tAxis bounds: <%f, %f, %f> - <%f, %f, %f>\n",
  584.                      mn[0], mn[2], mn[1], mx[0], mx[2], mx[1]);
  585.         }
  586.         if (!(prp.Props[PRP_SMOOTH]))
  587.             fprintf(ofh, "");
  588.  
  589.     }
  590.  
  591.     if (found & FND_PNTS)
  592.         free(pnts);
  593.     if (found & FND_EDGE)
  594.         free(edge);
  595.     if (found & FND_FACE)
  596.         free(face);
  597.     if (found & FND_TLST)
  598.         free(tlst);
  599.     if (found & FND_RLST)
  600.         free(rlst);
  601.     if (found & FND_CLST)
  602.         free(clst);
  603. }
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610. void GetObjChunk(int ifd, int len)
  611. {
  612.     Chunk    chunk;
  613.     
  614.     while (len) 
  615.     {
  616.         len -= read(ifd, &chunk, sizeof(Chunk));
  617.  
  618.         if (chunk.name == MakeName("EXTR")) 
  619.         {
  620.             fprintf(stdout, "\tEXTR:  found\n");
  621.             lseek(ifd, chunk.len, 1);
  622.             len -= chunk.len;
  623.         }
  624.         
  625.         else if (chunk.name == MakeName("TOBJ")) 
  626.         {
  627.             fprintf(stdout, "\tTOBJ:\n\n");
  628.             lseek(ifd, chunk.len, 1);
  629.             len -= chunk.len;
  630.         }
  631.         
  632.         else if (chunk.name == MakeName("DESC")) 
  633.         {
  634.             fprintf(stdout, "\tDESC:\n");
  635.             GetDescChunk(ifd, chunk.len);
  636.             len -= chunk.len;
  637.         }
  638.         
  639.         else 
  640.         {
  641.             fprintf(stdout, "\t%.4s:  Found unknown chunk\n", &chunk.name);
  642.             lseek(ifd, chunk.len, 1);
  643.             len -= chunk.len;
  644.         }
  645.     }
  646. }
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653. void GetInfoChunk(int ifd, int len)
  654. {
  655.     Chunk    chunk;
  656.     
  657.     while (len) 
  658.     {
  659.         len -= read(ifd, &chunk, sizeof(Chunk));
  660.  
  661.         if (chunk.name == MakeName("BRSH")) 
  662.         {
  663.             BRSH brsh;
  664.             len -= read(ifd, &brsh, sizeof(BRSH));
  665.             fprintf(stdout, "\tBRSH:  #%d = %s\n", brsh.Number, brsh.Filename);
  666.         }
  667.         
  668.         else if (chunk.name == MakeName("STNC")) 
  669.         {
  670.             STNC stnc;
  671.             len -= read(ifd, &stnc, sizeof(STNC));
  672.             fprintf(stdout, "\tSTNC:  #%d = %s\n", stnc.Number, stnc.Filename);
  673.         }
  674.         
  675.         else if (chunk.name == MakeName("TXTR")) 
  676.         {
  677.             TXTR txtr;
  678.             len -= read(ifd, &txtr, sizeof(TXTR));
  679.             fprintf(stdout, "\tTXTR:  #%d = %s\n", txtr.Number, txtr.Filename);
  680.         }
  681.         
  682.         else if (chunk.name == MakeName("OBSV")) 
  683.         {
  684.             OBSV obsv;
  685.             len -= read(ifd, &obsv, sizeof(OBSV));
  686.             fprintf(stdout, "\tOBSV:  Location = <%f, %f, %f>n", obsv.Camera.X/65536.0, obsv.Camera.Y/65536, obsv.Camera.Z/65536.0);
  687.             fprintf(stdout, "\t       Rotate = <%f, %f, %f>\n", obsv.Rotate.X/65536.0, obsv.Rotate.Y/65536, obsv.Rotate.Z/65536.0);
  688.             fprintf(stdout, "\t       Focal Len. = %f\n", obsv.Focal/65536.0);
  689.         }
  690.         
  691.         else if (chunk.name == MakeName("OTRK")) 
  692.         {
  693.             OTRK otrk;
  694.             len -= read(ifd, &otrk, sizeof(OTRK));
  695.             fprintf(stdout, "\tOTRK:  %s\n", otrk.Trackname);
  696.         }
  697.         
  698.         else if (chunk.name == MakeName("OSTR")) 
  699.         {
  700.             fprintf(stdout, "\tOSTR:  found\n");
  701.             lseek(ifd, chunk.len, 1);
  702.             len -= chunk.len;
  703.         }
  704.         
  705.         else if (chunk.name == MakeName("FADE")) 
  706.         {
  707.             fprintf(stdout, "\tFADE:  found\n");
  708.             lseek(ifd, chunk.len, 1);
  709.             len -= chunk.len;
  710.         }
  711.         
  712.         else if (chunk.name == MakeName("SKYC")) 
  713.         {
  714.             fprintf(stdout, "\tSKYC:  found\n");
  715.             lseek(ifd, chunk.len, 1);
  716.             len -= chunk.len;
  717.         }
  718.         
  719.         else if (chunk.name == MakeName("AMBI")) 
  720.         {
  721.             fprintf(stdout, "\tAMBI:  found\n");
  722.             lseek(ifd, chunk.len, 1);
  723.             len -= chunk.len;
  724.         }
  725.         
  726.         else if (chunk.name == MakeName("GLB0")) 
  727.         {
  728.             fprintf(stdout, "\tGLB0:  found\n");
  729.             lseek(ifd, chunk.len, 1);
  730.             len -= chunk.len;
  731.         }
  732.         
  733.         else 
  734.         {
  735.             fprintf(stdout, "\t%.4s:  Found unknown chunk\n", &chunk.name);
  736.             lseek(ifd, chunk.len, 1);
  737.             len -= chunk.len;
  738.         }
  739.     }
  740. }
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747. void main(int argc, char *argv[])
  748. {
  749.     int        ifd=-1;
  750.     Form    form;
  751.     Chunk    chunk;
  752.     int        len;
  753.     
  754.     if (argc < 3) 
  755.     {
  756.         fprintf(stdout, "usage: turbo2arrt turbofile.in arrtscript.out\n");
  757.         goto cleanup;
  758.     }
  759.     
  760.     if ((ifd = open(argv[1], O_RDONLY)) == -1) 
  761.     {
  762.         fprintf(stdout, "turbo2arrt:  could not open input file %s\n", argv[1]);
  763.         goto cleanup;
  764.     }
  765.     
  766.     if (!(ofh = fopen(argv[2], "w"))) 
  767.     {
  768.         fprintf(stdout, "turbo2arrt:  could not open output file %s\n", argv[2]);
  769.         goto cleanup;
  770.     }
  771.  
  772.     filename = argv[1];
  773.  
  774.     read(ifd, &form, sizeof(Form));
  775.     if ((form.form != MakeName("FORM")) || (form.type != MakeName("TDDD"))) 
  776.     {
  777.         fprintf(stdout, "turbo2arrt:  %s is not proper file type\n", argv[1]);
  778.         goto cleanup;
  779.     }
  780.     
  781.     len = read(ifd, &chunk, sizeof(Chunk));
  782.     while (len) 
  783.     {
  784.         if (chunk.name == MakeName("INFO")) 
  785.         {
  786.             fprintf(stdout, "INFO:\n");
  787.             GetInfoChunk(ifd, chunk.len);
  788.             fprintf(stdout, "\n\n");
  789.         }
  790.         
  791.         else if (chunk.name == MakeName("OBJ ")) 
  792.         {
  793.             fprintf(stdout, "OBJ :\n");
  794.             GetObjChunk(ifd, chunk.len);
  795.             fprintf(stdout, "\n");
  796.         }
  797.  
  798.         else 
  799.         {
  800.             fprintf(stdout, "%.4s:  Found unknown chunk\n\n\n", &chunk.name);
  801.             lseek(ifd, chunk.len, 1);
  802.         }
  803.  
  804.         len = read(ifd, &chunk, sizeof(Chunk));
  805.     }
  806.  
  807.     fprintf(stdout, "***\n\tBounds: <%f, %f, %f> - <%f, %f, %f>\n", imn[0], imn[2], imn[1], imx[0], imx[2], imx[1]);
  808.  
  809. cleanup:
  810.  
  811.     if (ifd != -1)
  812.         close(ifd);
  813.     if (ofh)
  814.         fclose(ofh);
  815. }
  816.