mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-06 03:05:30 -05:00
Use option to signal when no object is hit
This commit is contained in:
parent
1380a1a07f
commit
bf8996c953
1 changed files with 38 additions and 36 deletions
|
|
@ -9,10 +9,12 @@ type sphere = { center: Vec3.vec3;
|
|||
type hitable = Sphere of sphere
|
||||
| World of hitable list
|
||||
|
||||
type hit = { t : float;
|
||||
p: Vec3.vec3;
|
||||
normal: Vec3.vec3;
|
||||
hit: bool }
|
||||
type hit_rec = { t : float;
|
||||
p: Vec3.vec3;
|
||||
normal: Vec3.vec3; }
|
||||
|
||||
type hit = hit_rec option
|
||||
|
||||
|
||||
let hit_sphere sphere ray (tmin, tmax) =
|
||||
let oc = sub ray.origin sphere.center in
|
||||
|
|
@ -21,11 +23,6 @@ let hit_sphere sphere ray (tmin, tmax) =
|
|||
let c = (dot oc oc) -. (sphere.radius *. sphere.radius) in
|
||||
let discriminant = b*.b -. a*.c in
|
||||
|
||||
let no_hit = { t = -1.0;
|
||||
p = Vec3.of_floats (Float.infinity, Float.infinity, Float.infinity);
|
||||
normal = Vec3.of_floats (0., 0., 0.);
|
||||
hit = false } in
|
||||
|
||||
if (discriminant > 0.0)
|
||||
then
|
||||
let t = (-.b +. (sqrt discriminant)) /. a in
|
||||
|
|
@ -33,34 +30,33 @@ let hit_sphere sphere ray (tmin, tmax) =
|
|||
if (t < tmax && t > tmin)
|
||||
then
|
||||
let p = Ray.point_at_parameter ray t in
|
||||
{ t = t;
|
||||
p = p;
|
||||
normal = unit_vector (sub p sphere.center);
|
||||
hit = true }
|
||||
Some { t = t;
|
||||
p = p;
|
||||
normal = unit_vector (sub p sphere.center); }
|
||||
else
|
||||
let t = (-.b -. (sqrt discriminant)) /. a in
|
||||
if (t < tmax && t > tmin)
|
||||
then
|
||||
let p = Ray.point_at_parameter ray t in
|
||||
{ t = t;
|
||||
p = p;
|
||||
normal = unit_vector (sub p sphere.center);
|
||||
hit = true }
|
||||
else no_hit
|
||||
else no_hit
|
||||
Some { t = t;
|
||||
p = p;
|
||||
normal = unit_vector (sub p sphere.center); }
|
||||
else None
|
||||
else None
|
||||
|
||||
let rec hit_world world ray (tmin, tmax) =
|
||||
let init_rec = { t = tmax;
|
||||
p = Vec3.of_floats (-1., -1., -1.);
|
||||
normal = Vec3.of_floats (-1., -1., -1.);
|
||||
hit = false; } in
|
||||
List.fold world
|
||||
~init: init_rec
|
||||
~f: (fun acc h ->
|
||||
let hit_rec = (hit h ray (tmin, acc.t)) in
|
||||
if (hit_rec.hit)
|
||||
then hit_rec
|
||||
else acc)
|
||||
~init: None
|
||||
~f: (fun acc h ->
|
||||
let prev_rec = match acc with
|
||||
None -> { t = tmax;
|
||||
p = Vec3.of_floats (-1., -1., -1.);
|
||||
normal = Vec3.of_floats (-1., -1., -1.); }
|
||||
| Some r -> r in
|
||||
match (hit h ray (tmin, prev_rec.t)) with
|
||||
Some r -> Some r
|
||||
| None -> acc)
|
||||
|
||||
and hit h ray (tmin, tmax) =
|
||||
match h with
|
||||
Sphere s -> hit_sphere s ray (tmin, tmax)
|
||||
|
|
@ -72,13 +68,19 @@ let get_color ray =
|
|||
radius = 0.5 } in
|
||||
let sphere2 = Sphere {center = Vec3.of_floats (0., -100.5, -1.);
|
||||
radius = 100.0 } in
|
||||
let world = World [sphere1; sphere2] in
|
||||
let hit_result = (hit world ray (0., Float.infinity)) in
|
||||
let t = hit_result.t in
|
||||
if (hit_result.hit && (t > 0.0))
|
||||
then let n = hit_result.normal in
|
||||
mul 0.5 (Vec3.of_floats (n.x +. 1., n.y +. 1., n.z +. 1.))
|
||||
else let unit_direction = unit_vector ray.dir in
|
||||
let world = World [sphere2; sphere1] in
|
||||
|
||||
match (hit world ray (0., Float.infinity)) with
|
||||
Some hit_result ->
|
||||
let t = hit_result.t in
|
||||
if (t > 0.0)
|
||||
then let n = hit_result.normal in
|
||||
mul 0.5 (Vec3.of_floats (n.x +. 1., n.y +. 1., n.z +. 1.))
|
||||
else let unit_direction = unit_vector ray.dir in
|
||||
let t = 0.5 *. (unit_direction.y +. 1.0) in
|
||||
add (mul (1.0 -. t) {x= 1.0; y=1.0; z= 1.0}) (mul t {x= 0.5; y= 0.7; z= 1.0})
|
||||
| None ->
|
||||
let unit_direction = unit_vector ray.dir in
|
||||
let t = 0.5 *. (unit_direction.y +. 1.0) in
|
||||
add (mul (1.0 -. t) {x= 1.0; y=1.0; z= 1.0}) (mul t {x= 0.5; y= 0.7; z= 1.0})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue