Graphics source in C: hsalgs/scn_assmblr.c

Ken Turkowski ken at turtleva.UUCP
Thu Dec 22 15:57:23 AEST 1983


echo x - hsalgs/scn_assmblr.c
cat >hsalgs/scn_assmblr.c <<'!Funky!Stuff!'
/* ----------------------------------------------------------------
    scn_assmblr.c - scene assembler - Top-level object priority algorithm
        - Reads standard incremental scene description
        - Reads standard ASCII object descriptions
        - Assembles object structures to send to top-level transformation
          and sort program.
--------------------------------------------------------------------
*/

#include "scn_assmblr.h"
#define csystem system

/* -- lexically sorted object names - all predefined names are always here -- */
static  struct  {   char  name[LINE_LENGTH]; /* lexically sorted object names */
                    short postn;           }    obj_name[MAX_OBJECTS];

static  object_def  object[MAX_OBJECTS];           /* object definition array */
                                              /* priority ordered object list */
static  struct  {   short obj,insep;  }  p_list[MAX_OBJECTS];

static  short       char_cnt;   /* count of scanned characters (for err msgs) */
static  short       unused_obj;         /* first unused space in object array */
static  long        strm_sp;
static  FILE        *input,*strm_stk[STACK_LIMIT];
static  char        instrg[LINE_LENGTH];

short   ramp_lnth;                                   /* pseudocolor ramp size */
double  view_angle,ambient_lite,tilt_angle;          /* global view paramters */

/* ######################### MAIN ##################################### */
main()
{   char remainder[LINE_LENGTH],term[LINE_LENGTH],
         *strcat(),*getlogin(),*fgets(),*strptr;

    nocore();                             /* prevent dumping core on errs */

    initialize();                         /* initialize things */

/* main loop: interpret commands - one command per line, stop on EOF on stdin */

    while (((strptr = fgets(instrg,LINE_LENGTH,input)) != NULL) || (input != stdin))
    {   char_cnt = 0;

        if (strptr == NULL)    {    fclose(input);  /* EOF, go to last stream */
                                    input = strm_stk[strm_sp];    --strm_sp;
                                    continue;
                               }
        if (instrg[0] == '!')  {    csystem(&instrg[1]); putchar('>');
                                    continue;   
                               }                         /* shell escape */
        if (instrg[0] == '@')  {    FILE *new_input;
                                    get_term(&instrg[1],term,remainder);
                                    if ((new_input = fopen(term,"r")) == NULL)
                                    {   what("can't open file\n");
                                        putchar('>');
                                    }
                                    else 
                                    {   strm_sp++;    strm_stk[strm_sp] = input;
                                        input = new_input;
                                    }
                                    continue;
                               }        /* take input from new file */
        if (instrg[0] == '#')  continue;                    /* comment line */

        get_term(instrg,term,remainder);  /* get first delimited substring */

        if (strcmp(term,"?") == 0)  printf("        commands:\n\
                User convenience - \n\
                  dump_to   show      ? (help)  ! (shell) ^D (quit)\n\
                  @<filename> - take input from file\n\
                Image production -\n\
                  display_on          render_on           sketch_on\n\
                Object attributes and positioning -\n\
                  attach    call      delete\n\
                  paint     place     rotate    scale\n\
            special objects:\n\
                center_of_interest   eyepoint   light   light1 - light15\n\
                foreground           background\n\
            global parameters\n\
                set ( view_angle | ambient_lite | tilt_angle )\n\n");

                                                /* set up object hierarchy */
        else if (strcmp(term,"attach") == 0) attach(remainder);
                                                /* read in object and name it */
        else if (strcmp(term,"call") == 0)  call_by(remainder);
                                                             /* delete object */
        else if (strcmp(term,"delete") == 0)  delete(remainder);
                                                /* detach object from hierchy */
        else if (strcmp(term,"detach") == 0)  detach(remainder);
                                                   /* make picture - no bkgrd */
        else if (strcmp(term,"display_on") == 0)  display_on(remainder);
                                                    /* dump scene description */
        else if (strcmp(term,"dump_to") == 0)  dump_to(remainder);
                                                    /* assign color to object */
        else if (strcmp(term,"paint") == 0) paint(remainder);
                                                   /* place object on another */
        else if (strcmp(term,"place") == 0)  place(remainder);
                                                             /* load rotation */
        else if (strcmp(term,"rotate") == 0) rotate(remainder);
                                               /* make picture - high quality */
        else if (strcmp(term,"render_on") == 0)  render_on(remainder);
                                                   /* load axis scale factors */
        else if (strcmp(term,"scale") == 0) scale(remainder);
                                                      /* set global parameter */
        else if (strcmp(term,"set") == 0)  set(remainder);
                                                 /* display object parameters */
        else if (strcmp(term,"show") == 0)  show(remainder);
                                             /* make picture - bounding boxes */
        else if (strcmp(term,"sketch_on") == 0)  sketch_on(remainder);
                                                   /* no such command - error */
        else what("mistyped command?\n");

        putchar('>');                           /* print prompt */
    }
    puts(strcat(" see ya later ",getlogin()));
}




