home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 243.lha / QuickRayTrace_v1.5 / Sources / inout.c < prev    next >
C/C++ Source or Header  |  1989-04-29  |  24KB  |  1,144 lines

  1.  
  2. /**********************************************************
  3.  
  4.                     object loader language
  5.  
  6.  **********************************************************/
  7.  
  8. /* #define IODEBUG 1 */
  9.  
  10. #include "qrt.h"
  11. #include "pattern.h"
  12.  
  13. OBJ_PTR      new_obj(), Get_Object(), Get_Primitive(),
  14.              Get_Instance_Of();
  15. PATTERN_PTR  Attach_Pattern(), Get_Pattern();
  16. char         *malloc();
  17.  
  18. # ifdef AMIGA
  19.     float      atof();
  20. # endif
  21.  
  22. /**********************************************************
  23.  
  24.              External declarations from lexer
  25.  
  26.  **********************************************************/
  27.  
  28. float IsPos();
  29. float Get_Next_Num();
  30. short Get_Color_Val();
  31. char *Get_Next_Name();
  32.  
  33.  
  34.  
  35. /**********************************************************
  36.  
  37.    Global input line number.  If negative, error rountines
  38.    will not report line number (already reached EOF).
  39.  
  40.  **********************************************************/
  41.  
  42. extern int linenumber;
  43.  
  44. /**********************************************************
  45.  
  46.           Load the entire world from standard input
  47.  
  48.  **********************************************************/
  49.  
  50. int LoadWorld()                      /* load world from stdio */
  51. {
  52.   linenumber = 1;
  53.   if((THEWORLD.stack=Get_Object())==NULL)
  54.     Error(ILLEGAL_OBJECT,201);
  55.  
  56.   linenumber = -1;
  57.   return(TRUE);
  58. }
  59.  
  60. /**********************************************************
  61.  
  62.      Get an object and return a pointer to it. If it is
  63.      not an object, but some other world attribute
  64.      specification, note it, but keep trying until an
  65.      object is found or end of input is encountered.
  66.      This is slighly hacked out, but it works for now.
  67.      It calls itself recursively sometimes.
  68.  
  69.      Changed 12 Mar 89 to include fix by Paul Balyoz
  70.      to intitialize colorinfo structure (apparently some
  71.      machines have a problem with it otherwise).
  72.  
  73.  **********************************************************/
  74.  
  75. OBJ_PTR Get_Object() {
  76.   char str[SLEN], *name;
  77.   OBJ_PTR newobj, queue, temp;
  78.   VECTOR loc,rad,d,v3, upper, lower;
  79.   CINFO cinfo;
  80.   int found;
  81.  
  82.   def_colorinfo(&cinfo);          /* initialize color info */
  83.  
  84.   name=NULL; queue=NULL;
  85.   VectEqZero(&loc);
  86.   VectEqZero(&rad);
  87.   VectEqZero(&d);
  88.   VectEqZero(&v3);
  89.   VectEqZero(&upper);
  90.   VectEqZero(&lower);
  91.  
  92.   if (feof(stdin)) return(NULL);
  93.   while (!feof(stdin)) {
  94.     GetToken(str); found = FALSE;
  95.  
  96. #   ifdef IODEBUG
  97.       printf("GETOBJECT: token=%s\n",str);
  98. #   endif
  99.  
  100.     if (GetAttrib(str))
  101.       found = TRUE;
  102.  
  103.     if (strcmp(str,"BEGIN_INSTANCES")==0) {
  104.       found = TRUE;
  105.       THEWORLD.instances = Get_Object();
  106.     }
  107.  
  108.     if (strcmp(str,"END_INSTANCES")==0) {
  109. #     ifdef ROBUST
  110.         if (queue==NULL) Error(SYNTAX_ERROR,205);
  111. #     endif
  112.       found = TRUE;
  113.       return(queue);
  114.     }
  115.  
  116.     if (strcmp(str,"END_BBOX")==0) {
  117. #     ifdef ROBUST
  118.         if (queue==NULL) Error(SYNTAX_ERROR,206);
  119. #     endif
  120.       found = TRUE;
  121.       return(queue);
  122.     }
  123.  
  124.     if (strcmp(str,"BEGIN_BBOX")==0) {
  125.  
  126.        newobj=new_obj(BBOX,&loc,&rad,&d,&v3,&cinfo,NULL,NULL,name,
  127.                       &upper, &lower,
  128.                       (float)0.0, (float)0.0, (float)0.0);
  129.  
  130.        newobj->child = Get_Object();
  131.        newobj->nextobj = queue;
  132.        queue = newobj;
  133.        found = TRUE;
  134.  
  135.     }
  136.  
  137.     if (strcmp(str,"NAME")==0) {
  138.        name=Get_Next_Name();
  139.        found = TRUE;
  140.     }
  141.  
  142.     if ((temp=Get_Primitive(str))!=NULL) {
  143.       found = TRUE;
  144.       temp->nextobj=queue;
  145.       queue = temp;
  146.     }
  147.  
  148.     if (!found && !feof(stdin)) Error(SYNTAX_ERROR,207);
  149.  
  150.   }
  151.  
  152.   return(queue);
  153. }
  154.  
  155.  
  156. /**********************************************************
  157.  
  158.                  Load default color info
  159.  
  160.  **********************************************************/
  161.  
  162. def_colorinfo(cinfo)
  163.   CINFO_PTR cinfo;
  164. {
  165.   copy_colorinfo(cinfo,&(def.cinfo));
  166. }
  167.  
  168.  
  169. /**********************************************************
  170.  
  171.                     Copy color info
  172.  
  173.  **********************************************************/
  174.  
  175. copy_colorinfo(c1,c2)
  176.   CINFO_PTR c1,c2;
  177. {
  178.   if (c1 == NULL) return;
  179.  
  180.   SVectEQ(&(c1->amb),&(c2->amb));
  181.   SVectEQ(&(c1->diff),&(c2->diff));
  182.   SVectEQ(&(c1->mirror),&(c2->mirror));
  183.   SVectEQ(&(c1->trans),&(c2->trans));
  184.   VectEQ(&(c1->density),&(c2->density));
  185.  
  186.   c1->fuzz     = c2->fuzz;
  187.   c1->index    = c2->index;
  188.   c1->dither   = c2->dither;
  189.   c1->sreflect = c2->sreflect;
  190.   c1->reflect  = c2->reflect;
  191. }
  192.  
  193.  
  194. /**********************************************************
  195.  
  196.             Get defaults from input file
  197.  
  198.  **********************************************************/
  199.  
  200. int Get_Default()
  201. {
  202.   char        str[SLEN];
  203.   int         end, found;
  204.  
  205.   end=0;
  206.  
  207.   GetLeftParen();
  208.  
  209.   while (!end && !feof(stdin)) {
  210.     GetToken(str);
  211.  
  212. #   ifdef IODEBUG
  213.       printf("GETDEFAULT : token=%s\n",str);
  214. #   endif
  215.  
  216.     found = GetOpt(str,&(def.cinfo));
  217.  
  218.     if (strcmp(str,"NO_SHADOW")==0) {
  219.       def.shadow = FALSE;
  220.       found = TRUE;
  221.     }
  222.  
  223.     if (strcmp(str,"NO_LAMP")==0) {
  224.       def.vlamp = FALSE;
  225.       found = TRUE;
  226.     }
  227.  
  228.     if (strcmp(str,"THRESHOLD")==0) {
  229.       def.threshold = IsPos(Get_Next_Num());
  230.       found = TRUE;
  231.     }
  232.  
  233.     if (strcmp(str,"X_RES")==0) {
  234.       def.x_res    = (short)IsPos(Get_Next_Num());
  235.       found = TRUE;
  236.     }
  237.  
  238.     if (strcmp(str,"Y_RES")==0) {
  239.       def.y_res    = (short)IsPos(Get_Next_Num());
  240.       found = TRUE;
  241.     }
  242.  
  243.     if (strcmp(str,"ASPECT")==0) {
  244.       def.aspect = IsPos(Get_Next_Num());
  245.       found = TRUE;
  246.     }
  247.  
  248.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  249.  
  250.     if (!found) Error(UNDEFINED_PARAM,209);
  251.   }
  252.   return(TRUE);
  253. }
  254.  
  255.  
  256. /**********************************************************
  257.  
  258.                     Get object options
  259.  
  260.  **********************************************************/
  261.  
  262. int GetOpt(str,cinfo)
  263.   char str[];
  264.   CINFO_PTR cinfo;
  265. {
  266.   int found;
  267.  
  268.   found = FALSE;
  269.  
  270.   if (strcmp(str,"AMB")==0) {
  271.     GetSVector(&(cinfo->amb));
  272.     found = TRUE;
  273.   }
  274.  
  275.   if (strcmp(str,"DIFF")==0) {
  276.     GetSVector(&(cinfo->diff));
  277.     found = TRUE;
  278.   }
  279.  
  280.   if (strcmp(str,"MIRROR")==0) {
  281.     GetSVector(&(cinfo->mirror));
  282.     found = TRUE;
  283.   }
  284.  
  285.   if (strcmp(str,"TRANS")==0) {
  286.     GetSVector(&(cinfo->trans));
  287.     found = TRUE;
  288.   }
  289.  
  290.   if (strcmp(str,"DENSITY")==0) {
  291.     GetVector(&(cinfo->density));
  292.     found = TRUE;
  293.   }
  294.  
  295.   if (strcmp(str,"FUZZ")==0) {
  296.     cinfo->fuzz     = Get_Color_Val();
  297.     found = TRUE;
  298.   }
  299.  
  300.   if (strcmp(str,"INDEX")==0) {
  301.     cinfo->index    = IsPos(Get_Next_Num());
  302.     found = TRUE;
  303.   }
  304.   if (strcmp(str,"DITHER")==0) {
  305.     cinfo->dither   = (short)IsPos(Get_Next_Num());
  306.     found = TRUE;
  307.   }
  308.   if (strcmp(str,"SREFLECT")==0) {
  309.     cinfo->sreflect = IsPos(Get_Next_Num());
  310.     found = TRUE;
  311.   }
  312.   if (strcmp(str,"REFLECT")==0) {
  313.     cinfo->reflect = Get_Color_Val();
  314.     found = TRUE;
  315.   }
  316.  
  317.   return(found);
  318. }
  319.  
  320.  
  321. /**********************************************************
  322.  
  323.           Load a sphere and return pointer to it
  324.  
  325.  **********************************************************/
  326.  
  327. OBJ_PTR GetSphere()
  328. {
  329.   char        str[SLEN], *name;
  330.   VECTOR      loc, rad, d, v3, upper, lower;
  331.   float       xmult, ymult;
  332.   CINFO       cinfo;
  333.   OBJ_PTR     newobj;
  334.   PATTERN_PTR pattern, remove;
  335.   int         end, f, found;
  336.  
  337.   end=f=0;
  338.   def_colorinfo(&cinfo);
  339.   xmult=ymult=1;
  340.   pattern = remove = NULL;
  341.   name    = NULL;
  342.  
  343.   GetLeftParen();
  344.  
  345.   while (!end && !feof(stdin)) {
  346.     GetToken(str);
  347.  
  348. #   ifdef IODEBUG
  349.       printf("GETSPHERE : token=%s\n",str);
  350. #   endif
  351.  
  352.     found = GetOpt(str,&cinfo);
  353.  
  354.     if ((strcmp(str,"POS")==0)      ||
  355.         (strcmp(str,"LOC")==0)      ||
  356.         (strcmp(str,"POSITION")==0) ||
  357.         (strcmp(str,"LOCATION")==0)) {
  358.  
  359.       GetVector(&loc);
  360.       f|=1; found = TRUE;
  361.     }
  362.  
  363.     if (strcmp(str,"RADIUS")==0) {
  364.       rad.x = IsPos(Get_Next_Num());
  365.       f|=2; found = TRUE;
  366.     }
  367.     if (strcmp(str,"PATTERN")==0) {
  368.       pattern = Attach_Pattern();
  369.       found = TRUE;
  370.     }
  371.     if (strcmp(str,"REMOVE")==0) {
  372.       remove = Attach_Pattern();
  373.       found = TRUE;
  374.     }
  375.     if (strcmp(str,"XMULT")==0) {
  376.       xmult = IsPos(Get_Next_Num());
  377.       found=TRUE;
  378.     }
  379.     if (strcmp(str,"YMULT")==0) {
  380.       ymult = IsPos(Get_Next_Num());
  381.       found=TRUE;
  382.     }
  383.     if (strcmp(str,"NAME")==0) {
  384.        name=Get_Next_Name();
  385.        found = TRUE;
  386.     }
  387.  
  388.     if (strcmp(str,")")==0) { end = 1; found = TRUE; }
  389.  
  390.     if (!found) Error(UNDEFINED_PARAM,211);
  391.   }
  392.  
  393.   if (f!=3) Error(TOO_FEW_PARMS,212);
  394.   rad.y=rad.z=0;
  395.  
  396.   VectEqZero(&d);
  397.   VectEqZero(&upper);
  398.   VectEqZero(&lower);
  399.  
  400.   newobj=new_obj(SPHERE,&loc,&rad,&d,&v3,&cinfo,pattern,
  401.                  remove,name,
  402.                  &upper, &lower, (float)0.0, xmult, ymult);
  403.  
  404.   THEWORLD.objcount++;
  405.   return(newobj);
  406. }
  407.  
  408.  
  409. /**********************************************************
  410.  
  411.              Load lamp and attach to world
  412.  
  413.  **********************************************************/
  414.  
  415. int GetLamp()
  416. {
  417.   char str[SLEN];
  418.   VECTOR loc, rad, d, v3, upper, lower;
  419.   CINFO cinfo;
  420.   int   end, f, found;
  421.  
  422.   end=f=0;
  423.  
  424.   cinfo.amb.r=cinfo.amb.g=cinfo.amb.b=CNUM;
  425.   rad.y=150;
  426.  
  427.   GetLeftParen();
  428.  
  429.   while (!end && !feof(stdin)) {
  430.     GetToken(str); found = TRUE;
  431.  
  432. #   ifdef IODEBUG
  433.       printf("GETLAMP : token=%s\n",str);
  434. #   endif
  435.  
  436.     found = GetOpt(str,&cinfo);
  437.  
  438.     if ((strcmp(str,"POS")==0)      ||
  439.         (strcmp(str,"LOC")==0)      ||
  440.         (strcmp(str,"POSITION")==0) ||
  441.         (strcmp(str,"LOCATION")==0)) {
  442.  
  443.       GetVector(&loc);
  444.       f|=1; found = TRUE;
  445.     }
  446.  
  447.     if (strcmp(str,"RADIUS")==0) {
  448.       rad.x = IsPos(Get_Next_Num());
  449.       f|=2; found = TRUE;
  450.     }
  451.     if (strcmp(str,"DIST")==0) {
  452.       rad.y = IsPos(Get_Next_Num());
  453.       f|=4; found = TRUE;
  454.     }
  455.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  456.  
  457.     if (!found) Error(UNDEFINED_PARAM,214);
  458.   }
  459.  
  460.   if (f!=7) return(FALSE);
  461.  
  462.   rad.z=0;
  463.  
  464.   VectEqZero(&d);
  465.   VectEqZero(&v3);
  466.   VectEqZero(&upper);
  467.   VectEqZero(&lower);
  468.  
  469.   cinfo.diff.r=cinfo.diff.g=cinfo.diff.b=CNUM;
  470.  
  471.   add_lamp(new_obj(LAMP,&loc,&rad,&d,&v3,&cinfo,NULL,NULL,
  472.                    NULL, &upper, &lower,
  473.                    (float)0.0, (float)0.0, (float)0.0));
  474.  
  475.   THEWORLD.lampcount++;
  476.   return(TRUE);
  477. }
  478.  
  479.  
  480. /**********************************************************
  481.  
  482.          Load observer and attach him to the world
  483.  
  484.  **********************************************************/
  485.  
  486. int GetObserver()
  487. {
  488.   char   str[SLEN];
  489.   VECTOR loc, lk, up, dir, v3, upper, lower;
  490.   CINFO  cinfo;
  491.   int    end, f, found;
  492.  
  493.   def_colorinfo(&cinfo);
  494.  
  495.   end=f=0;
  496.   up.x = up.z = 0; up.y = 1;
  497.  
  498.   GetLeftParen();
  499.  
  500.   while (!end && !feof(stdin)) {
  501.     GetToken(str); found = FALSE;
  502.  
  503. #   ifdef IODEBUG
  504.       printf("GETOBSERVER : token=%s\n",str);
  505. #   endif
  506.  
  507.     if ((strcmp(str,"POS")==0)      ||
  508.         (strcmp(str,"LOC")==0)      ||
  509.         (strcmp(str,"POSITION")==0) ||
  510.         (strcmp(str,"LOCATION")==0)) {
  511.  
  512.       GetVector(&loc);
  513.       f|=1; found = TRUE;
  514.     }
  515.  
  516.     if (strcmp(str,"LOOKAT")==0) {
  517.       GetVector(&lk);
  518.       f|=2; found = TRUE;
  519.     }
  520.  
  521.     if (strcmp(str,"UP")==0) {
  522.       GetVector(&up);
  523.       found = TRUE;
  524.     }
  525.  
  526.     if (strcmp(str,")")==0) { end = 1; found = TRUE; }
  527.  
  528.     if (!found) Error(UNDEFINED_PARAM,216);
  529.   }
  530.  
  531.   VecSubtract(&dir,&lk,&loc);    /* find view direction */
  532.  
  533.   VectEqZero(&v3);
  534.   VectEqZero(&upper);
  535.   VectEqZero(&lower);
  536.  
  537.   if (f!=3) Error(TOO_FEW_PARMS,217);
  538.  
  539.   THEWORLD.observer=
  540.      new_obj(OBSERVER,&loc,&dir,&up,&v3,&cinfo,NULL,NULL,
  541.              NULL, &upper, &lower,
  542.              (float)0.0, (float)0.0, (float)0.0);
  543.  
  544.   return(TRUE);
  545. }
  546.  
  547.  
  548. /**********************************************************
  549.  
  550.           Load triangle  - not yet implimented
  551.  
  552.  **********************************************************/
  553.  
  554. OBJ_PTR GetTriangle()
  555. {
  556.   char        str[SLEN], *name;
  557.   CINFO       cinfo;
  558.   VECTOR      loc, v1, v2, v3, upper, lower;
  559.   OBJ_PTR     newobj;
  560.   PATTERN_PTR pattern, remove;
  561.   int         end, f, found;
  562.   float       xmult, ymult;
  563.  
  564.   end=f=0;
  565.   xmult=ymult=1;
  566.   def_colorinfo(&cinfo);
  567.   pattern = remove = NULL;
  568.   name    = NULL;
  569.  
  570.   GetLeftParen();
  571.  
  572.   while (!end && !feof(stdin)) {
  573.     GetToken(str);
  574.  
  575. #   ifdef IODEBUG
  576.       printf("GETTRIANGLE : token=%s\n",str);
  577. #   endif
  578.  
  579.     found = GetOpt(str,&cinfo);
  580.  
  581.     if ((strcmp(str,"POS")==0)      ||
  582.         (strcmp(str,"LOC")==0)      ||
  583.         (strcmp(str,"POSITION")==0) ||
  584.         (strcmp(str,"LOCATION")==0)) {
  585.  
  586.       GetVector(&loc);
  587.       f|=1; found = TRUE;
  588.     }
  589.  
  590.     if ((strcmp(str,"V1")==0)     ||
  591.         (strcmp(str,"VECT1")==0)) {
  592.  
  593.       GetVector(&v1);
  594.       f|=2; found = TRUE;
  595.     }
  596.  
  597.     if ((strcmp(str,"V2")==0)     ||
  598.         (strcmp(str,"VECT2")==0)) {
  599.  
  600.       GetVector(&v2);
  601.       f|=4; found = TRUE;
  602.     }
  603.  
  604.     if (strcmp(str,"PATTERN")==0) {
  605.       pattern=Attach_Pattern();
  606.       found = TRUE;
  607.     }
  608.     if (strcmp(str,"REMOVE")==0) {
  609.       remove=Attach_Pattern();
  610.       found = TRUE;
  611.     }
  612.  
  613.     if (strcmp(str,"XMULT")==0) {
  614.       xmult = IsPos(Get_Next_Num());
  615.       found=TRUE;
  616.     }
  617.     if (strcmp(str,"YMULT")==0) {
  618.       ymult = IsPos(Get_Next_Num());
  619.       found=TRUE;
  620.     }
  621.     if (strcmp(str,"NAME")==0) {
  622.        name=Get_Next_Name();
  623.        found = TRUE;
  624.     }
  625.  
  626.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  627.  
  628.     if (!found) Error(UNDEFINED_PARAM,219);
  629.   }
  630.  
  631.   if (f!=7) Error(TOO_FEW_PARMS,220);
  632.  
  633.   VectEqZero(&v3);
  634.   VectEqZero(&upper);
  635.   VectEqZero(&lower);
  636.  
  637.   newobj=new_obj(TRIANGLE,&loc,&v1,&v2,&v3,&cinfo,pattern,
  638.                  remove, name,
  639.                  &upper, &lower, (float)0.0, xmult, ymult);
  640.  
  641.   THEWORLD.objcount++;
  642.   return(newobj);
  643. }
  644.  
  645.  
  646. /**********************************************************
  647.  
  648.          Load sky data and attach it to the world
  649.  
  650.  **********************************************************/
  651.  
  652. int GetSky()
  653. {
  654.   VECTOR loc, v1, v2, v3, upper, lower;
  655.   CINFO  cinfo;
  656.   char   str[SLEN];
  657.   int    end, found;
  658.  
  659.   end=0;
  660.   GetLeftParen();
  661.  
  662.   def_colorinfo(&cinfo);
  663.  
  664.   while (!end && !feof(stdin)) {
  665.     GetToken(str);
  666.  
  667.     found = GetOpt(str,&cinfo);                    /*** DITHER ONLY ***/
  668.  
  669.     if (strcmp(str,"ZENITH")==0) {
  670.        GetSVector(&(THEWORLD.skycolor_zenith));
  671.        found = TRUE;
  672.     }
  673.  
  674.     if ((strcmp(str,"HORIZ")==0) ||
  675.         (strcmp(str,"HORIZON")==0)) {
  676.  
  677.        GetSVector(&(THEWORLD.skycolor_horiz));
  678.        found = TRUE;
  679.     }
  680.     if (strcmp(str,")")==0) { end=1; found=TRUE; }
  681.  
  682.     if (!found) Error(UNDEFINED_PARAM,222);
  683.   }
  684.  
  685.   VectEqZero(&v3);
  686.   VectEqZero(&upper);
  687.   VectEqZero(&lower);
  688.  
  689.   THEWORLD.sky=new_obj(SKY,&loc,&v1,&v2,&v3,&cinfo,NULL,NULL,
  690.                        NULL, &upper, &lower,
  691.                        (float)0.0, (float)0.0, (float)0.0);
  692.   return(TRUE);
  693. }
  694.  
  695. /**********************************************************
  696.  
  697.             Load ring and return pointer to it
  698.  
  699.  **********************************************************/
  700.  
  701. OBJ_PTR GetRing()
  702. {
  703.   char        str[SLEN], *name;
  704.   CINFO       cinfo;
  705.   VECTOR      loc, v1, v2, v3, upper, lower;
  706.   OBJ_PTR     newobj;
  707.   PATTERN_PTR pattern, remove;
  708.   int         end, f, found;
  709.   float       xmult, ymult;
  710.  
  711.   end=f=0;
  712.   xmult=ymult=1;
  713.   def_colorinfo(&cinfo);
  714.   pattern = remove = NULL;
  715.   name    = NULL;
  716.  
  717.   GetLeftParen();
  718.  
  719.   while (!end && !feof(stdin)) {
  720.     GetToken(str);
  721.  
  722. #   ifdef IODEBUG
  723.       printf("GETRING : token=%s\n",str);
  724. #   endif
  725.  
  726.     found = GetOpt(str,&cinfo);
  727.  
  728.     if ((strcmp(str,"POS")==0)      ||
  729.         (strcmp(str,"LOC")==0)      ||
  730.         (strcmp(str,"POSITION")==0) ||
  731.         (strcmp(str,"LOCATION")==0)) {
  732.  
  733.       GetVector(&loc);
  734.       f|=1; found = TRUE;
  735.     }
  736.  
  737.     if ((strcmp(str,"V1")==0)     ||
  738.         (strcmp(str,"VECT1")==0)) {
  739.  
  740.       GetVector(&v1);
  741.       f|=2; found = TRUE;
  742.     }
  743.  
  744.     if ((strcmp(str,"V2")==0)     ||
  745.         (strcmp(str,"VECT2")==0)) {
  746.  
  747.       GetVector(&v2);
  748.       f|=4; found = TRUE;
  749.     }
  750.  
  751.     if (strcmp(str,"RAD_1")==0) {
  752.        v3.x = IsPos(Get_Next_Num());
  753.        f|=8; found = TRUE;
  754.     }
  755.     if (strcmp(str,"RAD_2")==0) {
  756.        v3.y = IsPos(Get_Next_Num());
  757.        f|=16; found = TRUE;
  758.     }
  759.     if (strcmp(str,"PATTERN")==0) {
  760.        pattern=Attach_Pattern();
  761.        found = TRUE;
  762.     }
  763.     if (strcmp(str,"REMOVE")==0) {
  764.       remove=Attach_Pattern();
  765.       found = TRUE;
  766.     }
  767.     if (strcmp(str,"XMULT")==0) {
  768.       xmult = IsPos(Get_Next_Num());
  769.       found=TRUE;
  770.     }
  771.     if (strcmp(str,"YMULT")==0) {
  772.       ymult = IsPos(Get_Next_Num());
  773.       found=TRUE;
  774.     }
  775.     if (strcmp(str,"NAME")==0) {
  776.        name=Get_Next_Name();
  777.        found = TRUE;
  778.     }
  779.  
  780.     if (strcmp(str,")")==0) { end = 1; found = TRUE; }
  781.  
  782.     if (!found) Error(UNDEFINED_PARAM,224);
  783.   }
  784.  
  785.   if (f!=31) Error(TOO_FEW_PARMS,225);
  786.   v3.z = 0;
  787.   Normalize(&v1);
  788.   Normalize(&v2);
  789.  
  790.   newobj=new_obj(RING,&loc,&v1,&v2,&v3,&cinfo,pattern,
  791.                  remove, name,
  792.                  &upper, &lower, (float)0.0, xmult, ymult);
  793.  
  794.   THEWORLD.objcount++;
  795.   return(newobj);
  796. }
  797.  
  798.  
  799. /**********************************************************
  800.  
  801.        Load parallelogram and return pointer to it
  802.  
  803.  **********************************************************/
  804.  
  805. OBJ_PTR GetParallelogram()
  806. {
  807.   char        str[SLEN], *name;
  808.   CINFO       cinfo;
  809.   VECTOR      loc, v1, v2, v3, upper, lower;
  810.   OBJ_PTR     newobj;
  811.   PATTERN_PTR pattern, remove;
  812.   int         end, f, found;
  813.   float       xmult, ymult;
  814.  
  815.   end=f=0;
  816.   xmult=ymult=1;
  817.   def_colorinfo(&cinfo);
  818.   pattern = remove = NULL;
  819.   name    = NULL;
  820.  
  821.   GetLeftParen();
  822.  
  823.   while (!end && !feof(stdin)) {
  824.     GetToken(str);
  825.  
  826. #   ifdef IODEBUG
  827.       printf("GETPARREL : token=%s\n",str);
  828. #   endif
  829.  
  830.     found = GetOpt(str,&cinfo);
  831.  
  832.     if ((strcmp(str,"POS")==0)      ||
  833.         (strcmp(str,"LOC")==0)      ||
  834.         (strcmp(str,"POSITION")==0) ||
  835.         (strcmp(str,"LOCATION")==0)) {
  836.  
  837.       GetVector(&loc);
  838.       f|=1; found = TRUE;
  839.     }
  840.  
  841.     if ((strcmp(str,"V1")==0)     ||
  842.         (strcmp(str,"VECT1")==0)) {
  843.  
  844.       GetVector(&v1);
  845.       f|=2; found = TRUE;
  846.     }
  847.  
  848.     if ((strcmp(str,"V2")==0)     ||
  849.         (strcmp(str,"VECT2")==0)) {
  850.  
  851.       GetVector(&v2);
  852.       f|=4; found = TRUE;
  853.     }
  854.  
  855.     if (strcmp(str,"PATTERN")==0) {
  856.       pattern=Attach_Pattern();
  857.       found = TRUE;
  858.     }
  859.     if (strcmp(str,"REMOVE")==0) {
  860.       remove=Attach_Pattern();
  861.       found = TRUE;
  862.     }
  863.  
  864.     if (strcmp(str,"XMULT")==0) {
  865.       xmult = IsPos(Get_Next_Num());
  866.       found=TRUE;
  867.     }
  868.     if (strcmp(str,"YMULT")==0) {
  869.       ymult = IsPos(Get_Next_Num());
  870.       found=TRUE;
  871.     }
  872.     if (strcmp(str,"NAME")==0) {
  873.        name=Get_Next_Name();
  874.        found = TRUE;
  875.     }
  876.  
  877.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  878.  
  879.     if (!found) Error(UNDEFINED_PARAM,227);
  880.   }
  881.  
  882.   if (f!=7) Error(TOO_FEW_PARMS,228);
  883.  
  884.   VectEqZero(&v3);
  885.   VectEqZero(&upper);
  886.   VectEqZero(&lower);
  887.  
  888.   newobj=new_obj(PARALLELOGRAM,&loc,&v1,&v2,&v3,&cinfo,
  889.                  pattern, remove,name,
  890.                  &upper, &lower, (float)0.0, xmult, ymult);
  891.  
  892.   THEWORLD.objcount++;
  893.   return(newobj);
  894. }
  895.  
  896. /**********************************************************
  897.  
  898.                   Load quadratic surface
  899.  
  900.  **********************************************************/
  901.  
  902. OBJ_PTR GetQuadratic()
  903. {
  904.   char        str[SLEN], *name;
  905.   CINFO       cinfo;
  906.   VECTOR      loc, v1, v2, v3, upper, lower;
  907.   OBJ_PTR     newobj;
  908.   PATTERN_PTR pattern, remove;
  909.   int         end, f, found;
  910.   float       cterm, xmult, ymult;
  911.  
  912.   end=f=0;
  913.   xmult=ymult=1;
  914.   def_colorinfo(&cinfo);
  915.   pattern = remove = NULL;
  916.   name    = NULL;
  917.  
  918.   GetLeftParen();
  919.  
  920.   upper.x = upper.y = upper.z = 10;
  921.   lower.x = lower.y = lower.z = -10;
  922.  
  923.   v1.x = 0; v1.y = 1; v1.z = 0;
  924.  
  925.   while (!end && !feof(stdin)) {
  926.     GetToken(str);
  927.  
  928. #   ifdef IODEBUG
  929.       printf("GETQUAD : token=%s\n",str);
  930. #   endif
  931.  
  932.     found = GetOpt(str,&cinfo);
  933.  
  934.     if ((strcmp(str,"POS")==0)      ||
  935.         (strcmp(str,"LOC")==0)      ||
  936.         (strcmp(str,"POSITION")==0) ||
  937.         (strcmp(str,"LOCATION")==0)) {
  938.  
  939.       GetVector(&loc);
  940.       f|=1; found = TRUE;
  941.     }
  942.  
  943.     if (strcmp(str,"A")==0) {
  944.       v2.x  = Get_Next_Num();
  945.       f|=2; found = TRUE;
  946.     }
  947.     if (strcmp(str,"B")==0) {
  948.       v2.y  = Get_Next_Num();
  949.       f|=4; found = TRUE;
  950.     }
  951.     if (strcmp(str,"C")==0) {
  952.       v2.z  = Get_Next_Num();
  953.       f|=8; found = TRUE;
  954.     }
  955.     if (strcmp(str,"D")==0) {
  956.       cterm = Get_Next_Num();
  957.       f|=16; found = TRUE;
  958.     }
  959.  
  960.     if (strcmp(str,"XMIN")==0) {
  961.       lower.x  = Get_Next_Num();
  962.       found    = TRUE;
  963.     }
  964.     if (strcmp(str,"XMAX")==0) {
  965.       upper.x  = Get_Next_Num();
  966.       found    = TRUE;
  967.     }
  968.     if (strcmp(str,"YMIN")==0) {
  969.       lower.y  = Get_Next_Num();
  970.       found    = TRUE;
  971.     }
  972.     if (strcmp(str,"YMAX")==0) {
  973.       upper.y  = Get_Next_Num();
  974.       found    = TRUE;
  975.     }
  976.     if (strcmp(str,"ZMIN")==0) {
  977.       lower.z  = Get_Next_Num();
  978.       found    = TRUE;
  979.     }
  980.     if (strcmp(str,"ZMAX")==0) {
  981.       upper.z  = Get_Next_Num();
  982.       found    = TRUE;
  983.     }
  984.  
  985.     if (strcmp(str,"DIR")==0) {
  986.       GetVector(&v1);
  987.       found = TRUE;
  988.     }
  989.  
  990.     if (strcmp(str,"PATTERN")==0) {
  991.       pattern=Attach_Pattern();
  992.       found = TRUE;
  993.     }
  994.     if (strcmp(str,"REMOVE")==0) {
  995.       remove=Attach_Pattern();
  996.       found = TRUE;
  997.     }
  998.     if (strcmp(str,"XMULT")==0) {
  999.       xmult = IsPos(Get_Next_Num());
  1000.       found=TRUE;
  1001.     }
  1002.     if (strcmp(str,"YMULT")==0) {
  1003.       ymult = IsPos(Get_Next_Num());
  1004.       found=TRUE;
  1005.     }
  1006.     if (strcmp(str,"NAME")==0) {
  1007.        name=Get_Next_Name();
  1008.        found = TRUE;
  1009.     }
  1010.  
  1011.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  1012.  
  1013.     if (!found) Error(UNDEFINED_PARAM,230);
  1014.   }
  1015.  
  1016.   if (f!=31) Error(TOO_FEW_PARMS,231);
  1017.  
  1018.   VectEqZero(&v3);
  1019.  
  1020.   newobj=new_obj(QUADRATIC,&loc,&v1,&v2,&v3,&cinfo,pattern,
  1021.                  remove, name,
  1022.                  &upper, &lower, cterm, xmult, ymult);
  1023.  
  1024.   THEWORLD.objcount++;
  1025.   return(newobj);
  1026. }
  1027.  
  1028.  
  1029. /**********************************************************
  1030.  
  1031.        Load the focal length of the observers lens
  1032.  
  1033.  **********************************************************/
  1034.  
  1035. int GetFocLength() {
  1036.   THEWORLD.flength=IsPos(Get_Next_Num());
  1037.   return(TRUE);
  1038. }
  1039.  
  1040.  
  1041. /**********************************************************
  1042.  
  1043.     Load a primitive from input and return pointer to it
  1044.  
  1045.  **********************************************************/
  1046.  
  1047. OBJ_PTR Get_Primitive(str)                /* get an object */
  1048.   char str[];
  1049. {
  1050.   OBJ_PTR newobj;
  1051.  
  1052. # ifdef IODEBUG
  1053.     printf("GETPRIMITIVE : token=%s:\n",str);
  1054. # endif
  1055.  
  1056.   newobj=NULL;
  1057.   if (strcmp(str,"SPHERE")==0) {
  1058.     if ((newobj=GetSphere())==NULL)
  1059.       Error(ILLEGAL_OBJECT,232);
  1060.   }
  1061.   if (strcmp(str,"PARALLELOGRAM")==0) {
  1062.     if ((newobj=GetParallelogram())==NULL)
  1063.       Error(ILLEGAL_OBJECT,233);
  1064.   }
  1065.   if (strcmp(str,"TRIANGLE")==0) {
  1066.     if ((newobj=GetTriangle())==NULL)
  1067.       Error(ILLEGAL_OBJECT,234);
  1068.   }
  1069.   if (strcmp(str,"RING")==0) {
  1070.     if ((newobj=GetRing())==NULL)
  1071.       Error(ILLEGAL_OBJECT,235);
  1072.   }
  1073.   if (strcmp(str,"QUADRATIC")==0) {
  1074.     if ((newobj=GetQuadratic())==NULL)
  1075.       Error(ILLEGAL_OBJECT,236);
  1076.   }
  1077.   if (strcmp(str,"INSTANCE_OF")==0) {
  1078.     if ((newobj=Get_Instance_Of())==NULL)
  1079.       Error(ILLEGAL_OBJECT,237);
  1080.   }
  1081.   return(newobj);
  1082. }
  1083.  
  1084.  
  1085. /**********************************************************
  1086.  
  1087.      Load an attribute from input and do stuff with it
  1088.  
  1089.  **********************************************************/
  1090.  
  1091. int GetAttrib(str)                    /* get an object */
  1092.   char str[];
  1093. {
  1094.   int found, scrap;
  1095.  
  1096.   found=FALSE;
  1097.  
  1098. # ifdef IODEBUG
  1099.     printf("GETATTRIB : token=%s:\n",str);
  1100. # endif
  1101.  
  1102.   if (strcmp(str,"SKY")==0) {
  1103.     if (!GetSky())      Error(INTERNAL_ERROR,238);
  1104.     found=TRUE;
  1105.   }
  1106.   if (strcmp(str,"FOC_LENGTH")==0) {
  1107.     if (!GetFocLength()) Error(INTERNAL_ERROR,239);
  1108.     found=TRUE;
  1109.   }
  1110.   if (strcmp(str,"DEFAULT")==0) {
  1111.     if (!Get_Default()) Error(INTERNAL_ERROR,240);
  1112.     found=TRUE;
  1113.   }
  1114.   if (strcmp(str,"FILE_NAME")==0) {
  1115.     THEWORLD.outfile=Get_Next_Name();
  1116.     found=TRUE;
  1117.   }
  1118.   if (strcmp(str,"LAMP")==0) {
  1119.     if (!GetLamp())     Error(INTERNAL_ERROR,241);
  1120.     found=TRUE;
  1121.   }
  1122.   if (strcmp(str,"OBSERVER")==0) {
  1123.     if (!GetObserver()) Error(INTERNAL_ERROR,242);
  1124.     found=TRUE;
  1125.   }
  1126.   if (strcmp(str,"PATTERN")==0) {
  1127.     if (!GetPattern())  Error(INTERNAL_ERROR,243);
  1128.     found=TRUE;
  1129.   }
  1130.   if (strcmp(str,"FIRST_SCAN")==0) {
  1131.     Warning(OBSOLETE_OPTION,"FIRST_SCAN");
  1132.     scrap = (int)IsPos(Get_Next_Num());
  1133.     found=TRUE;
  1134.   }
  1135.   if (strcmp(str,"LAST_SCAN")==0) {
  1136.     Warning(OBSOLETE_OPTION,"LAST_SCAN");
  1137.     scrap = (int)IsPos(Get_Next_Num());
  1138.     found=TRUE;
  1139.   }
  1140.  
  1141.   return(found);
  1142. }
  1143.  
  1144.