Lab 11: hits()

Objectives:

To implement and exercise the model_t object

Just as in Lab 5, we also need to rewrite the find_closest function, which now is part of the model_t object. The idea is (still):

  1. given the following input: object list, ray base and direction
  2. find the object that (a) intersects the ray and (b) is the closest object to the ray base along the ray (smallest t value)
  3. set the (pass-by-reference) distance value to the intersection point, set the hit and N vectors to the surface hit point and the normal at that hit point, and return the pointer to the closest object
    This point is important since it requires calling find_closest with the address of the hit and N vectors, meaning using &hit and &N arguments when calling find_closest.

Assignment

  1. Following the class notes, define the model_t object in the model.h interface, providing the following class data members:
      list_t *mats;
      list_t *objs;
    	
    and member functions:
    // - instance methods
      // constructors (overloaded)
    - (id) init;
        
      // accessor/mutator
    - (list_t *)  objs;
    - (list_t *)  mats;
    
      // operators            
    
      // members
    - (void) read: (FILE *) _in;
    - (void) write: (FILE *) _out;
    	
  2. The two i/o member functions (a.k.a. methods) read: and write: must be implemented in the model_t implementation mocdel.m
  3. The search function find_closest() must be implemented as a protocol and so must be implemented in the model_t implementation mocdel.m; this function calls the polymorphic [obj hits: ...] function (which must be provided by the object_t and plane_t objects)
  4. Before calling [obj hits: ...], find_closest() should make sure that the object obj conforms to the intersecting protocol (use conformsToProtocol built-in member function)
  5. Your code should be such that the following main() routine works unaltered:
    int main(int argc, char *argv[])
    {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
            model_t         *model = [(model_t *)[model_t alloc] init];
            FILE            *model_file=NULL, *hits_file=NULL;
    
            vec_t           *pos = [(vec_t *)[vec_t alloc] init: 4.0: 3.0:  5.0];
            vec_t           *dir = [(vec_t *)[vec_t alloc] init: 0.0: 0.0: -1.0];
    
            vec_t           *N = [(vec_t *)[vec_t alloc] init: 0.0: 0.0:  0.0];
            vec_t           *hit = [(vec_t *)[vec_t alloc] init: 0.0: 0.0: 0.0];
    
            double           dis = 0.0;
    
            object_t        *obj = nil;
      
      NSLog(@"main start");
      NSLog(@"reading stdin");
      
      if(argc != 3) {
        fprintf(stderr,"Usage: %s  \n",argv[0]);
        exit(1); 
      }   
    
      // open model file
      if((model_file = fopen(argv[1],"r")) == NULL) { 
         printf("Error opening input file: %s\n",argv[1]);
         return;
      } 
        
      [model read: model_file];
          
      fclose(model_file);
        
      [model write: stdout];
    
      // open hits file
      if((hits_file = fopen(argv[2],"r")) == NULL) {
         printf("Error opening input file: %s\n",argv[2]);
         return;
      }
    
      while([dir read: hits_file]) {
        [dir write: stderr: "Ray direction:"];
        [dir autorelease];
        dir = [[dir unit] retain];
    
        dis = 0.0;
        obj = [model find_closest: pos: dir: &dis: &hit: &N];
    
        if(dis > 0) {
          fprintf(stderr,"Hit: %-12s ",[[obj getname] UTF8String]);
    
          fprintf(stderr,"Dist = %8.3lf ",dis);
          [hit write: stderr: "Loc = "];
        } else
          fprintf(stderr,"Dist = %8.3lf \n", dis);
    
        fprintf(stderr, "\n\n");
        obj = [model find_closest: pos: dir: &dis: &hit: &N];
        if(dis > 0) {
          fprintf(stderr,"Hit: %-12s ",[[obj getname] UTF8String]);
    
          fprintf(stderr,"Dist = %8.3lf ",dis);
          [hit write: stderr: "Loc = "];
        } else
          fprintf(stderr,"Dist = %8.3lf \n", dis);
      }
    
      fclose(hits_file);
    
      [pool drain];
    
      return 0;
    }
    	
  6. Sample input (model.txt):
    material green
    {
       ambient 0 5 0
    }
    
    material yellow
    {
       ambient 6 5 0
    }
    
    material gray
    {
       ambient 4 4 4
    }
    
    plane leftwall
    {
       material green
       normal 3 0 1
       point  0 0 0
    }
    
    plane rightwall
    {
       material yellow
       normal -3 0 1
       point  8 0 0
    }
    
    plane floor
    {
       material gray
       normal 0 1 0
       point  0 0 0
    }
    	
  7. Sample input (hittest.txt):
    -0.5 -0.1 -1
     0.5 -0.1 -1
     0  -0.5 -1.0
     1   1   1
    	
  8. Sample output (note that the timestamps will differ):
    2013-01-17 13:38:18.324 main[65437:903] main start
    2013-01-17 13:38:18.326 main[65437:903] reading stdin
    material green
    {
       ambient 0 5 0
    }
    
    material yellow
    {
       ambient 6 5 0
    }
    
    material gray
    {
       ambient 4 4 4
    }
    
    plane leftwall
    {
       material green
       normal 3 0 1
       point 0 0 0
    }
    
    plane rightwall
    {
       material yellow
       normal  -3 0 1
       point 8 0 0
    }
    
     floor
    {
       material gray
       normal 0 1 0
       point 0 0 0
    }
    
    Ray direction:    -0.500    -0.100    -1.000
    Hit: leftwall     Dist =    7.633 Loc =    0.600   2.320    -1.800
    
    
    Hit: leftwall     Dist =   15.266 Loc =    0.600   2.320    -1.800
    Ray direction:   0.500    -0.100    -1.000
    Hit: rightwall    Dist =    7.633 Loc =    7.400   2.320    -1.800
    
    
    Hit: rightwall    Dist =   15.266 Loc =    7.400   2.320    -1.800
    Ray direction:   0.000    -0.500    -1.000
    Hit: floor        Dist =    6.708 Loc =    4.000   0.000    -1.000
    
    
    Hit: floor        Dist =   13.416 Loc =    4.000   0.000    -1.000
    Ray direction:   1.000   1.000   1.000
    Dist =    0.000 
    
    
    Dist =    0.000
    	

Turn in

Turn in all of your code, in one tar.gz archive of your lab11/ directory, including:
  1. A README file containing
    1. Course id--section no
    2. Name
    3. Lab 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 submit notes.