/* +++++++++++++++++++++++ ATTACH +++++++++++++++++++++++++++++++ */
attach(instrg)                          /* set up object hierarchy */
char *instrg;
{   char obj_name[LINE_LENGTH],remainder[LINE_LENGTH],substr[LINE_LENGTH];
    short i,child,dum,parent;    double atof();

    get_term(instrg,obj_name,remainder);        /* get object name */
    get_obj_index(&child,&dum,obj_name);    /* get index into object array */
    if (child == -1)  {   what("can't find this object\n");    return;  }
    if (object[child].parent != 0) what(" re-attaching to object\n");
    get_term(remainder,substr,remainder);
    if (strcmp(substr,"to") != 0) { what("this should be \"to\"\n"); return;}
    get_term(remainder,obj_name,remainder);
    get_obj_index(&parent,&dum,obj_name);
    if (parent == -1) {   what("can't find this object\n");    return;  }
    get_term(remainder,substr,remainder);
    if (strcmp(substr,"at") != 0) { what("this should be \"at\"\n"); return;}
    object[child].parent = parent;              /* set pointer to parent */
    object[child].supported = FALSE;            /* not "on" parent object */
    object[child].new_mtx = TRUE;               /* ensures matrix composition */
    for (i=0; i<3; i++)
    {   get_term(remainder,substr,remainder);
        object[child].postn[i] = atof(substr);
    }
}




/* +++++++++++++++++++++++ CALLBY ++++++++++++++++++++++++++++++++ */
call_by(instrg)                         /* read in object and name it */
char *instrg;
{   short i,j,k,n,save,lexpos;    
    char name[LINE_LENGTH],file_name[LINE_LENGTH],remainder[LINE_LENGTH];
    double atof(),sqrt();    char box_found;
    FILE *input;

    get_term(instrg,file_name,remainder);

    if ((input = fopen(file_name,"r")) == NULL)
    {   what("can't find this file\n"); return;   }

    save = char_cnt; /* save line position for later messages about this file */
    get_term(remainder,name,remainder);
    if (strcmp(name,"by") != 0)  
    {    what("should be \"by\"\n");    return;   }

    get_term(remainder,name,remainder);
    for (i=0; i<FIRST_OBJ; i++)    /* check for reserved name (FRG & BKG ok) */
        if (strcmp(name,obj_name[i].name) == 0)
        {   j = obj_name[i].postn;
            if ((j==FRG) || (j==BKG))  
            {   strcpy(object[j].filename,file_name);    return;   }
            else  {  what("name in use \n");    return;  }  /* not FRG or BKG */
        }
    i = FIRST_OBJ;                         /* check for previously used names */
    while ((strcmp(name,obj_name[i].name) > 0) && ( i < MAX_OBJECTS ) &&
           (obj_name[i].name[0] != NULLCHAR)) i++; /* search for lexically >= */
    if (strcmp(name,obj_name[i].name) == 0)
    {  what("name in use \n");    return;  }
    lexpos = i;

    for (n=unused_obj; n<MAX_OBJECTS; n++)      /* find available spot */
    {   if (object[n].name[0] == NULLCHAR) break;
        else if (n+1 == MAX_OBJECTS) 
                {  what("sorry no more room for objects\n");  return;  }
    }
    unused_obj = n+1;                               /* set up for next object */
    strcpy(object[n].filename,file_name);                  /* store file name */

    /* read object file for salient info */
    {   FILE *test;    
        char line[LINE_LENGTH],term[LINE_LENGTH],strng[LINE_LENGTH];
        box_found = FALSE;
        for (k=0; k<3; k++) object[n].clr[k] = 1.0;     /* set default color */
        while (fgets(line,LINE_LENGTH,input) != NULL)
        {   get_term(line,term,line);

            if ((strcmp(term,"bounding_box") == 0) ||   /* bounding box */
                (strcmp(term,"boundingbox") == 0))
            {   short i;   
                for (i=0; i<3; i++)
                {  get_term(line,term,line);  object[n].box[i*2]   = atof(term);
                   get_term(line,term,line);  object[n].box[i*2+1] = atof(term);
                   if (object[n].box[i*2] > object[n].box[i*2+1])
                   {   char_cnt = save; /* restore top level character count */
                       what("min > max in bounding box\n");
                       fclose(input);   return;
                   }
                }
                /* get centroid and radius from bounding box */
                object[n].centroid[0] = (object[n].box[0] + object[n].box[1])/2;
                object[n].centroid[1] = (object[n].box[2] + object[n].box[3])/2;
                object[n].centroid[2] = (object[n].box[4] + object[n].box[5])/2;
                object[n].radius = sqrt(sqr(object[n].box[1] - object[n].box[0])
                         + sqr(object[n].box[3] - object[n].box[2]) 
                         + sqr(object[n].box[5] - object[n].box[4])) / 2;

                box_found = TRUE;
            }

            else if (strcmp(term,"display") == 0)       /* display routine  */
            {   get_term(line,term,line);
                if ((test = fopen(term,"r")) == NULL)
                    if ((test = fopen(strcat(strcpy(strng,"/usr/local/"),term),
                                                                  "r")) == NULL)
                    {  char_cnt = save;  what("can't find display routine\n");
                       fclose(input);    return; 
                    }
                fclose(test);           /* close file again if found */
                strcpy(object[n].display,term);     /* load filename */
            }
            else if (strcmp(term,"color") == 0)         /* object color */
            {   short i;
                for (i=0; i<3; i++)
                {  get_term(line,term,line);  object[n].clr[i] = atof(term);  }
            }
        }
        fclose(input);                  /* close object description file */
    }
    char_cnt = save;            /* restore top level character count */
    if (!box_found)  {  what("no bounding box in file\n");
                        object[n].name[0] = NULLCHAR;    return;   }

    j = lexpos;
    while (obj_name[j].name[0] != NULLCHAR) j++;         /* find end of list */
    for (k=j; k>=lexpos; k--)                        /* open space for entry */
    {   strcpy(obj_name[k].name,obj_name[k-1].name);
        obj_name[k].postn = obj_name[k-1].postn;   }
    strcpy(obj_name[lexpos].name,name);                       /* insert name */
    strcpy(object[n].name,name);
    obj_name[lexpos].postn = n;                     /* insert object pointer */
    for (k=0; k<3; k++) object[n].scale[k] = 1.0;       /* set default scale */
    for (k=0; k<3; k++) object[n].postn[k] = 0.0;    /* set default position */
    object[n].new_mtx = TRUE;                           /* flag new matrix   */
}




/* ++++++++++++++++++++++ DELETE ++++++++++++++++++++++++++++++++++ */
delete(instrg)                          /* remove objects from further use */
char *instrg;
{   short j;    char name[LINE_LENGTH],remainder[LINE_LENGTH];
    get_term(instrg,name,remainder);
    if (strcmp(name,"all") == 0)        /* delete everything */
    {   j = LIT + 1;
        while (obj_name[j].name[0] != NULLCHAR)
        {   delete_obj(obj_name[j].name);  if (j < FIRST_OBJ) j++;   }
        while (obj_name[j].name[0] != NULLCHAR) delete_obj(obj_name[j++].name);
    }
    else delete_obj(name);
}


delete_obj(name)                /* remove an object from further use */
char *name;
{   short j,i,n;
    get_obj_index(&n,&i,name);
    if (n > 0)
    {   if ((n > LIT) && (object[n].name[0] != NULLCHAR))    /* clear object */
        {   printf(" deleting %s\n",object[n].name);
            object[n].name[0] = NULLCHAR;
        }
        for (j=0; j<MAXROT; j++)  object[n].angle[0] = 0;
        object[n].supported = FALSE;
        object[n].parent = 0;

        if (n < FIRST_OBJ) return;  /* collapse sorted name list unless light */
        if (unused_obj > obj_name[i].postn)  unused_obj = obj_name[i].postn;
        while (obj_name[i].name[0] != NULLCHAR) /* fill in hole */
        {   strcpy(obj_name[i].name,obj_name[i+1].name);
            obj_name[i].postn = obj_name[i+1].postn;    i++;   }
    }
    else  what("name not in use\n");
}




/* ++++++++++++++++++++++++ DETACH +++++++++++++++++++++++++++++++++++ */
detach(instrg)                          /* remove from hierarchy */
char *instrg;
{   short object_no,dum;    char obj_name[LINE_LENGTH],remainder[LINE_LENGTH];
    get_term(instrg,obj_name,remainder);
    get_obj_index(&object_no,&dum,obj_name);
    object[object_no].parent = 0;
    object[object_no].supported = FALSE;
}




