static float *ft_reflect(t_th *mlx, t_obj *tmp, t_vec *pos, float *tab) { t_obj *tmp2; t_obj *light; t_vec dist; double d; if (mlx->cpt >= mlx->maxref || (light = mlx->light) == NULL) return (tab); if ((tmp2 = ft_ref_init(mlx, tmp, pos)) == NULL || (mlx->cpt++) < 0) return (tab); while (light != NULL) { LAMBERT = 0.14; dist = ft_vectorsub(&light->pos, pos); d = ft_clamp(1.0 / sqrtf(sqrtf(ft_vectordot(&dist, &dist))), 0.0, 1.0); ft_vectornorm(&dist); if (ft_shadow(mlx, tmp2, light, *pos) == 0) LAMBERT += ft_clamp(ft_vectordot(&dist, &mlx->norm), 0.0, 1.0); tab = ft_endlight(tmp2, light, tab, d); tab[0] += (COND1) ? ft_spec(mlx, dist, d, tab[3]) : 0.0; tab[1] += (COND1) ? ft_spec(mlx, dist, d, tab[3]) : 0.0; tab[2] += (COND1) ? ft_spec(mlx, dist, d, tab[3]) : 0.0; light = light->next; } return ((PREF1) ? tab : ft_reflect(mlx, tmp2, pos, tab)); }
float *ft_lambert(t_th *mlx, t_obj *tmp, t_obj *light, float *tab) { t_vec pos; t_vec dist; float d; pos = (t_vec){mlx->cam_pos.x + mlx->t * mlx->ray_dir.x, mlx->cam_pos.y + mlx->t * mlx->ray_dir.y, mlx->cam_pos.z + mlx->t * mlx->ray_dir.z}; mlx->norm = ft_norm(mlx, tmp, pos); while (light != NULL) { LAMBERT = 0.15; dist = ft_vectorsub(&light->pos, &pos); d = ft_clamp((1.0 / sqrtf(sqrtf(ft_vectordot(&dist, &dist)))), 0., 1.); ft_vectornorm(&dist); if (ft_shadow(mlx, tmp, light, pos) == 0) LAMBERT += ft_clamp(ft_vectordot(&dist, &mlx->norm), 0.0, 1.0); tab = ft_endlight(tmp, light, tab, d); tab[0] += (COND2) ? ft_spec(mlx, dist, d, tab[3]) : 0.0; tab[1] += (COND2) ? ft_spec(mlx, dist, d, tab[3]) : 0.0; tab[2] += (COND2) ? ft_spec(mlx, dist, d, tab[3]) : 0.0; light = light->next; } mlx->refpos = (t_vec){mlx->ray_dir.x, mlx->ray_dir.y, mlx->ray_dir.z}; return ((PREF2) ? tab : ft_reflect(mlx, tmp, &pos, tab)); }
float ft_shadow(t_scene *scene, t_3d p_beg, t_3d v_ray, t_obj *obj) { t_ray ray; ray.o = obj; ray.p_beg = p_beg; ray.v_ray = v_ray; ray.obj = scene->object; ray.obj_hit = NULL; ray.ret = 0; ray.intersection = scene->intersection; ft_list_inter(&ray); ft_get_obj_hit(&ray, scene->object); if (ray.obj_hit != NULL && ray.obj_hit->distance < ft_norme(&v_ray)) { if (scene->transparency == 0 || ray.obj_hit->transparency == 0) return (0.); else return ((ray.obj_hit->transparency / 100.) * ft_shadow(scene, ray.obj_hit->p_inter, v_ray, ray.obj_hit)); } return (1); }