cone_surfcae.c
1 /* ************************************************************************** */ 2 /* */ 3 /* ::: :::::::: */ 4 /* cone_surfcae.c :+: :+: :+: */ 5 /* +:+ +:+ +:+ */ 6 /* By: salee2 <salee2@student.42seoul.kr> +#+ +:+ +#+ */ 7 /* +#+#+#+#+#+ +#+ */ 8 /* Created: 2023/05/24 20:21:37 by salee2 #+# #+# */ 9 /* Updated: 2023/05/24 20:21:39 by salee2 ### ########.fr */ 10 /* */ 11 /* ************************************************************************** */ 12 13 #include "include/minirt.h" 14 15 static t_coefficient get_coefficient(const t_cone *cone, t_ray *ray, \ 16 t_vec3 h_hat) 17 { 18 t_coefficient coef; 19 const t_vec3 w = sub(ray->origin, cone->tip_center); 20 const double m = cone->radius_sq / mag_sq(cone->h_dir); 21 const double v_dot_h = dot(ray->dir, h_hat); 22 const double w_dot_h = dot(w, h_hat); 23 24 coef.a = mag_sq(ray->dir) - (m + 1) * v_dot_h * v_dot_h; 25 coef.b = dot(ray->dir, w) - (m + 1) * v_dot_h * w_dot_h; 26 coef.c = mag_sq(w) - (m + 1) * w_dot_h * w_dot_h; 27 return (coef); 28 } 29 30 static double ray_surface_intersection(const t_cone *cone, t_ray *ray, \ 31 t_hit *hit, t_vec3 h_hat) 32 { 33 const t_coefficient coef = get_coefficient(cone, ray, h_hat); 34 const double d = coef.b * coef.b - coef.a * coef.c; 35 double root; 36 double height; 37 t_vec3 hp; 38 39 if (d < 0.0) 40 return (INVALID_ROOT); 41 root = (-coef.b - sqrt(d)) / coef.a; 42 if (root < hit->t_min || hit->t_max < root) 43 { 44 root = (-coef.b + sqrt(d)) / coef.a; 45 if (root < hit->t_min || hit->t_max < root) 46 return (INVALID_ROOT); 47 } 48 hp = sub(ray_at(root, ray), cone->tip_center); 49 height = dot(hp, h_hat); 50 if (height < 0 || cone->height < height) 51 return (INVALID_ROOT); 52 return (root); 53 } 54 55 t_vec3 interface_normal(const t_cone *cone, t_point3 point) 56 { 57 double cos_theta; 58 double hypotenuse; 59 t_vec3 normal; 60 const t_vec3 hp = sub(point, cone->tip_center); 61 62 cos_theta = mag(cone->h_dir) / sqrt(cone->radius_sq + mag_sq(cone->h_dir)); 63 hypotenuse = mag(hp) / cos_theta; 64 normal = sub(point, add(cone->tip_center, \ 65 scl_mul(hypotenuse, cone->h_normal))); 66 return (normal); 67 } 68 69 t_bool intersect_cone_surface(t_object *object, t_ray *ray, t_hit *hit) 70 { 71 const t_cone *cone = object->element; 72 const double root = ray_surface_intersection(cone, ray, hit, \ 73 cone->h_normal); 74 75 if (root == INVALID_ROOT) 76 return (FALSE); 77 hit->t = root; 78 hit->t_max = hit->t; 79 hit->point = ray_at(hit->t, ray); 80 hit->normal = interface_normal(cone, hit->point); 81 if (dot(ray->dir, hit->normal) > 0) 82 hit->normal = scl_mul(-1, hit->normal); 83 hit->albedo = object->albedo; 84 return (TRUE); 85 }