/* ++++++++++++++++++++++ DEV_SETUP +++++++++++++++++++++++++++++++++++ */
dev_setup(instrg,dvc,bits,divisions,frmnum,clear)  /* check device and clear */
char *instrg,*dvc;    short *bits,*divisions,*frmnum,clear;
{   short i;
    FILE *popen(),*stream;    char string[LINE_LENGTH],*sprintf();
    char remainder[LINE_LENGTH];
    *bits = *divisions = *frmnum = 0;

    get_term(instrg,dvc,remainder);             /* get device name */
    sscanf(remainder,"%hd %hd %hd",bits,divisions,frmnum); 
    if ((clear == -1) && (*bits < 24)) return;  /* render_on only full color */

    if      (strcmp(dvc,"meg") == 0 || strcmp(dvc,"crt") == 0 || 
             strcmp(dvc,"h19") == 0 || strcmp(dvc, "vt") == 0)
         {   *bits = *frmnum = *divisions = 0;         /* line_drawing device */
             if (strcmp(dvc,"vt") == 0) if (clear) csystem("vtclear");
                                        else       csystem("clear");
         }
    else if (strcmp(dvc,"fb") == 0)                    /* Marc I frame buffer */
         {   *frmnum = *bits;   *divisions = 0;   *bits = (*bits)?  8 : 10;
             if (clear) csystem(sprintf(string,"fbclear %d 0",*frmnum));
         }
    else if (strcmp(dvc,"bb") == 0)                   /* Marc II frame buffer */
         {   if (strlen(instrg) < 6)  *bits = *divisions = *frmnum = 0;
             if (*divisions == 0)  *divisions = 1;     /* default bb settings */
             if ((*bits == 0) || (*bits == 24))  *bits = 32;

             if (*frmnum%(32 / *bits) == 0) /* clear when using 0th bit in BB */
                 if (*divisions > 1)                        /* partial frame */
                 {   double sqrt();    short mult,Xres,Xofset,Yres,Yofset;
                     csystem("bbreset");   /* loads rgb pallette and unzooms */
                     mult = sqrt((double)*divisions);    
                     Xres = 640/mult;    Yres = 484/mult;
                     Xofset = (*frmnum / (32 / *bits)) % mult * Xres;  
                     Yofset = (mult-1 - (*frmnum/(32 / *bits))/mult) * Yres;
                     if (((*bits >= 24) && (clear)) || (*bits < 16))
                        csystem(sprintf(string,"bbclear 0 %g %g %g %d %d %d %d",
                                object[BKG].clr[0],object[BKG].clr[1],
                                object[BKG].clr[2],Xres,Xofset,Yres,Yofset));
                 }
                 else if ((*bits >= 24) && (clear))      /* full frame clear */
                            csystem(sprintf(string,"bbclear 0 %g %g %g",
                                         object[BKG].clr[0],object[BKG].clr[1],
                                         object[BKG].clr[2]));
                      else if (clear) csystem("bbclear 0 0 0 0");
         }
    else if (strcmp(dvc,"aed") == 0)
         {   *divisions = *frmnum = 0;    *bits = 8;
             csystem("aedclear 0");
         }
    else if (strcmp(dvc,"file") == 0)
         {   *bits = 48;  *divisions = 1;  *frmnum = 0;/* file will be opened */
         }                             /* by first process to actually use it */
    else if (strcmp(dvc,"dummy") == 0);                /* do nothing if dummy */
    else {   puts("bad device syntax");    return;   }


    if ((*bits == 8) || (*bits == 10))              /* set up for pseudocolor */
    {   double pow();
        stream = popen("hueload","w");
        if (strcmp(dvc,"fb") == 0)  fprintf(stream," %s %d\n",dvc,*frmnum);
        else   fprintf(stream," %s %d\n",dvc,*bits);            /* bb, or aed */
        fprintf(stream," %g %g %g\n",object[BKG].clr[0],object[BKG].clr[1],
                                         object[BKG].clr[2]);   /* background */

            i = FIRST_OBJ;
            while (obj_name[i].name[0] != NULLCHAR)
            {   short j;         /* object colors */
                j =  obj_name[i].postn;
                { fprintf(stream,"%g %g %g\n",object[j].clr[0],object[j].clr[1],
                                              object[j].clr[2]);
                }
                object[j].clr_num = i - FIRST_OBJ;
                i++;
            }
        pclose(stream);    /* send EOF to hueload and wait for completion */
        ramp_lnth = (pow(2.,(double)(*bits)) - 1)/(i - FIRST_OBJ);/* clr ramp */
    }
}
 



/* ++++++++++++++++++++++ DISPLAY_ON +++++++++++++++++++++++++++++++++ */
display_on(instrg)      /* generate image without foreground or background */
char *instrg;
{   short bits,divisions,frmnum;    char dvc[LINE_LENGTH];
    dev_setup(instrg,dvc,&bits,&divisions,&frmnum,FALSE);    /* get device */
    obj_sort(object,p_list);
    task_master(object,p_list,dvc,bits,divisions,frmnum);
}



/* +++++++++++++++++++++++ DUMP_TO +++++++++++++++++++++++++++++++++++++ */
dump_to(instrg)         /* write input script based on current state */
char *instrg;
{   char filename[LINE_LENGTH],remainder[LINE_LENGTH];
    FILE *output;    short i;
    
    get_term(instrg,filename,remainder);
    output = fopen(filename,"w");
    if (output == NULL)  {  what("can't open file\n");    return;  }

    for (i=FIRST_OBJ; i<MAX_OBJECTS; i++)  if (obj_name[i].name[0] != NULLCHAR)
    {   short k;
        k = obj_name[i].postn;
        fprintf(output,"call  %s by %s\n",object[k].filename,object[k].name);
        fprintf(output,"scale %s by %g %g %g\n",object[k].name,
                object[k].scale[0],object[k].scale[1],object[k].scale[2]);
    }
    for (i=0; i<MAX_OBJECTS; i++)  
        if ((obj_name[i].name[0] != NULLCHAR) &&
            (object[obj_name[i].postn].name[0] != NULLCHAR))
    {   short k,j;
        k = obj_name[i].postn;
        if (object[k].supported)
            fprintf(output,"place %s on %s at %g %g %g\n",object[k].name,
                    object[object[k].parent].name,object[k].postn[0],
                    object[k].postn[1],object[k].postn[2]);
        else if (object[k].parent != 0)
            fprintf(output,"attach %s to %s at %g %g %g\n",object[k].name,
                    object[object[k].parent].name,object[k].postn[0],
                    object[k].postn[1],object[k].postn[2]);
        else if ((k != BKG) && (k != FRG))
            fprintf(output,"place %s at %g %g %g\n",object[k].name,
                    object[k].postn[0],object[k].postn[1],object[k].postn[2]);

        if ((k < FIRST_OBJ) && (k >= LIT) && (object[k].radius > 0.))/* light */
            fprintf(output,"scale %s by %g\n",object[k].name,object[k].radius);

        if (object[k].new_clr)                  /* explicitly modified colors */
        {   fprintf(output,"paint %s with %g %g %g\n",object[k].name,
                            object[k].clr[0],object[k].clr[1],object[k].clr[2]);
        }
        k = 0;
        for (j=0; j<MAXROT; j++) if (object[k].angle[j] != 0.)
        {   if (j > 0) 
            {   fprintf(output," then\n");
                fprintf(output,"\t\t about %g %g %g %g %g %g by %g",
                        object[k].rotbas[j][0],object[k].rotbas[j][1],
                        object[k].rotbas[j][2],object[k].rotend[j][0],
                        object[k].rotend[j][1],object[k].rotend[j][2],
                        object[k].angle[j]);
                k++;
            }
            else
            {   fprintf(output,"rotate %s\tabout %g %g %g %g %g %g by %g",
                        object[k].name,
                        object[k].rotbas[j][0],object[k].rotbas[j][1],
                        object[k].rotbas[j][2],object[k].rotend[j][0],
                        object[k].rotend[j][1],object[k].rotend[j][2],
                        object[k].angle[j]);
                k++;
            }
        }
        if (k > 0) fprintf(output,"\n");
    }

    if (view_angle !=  45.) fprintf(output,"set view_angle to %g\n",view_angle);
    if (tilt_angle !=   0.) fprintf(output,"set tilt_angle to %g\n",tilt_angle);
    if (ambient_lite != .3) fprintf(output,"set ambient_lite to %g\n",
                                                                  ambient_lite);

    fclose(output);
}




