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

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

Objectives:
To implement and test the hits function

Due date:
11/08/10

What to hand in:
A tar.gz archive of your asg5/ 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 object_t and plane_t classes developed in lab 11, provide the virtual hits function to calculate the ray/plane intersection, if any:
      virtual double        hits(const vec_t&, const vec_t&);
    		

  2. Your code should be such that the following main() and test_hits() routines work unaltered:
    int main(int argc, char *argv[])
    {
            list_t          mats;
            list_t          objs;
            material_t      *mat;
            object_t        *obj;
            std::string     token,name;
            vec_t           pos(4.0, 3.0, 5.0);
            vec_t           dir(0.0, 0.0,-1.0);
            int             firsttime=1;
    
      // input should consist only of material definitions
      // but there can be any number of material defs in the file
      while(!std::cin.eof()) {
    
        if((std::cin >> token).good()) {
    
          if(token == "material") {
            std::cin >> (mat = new material_t());
            std::cerr << "loaded " << mat->getname() << std::endl;
            mats.add((void *)mat);
          }
    
          if(token == "plane") {
            std::cin >> (obj = new plane_t(token));
            std::cerr << "loaded " << obj->getname() << std::endl;
            objs.add((void *)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
              std::cerr << "vertical ray test" << std::endl;
              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
              std::cerr << "positive z test" << std::endl;
              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);
    
      // verify that we have all materials
      object_list_print(objs);
    }
    
    void test_hits(object_t *obj, vec_t& pos, vec_t& dir)
    {
            double  dist=0.0;
    
      obj->setlast_hit(0.0,0.0,0.0);
    
      dist = obj->hits(pos,dir);
    
      std::cerr << "dist to plane " << obj->getname() << " " << dist << std::endl;
      std::cerr << "hit point " << obj->getlast_hit() << std::endl;
    }
    		
  3. Sample output:
    loaded green
    loaded brown
    loaded wall
    dist to plane wall 12
    hit point 4 3 -7
    vertical ray test
    dist to plane wall -1
    hit point 0 0 0
    loaded floor
    dist to plane floor 15
    hit point 4 3 -10
    positive z test
    dist to plane floor -1
    hit point 4 -7.16129 0.16129
    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
    }