/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* phong.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: gbrochar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/02/08 15:38:13 by gbrochar #+# #+# */ /* Updated: 2019/02/22 18:12:11 by gbrochar ### ########.fr */ /* */ /* ************************************************************************** */ #include "rtv1.h" t_ray get_light_ray(t_ray r, double t, t_spot spot) { t_ray l_r; l_r.o = vec_add(r.o, vec_mul(r.d, t)); l_r.d = vec_sub(spot.o, l_r.o); normalize(&l_r.d); return (l_r); } double get_intensity(t_env *e, t_ray r, t_spot spot, t_obj_list obj) { t_ray l_r; t_vec normal; double length; double i; l_r = get_light_ray(r, obj.t, spot); length = vec_length(vec_sub(spot.o, l_r.o)); normal = e->func.normal_obj[obj.type](obj.obj, r, obj.t); i = dot_product(l_r.d, normal); if (i > 0) return ((spot.i * i) / (length * length)); return (0); } int intersect_phong(t_env *e, t_ray r, t_spot spot, t_obj_list obj) { t_ray l_r; double length; t_obj_list *ret; l_r = get_light_ray(r, obj.t, spot); length = vec_length(vec_sub(spot.o, l_r.o)); if (!(ret = intersect_ray(e, l_r)) || ret->t > length) return (SUCCESS); return (FAILURE); } double get_specular(t_env *e, t_ray ray, t_spot spot, t_obj_list obj) { t_vec normal; t_vec i; t_vec r; t_vec v; double spec_coef; v = vec_sub(ray.o, vec_add(ray.o, vec_mul(ray.d, obj.t))); i = vec_sub(vec_add(ray.o, vec_mul(ray.d, obj.t)), spot.o); normal = e->func.normal_obj[obj.type](obj.obj, ray, obj.t); normalize(&i); r = get_r_vec(v, normal); normalize(&r); spec_coef = dot_product(r, i); if (spec_coef > M_PI / 2 - e->spec_radius && spec_coef < M_PI / 2 + e->spec_radius && dot_product(normal, vec_mul(i, -1)) > 0) return ((spec_coef + e->spec_radius - M_PI / 2) * e->spec_ratio); return (0); } t_color phong(t_env *e, t_ray r, t_obj_list *obj) { t_spot_list *browser; t_obj_list backup; double i; double specular; i = 0; specular = 0; backup = *obj; browser = e->spots; while (browser) { if (SUCCESS == intersect_phong(e, r, browser->spot, backup)) i += get_intensity(e, r, browser->spot, backup); specular += get_specular(e, r, browser->spot, backup); browser = browser->next; } if (i > 1) i = 1; return (color_cap(color_add( color_mul(obj->c, e->ambient + ((double)1 - e->ambient) * i), color_mul(color(255, 255, 255), specular)))); }