/* ++++++++++++++++++++ GET_OBJ_INDEX ++++++++++++++++++++++++++++ */
get_obj_index(obj_index,name_index,name)        /* search for object name */
                                        /* this should be a binary search */
short *obj_index,*name_index;    char *name;    /* return ptr to object entry */
{   short i;
    i = 0;                              /* find name in reserved name list */
    while ((strcmp(name,obj_name[i].name) > 0) && (i < FIRST_OBJ))  i++;
    if (strcmp(name,obj_name[i].name) == 0)     /* check for exact match */
    {   *obj_index = obj_name[i].postn;  *name_index = i;  return *obj_index;  }

    i = FIRST_OBJ;                      /* find name in object name list */
    while ((strcmp(name,obj_name[i].name) > 0) && 
           (obj_name[i].name[0] != NULLCHAR)) i++; /* search for lexically >= */
    if (strcmp(name,obj_name[i].name) == 0)     /* check for exact match */
        {   *obj_index = obj_name[i].postn;    *name_index = i;   }
    else  {  *obj_index = -1;   *name_index = -1;  } /* return -1 if no match */
    return *obj_index;
}




/* +++++++++++++++++++++ GET_TERM +++++++++++++++++++++++++++++++++ */
get_term(instrg,term,remainder)         /* remove first term from string */
char *instrg,*term,*remainder;  /* blanks, tabs, nulls, commas are separators */
{   short i,index1,index2;
    index1 = 0;                         /* find first non-separator */
    while ((instrg[index1] == ' ')      || (instrg[index1] == '\t') ||
           (instrg[index1] == NULLCHAR) || (instrg[index1] == ',' )) index1++;
    index2 = index1;                    /* find next separator */
    while ((instrg[index2] != ' ')      && (instrg[index2] != '\t') &&
           (instrg[index2] != NULLCHAR) && (instrg[index2] != ',' ) &&
           (instrg[index2] != '\n'))                                 index2++;
    for (i=index1; i<index2; i++)  term[i-index1] = instrg[i];
    term[i-index1] = NULLCHAR;
    while ((instrg[i] != NULLCHAR) && (instrg[i] != '\n'))
        {  remainder[i-index2] = instrg[i];  i++;  }
    remainder[i-index2] = NULLCHAR;
    char_cnt = char_cnt + index2;
}




/* +++++++++++++++++++++++++ INITIALIZE +++++++++++++++++++++++++++++ */
initialize()                            /* set up initial conditions */
{   /* remember, obj_name[] is lexically sorted */
    short i,j;
    strcpy(obj_name[0].name,"background");          obj_name[0].postn = BKG;
    strcpy(object[BKG].name,"background");
    for (i=0; i<3; i++) object[BKG].scale[i] = 1.0;
    object[BKG].new_mtx = TRUE;
    object[BKG].clr[0] =     .2;
    object[BKG].clr[1] =     .3;
    object[BKG].clr[2] =     .6;
    
    strcpy(obj_name[3].name,"foreground");          obj_name[3].postn = FRG;
    strcpy(object[FRG].name,"foreground");
    for (i=0; i<3; i++) object[FRG].scale[i] = 1.0;
    object[FRG].new_mtx = TRUE;

    strcpy(obj_name[1].name,"center_of_interest");  obj_name[1].postn = CI;
    strcpy(object[CI].name,"center_of_interest");
    object[CI].postn[0] =  0.;
    object[CI].postn[1] =  0.;
    object[CI].postn[2] =  0.;
    for (i=0; i<3; i++) object[CI].scale[i] = 1.0;
    object[CI].new_mtx = TRUE;

    strcpy(obj_name[2].name,"eyepoint");            obj_name[2].postn = EP;
    strcpy(object[EP].name,"eyepoint");
    object[EP].postn[0] =    0.;
    object[EP].postn[1] =  -10.;
    object[EP].postn[2] =    5.;
    for (i=0; i<3; i++) object[EP].scale[i] = 1.0;
    object[EP].new_mtx = TRUE;

    for (j=0; j<16; j++)           /* put in light names "light1" - "light15" */
    {   short k;    char str[16];
        k = (j > 9)?  j - 8 : j + 6;   if (j <= 1) k = j; /*keep lexical order*/
        strcpy(obj_name[LIT+k].name,sprintf(str,"light%d",j)); 
        obj_name[LIT+k].postn = LIT+j;
        for (i=0; i<3; i++) object[LIT+j].scale[i] = 1.0;
        object[LIT+j].new_mtx = TRUE;
        for (i=0; i<3; i++) object[LIT+j].clr[i] = 1.0;
        object[LIT+j].radius = 93000000. * 5280.; /* shines 93 million miles */
    }
    strcpy(obj_name[LIT].name,"light");  /* turn on and initialize 0th light */ 
    strcpy(object[LIT].name,"light");   obj_name[LIT].postn = LIT;
    object[LIT].postn[0] =  1000.;       /* by entering name in object array */
    object[LIT].postn[1] = -1000.;
    object[LIT].postn[2] =   500.;

    view_angle = 45.;
    tilt_angle =  0.;
    ambient_lite = .3;

    unused_obj = FIRST_OBJ;     /* first unused object array element */
    strm_sp = 0;                /* stack pointer for input stream stack */
    input = stdin;
    putchar('>');
}



