diff --git a/a.out b/a.out index 3a5581b..05debd3 100755 Binary files a/a.out and b/a.out differ diff --git a/display.cmi b/display.cmi index b86063e..9eb22df 100644 Binary files a/display.cmi and b/display.cmi differ diff --git a/display.cmo b/display.cmo index ac33f45..c3f4913 100644 Binary files a/display.cmo and b/display.cmo differ diff --git a/display.ml b/display.ml index f28baf8..f36cd8c 100644 --- a/display.ml +++ b/display.ml @@ -16,6 +16,11 @@ ocamlfind ocamlc -linkpkg -package unix -linkpkg -package graphics -thread -pack type 'a dynamic = {mutable tab : 'a array ; mutable len : int ; mutable memlen : int} ;; +type pt_3d = {mutable x : float ; mutable y : float ; mutable z : float} ;; +type pt_2d = {mutable x : float ; mutable y : float} ;; + +type coloredCube = {cube : pt_3d array ; red : int ; green : int ; blue : int} ;; + let dyn_create i = {tab = Array.make 10 i ; len = 0 ; memlen = 10} ;; @@ -63,9 +68,6 @@ let absf x = if x >= 0. then x else -.(x) ;; (* ------------------------------------------------------------- *) -type pt_3d = {mutable x : float ; mutable y : float ; mutable z : float} ;; -type pt_2d = {mutable x : float ; mutable y : float} ;; - (* ------------------------------------------------------------- *) let camera_xyz = {x = 0.0 ; y = 0.0 ; z = 0.0} ;; let camera_angle_x = ref 0 ;; @@ -524,6 +526,36 @@ let draw_multiples_cubes_colored (cubes : pt_3d array dynamic) rs gs bs screen_w end done ;; +let draw_multiples_cubes_colored_hash (dyna : coloredCube dynamic) screen_wd screen_ht fov = + let n = dyna.len in + + (*Printf.printf ">> %d <<" n; + Stdlib.print_endline " ";*) + + let distances = Array.make n 0. in + + for i = 0 to n-1 do + distances.(i) <- cube_dist dyna.tab.(i).cube; + done ; + + for i = 0 to n-1 do + let cur_max = ref distances.(i) in + let idmax = ref i in + for j = i to n-1 do + if distances.(j) > !cur_max then begin + cur_max := distances.(j); + idmax := j; + end + done; + swap distances i !idmax; + swap dyna.tab i !idmax; + done; + for i = 0 to n-1 do + (*Printf.printf "(%d, %d, %d)" (dyna.tab.(i).red) (dyna.tab.(i).green) (dyna.tab.(i).blue); + 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) + done ;; + let create_cube x0' y0' z0' sz' = let x0 = float_of_int x0' and y0 = float_of_int y0' @@ -591,6 +623,10 @@ and depth = 15 ;; (* dimensions *) let render_distance = 7 ;; +let chunk_dist = 1 ;; + +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 @@ -599,17 +635,25 @@ 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) = - (*Printf.printf "testing cube [%b, %b, %b, %b, %b, %b] :" - (cube.(0).x >= (-. cam_coords.x)) - (cube.(0).y >= (-. cam_coords.x)) - (cube.(0).z >= cam_coords.z) - (cube.(6).x <= (-. cam_coords.x)) - (cube.(6).y <= (-. cam_coords.y)) - (cube.(6).z <= cam_coords.z) ; - Printf.printf "\n||{%f, %f, %f}, {%f, %f, %f}||\n" cube.(0).x cube.(0).y cube.(0).z cube.(6).x cube.(6).y cube.(6).z; - Printf.printf "with coords (%f, %f, %f)\n" (-. cam_coords.x) (-. cam_coords.y) cam_coords.z; - Stdlib.print_endline " ";*) cube.(0).x <= (-. cam_coords.x) && cube.(0).y <= (-. cam_coords.y) && cube.(0).z <= cam_coords.z && @@ -633,6 +677,22 @@ let is_collision (cam_coords : pt_3d) (cubes : pt_3d array array) = done; !res ;; +let is_collision_hash (cam_coords : pt_3d) (cubes : coloredCube dynamic) = + let res = ref false in + let n = cubes.len in + + let distances = Array.make n 0. in + + for i = 0 to n-1 do + distances.(i) <- cube_dist cubes.tab.(i).cube; + done ; + + for i = 0 to n-1 do + if not !res && distances.(i) < 2. then + res := is_collision_cube cam_coords cubes.tab.(i).cube + done; + !res ;; + let convert_laby laby = let width = Array.length laby and height = Array.length laby.(0) @@ -659,6 +719,45 @@ let convert_laby laby = done; (cubes, reds, greens, blues) ;; +let chunkify laby sz = + let width = Array.length laby + and height = Array.length laby.(0) + and depth = Array.length laby.(0).(0) in + + let cubes = Hashtbl.create 300 in + + let add_to_table w h d cw ch cd = + (*Printf.printf "(%d, %d, %d) (%d, %d, %d)\n" w h d cw ch cd;*) + match Hashtbl.find_opt cubes (cw, ch, cd) with + | None -> begin + let dyna = dyn_create {cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = 220; green = 220; blue = 220} in + Hashtbl.add cubes (cw, ch, cd) dyna + end + | Some dyna -> begin + Hashtbl.remove cubes (cw, ch, cd); + dyn_append dyna {cube = create_cube (w*sz) (h*sz) (d*sz) sz; red = 220; green = 220; blue = 220}; + Hashtbl.add cubes (cw, ch, cd) dyna + end + in + + for w = 0 to width-1 do + for h = 0 to height-1 do + for d = 0 to depth-1 do + if laby.(w).(h).(d) <> Free then begin + for i = -chunk_dist to chunk_dist do + for j = -chunk_dist to chunk_dist do + for k = -chunk_dist to chunk_dist do + add_to_table w h d (w/chunk_size + i) (h/chunk_size + j) (d/chunk_size + k) + done + done + done + end(*; + Stdlib.print_endline " ";*) + done + done + done; + cubes ;; + let cheesify (laby : tile array array array) = let width = Array.length laby and height = Array.length laby.(0) @@ -680,14 +779,6 @@ let cheesify (laby : tile array array array) = done done;; -let print_cubes (cubes : pt_3d array array) = - for i = 0 to !n_walls -1 do - for j = 0 to 7 do - Printf.printf " {%f, %f, %f}\n" cubes.(i).(j).x cubes.(i).(j).y cubes.(i).(j).z - done; - Stdlib.print_endline " " - 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' -> @@ -744,4 +835,68 @@ let play laby = move_cam cs.tab true usr_input done ;; -play laby ;; \ No newline at end of file +let rec move_cam_hash (cubes : coloredCube dynamic) b c =(* Printf.printf "[%b]" b; Stdlib.print_endline " " ; *)match c with + | 'z' -> + camera_xyz.z <- camera_xyz.z +. Float.cos ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); + camera_xyz.x <- camera_xyz.x +. Float.sin ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); + if b && (is_collision_hash camera_xyz cubes) then move_cam_hash cubes false 's' + | 'q' -> + camera_xyz.z <- camera_xyz.z +. Float.cos (((float_of_int !camera_angle_y) +. 90.) *. 3.1415926535 /. 180.); + camera_xyz.x <- camera_xyz.x +. Float.sin (((float_of_int !camera_angle_y) +. 90.) *. 3.1415926535 /. 180.); + if b && (is_collision_hash camera_xyz cubes) then move_cam_hash cubes false 'q' + | 's' -> + camera_xyz.z <- camera_xyz.z -. Float.cos ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); + camera_xyz.x <- camera_xyz.x -. Float.sin ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); + if b && (is_collision_hash camera_xyz cubes) then move_cam_hash cubes false 'z' + | 'd' -> + camera_xyz.z <- camera_xyz.z +. Float.cos (((float_of_int !camera_angle_y) -. 90.) *. 3.1415926535 /. 180.); + camera_xyz.x <- camera_xyz.x +. Float.sin (((float_of_int !camera_angle_y) -. 90.) *. 3.1415926535 /. 180.); + if b && (is_collision_hash camera_xyz cubes) then move_cam_hash cubes false 'q' + | 'p' -> + camera_xyz.y <- camera_xyz.y -. 1.; + if b && (is_collision_hash camera_xyz cubes) then move_cam_hash cubes false 'm' + | 'm' -> + camera_xyz.y <- camera_xyz.y +. 1.; + if b && (is_collision_hash camera_xyz cubes) then move_cam_hash cubes false 'p' + | 'a' -> camera_angle_y := !camera_angle_y + 30 + | 'e' -> camera_angle_y := !camera_angle_y - 30 + | _ -> () ;; + +let play_dos laby = + try + cheesify laby; + let hash = chunkify laby 1 in + + camera_xyz.z <- -. (1.5) ; + camera_xyz.x <- -. (float_of_int width) /. 2. ; + camera_xyz.y <- -. (float_of_int height) /. 2. ; + + (*print_cubes cs ;*) + + while true do + ignore (Sys.command "clear") ; + + auto_synchronize false; + open_graph " 1500x1000"; + set_color black; + fill_poly [|(0, 0); (1500, 0); (1500, 1000); (0, 1000); (0, 0)|]; + set_color white; + + 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 ; + + auto_synchronize true; + + Printf.printf "current pos : (%f, %f, %f)\n" (-. camera_xyz.x) (-. camera_xyz.y) camera_xyz.z; + Printf.printf "current chunk : (%d, %d, %d)" ch_x ch_y ch_z; + Stdlib.print_endline " "; + + let usr_input = get1char () in + move_cam_hash (Hashtbl.find hash (ch_x, ch_y, ch_z)) true usr_input + done ; + () + with + | Not_found -> Stdlib.print_endline "Looks like you tried to load an uninitialized chunk..." ;; + +play_dos laby ;; \ No newline at end of file