CPSC 102-001 Computer Science II
(Advanced C Programming)

Fall 2010
09:05-09:55MW Daniel 415
Assignment 1

Objectives:
To implement and test the plane_hits function

Due date:
09/20/10

What to hand in:
A tar.gz archive of your asg1/ directory, including:
  1. A README file containing
    1. Course id--section no
    2. Name
    3. Assignment description
    4. Brief solution description (e.g., program design, description of algorithm, etc., however appropriate).
    5. Lessons learned, identified interesting features of your program
    6. Any special usage instructions
  2. Makefile
  3. source code (.h headers and .c source)
  4. object code (do a make clean before tar)
How to hand in:
See handin notes

Description:
  1. Using the code developed in lab 4, namely the plane_print function, write the plane_hits function to calculate the ray/plane intersection, if any.
  2. Among others, provide the function
    	double plane_hits(object_t *obj, vec_t base, vec_t dir);
    		
    to test whether the ray defined by base and dir intersects the plane object. Recall that this function is pointed to by the generic object's function pointer
    	double     (*hits)(struct object_type*,vec_t,vec_t);
    		

  3. Your code should be such that the following main() and test_hits() routines work unaltered:
    int main()
    {
            list_t          *mats;
            list_t          *objs;
            material_t      *mat;
            object_t        *obj;
            char            token[16];
            drgb_t          pix;
            vec_t           pos = { 4.0,  3.0,  5.0};
            vec_t           dir = { 0.0,  0.0, -1.0};
            int             firsttime=1;
    
      // create material and object lists
      mats = list_init();
      objs = list_init();
    
      // input should consist of material definitions followed by
      // object definitions
      while(fscanf(stdin,"%s",token) == 1) {
    
        if(!strcmp(token,"material")) {
          // create material_t structure and read attributes
          material_init(stdin,mats,0);
    
          // this test is designed to ensure that list_add
          // pointed current to the material just loaded
          mat = (material_t *)list_get_data(mats);
          assert(mat->cookie == MAT_COOKIE);
          fprintf(stderr,"loaded %s \n",material_getname(mat));
        }
    
        if(!strcmp(token,"plane")) {
          // create plane object
          plane_init(stdin,objs,mats,0);
    
          // this test is designed to ensure that list_add
          // pointed current to the object just loaded
          obj = (object_t *)list_get_data(objs);
          assert(obj->cookie == OBJ_COOKIE);
          fprintf(stderr,"loaded %s \n",object_getname(obj));
    
          // test hits function
          pos[0] =  4.0; pos[1] =  3.0; pos[2] =  5.0;
          dir[0] =  0.0; dir[1] =  0.0; dir[2] = -1.0;
          test_hits(obj,pos,dir);
    
          if(firsttime) {
            // make sure we don't get a hit on a miss...shoot
            // straight down at backwall
            fprintf(stderr,"vertical ray test\n");
            pos[0] =  4.0; pos[1] =  3.0; pos[2] =  5.0;
            dir[0] =  0.0; dir[1] = -2.1; dir[2] =  0.0;
            test_hits(obj,pos,dir);
            firsttime = 1-firsttime;
          } else {
            // make sure we don't get a hit in +z space
            fprintf(stderr,"positive z test\n");
            pos[0] =  4.0; pos[1] =  3.0; pos[2] =  5.0;
            dir[0] =  0.0; dir[1] = -2.1; dir[2] = -1.0;
            test_hits(obj,pos,dir);
          }
        }
      }
    
      // verify that we have all materials
      material_list_print(mats,stdout);
    
      // verify that we have all objects
      object_list_print(objs,stdout);
    
      return(0);
    }
    
    void test_hits(object_t *obj,vec_t pos,vec_t dir)
    {
            double  dist=0.0;
    
      vec_unit(dir,dir);
      memset(obj->last_hit,0,sizeof(vec_t));
      dist = obj->hits(obj,pos,dir);
    
      fprintf(stderr,"dist to plane %s %8.3lf \n",obj->name,dist);
      vec_print(stderr,"hit point",obj->last_hit);
    }
    		
  4. Sample output:
    loaded green 
    loaded brown 
    loaded wall 
    dist to plane wall   12.000 
    hit point   4.000   3.000  -7.000
    vertical ray test
    dist to plane wall   -1.000 
    hit point   0.000   0.000   0.000
    loaded floor 
    dist to plane floor   15.000 
    hit point   4.000   3.000 -10.000
    positive z test
    dist to plane floor   -1.000 
    hit point   4.000  -7.161   0.161
    material green
    {
       ambient 0 5 0
    }
    
    material brown
    {
       ambient 3 3 0
    }
    
    plane wall
    {
       material green
       normal 0 0 1
       point  0 0 -7
    }
    
    plane floor
    {
       material brown
       normal 0 1 1
       point  0 0 -7
    }