/* ++++++++++++++++++++++++++ PAINT ++++++++++++++++++++++++++++++++ */
paint(instrg)                           /* assign color to object */
char *instrg;
{   char obj_name[LINE_LENGTH],remainder[LINE_LENGTH],term[LINE_LENGTH];
    short i,obj_index,dum;    double atof();

    get_term(instrg,obj_name,remainder);        /* get object name */
    get_obj_index(&obj_index,&dum,obj_name);   /* get index into object array */
    if (obj_index < 0)  {   what("can't find this object\n");    return;  }
    get_term(remainder,term,remainder);
    if (strcmp(term,"with") != 0) 
    {   what("this should be \"with\"\n");    return;   }
                                           /* update .obj file with new color */
    if (obj_index >= FIRST_OBJ)
        csystem(sprintf(term,"update_obj %s color %s",
                                        object[obj_index].filename,remainder));
    for (i=0; i<3; i++)
    {   float number;
        get_term(remainder,term,remainder);   number = atof(term);
        if ((number < 0.) || (number > 1.))
        {   what("between 0 and 1 please\n");    return;   }
        object[obj_index].clr[i] = number;
    }
    object[obj_index].new_clr = TRUE;   /* flag for new color computation */

    if ((obj_index >= LIT) && (obj_index <= LIT+15))  
        strcpy(object[obj_index].name,obj_name);   /* turn on light by naming */
}




/* ++++++++++++++++++++++++++++ PLACE +++++++++++++++++++++++++++++++ */
place(instrg)                           /* position object (on another) */
char *instrg;
{   char obj_name[LINE_LENGTH],remainder[LINE_LENGTH],term[20];
    short i,obj_index,dum,parent_index; double atof();

    get_term(instrg,obj_name,remainder);        /* get object name */
    get_obj_index(&obj_index,&dum,obj_name);    /* get index into obj. array */
    if (obj_index < 0)  {  what("can't find this object\n");    return;  }
    get_term(remainder,term,remainder);
    if (strcmp(term,"on") == 0) /* check for attachment */
    {   get_term(remainder,obj_name,remainder); /* get 2nd object name */
        get_obj_index(&parent_index,&dum,obj_name);
        if (parent_index < 0)  {  what("can't find this object\n");  return;  }
        if (object[obj_index].parent != 0)  {  what(" re-attaching object\n");
                                               return;  }
        object[obj_index].parent = parent_index;
        object[obj_index].supported = TRUE;
        get_term(remainder,term,remainder);             /* get "at" */
    }
    if (strcmp(term,"at") != 0)  
    {   what(" this should be \"at\" or \"on\"\n");    return;   }
    for (i=0; i<3; i++)                         /* read position x,y,z */
    {   get_term(remainder,term,remainder);
        object[obj_index].postn[i] = atof(term);
    }
    object[obj_index].new_mtx = TRUE;           /* flag to compute new matrix */

    if ((obj_index >= LIT) && (obj_index <= LIT+15))  
        strcpy(object[obj_index].name,obj_name);   /* turn on light by naming */

}



