Commits

David Jones  committed b877236

foo.

  • Participants
  • Parent commits 9d5312b

Comments (0)

Files changed (7)

 static struct Primitive_Ops plane_ops  =
   {*plane_intersects, 
    *plane_normal,
-   *plane_get_color,
+   *plane_get_material,
    *plane_is_light};
 
 
   return (Primitive *) p;
 }
 
-Color
-plane_get_color(Primitive * prim)
+Material *
+plane_get_material(Primitive * prim)
 {
   assert(prim != NULL);
-  return ((Plane *)prim)->color;
+  return &((Plane *)prim)->material;
 }
 
 
   struct Primitive_Ops * ops;
   Vec3 normal;
   Vec3 origin;
-  Color color;
+  Material material;
   int light;
 } Plane;
 
 void 
 plane_init(Plane * s);
 
-Color
-plane_get_color(Primitive * prim);
+Material *
+plane_get_material(Primitive * prim);
 
 int 
 plane_is_light(Primitive * p);
 */
 
 
-
+int do_log = 0;
+int MAX_DEPTH = 5;
 void write_image(Image * ptr, 
                  const char * filename)
 {
 
 char log_buffer[1024];
 
-
 int 
 intersects(Primitive * p, Ray * r, Vec3 * po) 
 {
   assert(p->ops != NULL);
   assert(p->ops->intersects != NULL);
   return (p->ops->intersects)(p,r,po);
-
 }
 
 void 
   assert(p->ops != NULL);
   assert(p->ops->get_normal != NULL);
   (p->ops->get_normal)(p,r,po);
-
 }
 
 
+Material *
+get_material(Primitive * p)
+{
+  assert(p != NULL);
+  assert(p->ops != NULL);
+  assert(p->ops->get_material != NULL);
+  return (p->ops->get_material)(p);
+}
+
 int
 is_light(Primitive * p)
 {
 }
 
 Primitive *
