home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / macraysh.sit / Code / Source / macgenerate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-11  |  17.7 KB  |  714 lines

  1. /* Macgenerate.c
  2.  *
  3.  * Script file generator for the masses
  4.  */
  5.  
  6.  
  7. #include "atmosphere.h"
  8. #include "surface.h"
  9. #include "texture.h"
  10. #include "image.h"
  11. #include "geom.h"
  12. #include "light.h"
  13. #include "options.h"
  14. #include "stats.h"
  15. #include "viewing.h"
  16.  
  17. #include "blob.h"
  18. #include "box.h"
  19. #include "cone.h"
  20. #include "csg.h"
  21. #include "cylinder.h"
  22. #include "disc.h"
  23. #include "grid.h"
  24. #include "hf.h"
  25. #include "instance.h"
  26. #include "list.h"
  27. #include "plane.h"
  28. #include "poly.h"
  29. #include "sphere.h"
  30. #include "torus.h"
  31. #include "triangle.h"
  32.  
  33. #include "point.h"
  34. #include "infinite.h"
  35. #include "spot.h"
  36. #include "jittered.h"
  37. #include "extended.h"
  38.  
  39. #include "blotch.h"
  40. #include "bump.h"
  41. #include "checker.h"
  42. #include "cloud.h"
  43. #include "fbm.h"
  44. #include "fbmbump.h"
  45. #include "gloss.h"
  46. #include "imagetext.h"
  47. #include "marble.h"
  48. #include "mount.h"
  49. #include "sky.h"
  50. #include "stripe.h"
  51. #include "windy.h"
  52. #include "wood.h"
  53.  
  54. #include "fog.h"
  55. #include "fogdeck.h"
  56. #include "mist.h"
  57.  
  58. #include "rotate.h"
  59. #include "scale.h"
  60. #include "translate.h"
  61.  
  62. #include "maccreate.h"
  63. #include "maceditor.h"
  64.  
  65. extern Surface *Surfaces ;
  66. extern Geom *Objects, *World ;
  67. extern Light *Lights ;
  68.  
  69. static FILE *script ;
  70. static char ind = 0 ;
  71.  
  72. void indent()
  73. {
  74.     char i ;
  75.     for(i = 0 ; i < ind ; i++)
  76.         fprintf(script,"\t") ;
  77. }
  78.  
  79. void GenerateLightInstance(Light *l)
  80. {
  81.     int type ;
  82.  
  83.     if(!l) return ;
  84.     type = LightType(l) ;
  85.     if(type != -1) {
  86.         indent() ;
  87.         if((l->color.r == l->color.b) && (l->color.r == l->color.g))
  88.             fprintf(script,"light %.4f ",l->color.r) ;
  89.         else
  90.             fprintf(script,"light %.4f %.4f %.4f ",l->color.r,l->color.g,l->color.b) ;
  91.         indent() ;
  92.         switch(type) {
  93.             case L_POINT:
  94.                 fprintf(script,"point %.4f %.4f %.4f\n",((Pointlight *)l->light)->pos.x,
  95.                         ((Pointlight *)l->light)->pos.y,((Pointlight *)l->light)->pos.z) ;
  96.                 break ;
  97.             case L_INFINITE:
  98.                 fprintf(script,"directional %.4f %.4f %.4f\n",((Infinite *)l->light)->dir.x,
  99.                     ((Infinite *)l->light)->dir.y,((Infinite *)l->light)->dir.z) ;
  100.                 break ;
  101.             case L_SPOT:
  102.                 {
  103.                     Float in, out ;
  104.                     in = acos(((Spotlight *)l->light)->radius)*360/TWOPI,
  105.                     out = acos(((Spotlight *)l->light)->falloff)*360/TWOPI,
  106.                     fprintf(script,"spot %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",
  107.                                 ((Spotlight *)l->light)->pos.x,
  108.                                 ((Spotlight *)l->light)->pos.y,
  109.                                 ((Spotlight *)l->light)->pos.z,
  110.                                 ((Spotlight *)l->light)->dir.x,
  111.                                 ((Spotlight *)l->light)->dir.y,
  112.                                 ((Spotlight *)l->light)->dir.z,
  113.                                 ((Spotlight *)l->light)->coef,
  114.                                 in,out) ;
  115.                 }
  116.                 break ;
  117.             case L_JITTERED:                
  118.                 break ;
  119.             case L_EXTENDED:
  120.                 fprintf(script,"extended %.4f %.4f %.4f %.4f\n",((Extended *)l->light)->radius,
  121.                     ((Extended *)l->light)->pos.x,((Extended *)l->light)->pos.y,
  122.                     ((Extended *)l->light)->pos.z) ;
  123.                 break ;
  124.         }
  125.     }
  126. }
  127.  
  128.  
  129. void GenerateSurfaceProperties(Surface *s)
  130. {
  131.     indent() ;
  132.     fprintf(script,"ambient %.4f %.4f %.4f\n",s->amb.r,s->amb.g,s->amb.b) ;
  133.     indent() ;
  134.     fprintf(script,"diffuse %.4f %.4f %.4f\n",s->diff.r,s->diff.g,s->diff.b) ;
  135.     indent() ;
  136.     fprintf(script,"specular %.4f %.4f %.4f\n",s->spec.r,s->spec.g,s->spec.b) ;
  137.     indent() ;
  138.     fprintf(script,"specpow %.4f\n",s->srexp) ;
  139.     indent() ;
  140.     fprintf(script,"body %.4f %.4f %.4f\n",s->body.r,s->body.g,s->body.b) ;
  141.     indent() ;
  142.     fprintf(script,"extinct %.4f\n",s->statten) ;
  143.     indent() ;
  144.     fprintf(script,"transp %.4f\n",s->transp) ;
  145.     indent() ;
  146.     fprintf(script,"reflect %.4f\n",s->reflect) ;
  147.     indent() ;
  148.     fprintf(script,"index %.4f\n",s->index) ;
  149.     indent() ;
  150.     fprintf(script,"translu %.4f %.4f %.4f %.4f %.4f\n",s->translucency,s->translu.r,s->translu.g,s->translu.b,s->stexp) ;
  151.     indent() ;
  152.     if(s->noshadow) {
  153.         fprintf(script,"noshadow\n") ;
  154.         indent() ;
  155.     }
  156. }
  157.  
  158. void GenerateSurface(Surface *s)
  159. {
  160.     Surface *s2 ;
  161.     
  162.     if(!s) return ;
  163.  
  164.     s2 = Surfaces ;
  165.     while(s2 && (s2 != s)) s2 = s2->next ;
  166.     
  167.     if(s2 == s) {
  168.         fprintf(script,"%s ",s->name) ;
  169.     }
  170.     else {
  171.         fprintf(script,"\n") ;
  172.         GenerateSurfaceProperties(s) ;
  173.     }
  174. }
  175.  
  176. void GenerateSurfaceInstance(Surface *s)
  177. {
  178.     if(!s) return ;
  179.     
  180.     fprintf(script,"surface %s\n",s->name) ;
  181.     ind++ ;
  182.     GenerateSurfaceProperties(s) ;
  183.     fprintf(script,"\n") ;
  184.     ind-- ;
  185.     
  186.     /*
  187.     fprintf(script,"    {\n");
  188.     fprintf(script,"        \"%s\",\n",s->name);
  189.     fprintf(script,"        { %.4f,%.4f,%.4f },\n",s->amb.r,s->amb.g,s->amb.b);
  190.     fprintf(script,"        { %.4f,%.4f,%.4f },\n",s->diff.r,s->diff.g,s->diff.b);
  191.     fprintf(script,"        { %.4f,%.4f,%.4f },\n",s->spec.r,s->spec.g,s->spec.b);
  192.     fprintf(script,"        { %.4f,%.4f,%.4f },\n",s->translu.r,s->translu.g,s->translu.b);
  193.     fprintf(script,"        { %.4f,%.4f,%.4f },\n",s->body.r,s->body.g,s->body.b);
  194.     fprintf(script,"        %.4f,\n",s->srexp);
  195.     fprintf(script,"        %.4f,\n",s->stexp);
  196.     fprintf(script,"        %.4f,\n",s->statten);
  197.     fprintf(script,"        %.4f,\n",s->index);
  198.     fprintf(script,"        %.4f,\n",s->reflect);
  199.     fprintf(script,"        %.4f,\n",s->transp);
  200.     fprintf(script,"        %.4f,\n",s->translucency);
  201.     fprintf(script,"        %d,\n",s->noshadow);
  202.     fprintf(script,"        NULL\n");
  203.     fprintf(script,"    },\n");
  204.     */
  205. }
  206.  
  207. void GenerateTransforms(Trans *t)
  208. {
  209.     Rotate *rot ;
  210.     Scale *sca ;
  211.     Translate *tra ;
  212.     RSMatrix *mat;
  213.     
  214.     if(!t) return ;
  215.     mat = &t->trans;
  216.     if(!mat) return;
  217.  
  218.     fprintf(script,"transform %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f",
  219.         mat->matrix[0][0],mat->matrix[0][1],mat->matrix[0][2],
  220.         mat->matrix[1][0],mat->matrix[1][1],mat->matrix[1][2],
  221.         mat->matrix[2][0],mat->matrix[2][1],mat->matrix[2][2],
  222.         mat->translate.x,mat->translate.y,mat->translate.z);
  223.  
  224. /*    switch(TransformType(t)) {
  225.         case TR_ROTATE:
  226.             rot = t->tr ;
  227.             fprintf(script,"rotate %.4f %.4f %.4f %.4f\n",rot->x,rot->y,rot->z,rot->theta) ;
  228.             break ;
  229.         case TR_SCALE:
  230.             sca = t->tr ;
  231.             fprintf(script,"scale %.4f %.4f %.4f\n",sca->x,sca->y,sca->z) ;
  232.             break ;
  233.         case TR_TRANSLATE:
  234.             tra = t->tr ;
  235.             fprintf(script,"translate %.4f %.4f %.4f\n",tra->x,tra->y,tra->z) ;
  236.             break ;
  237.         default:
  238.             printf(" Bad transform found \n") ;
  239.     }
  240. */
  241. }
  242.  
  243. void GenerateTexture(Texture *t)
  244. {
  245.     if(!t) return ;
  246.     fprintf(script," texture ") ;
  247.     switch(TextureType(t)) {
  248.         case T_BLOTCH:
  249.             fprintf(script,"blotch %.4f ",((Blotch *)t->data)->mix) ;
  250.             GenerateSurface(((Blotch *)t->data)->surf) ;
  251.             break ;
  252.         case T_BUMP:
  253.             fprintf(script,"bump %.4f ",((Bump *)t->data)->size) ;
  254.             break ;
  255.         case T_CHECKER:
  256.             fprintf(script,"checker ") ;
  257.             GenerateSurface(((Checker *)t->data)->surf) ;
  258.             break ;
  259.         case T_CLOUD:
  260.             fprintf(script,"cloud %.4f %.4f %.4f %d %.4f %.4f %.4f ",
  261.                 ((CloudText *)t->data)->scale,
  262.                 (((CloudText *)t->data)->beta/2.)-1.,
  263.                 ((CloudText *)t->data)->lambda,
  264.                 ((CloudText *)t->data)->octaves,
  265.                 ((CloudText *)t->data)->cthresh,
  266.                 ((CloudText *)t->data)->range+((CloudText *)t->data)->cthresh,
  267.                 ((CloudText *)t->data)->transcale
  268.                 ) ;
  269.             break ;
  270.         case T_FBM:
  271.             fprintf(script,"fbm %.4f %.4f %.4f %.4f %d %.4f ",
  272.                 ((FBm *)t->data)->offset,
  273.                 ((FBm *)t->data)->scale,
  274.                 (((FBm *)t->data)->beta/2.)-1.,
  275.                 ((FBm *)t->data)->lambda,
  276.                 ((FBm *)t->data)->octaves,
  277.                 ((FBm *)t->data)->thresh            
  278.             ) ;
  279.             break ;
  280.         case T_FBMBUMP:
  281.             fprintf(script,"fbmbump %.4f %.4f %.4f %.4f %d ",
  282.                 ((FBm *)t->data)->offset,
  283.                 ((FBm *)t->data)->scale,
  284.                 (((FBm *)t->data)->beta/2.)-1.,
  285.                 ((FBm *)t->data)->lambda,
  286.                 ((FBm *)t->data)->octaves
  287.             ) ;
  288.             break ;
  289.         case T_GLOSS:
  290.             fprintf(script,"gloss ",((Gloss *)t->data)->glossy) ;
  291.             break ;
  292.         case T_IMAGE:
  293.             fprintf(script,"/* Image mapping not supported by this release of Rayshade-M */") ;
  294.             break ;
  295.         case T_MARBLE:
  296.             fprintf(script,"marble ") ;
  297.             break ;
  298.         case T_SKY:
  299.             fprintf(script,"sky %.4f %.4f %.4f %d %.4f %.4f ",
  300.                 ((Sky *)t->data)->scale,
  301.                 (((Sky *)t->data)->beta/2.)-1.,
  302.                 ((Sky *)t->data)->lambda,
  303.                 ((Sky *)t->data)->octaves,
  304.                 ((Sky *)t->data)->cthresh,
  305.                 ((Sky *)t->data)->lthresh
  306.                 ) ;
  307.             break ;
  308.         case T_STRIPE:
  309.             fprintf(script,"stripe ") ;
  310.             GenerateSurface(((Stripe *)t->data)->surf) ;
  311.             fprintf(script," %.4f %.4f ",((Stripe *)t->data)->width,((Stripe *)t->data)->bump) ;
  312.             break ;
  313.         case T_WOOD:
  314.             fprintf(script,"wood ") ;
  315.             break ;
  316.     }
  317.     if(t->trans) {
  318.         Trans *tr ;
  319.         tr = t->trans ;
  320.         do {
  321.             GenerateTransforms(tr);
  322.             tr = tr->next ;    
  323.         } while(tr) ;
  324.     }
  325.     fprintf(script,"\n");
  326. }
  327.  
  328.  
  329. void GenerateObject(Geom *o)
  330. {
  331.     int loop ;
  332.  
  333.     if(!o) return ;
  334.  
  335.     fprintf(script,"\n");
  336.     ind++ ;
  337.     switch(ObjectType(o)) {
  338.         case PLANE:
  339.             indent() ;
  340.             fprintf(script,"plane ") ;
  341.             GenerateSurface(o->surf) ;
  342.             fprintf(script,"%.4f %.4f %.4f %.4f %.4f %.4f\n",
  343.                         ((Plane *)o->obj)->pos.x ,((Plane *)o->obj)->pos.y,
  344.                         ((Plane *)o->obj)->pos.z ,((Plane *)o->obj)->norm.x,
  345.                         ((Plane *)o->obj)->norm.y,((Plane *)o->obj)->norm.z) ;
  346.             break ;
  347.         case DISC:
  348.             indent() ;
  349.             fprintf(script,"disc ") ;
  350.             GenerateSurface(o->surf) ;
  351.             fprintf(script,"%.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",
  352.                         ((Disc *)o->obj)->radius,((Disc *)o->obj)->pos.x,
  353.                         ((Disc *)o->obj)->pos.y ,((Disc *)o->obj)->pos.z,
  354.                         ((Disc *)o->obj)->norm.x,((Disc *)o->obj)->norm.y,
  355.                         ((Disc *)o->obj)->norm.z) ;
  356.             break ;
  357.         case SPHERE:
  358.             indent() ;
  359.             fprintf(script,"sphere ") ;
  360.             GenerateSurface(o->surf) ;
  361.             fprintf(script,"%.4f %.4f %.4f %.4f\n",
  362.                     ((Sphere *)o->obj)->r,((Sphere *)o->obj)->x,
  363.                     ((Sphere *)o->obj)->y,((Sphere *)o->obj)->z) ;
  364.             break ;
  365.         case TRIANGLE:
  366.             {
  367.                 Triangle *tri ;
  368.                 
  369.                 tri = o->obj ;
  370.                 indent() ;
  371.                 fprintf(script,"triangle ") ;
  372.                 GenerateSurface(o->surf) ;
  373.                 fprintf(script,"\n") ;
  374.                 if(tri->type == FLATTRI) {
  375.                     for(loop = 0 ; loop < 3 ; loop++) {
  376.                         indent() ;
  377.                         fprintf(script,"%.4f %.4f %.4f\n",((Triangle *)o->obj)->p[loop].x,
  378.                                 ((Triangle *)o->obj)->p[loop].y,
  379.                                 ((Triangle *)o->obj)->p[loop].z) ;
  380.                         }
  381.                 
  382.                 }
  383.                 else {
  384.                     for(loop = 0 ; loop < 3 ; loop++) {
  385.                         indent() ;
  386.                         fprintf(script,"%.4f %.4f %.4f %.4f %.4f %.4f\n",
  387.                                 ((Triangle *)o->obj)->p[loop].x,
  388.                                 ((Triangle *)o->obj)->p[loop].y,
  389.                                 ((Triangle *)o->obj)->p[loop].z,
  390.                                 ((Triangle *)o->obj)->vnorm[loop].x,
  391.                                 ((Triangle *)o->obj)->vnorm[loop].y,
  392.                                 ((Triangle *)o->obj)->vnorm[loop].z) ;
  393.                     }
  394.                 }
  395.             }
  396.             break ;
  397.         case POLYGON:
  398.             indent() ;
  399.             fprintf(script,"polygon ") ;
  400.             GenerateSurface(o->surf) ;
  401.             fprintf(script,"\n") ;
  402.             for(loop = 0 ; loop < ((RPolygon *)o->obj)->npoints ; loop++) {
  403.                 indent() ;
  404.                 fprintf(script,"%.4f %.4f %.4f\n",((RPolygon *)o->obj)->points[loop].x,
  405.                             ((RPolygon *)o->obj)->points[loop].y,
  406.                             ((RPolygon *)o->obj)->points[loop].z) ;
  407.             }
  408.             break ;
  409.         case BOX:
  410.             indent() ;
  411.             fprintf(script,"box ") ;
  412.             GenerateSurface(o->surf) ;
  413.             fprintf(script,"%.4f %.4f %.4f %.4f %.4f %.4f\n",
  414.                     ((Box *)o->obj)->bounds[0][0],((Box *)o->obj)->bounds[0][1],
  415.                     ((Box *)o->obj)->bounds[0][2],((Box *)o->obj)->bounds[1][0],
  416.                     ((Box *)o->obj)->bounds[1][1],((Box *)o->obj)->bounds[1][2]) ;
  417.             break ;
  418.         case CYLINDER:
  419.             {
  420.                 Cylinder *cyl ;
  421.                 Vector dummy, bottom, top ;
  422.                 Float radius ;
  423.  
  424.                 indent() ;
  425.                 fprintf(script,"cylinder ") ;
  426.                 GenerateSurface(o->surf) ;
  427.  
  428.                 cyl = o->obj ;
  429.                 /* Top and bottom of our normalized cylinder */
  430.                 bottom.x = bottom.y = bottom.z = 0. ;
  431.                 top.x = top.y = 0. ; top.z = 1. ;
  432.                 /* Dummy is a point on the edge of our normalized cylinder */
  433.                 dummy.x = 1.0 ; dummy.y = dummy.z = 0. ;
  434.  
  435.                 /* Now transform these points */
  436.                 PointTransform(&top,&cyl->trans.trans) ;
  437.                 PointTransform(&bottom,&cyl->trans.trans) ;
  438.                 PointTransform(&dummy,&cyl->trans.trans) ;
  439.     
  440.                 /* The radius value is the distance between bottom and dummy */
  441.                 VecSub(bottom,dummy,&dummy) ;
  442.                 radius = VecNormalize(&dummy) ;
  443.                 fprintf(script,"%.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",
  444.                         radius,bottom.x,bottom.y,bottom.z,top.x,top.y,top.z) ;
  445.             }
  446.         case CONE:
  447.             {
  448.                 Cone *cone ;
  449.                 Vector bottomr, bottom, apex ;
  450.                 Float br, ar ;
  451.  
  452.                 indent() ;
  453.                 fprintf(script,"cone ") ;
  454.                 GenerateSurface(o->surf) ;
  455.  
  456.                 cone = o->obj ;
  457.                 /* apex and bottom of our normalized cone */
  458.                 bottom.x = bottom.y = 0 ; bottom.z = 1. ;
  459.                 apex.x = apex.y = 0. ; apex.z = cone->start_dist ;
  460.                 /* Point on the edge of our normalized cone */
  461.                 bottomr.x = 1.0 ; bottomr.y = 0 ; bottomr.z = 1. ;
  462.  
  463.                 /* Now transform these points */
  464.                 PointTransform(&apex,&cone->trans.trans) ;
  465.                 PointTransform(&bottom,&cone->trans.trans) ;
  466.                 PointTransform(&bottomr,&cone->trans.trans) ;
  467.     
  468.                 /* Now calculate the radii */
  469.                 VecSub(bottom,bottomr,&bottomr) ;
  470.                 br = VecNormalize(&bottomr) ;
  471.                 ar = cone->start_dist * br ;
  472.                 fprintf(script,"%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",
  473.                                 br,bottom.x,bottom.y,bottom.z,
  474.                                 ar,apex.x,apex.y,apex.z) ;
  475.             }
  476.             break ;
  477.         case TORUS:
  478.             {
  479.                 Torus *tor ;
  480.                 Vector norm, pos ;
  481.                 
  482.                 indent() ;
  483.                 fprintf(script,"torus ") ;
  484.                 GenerateSurface(o->surf) ;
  485.  
  486.                 tor = o->obj ;
  487.                 pos.x = pos.y = pos.z = 0. ;
  488.                 norm.x = norm.y = 0. ; norm.z = 1. ;
  489.                 PointTransform(&pos,&tor->trans.trans) ;
  490.                 PointTransform(&norm,&tor->trans.trans) ;
  491.                 fprintf(script,"%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",
  492.                             tor->a,tor->b,pos.x,pos.y,pos.z,
  493.                             norm.x,norm.y,norm.z) ;
  494.             }
  495.             break ;
  496.         case BLOB:
  497.             {
  498.                 Blob *blob ;
  499.                 int loop ;
  500.                 
  501.                 indent() ;
  502.                 fprintf(script,"blob ") ;
  503.                 GenerateSurface(o->surf) ;
  504.                 blob = o->obj ;
  505.                 fprintf(script," %.4f\n",blob->T) ;
  506.                 ind++ ;
  507.                 for(loop = 0 ; loop < blob->num ; loop++) {
  508.                     indent() ;
  509.                     fprintf(script,"%.4f %.4f %.4f %.4f %.4f\n",
  510.                             blob->list[loop].c0,
  511.                             blob->list[loop].rs,
  512.                             blob->list[loop].x,
  513.                             blob->list[loop].y,
  514.                             blob->list[loop].z) ;
  515.                 }
  516.                 ind-- ;
  517.             } 
  518.             break ;
  519.         case HF:
  520.             fprintf(script,"/* A height field object has been removed from the script !!*/\n") ;
  521.             break ;
  522.         case INSTANCE:
  523.             {
  524.                 Geom *o2 ;
  525.                 
  526.                 o2 = Objects ;
  527.                 while(o2 && (o2 != ((Instance *)o->obj)->obj)) o2 = o2->next ;
  528.                 if(o2==((Instance *)o->obj)->obj) {
  529.                     indent() ;
  530.                     fprintf(script,"object ") ;
  531.                     GenerateSurface(o->surf) ;
  532.                     fprintf(script," %s\n",o2->name) ;
  533.                 }
  534.                 else
  535.                     fprintf(script,"/* Oh dear i just tried to generate a non-existant reference ! */\n") ;
  536.             }
  537.             break ;
  538.         case CSG:
  539.             {
  540.                 Csg *csg ;
  541.                 
  542.                 csg = o->obj ;
  543.                 indent() ;
  544.                 if(csg->operator == CSG_UNION)
  545.                     fprintf(script,"union\n") ;
  546.                 else if(csg->operator == CSG_INTERSECT)
  547.                     fprintf(script,"intersect\n") ;
  548.                 else if(csg->operator == CSG_DIFFERENCE)
  549.                     fprintf(script,"difference\n") ;
  550.                 GenerateObject(csg->obj1) ;
  551.                 GenerateObject(csg->obj2) ;
  552.                 indent() ;
  553.                 fprintf(script,"end\n") ;
  554.             }
  555.             break ;
  556.         case LIST:
  557.             {
  558.                 Geom *o2 ;
  559.  
  560.                 indent() ;
  561.                 fprintf(script,"list\n") ;
  562.                 for(o2 = ((List *)o->obj)->list ; o2 ; o2 = o2->next)
  563.                     GenerateObject(o2) ;
  564.                 for(o2 = ((List *)o->obj)->unbounded ; o2 ; o2 = o2->next)
  565.                     GenerateObject(o2) ;
  566.                 indent() ;
  567.                 fprintf(script,"end\n") ;
  568.             }
  569.             break ;
  570.         case GRID:
  571.             {
  572.                 Geom *o2 ;
  573.  
  574.                 indent() ;
  575.                 fprintf(script,"grid %d %d %d\n",
  576.                     ((Grid *)o->obj)->xsize,
  577.                     ((Grid *)o->obj)->ysize,
  578.                     ((Grid *)o->obj)->zsize) ;
  579.                 for(o2 = ((Grid *)o->obj)->objects ; o2 ; o2 = o2->next)
  580.                     GenerateObject(o2) ;
  581.                 for(o2 = ((Grid *)o->obj)->unbounded ; o2 ; o2 = o2->next)
  582.                     GenerateObject(o2);
  583.                 indent();
  584.                 fprintf(script,"end\n");
  585.             }
  586.             break ;
  587.     }
  588.     ind++ ;
  589.     if(o->trans) {
  590.         Trans *t ;
  591.         
  592.         t = o->trans ;
  593.         do {
  594.             indent() ;
  595.             GenerateTransforms(t);
  596.             t = t->next ;
  597.         } while(t) ;
  598.     }
  599.     if(o->texture) {
  600.         Texture *t ;
  601.         
  602.         t = o->texture ;
  603.         do {
  604.             indent() ;
  605.             GenerateTexture(t);
  606.             t = t->next ;
  607.         } while (t) ;
  608.     }
  609.     ind-- ;
  610.     ind-- ;
  611.     printf("\n") ;
  612. }
  613.  
  614. void GenerateObjectInstance(Geom *o)
  615. {
  616.     if(!o) return ;
  617.     
  618.     fprintf(script,"name %s\n",o->name) ;
  619.     GenerateObject(o) ;
  620. }
  621.  
  622. void GenerateIntro()
  623. {
  624.     fprintf(script,"/* Rayshade-M machine generated output */\n") ;
  625. }
  626.  
  627. void GenerateEnd()
  628. {
  629.     fprintf(script,"\n\n/* End of script */\n") ;
  630. }
  631.  
  632. void GenerateInstances()
  633. {
  634.     Light *l ;
  635.     Surface *s ;
  636.     Geom *o, *obuffer[100] ;
  637.     int size,loop ;
  638.  
  639.     if(Lights) {
  640.         fprintf(script,"\n/* Lights */\n") ;
  641.         for(l = Lights ; l ; l = l->next)
  642.             GenerateLightInstance(l) ;
  643.     }
  644.  
  645.     if(Surfaces) {
  646.         fprintf(script,"\n/* Surfaces */\n") ;
  647.         for(s = Surfaces ; s ; s = s->next)
  648.             GenerateSurfaceInstance(s) ;
  649.     }
  650.  
  651.     /* Objects must be defined backwards - no forward referencing :( */
  652.     if(Objects) {
  653.         size = 0 ;
  654.         fprintf(script,"\n/* Objects */\n") ;
  655.         for(o = Objects ; o ; o = o->next)
  656.             obuffer[size++] = o ;
  657.         for(loop = size-1 ; loop >=0 ; loop--)
  658.             GenerateObjectInstance(obuffer[loop]) ;
  659.     }
  660. }
  661.  
  662. void GenerateRenderOptions()
  663. {
  664.     fprintf(script,"\n/* Render options */\n") ;
  665.     fprintf(script,"background %.4f %.4f %.4f\n",Screen.background.r,Screen.background.g,Screen.background.b) ;
  666.     if(Options.imgname)
  667.         fprintf(script,"outfile %s\n",Options.imgname) ;
  668.     fprintf(script,"contrast %.4f %.4f %.4f\n",Options.contrast.r,Options.contrast.g,Options.contrast.b) ;
  669.     if(Options.shadowtransp)
  670.         fprintf(script,"shadowtransp\n") ;
  671.     fprintf(script,"\n") ;
  672. }
  673.  
  674.  
  675. void GenerateCameraInfo()
  676. {
  677.     fprintf(script,"\n/* Camera options */\n") ;
  678.     fprintf(script,"eyep %.4f %.4f %.4f\n",Camera.pos.x,Camera.pos.y,Camera.pos.z) ;
  679.     fprintf(script,"lookp %.4f %.4f %.4f\n",Camera.lookp.x,Camera.lookp.y,Camera.lookp.z) ;
  680.     fprintf(script,"up %.4f %.4f %.4f\n",Camera.up.x,Camera.up.y,Camera.up.z) ;
  681.     fprintf(script,"fov %.4f %.4f\n", Camera.hfov,Camera.vfov) ;
  682.     fprintf(script,"aperture %.4f\n",Camera.aperture) ;
  683.     fprintf(script,"focaldist %.4f\n",Camera.focaldist) ;
  684.     fprintf(script,"shutter %.4f\n",Options.shutterspeed) ;
  685.     fprintf(script,"screen %d %d\n",Screen.xres,Screen.yres) ;
  686. }
  687.  
  688. void GenerateObjects()
  689. {
  690.     Geom *l ;
  691.  
  692.     fprintf(script,"\n/* The World */\n") ;
  693.     
  694.     /* The world is a list we dont want to see */
  695.     
  696.     for(l = ((List *)World->obj)->list ; l ; l = l->next)
  697.         GenerateObject(l) ;
  698.     for(l = ((List *)World->obj)->unbounded ; l ; l = l->next)
  699.         GenerateObject(l) ;
  700. }
  701.  
  702. void GenerateScript(char *name)
  703. {
  704.     script = fopen(name,"w+") ;
  705.     if(script) {
  706.         GenerateIntro() ;
  707.         GenerateRenderOptions() ;
  708.         GenerateCameraInfo() ;
  709.         GenerateInstances() ;
  710.         GenerateObjects() ;
  711.         GenerateEnd() ;
  712.         fclose(script) ;
  713.     }
  714. }