/* +++++++++++++++++++++++++++ RENDER_ON ++++++++++++++++++++++++++++ */
render_on(instrg)       /* generate high-quality image */
char *instrg;
{   short bits,divisions,frmnum;    char dvc[LINE_LENGTH],string[LINE_LENGTH];
    dev_setup(instrg,dvc,&bits,&divisions,&frmnum,-1);  /* set up, clear dsp. */
    if (bits < 24) { printf(" render_on only for BB right now\n");   return; }

    /* ----- load foreground image into BB or "temp_frame" if called for ---- */
    if (object[FRG].filename[0] != NULLCHAR)             /* foreground image? */
        if (bits == 32) csystem(sprintf(string,"bbshow %s",object[FRG].name));
        else            csystem(sprintf(string,"fileshow temp_frame %s",
                                                          object[FRG].name));

    /* ------------------ sort and display objects -------------------------- */
    obj_sort(object,p_list);                         /* priority sort objects */
                       /* distribute object display tasks to display programs */
    if (bits != 32) task_master(object,p_list,"file temp_frame",32,divisions,0);
    else            task_master(object,p_list,dvc,bits,divisions,frmnum);

    /* ----- load background image into BB or "temp_frame" if called for ---- */
    if (object[BKG].filename[0] != NULLCHAR)             /* background image? */
        if (bits == 32) csystem(sprintf(string,"bbshow %s",object[BKG].name));
        else            csystem(sprintf(string,"fileshow temp_frame %s",
                                                          object[BKG].name));
    else                                         /* fill in with solid color */
         if (bits == 32)
             if (divisions > 1)                     /* partial frame */
             {   double sqrt();    short mult,Xres,Xofset,Yres,Yofset;
                 mult = sqrt((double)divisions);    
                 Xres = 640/mult;    Yres = 484/mult;
                 Xofset = (frmnum/(32/bits))%mult * Xres;  
                 Yofset = (mult-1 - (frmnum/(32/bits))/mult) * Yres;
                 csystem(sprintf(string,"bbackfill %g %g %g %d %d %d %d",
                                object[BKG].clr[0],object[BKG].clr[1],
                                object[BKG].clr[2],Xres,Xofset,Yres,Yofset));
             }
             else 
                 csystem(sprintf(string,"bbackfill %g %g %g 640 0 484 0",
                                    object[BKG].clr[0],object[BKG].clr[1],
                                    object[BKG].clr[2]));
         else 
             csystem(sprintf(string,"filebkfill temp_frame %g %g %g",
                    object[BKG].clr[0],object[BKG].clr[1],object[BKG].clr[2]));

    /* ------------- dither to display if not full-color -------------------- */
    if (bits < 16)  csystem(sprintf(string,"dither_on temp_frame %s %d %d %d",
                                                  dvc,bits,divisions,frmnum));

    /* ----------------- change file name if file output ------------------ */
    if (strcmp(dvc,"file") == 0) 
    {   char filename[LINE_LENGTH];
        get_term(instrg,filename,instrg);   /* burn device field */
        get_term(instrg,filename,instrg);   
        csystem(sprintf(string,"mv temp_frame %s",filename));
    }
}


/* ++++++++++++++++++++++++++ ROTATE +++++++++++++++++++++++++++++++++ */
rotate(instrg)
char *instrg;
{   char obj_name[LINE_LENGTH],remainder[LINE_LENGTH],term[20];
    short i,j,obj_index,dum;    double atof();

    get_term(instrg,obj_name,remainder);        /* get object name */
    get_obj_index(&obj_index,&dum,obj_name);        /* get index into object array */
    if (obj_index < 0)  {   what("can't find this object\n");    return;  }
    j = 0;
    do
    {   get_term(remainder,obj_name,remainder);
        if (strcmp(obj_name,"about") != 0) 
        {   what("this should be \"about\"\n");    return;   }
        for (i=0; i<3; i++)
        {   get_term(remainder,term,remainder);
            object[obj_index].rotbas[j][i] = atof(term);
        }
        for (i=0; i<3; i++)
        {   get_term(remainder,term,remainder);
            object[obj_index].rotend[j][i] = atof(term);
        }
        get_term(remainder,obj_name,remainder);
        if (strcmp(obj_name,"by") != 0) 
        {   what("this should be \"by\"\n");    return;   }
        get_term(remainder,term,remainder);
        object[obj_index].angle[j] = atof(term);
        get_term(remainder,term,remainder);
        if (strcmp(term,"then") == 0)  fgets(remainder,LINE_LENGTH,input);
        j++;
    }   while ((strcmp(term,"then") == 0) && (j <= MAXROT));
    for (i=j; i<MAXROT; i++) object[obj_index].angle[i] = 0;/* rest of angles */
    object[obj_index].new_mtx = TRUE;           /* flag to compute new matrix */

    if ((obj_index >= LIT) && (obj_index <= LIT+15))  
        strcpy(object[obj_index].name,obj_name);   /* turn on light by naming */
}



/* ++++++++++++++++++++++++++++ SCALE ++++++++++++++++++++++++++++++++++ */
scale(instrg)
char *instrg;
{   char obj_name[LINE_LENGTH],remainder[LINE_LENGTH],
         preposition[LINE_LENGTH],term[20];
    short i,obj_index,dum;    double atof();

    get_term(instrg,obj_name,remainder);        /* get object name */
    get_obj_index(&obj_index,&dum,obj_name);        /* get index into object array */
    if (obj_index < 0)  {   what("can't find this object\n");    return;  }
    get_term(remainder,preposition,remainder);
    if (strcmp(preposition,"by") != 0) 
    {   what("this should be \"by\"\n");    return;   }
    for (i=0; i<3; i++)
    {   get_term(remainder,term,remainder);
        if (obj_index < FIRST_OBJ)              /* set radius if light source */
        {   object[obj_index].radius = atof(term);    break;   }
        else  object[obj_index].scale[i] = atof(term);
    }
    object[obj_index].new_mtx = TRUE;           /* flag to compute new matrix */

    if ((obj_index >= LIT) && (obj_index <= LIT+15))  
        strcpy(object[obj_index].name,obj_name);   /* turn on light by naming */
}




/* ++++++++++++++++++++++++++++++ SET ++++++++++++++++++++++++++++++++++ */
set(instrg)
char *instrg;
{   char par_name[LINE_LENGTH],remainder[LINE_LENGTH],str[LINE_LENGTH];
    double par_value;
    get_term(instrg,par_name,remainder);
    get_term(remainder,str,remainder);  
    if (strcmp(str,"to") != 0)  {  what("this should be 'to'");   return;  }
    get_term(remainder,str,remainder);
    par_value = atof(str);
    if      (strcmp(par_name,"view_angle") == 0)   view_angle = par_value;
    else if (strcmp(par_name,"tilt_angle") == 0)   tilt_angle = par_value;
    else if (strcmp(par_name,"ambient_lite") == 0)  ambient_lite = par_value;
    else what("undefined global parameter - can't set");
}




