diff --git a/a.out b/a.out index 08a21fb..20ffbef 100755 Binary files a/a.out and b/a.out differ diff --git a/display.cmi b/display.cmi index 24f5f56..2cd14a5 100644 Binary files a/display.cmi and b/display.cmi differ diff --git a/display.cmo b/display.cmo index 57713bc..7660b63 100644 Binary files a/display.cmo and b/display.cmo differ diff --git a/display.cmx b/display.cmx new file mode 100644 index 0000000..42e6acc Binary files /dev/null and b/display.cmx differ diff --git a/display.ml b/display.ml index 715fd42..3c22c26 100644 --- a/display.ml +++ b/display.ml @@ -5,9 +5,27 @@ Random.self_init () ;; let __width__ = 1500 and __height__ = 1000 ;; +type tile = Free | Wall | Crate | Exit | Craxit | Camera ;; + +let width = 15 +and height = 15 +and depth = 15 ;; +(* dimensions *) + +let render_distance = 7 ;; +let chunk_dist = 2 ;; + +let chunk_size = 4 ;; +let chunk_size_f = float_of_int chunk_size ;; + +(* -------------------------------------------------------------------------------------------------------- *) +(* -------------------------------------------------------------------------------------------------------- *) +(* -------------------------------------------------------------------------------------------------------- *) +(* -------------------------------------------------------------------------------------------------------- *) + (* -ocamlfind ocamlc -linkpkg -package unix -linkpkg -package graphics -thread -package threads -linkpkg display.ml +ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics -thread -package threads -linkpkg display.ml *) @@ -111,7 +129,7 @@ let parse_texture filename = tex | exn -> close_in ptr ; raise exn ;; -let stone = parse_texture "texture404.txt" ;; +let stone = parse_texture "output.txt" ;; (* ------------------------------------------------------------- *) (* ------------------------------------------------------------- *) @@ -249,6 +267,14 @@ let adjust_to_camera (shape : pt_3d array) = (*debug_1 res2 ;*) res2 ;; +let adjust_pt (pt : pt_3d) = + let tpt = {x = pt.x +. camera_xyz.x ; y = pt.y +. camera_xyz.y ; z = pt.z -. camera_xyz.z} in + { + x = tpt.x *. Float.cos ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.) +. tpt.z *. Float.sin ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.); + y = tpt.y; + z = tpt.z *. Float.cos ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.) -. tpt.x *. Float.sin ((float_of_int !camera_angle_y) *. 3.14159255358 /. 180.) + } ;; + let sq x = x *. x ;; let dist_from_camera (p : pt_3d) = @@ -282,34 +308,150 @@ let convex_pt (p1 : int * int) (p2 : int * int) theta maxtheta = and mid_y = int_of_float ((1. -. ratio) *. (float_of_int (snd p1)) +. ratio *. (float_of_int (snd p2))) in (mid_x, mid_y) ;; +let convex_3d (p1 : pt_3d) (p2 : pt_3d) theta maxtheta = + let ratio = (float_of_int theta) /. (float_of_int maxtheta) in + { + x = (1. -. ratio) *. p1.x +. ratio *. p2.x; + y = (1. -. ratio) *. p1.y +. ratio *. p2.y; + z = (1. -. ratio) *. p1.z +. ratio *. p2.z + } ;; + + + +(* +----\\ WARNING : THIS BIT YIELDS A SEGMENTATION FAULT //----- + +exception Out_of_bounds ;; +let get_single_pt pt = + try + Graphics.point_color (fst pt) (snd pt) + with + | Graphics.Graphic_failure _ -> raise Out_of_bounds ;; + +let is_hidden (rect : (int * int) array) = + try + let midpt = ((fst rect.(0) + fst rect.(1) + fst rect.(2) + fst rect.(3))/4, (snd rect.(0) + snd rect.(1) + snd rect.(2) + snd rect.(3))/4) in + let color_BL = get_single_pt rect.(0) + and color_BR = get_single_pt rect.(1) + and color_TL = get_single_pt rect.(2) + and color_TR = get_single_pt rect.(3) + and color_C = get_single_pt midpt in + (color_BL = 0) || (color_BR = 0) || (color_TL = 0) || (color_TR = 0) || (color_C = 0) + with + | Out_of_bounds -> false ;; +*) + +let ctc_one x = + if x >= 0 then + x / chunk_size + else + x / chunk_size -1 ;; + +let ctcf_one x = + if x >= 0. then + int_of_float (x /. chunk_size_f) + else + int_of_float (x /. chunk_size_f) -1 ;; + +let coords_to_chunk x y z = + (ctc_one x, ctc_one y, ctc_one z) ;; + +let coords_to_chunk_f x y z = + (ctcf_one x, ctcf_one y, ctcf_one z) ;; + +(* -------------------------------------------------------------------------------------- *) + +let is_in_cube (pt : pt_3d) (cube : pt_3d array) = + (* cube and pt are relative to the camera *) + (*Printf.printf " comparing with cube : (%f, %f, %f)" cube.(0).x cube.(0).y cube.(0).z; + Stdlib.print_endline " ";*) + (cube.(0).x <= pt.x) && + (cube.(0).y <= pt.y) && + (cube.(0).z <= pt.z) && + (cube.(6).x >= pt.x) && + (cube.(6).y >= pt.y) && + (cube.(6).z >= pt.z) ;; + +let seg_len (p1 : pt_3d) (p2 : pt_3d) = + Float.sqrt ((sq (p1.x -. p2.x)) +. (sq (p1.y -. p2.y)) +. (sq (p1.z -. p2.z))) ;; + +exception ReturnBool of bool ;; +let is_visible (pt0 : pt_3d) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) = + try + let pt = pt0 in + (*Printf.printf " current pt : (%f, %f, %f)\n" pt.x pt.y pt.z; + Printf.printf " camera pt : (%f, %f, %f)\n" (-. camera_xyz.x) (-. camera_xyz.y) camera_xyz.z;*) + + let segment_length = dist_from_camera pt in + let n_iter = int_of_float (segment_length /. 1.7) in + + (*Printf.printf " distance : %f\n" segment_length; + Printf.printf " n_iter : %d" n_iter; + Stdlib.print_endline " ";*) + + for i = 1 to n_iter -1 do + let cur_pt = convex_3d pt {x = -. camera_xyz.x ; y = -. camera_xyz.y ; z = camera_xyz.z} i n_iter in + let (ch_x, ch_y, ch_z) = coords_to_chunk_f cur_pt.x cur_pt.y cur_pt.z in + + (*Printf.printf " regarding pt : (%f, %f, %f) in chunk (%d, %d, %d)" cur_pt.x cur_pt.y cur_pt.z ch_x ch_y ch_z; + Stdlib.print_endline " ";*) + + let cubes = Hashtbl.find hash (ch_x, ch_y, ch_z) in + for c = 0 to cubes.len -1 do + if is_in_cube cur_pt cubes.tab.(c).cube then + raise (ReturnBool false) + done + done; + (*Stdlib.print_endline " No collision detected";*) + true + with + | Not_found -> (*Stdlib.print_endline " EMPTY"; *)true + | ReturnBool b -> (*Printf.printf " Aborted to %b" b ; Stdlib.print_endline " "; *)b ;; + +let is_visible_cube (cube : pt_3d array) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) = + (*Printf.printf "cube (%f, %f, %f)" cube.(0).x cube.(0).y cube.(0).z; + Printf.printf "[of length %d]" (Array.length cube); + Stdlib.print_endline " ";*) + let res = ref false in + for i = 0 to Array.length cube -1 do + res := !res || (is_visible cube.(i) hash) + done; + (*Printf.printf "yielding %b" !res; + Stdlib.print_endline " "; *) + !res ;; + let draw_texture (rect : (int * int) array) (text : texture) light = (*set_color white; fill_poly rect ;;*) for i = 0 to text.width -1 do for j = 0 to text.height -1 do - let face_R = int_of_float ((float_of_int text.arr_red.(i).(j)) *. light) - and face_G = int_of_float ((float_of_int text.arr_green.(i).(j)) *. light) - and face_B = int_of_float ((float_of_int text.arr_blue.(i).(j)) *. light) in - set_color (rgb face_R face_G face_B); + if true then begin + let face_R = int_of_float ((float_of_int text.arr_red.(i).(j)) *. light) + and face_G = int_of_float ((float_of_int text.arr_green.(i).(j)) *. light) + and face_B = int_of_float ((float_of_int text.arr_blue.(i).(j)) *. light) in + set_color (rgb face_R face_G face_B); - let pt_a = convex_pt rect.(0) rect.(1) i text.width - and pt_b = convex_pt rect.(0) rect.(1) (i+1) text.width + let pt_a = convex_pt rect.(0) rect.(1) i text.width + and pt_b = convex_pt rect.(0) rect.(1) (i+1) text.width - and pt_e = convex_pt rect.(3) rect.(2) (i+1) text.width - and pt_f = convex_pt rect.(3) rect.(2) i text.width in + and pt_e = convex_pt rect.(3) rect.(2) (i+1) text.width + and pt_f = convex_pt rect.(3) rect.(2) i text.width in - let bot_left = convex_pt pt_a pt_f j text.height - and bot_right = convex_pt pt_b pt_e j text.height - and top_left = convex_pt pt_a pt_f (j+1) text.height - and top_right = convex_pt pt_b pt_e (j+1) text.height in - fill_poly [|bot_left; bot_right; top_right; top_left|] + let bot_left = convex_pt pt_a pt_f j text.height + and bot_right = convex_pt pt_b pt_e j text.height + and top_left = convex_pt pt_a pt_f (j+1) text.height + and top_right = convex_pt pt_b pt_e (j+1) text.height in + fill_poly [|bot_left; bot_right; top_right; top_left|] + end done done ;; -let draw_cube_p (cube : pt_3d array) screen_wd screen_ht fov r g b = +let draw_cube_p (cube : pt_3d array) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) screen_wd screen_ht fov r g b = let adjusted = adjust_to_camera cube in let (draw_faces, draw_cube) = are_faces_behind adjusted in - if draw_cube then begin + if draw_cube && (is_visible_cube cube hash) then begin + (*Printf.printf "drawing cube (%f, %f, %f)" cube.(0).x cube.(0).y cube.(0).z ; + Stdlib.print_endline " ";*) let proj = project adjusted screen_wd screen_ht fov in let graphed = to_graphics proj screen_wd screen_ht in @@ -358,16 +500,16 @@ let draw_cube_p (cube : pt_3d array) screen_wd screen_ht fov r g b = swap order i !idmax; swap draw_faces i !idmax; done; - set_line_width 5; + set_line_width 2; for i = 0 to 5 do if draw_faces.(i) then begin let light = max (0.) (1. -. (distances.(i)) /. 12.5) in - let face_R = int_of_float ((float_of_int r) *. light) + (*let face_R = int_of_float ((float_of_int r) *. light) and face_G = int_of_float ((float_of_int g) *. light) and face_B = int_of_float ((float_of_int b) *. light) in set_color (rgb face_R face_G face_B); - fill_poly order.(i); - (*draw_texture order.(i) stone light ;*) + fill_poly order.(i);*) + draw_texture order.(i) stone light ; set_color black; draw_poly_line order.(i); end @@ -403,7 +545,7 @@ let cube_dist (c : pt_3d array) = } in dist_from_camera mid_pt ;; -let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs screen_wd screen_ht fov render_dist = +let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs hash screen_wd screen_ht fov render_dist = let n = cubes.len in let distances = Array.make n 0. in @@ -426,11 +568,11 @@ let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs screen_w done; for i = 0 to n-1 do if distances.(i) <= (float_of_int render_dist) then begin - draw_cube_p cubes.tab.(i) screen_wd screen_ht fov rs.tab.(i) gs.tab.(i) bs.tab.(i) + draw_cube_p cubes.tab.(i) hash screen_wd screen_ht fov rs.tab.(i) gs.tab.(i) bs.tab.(i) end done ;; -let draw_multiples_cubes_colored_hash (dyna : coloredCube dynamic) screen_wd screen_ht fov = +let draw_multiples_cubes_colored_hash (dyna : coloredCube dynamic) (hash : (int * int * int, coloredCube dynamic) Hashtbl.t) screen_wd screen_ht fov = let n = dyna.len in (*Printf.printf ">> %d <<" n; @@ -457,7 +599,7 @@ let draw_multiples_cubes_colored_hash (dyna : coloredCube dynamic) screen_wd scr for i = 0 to n-1 do (*Printf.printf "drawing (%f, %f, %f)" (dyna.tab.(i).cube.(0).x) (dyna.tab.(i).cube.(0).y) (dyna.tab.(i).cube.(0).z); Stdlib.print_endline " ";*) - draw_cube_p (dyna.tab.(i).cube) screen_wd screen_ht fov (dyna.tab.(i).red) (dyna.tab.(i).green) (dyna.tab.(i).blue) + draw_cube_p (dyna.tab.(i).cube) hash screen_wd screen_ht fov (dyna.tab.(i).red) (dyna.tab.(i).green) (dyna.tab.(i).blue) done ;; let create_cube x0' y0' z0' sz' = @@ -519,24 +661,6 @@ let get1char () = (* -------------------------------------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------------------------------------- *) -type tile = Free | Wall | Crate | Exit | Craxit | Camera ;; - -let width = 15 -and height = 15 -and depth = 15 ;; -(* dimensions *) - -let render_distance = 7 ;; -let chunk_dist = 2 ;; - -let chunk_size = 4 ;; -let chunk_size_f = float_of_int chunk_size ;; - -(* -------------------------------------------------------------------------------------------------------- *) -(* -------------------------------------------------------------------------------------------------------- *) -(* -------------------------------------------------------------------------------------------------------- *) -(* -------------------------------------------------------------------------------------------------------- *) - let laby = Array.make width [|[||]|] ;; for i = 0 to width -1 do laby.(i) <- Array.make_matrix height depth Wall @@ -544,24 +668,6 @@ done ;; let n_walls = ref (width*height*depth) ;; -let ctc_one x = - if x >= 0 then - x / chunk_size - else - x / chunk_size -1 ;; - -let ctcf_one x = - if x >= 0. then - int_of_float (x /. chunk_size_f) - else - int_of_float (x /. chunk_size_f) -1 ;; - -let coords_to_chunk x y z = - (ctc_one x, ctc_one y, ctc_one z) ;; - -let coords_to_chunk_f x y z = - (ctcf_one x, ctcf_one y, ctcf_one z) ;; - let is_collision_cube (cam_coords : pt_3d) (cube : pt_3d array) = cube.(0).x <= (-. cam_coords.x) && cube.(0).y <= (-. cam_coords.y) && @@ -775,7 +881,7 @@ let cheesify (laby : tile array array array) = done done done;; - +(* (* z q s d for movement, p to go up, m to go down, a to rotate left, e to rotate right *) let rec move_cam (cubes : pt_3d array array) b c =(* Printf.printf "[%b]" b; Stdlib.print_endline " " ; *)match c with | 'z' -> @@ -821,7 +927,7 @@ let play laby = fill_poly [|(0, 0); (1500, 0); (1500, 1000); (0, 1000); (0, 0)|]; set_color white; - draw_multiples_cubes_colored cs rs gs bs __width__ __height__ fov render_distance ; + draw_multiples_cubes_colored cs rs gs bs hash __width__ __height__ fov render_distance ; auto_synchronize true; @@ -830,7 +936,7 @@ let play laby = let usr_input = get1char () in move_cam cs.tab true usr_input - done ;; + done ;;*) let rec move_cam_hash (cubes : coloredCube dynamic) b c =(* Printf.printf "[%b]" b; Stdlib.print_endline " " ; *)match c with | 'z' -> @@ -936,7 +1042,7 @@ let rec move_cam_hash_2 hash cx cy cz b c =(* Printf.printf "[%b]" b; Stdlib.pri let manage_unexisting_chunk hash ch_x ch_y ch_z screen_wd screen_ht fov = try - draw_multiples_cubes_colored_hash (Hashtbl.find hash (ch_x, ch_y, ch_z)) screen_wd screen_ht fov + draw_multiples_cubes_colored_hash (Hashtbl.find hash (ch_x, ch_y, ch_z)) hash screen_wd screen_ht fov with | Not_found -> () ;; @@ -952,6 +1058,7 @@ let render_chunks hash camx camy camz ch_distance screen_wd screen_ht fov = done done; let sort_fct elt1 elt2 = + (*- (snd (snd elt2)) + (snd (snd elt1))*) (snd (snd elt2)) - (snd (snd elt1)) in @@ -987,7 +1094,6 @@ let play_dos laby = let (ch_x, ch_y, ch_z) = coords_to_chunk_f (-. camera_xyz.x) (-. camera_xyz.y) camera_xyz.z in - (*draw_multiples_cubes_colored_hash (Hashtbl.find hash (ch_x, ch_y, ch_z)) __width__ __height__ fov ;*) render_chunks hash ch_x ch_y ch_z chunk_dist __width__ __height__ fov ; auto_synchronize true; diff --git a/display.o b/display.o new file mode 100644 index 0000000..c3549b7 Binary files /dev/null and b/display.o differ diff --git a/texture404.txt b/texture404.txt index ec9e1df..fc23af2 100644 --- a/texture404.txt +++ b/texture404.txt @@ -1,3 +1,3 @@ 2 2 -250,0,250 0,0,0 -0,0,0 250,0,250 +250,0,250 2,2,2 +2,2,2 250,0,250