-ray_trace(Scene * s, Ray * ray, Color * color, int depth, Vec3 * point)
+ray_trace(Scene * scene, Ray * ray, 
+          Color * color, int depth, Vec3 * point)
 {
-  assert(s != NULL);
+  assert(scene != NULL);
   assert(ray != NULL);
   assert(color != NULL);
   assert(point != NULL);
-
+  
+  if(do_log) {
+    sprintf(log_buffer, "ray_trace.  ray.origin: %f,%f,%f ray.direction: %f,%f,%f depth: %d",
+            ray->origin.x, ray->origin.y,ray->origin.z, 
+            ray->direction.x, ray->direction.y,ray->direction.z, 
+            depth);
+    log_message(log_buffer, 1, 1);
+  }
 
   Vec3 best_point;
   float best_dist = 1e38;
   int best_prim = -1;
-  Primitive * c;
+  Primitive * prim;
   int ii = 0;
 
-  for(ii = 0; ii < s->num_primitives; ++ii) {
+  for(ii = 0; ii < scene->num_primitives; ++ii) {
     // for each primitive
     // printf("\na");
-    c = s->primitives[ii];
-    int tmp = intersects(c, ray, point);
+    prim = scene->primitives[ii];
+
     // find distance
-    if(tmp) {
+    if(intersects(prim, ray, point)) {
       Vec3 dist;
       vec_subtract(&(ray->origin), point, &dist);
       float d = vec_dot(&dist, &dist);
       }
     }
   }
-  
+    
   if(best_prim == -1) {
+    if(do_log) {
+      sprintf(log_buffer, "Nothing hit...");
+      log_message(log_buffer, 1, 1);
+    }
     return 0;
+  } else if (is_light(scene->primitives[best_prim])) {
+    if(do_log) {
+      sprintf(log_buffer, "Hit a light, primitive: %d", best_prim);
+      log_message(log_buffer, 1, 1);
+    }
+    *color = get_material(scene->primitives[best_prim])->color;
+    return scene->primitives[best_prim];
   } else {
     //sprintf(log_buffer,"hit primitive: %d, point: <%f,%f,%f>",
     //best_prim, best_point.x, best_point.y, best_point.z);
     //log_message(log_buffer,1,1);
-    c = s->primitives[best_prim];
+    prim = scene->primitives[best_prim];
+    Material * prim_material = get_material(prim);
 
-    int ii = 0;
-    
-    for(ii = 0; ii < s->num_primitives; ++ii) {
-      Primitive * li_tmp = s->primitives[ii];
-      //printf("\nh");
-      if ((li_tmp->ops->is_light)(li_tmp) == 0) continue;
-      // printf("k\n");
-      Sphere * li = (Sphere *) li_tmp;
-      Vec3 normal;
+    Vec3 normal;
+    (prim->ops->get_normal)(prim, &best_point, &normal);
+
+
+    for(ii = 0; ii < scene->num_primitives; ++ii) {
+      Primitive * li_prim = scene->primitives[ii];
+      if ((li_prim->ops->is_light)(li_prim) == 0) continue;
+
+      Sphere * li = (Sphere *) li_prim;
       Vec3 to_light;
       float shade = 1.0;
+
       vec_subtract(&(li->center), &best_point, &to_light);
       float dist_to_light = vec_dot(&to_light, &to_light);
       float divisor = 1.0/vec_dot(&to_light, &to_light);
         vec_mult_scalar(.001, &xx, &xx);
         vec_add(&tmp.origin, &xx, &tmp.origin);
 
-        for(jj = 0; jj < s->num_primitives; ++jj) {
+        for(jj = 0; jj < scene->num_primitives; ++jj) {
           if(jj == best_prim) continue;
-          Primitive * cp = s->primitives[jj];
+          Primitive * cp = scene->primitives[jj];
           Vec3 np;
           int r = intersects(cp, &tmp, &np);
 
         
 
       vec_norm(&to_light,&to_light);
-      (c->ops->get_normal)(c, &best_point, &normal);
+
       // log_message("TRACE",1,1);
 
-      float dot = vec_dot(&normal, &to_light);
+
+
+      if(get_material(prim)->diffuse > 0) {
+        float dot = vec_dot(&normal, &to_light);
       
-      if (dot > 0) {
-        Color prim_color = (c->ops->get_color)(c);
-        color_scalar_mult(&prim_color, shade * dot, &prim_color);
-        color_mult(&prim_color, &li->color, &prim_color);
-        color_add(color, &prim_color, color);
-      } else {
+        if (dot > 0) {
+          Color prim_color = prim_material->color;
+          Color light_color = get_material(li_prim)->color;
+          color_scalar_mult(&prim_color, prim_material->diffuse * shade * dot, &prim_color);
+          color_mult(&prim_color, &light_color, &prim_color);
+          color_add(color, &prim_color, color);
+        }
+      }
+      if(get_material(prim)->specular > 0) {
+        Vec3 reflection;
+        vec_mult_scalar(2.0*vec_dot(&to_light, &normal), &normal, &reflection);
+        vec_subtract(&to_light, &reflection, &reflection);
+        float dot = vec_dot(&ray->direction, &reflection);
+        if (dot > 0) {
+          dot = dot * dot;
+          dot = dot * dot;
+          dot = dot * dot;
+          Color light_color = get_material(li_prim)->color;
+          color_scalar_mult(&light_color, prim_material->specular * shade * dot, 
+                            &light_color);
+          // color_mult(&prim_color, &light_color, &prim_color);
+          color_add(color, &light_color, color);
+        }
       }
     }
+    float reflection = prim_material->reflection;
+    if(reflection > 0) {
+      if (depth < MAX_DEPTH) {
+        
+        Vec3 reflected_ray;
+        vec_mult_scalar(2.0*vec_dot(&ray->direction, &normal), &normal, &reflected_ray);
+        vec_subtract(&ray->direction, &reflected_ray, &reflected_ray);
+        Color rcol;
+        rcol.r = 0; rcol.g = 0; rcol.b = 0;
+        
+        Ray new_ray;
+        new_ray.direction = reflected_ray;
+        Vec3 tmp_dir;
+        vec_mult_scalar(1.0001, &reflected_ray, &tmp_dir);
+        vec_add(&best_point, &tmp_dir, &new_ray.origin);
+        
+        Primitive * r = ray_trace(scene, &new_ray, &rcol, depth + 1, &tmp_dir);
+        if(do_log) {
+          sprintf(log_buffer,"in reflection: best_point <%f,%f,%f>\nnew_ray.dir %f,%f,%f\nrcol: %f,%f,%f", best_point.x, best_point.y, best_point.z, new_ray.direction.x, new_ray.direction.y, new_ray.direction.z, rcol.r, rcol.g, rcol.b);
+          log_message(log_buffer,1,1);
+          sprintf(log_buffer,"best_prim: %d, best_prim 0x%X, r 0x%x", best_prim,
+                  (int)scene->primitives[best_prim], (int)r);
+          log_message(log_buffer,1,1);
+        }
+
+        color_scalar_mult( &rcol, reflection, &rcol);
+        color_mult(&rcol, &prim_material->color, &rcol);
+        color_add(color, &rcol, color);
+
+      }
+      
+    }
+    return scene->primitives[best_prim];
   }
   // log_message("TRACE2",1,1);
 }
 
 
 void 
-render(Scene * s, 
+render(Scene * scene, 
           const char * filename) 
 {
   Image im;
   int i, j;
-  assert(s != NULL);
-  im.width = s->view_width;
-  im.height = s->view_height;
-  im.image = dmalloc(sizeof(Color) * s->view_height * s->view_width);
+  assert(scene != NULL);
+  im.width = scene->view_width;
+  im.height = scene->view_height;
+  im.image = dmalloc(sizeof(Color) * scene->view_height * scene->view_width);
 
   Ray ray;
-  ray.origin = s->camera_position;
+  ray.origin = scene->camera_position;
 
-  for(j = 0; j < s->view_height; ++j) {
-    for(i = 0; i < s->view_width; ++i) {
+  for(i = 0; i < scene->num_primitives; ++i) {
+    sprintf(log_buffer, "primitive %d 0x%x", i, (int)scene->primitives[i]);
+    log_message(log_buffer, 1, 1);
+  }
+           
+  for(j = 0; j < scene->view_height; ++j) {
+   for(i = 0; i < scene->view_width; ++i) {
+     //for(j = 290; j < 310; ++j) {
+     // for(i = 75; i < 100; ++i) {
       //sprintf(log_buffer, "i: %d, j: %d", i, j);
       //log_message(log_buffer, 1,0);
       {
         Vec3 a;
-        a.x = -(s->view_width/2) + j; //+ 1.0*rand()/RAND_MAX ;;
-        a.y = (s->view_height/2) - i;// + 1.0*rand()/RAND_MAX ;
+        a.x = -(scene->view_width/2) + j; //+ 1.0*rand()/RAND_MAX ;;
+        a.y = (scene->view_height/2) - i;// + 1.0*rand()/RAND_MAX ;
         a.z = -0;
         // printf("point: ");
         // vec_print(stdout, &a);
       color.g = 0;
       color.b = 0;
       Vec3 point;
-      ray_trace(s, &ray, &color, 1, &point);
-      im.image[i*s->view_width + j] = color;
+      ray_trace(scene, &ray, &color, 1, &point);
+      im.image[i*scene->view_width + j] = color;
     }
   }
   write_image(&im, filename);
 int main()
 {
   
-  Scene s;
+  Scene scene;
   int bookmark = get_bookmark();
-  s.camera_position.x = 0;
-  s.camera_position.y = 0;
-  s.camera_position.z = -500;
-  s.view_center.x = 0;
-  s.view_center.y = 0;
-  s.view_center.z = 0;
+  scene.camera_position.x = 0;
+  scene.camera_position.y = 0;
+  scene.camera_position.z = -500;
+  scene.view_center.x = 0;
+  scene.view_center.y = 0;
+  scene.view_center.z = 0;
   
-  s.view_height = 400;
-  s.view_width = 400;
+  scene.view_height = 400;
+  scene.view_width = 400;
 
-  s.num_primitives = 6;
-  s.primitives = dmalloc(s.num_primitives*sizeof(Primitive*));
+  scene.num_primitives = 6;
+  scene.primitives = dmalloc(scene.num_primitives*sizeof(Primitive*));
 
-  s.primitives[4] = dmalloc(sizeof(Sphere));
-  sphere_init((Sphere*)s.primitives[4]);
-  Sphere * tmps = (Sphere *) s.primitives[4];
+  scene.primitives[4] = dmalloc(sizeof(Sphere));
+  sphere_init((Sphere*)scene.primitives[4]);
+  Sphere * tmps = (Sphere *) scene.primitives[4];
   tmps->light = 1;
 
   tmps->center.y = 2000;
   tmps->center.x =  -20000;
   tmps->center.z = -5000;
-  tmps->radius = 100;
-  tmps->color.r = .1;
-  tmps->color.g = .1;
-  tmps->color.b = .9;
+  tmps->radius = 1000;
+  tmps->material.color.r = .9;
+  tmps->material.color.g = .9;
+  tmps->material.color.b = .9;
 
-  s.primitives[5] = dmalloc(sizeof(Sphere));
-  sphere_init((Sphere*)s.primitives[5]);
-  tmps = (Sphere *) s.primitives[5];
+  scene.primitives[5] = dmalloc(sizeof(Sphere));
+  sphere_init((Sphere*)scene.primitives[5]);
+  tmps = (Sphere *) scene.primitives[5];
   tmps->light = 1;
   tmps->center.x = 10000;
   tmps->center.y = 10000;
   tmps->center.z = 5000;
-  tmps->radius = 100;
-  tmps->color.r = .9;
-  tmps->color.g = .4;
-  tmps->color.b = .4;
+  tmps->radius = 1000;
+  tmps->material.color.r = .9;
+  tmps->material.color.g = .4;
+  tmps->material.color.b = .4;
 
-  s.primitives[0] = dmalloc(sizeof(Sphere));
-  sphere_init((Sphere*)s.primitives[0]);
-  tmps = (Sphere *) s.primitives[0];
+  scene.primitives[0] = dmalloc(sizeof(Sphere));
+  sphere_init((Sphere*)scene.primitives[0]);
+  tmps = (Sphere *) scene.primitives[0];
   tmps->center.x = 5000;
   tmps->center.y = 2000;
   tmps->center.z = 15000;
   tmps->radius = 3000.0;
-  tmps->color.r = .9;
-  tmps->color.g = .9;
-  tmps->color.b = .9;
+  tmps->material.color.r = .9;
+  tmps->material.color.g = .9;
+  tmps->material.color.b = .9;
+  tmps->material.diffuse = .8;
+  tmps->material.specular = .1;
+  tmps->material.reflection = 1.0;
 
-
-  s.primitives[1] = dmalloc(sizeof(Sphere));
-  sphere_init((Sphere*)s.primitives[1]);
-  tmps = (Sphere *) s.primitives[1];
+  scene.primitives[1] = dmalloc(sizeof(Sphere));
+  sphere_init((Sphere*)scene.primitives[1]);
+  tmps = (Sphere *) scene.primitives[1];
 
   tmps->center.y = 1000;
   tmps->center.x = -3000;
   tmps->center.z = 15000;
   tmps->radius =   3000;
-  tmps->color.r = .1;
-  tmps->color.g = .9;
-  tmps->color.b = .9;
+  tmps->material.color.r = .1;
+  tmps->material.color.g = .1;
+  tmps->material.color.b = .9;
+  tmps->material.diffuse = .8;
+  tmps->material.specular =.1 ;
+  tmps->material.reflection = 1.0;
 
-
-
-  s.primitives[2] = dmalloc(sizeof(Sphere));
-  sphere_init((Sphere*)s.primitives[2]);
-  tmps = (Sphere *) s.primitives[2];
-
+  scene.primitives[2] = dmalloc(sizeof(Sphere));
+  sphere_init((Sphere*)scene.primitives[2]);
+  tmps = (Sphere *) scene.primitives[2];
+  tmps->light = 0;
   tmps->center.y = -4800;
   tmps->center.x = -4000;
   tmps->center.z = 17000;
-  tmps->radius =   1000;
-  tmps->color.r = .9;
-  tmps->color.g = .9;
-  tmps->color.b = .9;
+  tmps->radius =   50;
+  tmps->material.color.r = 0;
+  tmps->material.color.g = .9;
+  tmps->material.color.b = 0;
+  tmps->material.diffuse = 1;
+  tmps->material.specular = .1;
+  tmps->material.reflection = 1;
 
 
-
-  s.primitives[3] = dmalloc(sizeof(Plane));
-  plane_init((Plane*)s.primitives[3]);
-  Plane * tmpp = (Plane *) s.primitives[3];
+  scene.primitives[3] = dmalloc(sizeof(Plane));
+  plane_init((Plane*)scene.primitives[3]);
+  Plane * tmpp = (Plane *) scene.primitives[3];
 
   tmpp->origin.y = 0;
   tmpp->origin.x = 0;
-  tmpp->origin.z = 80000;
+  tmpp->origin.z = 40000;
 
-  tmpp->normal.y = 1;
+  tmpp->normal.y = 0;
   tmpp->normal.x = 0;
-  tmpp->normal.z = -.2;
+  tmpp->normal.z = -1;
 
-  tmpp->color.r = .9;
-  tmpp->color.g = .9;
-  tmpp->color.b = .9;
-
-
+  tmpp->material.color.r = .1;
+  tmpp->material.color.g = .7;
+  tmpp->material.color.b = .6;
+  tmpp->material.diffuse = .9;
+  tmpp->material.specular = .09;
+  tmpp->material.reflection = 0;
   printf("------------\n");
 
-  render(&s, ",output.ppm");
+  render(&scene, ",output.ppm");
   /* 
   im.width = 256;
   im.height = 256;
   Color color;
 } Light;
 
+typedef struct
+{
+  Color color;
+  float diffuse;
+  float specular;
+  float reflection;
+} Material;
+
 
 typedef struct 
 {
   void (*get_normal)(Primitive * prim,
                      Vec3* point,
                      Vec3 * normal);
-  Color (*get_color)(Primitive * prim);
+  Material* (*get_material)(Primitive * prim);
   int (*is_light)(Primitive * prim);
 
 };
 static struct Primitive_Ops sphere_ops  =
   {*sphere_intersects,
    *sphere_normal,
-   *sphere_get_color,
+   *sphere_get_material,
    *sphere_is_light};
 
 
   return ans;
 }
 
-Color
-sphere_get_color(Primitive * prim)
+Material *
+sphere_get_material(Primitive * prim)
 {
   assert(prim != NULL);
-  return ((Sphere *)prim)->color;
+  return &((Sphere *)prim)->material;
 }
 
 int
   struct Primitive_Ops * ops;
   Vec3 center;
   float radius;
-  Color color;
+  Material material;
   int light;
 } Sphere;
 
 void 
 sphere_init(Sphere * s);
 
-Color
-sphere_get_color(Primitive * prim);
+Material *
+sphere_get_material(Primitive * prim);
 
 int
 sphere_is_light(Primitive * p);
   tmpp->normal.z = 1;
 
 
-  tmpp->color.r = 1.0;
-  tmpp->color.g = 1.0;
-  tmpp->color.b = 1.0;
+  tmpp->material.color.r = 1.0;
+  tmpp->material.color.g = 1.0;
+  tmpp->material.color.b = 1.0;
 
   Ray ray;
   ray.origin.x = 10;