104 lines
3.0 KiB
C
104 lines
3.0 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* phong.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: gbrochar <marvin@42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* 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))));
|
|
}
|