Commits

Anonymous committed 43cc2c6

working plane and sphere rendering

  • Participants
  • Parent commits 2e5cd3b

Comments (0)

Files changed (1)

 
 type vector3 = float * float * float
 type color = int * int * int
+type normal = Normal of vector3
 type light = {light_center:vector3; light_color:color}
 type sphere = {center:vector3; radius:float; color:color; sph_id:int}
-type normal = Normal of vector3
-type shape = Sphere of sphere
+type plane = {plane_normal:normal; offset:float; plane_color:color;
+	      plane_id:int}
+type shape = Sphere of sphere | Plane of plane
 type intersection = {location:vector3;normal:normal;obj:shape}
 type camera = {origin:vector3; out:normal; up:normal; width:int;
 	       height:int; xangle:float; yangle:float}
 let compare_shapes (s1:shape) (s2:shape) : bool =
   match (s1,s2) with
     | (Sphere sph1, Sphere sph2) -> sph1.sph_id = sph2.sph_id
-(*    | _ -> false*)
+    | (Plane p1, Plane p2) -> p1.plane_id = p2.plane_id
+    | _ -> false
 
 let shape_color (s:shape) : color =
   match s with
       Sphere sph -> sph.color
+    | Plane p -> p.plane_color
+
 
 let sphere_intersect (sph:sphere) (src:vector3) (dir:normal) :
     intersection option =
+  let center = v3_sub sph.center src in
   let l = match dir with Normal n -> n in
-  let lcdot = v3_dot l sph.center in
+  let lcdot = v3_dot l center in
   let lcdot2 = sq lcdot in
-  let magc2 = v3_magnitudesq sph.center in
+  let magc2 = v3_magnitudesq center in
   let r2 = sq sph.radius in
   let radical = lcdot2 -. magc2 +. r2 in
   let solution () =
     let plus_closer = (v3_l2distsq src plus) < (v3_l2distsq src minus) in
     let loc = if plus_closer then plus else minus in
     let norm = v3_norm (v3_sub loc sph.center) in
-      if v3_dot (v3_sub loc src) l > 0.0 then
-	Some {location=loc;normal=norm;obj=(Sphere sph)} else None
+      Some {location=loc;normal=norm;obj=(Sphere sph)}
   in
     if radical >= 0.0 then solution() else None
 
+let plane_intersect (p:plane) (src:vector3) (dir:normal) : intersection option =
+  let l = match dir with Normal n -> n in
+  let n = match p.plane_normal with Normal n -> n in
+  let denom = v3_dot l n in
+    if (fabs denom) < 0.000000001 then None else (
+      let t = ((-.p.offset) -. (v3_dot src n)) /. denom in
+      let loc = v3_add (v3_mul l (t)) src in
+      let norm = p.plane_normal in
+	if t > 0.0 then
+	  (Some {location=loc; normal=norm; obj=Plane p})
+	else 
+	  None)
+
 let shape_intersect (src:vector3) (dir:normal) (shape:shape) :
     intersection option =
   match shape with
     | Sphere s -> sphere_intersect s src dir
+    | Plane p -> plane_intersect p src dir
 
 let closest_intersection_excluded (source_isect:intersection option) 
     (shapes:shape list) (src:vector3) (dir:normal) : intersection option =
 	      | Some orig_isect -> (
 		  if (compare_shapes orig_isect.obj s) &&
 		    ((v3_l2distsq orig_isect.location isect.location)
-		     < 0.0001) then acc else isect::acc))
+		     < 0.0000001) then acc else isect::acc))
     in
       List.fold_left filter_isect [] shapes
   in
 let render_scene (camera:camera) (shapes:shape list) (lights:light list)
     (bg:color) (ambience:float) : color list =
   let rays = build_rays camera in
-    print_endline ("all " ^ (string_of_int (List.length rays)) ^ " rays built");
-    List.map (render_ray camera.origin shapes lights bg ambience) rays
+  let f = render_ray camera.origin shapes lights bg ambience in
+  let rec loop ret rem =
+    match rem with
+      | [] -> List.rev ret
+      | hd::rest -> loop ((f hd)::ret) rest
+  in
+    loop [] rays
 
 let dump_bitmap (out:out_channel) (camera:camera) (colors:color list)  : unit =
   let n_pixels = List.length colors in
   let image_size = n_pixels * 3 in
   let header_size = 54 in
   let total_size = image_size + header_size in
-    print_endline ("total size " ^ (string_of_int total_size));
-    print_endline ("image size " ^ (string_of_int image_size));    
   let out_byte (i:int) = output_byte out i in
   let out_int (i:int) =
     out_byte i;
     dump_bitmap out camera colors;
     close_out out
 
-let shapes = [Sphere {center=(10.0,0.0,0.0); radius=1.0; color=rgb_green;
-		      sph_id=0}]
-let lights = [{light_center=(10.0,10.0,0.0); light_color=rgb_white}]
+let shapes = [Sphere {center=(10.0,0.0,0.0); radius=2.0; color=rgb_green;
+		      sph_id=0};
+	      Plane {plane_normal=v3_norm (0.0,1.0,0.0); offset=(5.0);
+		    plane_color=rgb_blue; plane_id=1};
+	      Plane {plane_normal=v3_norm (-.1.0,0.0,0.5); offset=(15.0);
+		     plane_color=(0,255,255); plane_id=2};
+	      Plane {plane_normal=v3_norm (0.0,0.0,-1.0); offset=10.0;
+		     plane_color=(255,255,0); plane_id=3}]
+let lights = [{light_center=(0.0,10.0,0.0); light_color=(200,200,200)};
+	      {light_center=(3.0,0.0,-.4.0);light_color=(100,255,100)}]
 let camera = {origin=v3_origin; out=v3_norm (1.0,0.0,0.0);
-	      up=v3_norm (0.0,1.0,0.0); width=240; height=240;
-	      xangle=2.4; yangle=2.4}
+	      up=v3_norm (0.0,1.0,0.0); width=1024; height=768;
+	      xangle=2.0; yangle=1.5}
 
-let colors = render_scene camera shapes lights rgb_red 0.00
+let colors = render_scene camera shapes lights rgb_red 0.07
 let out = write_bitmap "rendered.bmp" camera colors
 
 let dtest =