/* ++++++++++++++++++++++++++++ SHOW +++++++++++++++++++++++++++++++++++ */
show(instrg)                            /* display object parameters */
char *instrg;
{   char name[LINE_LENGTH],remainder[LINE_LENGTH];
    get_term(instrg,name,remainder);    /* get object name */
    if (strcmp(name,"all") == 0)        /* brief summary */
    {   short j;
        printf("ambient light = %g,  view angle = %g,  tilt angle = %g\n",
                                        ambient_lite,view_angle,tilt_angle);
        for (j=0; j<MAX_OBJECTS; j++)  if (object[j].name[0] != NULLCHAR)
        {   if (strcmp(object[j].name,"background") == 0)
            {   printf(" background color %g %g %g\n",
                        object[j].clr[0],object[j].clr[1],object[j].clr[2]);
                if (object[j].filename[0] != NULLCHAR)
                    printf(" background file %s\n",object[j].filename);
                continue;
            }
            if (strcmp(object[j].name,"foreground") == 0)
            {   if (object[j].filename[0] != NULLCHAR)
                    printf(" foreground file %s\n",object[j].filename);
                continue;
            }
            if (object[j].parent > 0)
                if (object[j].supported)
                    printf(" %s on %s at %g %g %g",object[j].name,
                        object[object[j].parent].name,object[j].postn[0],
                        object[j].postn[1],object[j].postn[2]);
                else
                    printf(" %s attached to %s at %g %g %g",object[j].name,
                        object[object[j].parent].name,object[j].postn[0],
                        object[j].postn[1],object[j].postn[2]);
            else
                printf(" %s at\t %g %g %g",object[j].name,object[j].postn[0],
                        object[j].postn[1],object[j].postn[2]);

            if (j >= LIT)  printf(",  \tcolor %g %g %g",object[j].clr[0],
                        object[j].clr[1],object[j].clr[2]);
            if ((j >= LIT) && (j < FIRST_OBJ)) printf(", \tradius %g",
                        object[j].radius);     /* radius of influence if lite */
            printf("\n");
        }
    }
    else                        /* specific info on object */
    {   short n,i,dum;
        get_obj_index(&n,&dum,name);            /* get index to object array */
        if (n < 0)  {   what("name not in use\n");    return;   }
        printf(" file name:      %s\n",object[n].filename);
        printf(" scale factors:  %g %g %g\n",
            object[n].scale[0],object[n].scale[1],object[n].scale[2]);
        for (i=0; i<MAXROT; i++) if (object[n].angle[i] != 0.)
        {  printf(" rotation:      %g %g %g (base) %g %g %g (end) %g (angle)\n",
           object[n].rotbas[i][0],object[n].rotbas[i][1],object[n].rotbas[i][2],
           object[n].rotend[i][0],object[n].rotend[i][1],object[n].rotend[i][2],
           object[n].angle[i]);
        }
        printf(" position:      %g %g %g\n",
            object[n].postn[0],object[n].postn[1],object[n].postn[2]);
        printf(" color:         %g %g %g\n",object[n].clr[0],object[n].clr[1],
            object[n].clr[2]);
        if (object[n].parent > 0)
            printf(" connected to %s\n",object[object[n].parent].name);
        printf(" bounding box:  %g < E - W < %g\n\
                %g < N - S < %g\n\
                %g < hight < %g\n",
            object[n].box[0], object[n].box[1], object[n].box[2],
            object[n].box[3], object[n].box[4], object[n].box[5]);
        printf(" centroid: %g %g %g   radius: %g\n\n\n",object[n].centroid[0],
            object[n].centroid[1],object[n].centroid[2],object[n].radius);
    }
}



/* +++++++++++++++++++++++++++ SKETCH_ON +++++++++++++++++++++++++++++ */
sketch_on(instrg)                       /* make image of bounding boxes */
char *instrg;
{   short bits,divisions,frmnum;    char dvc[LINE_LENGTH];
  
    dev_setup(instrg,dvc,&bits,&divisions,&frmnum,TRUE);
    obj_sort(object,p_list);
    bbox_task(object,p_list,dvc,bits,divisions,frmnum);
}




/* +++++++++++++++++++++++++++++ WHAT ++++++++++++++++++++++++++++++++++ */
what(string)                            /* error message with position noted */
char *string;
{   short i;    char outstrg[2*LINE_LENGTH],*strcat();
    for (i=0; i<char_cnt; i++)  outstrg[i] = '_';  /* build position string */
    outstrg[char_cnt] = NULLCHAR;
    strcat(outstrg,"^  ");
    if (input != stdin) { puts(" "); puts(instrg); }   /* echo input line if from file */
    fputs(outstrg,stdout);   puts(string);    /* write out position + message */
}





/*
csystem() is just a cobbled-up version of system().  I believe the only
differences lay in the path searches on file names.  csystem() allows
shorter versions of the path names, in general.  -- FC
*/
!Funky!Stuff!



More information about the Comp.sources.unix mailing list