t_vec3f single_tracer(t_params p, t_ray *ray, t_objects *sp) { int i; t_vec3f trans; t_vec3f tmp; t_vec3f light_dir; t_color scolor; i = 0; if (dot_vec3f(&ray->dir, &p.nhit) > 0) p.nhit = scale_vec3f(&p.nhit, -1); scolor = new_uni_color(0); while (i < sp->top) { if (sp->store[i].type == LIGHT) { light_dir = normalize_vec3f(sub_vec3f(&sp->store[i].pos, &p.phit)); if (sp->store[i].nature == AREA_LIGHT) trans = soft_shadows(p, ray, sp, i); else trans = sharp_shadows(p, ray, sp, light_dir); tmp = phong_shading(trans, ray, p, light_dir, sp->store[i].ecolor); scolor = add_vec3f(&scolor, &tmp); } i++; } return (add_vec3f(&scolor, &p.sphere->ecolor)); }
static inline t_color soft_shadows(t_params p, t_ray *r, t_objects *s, int j) { int x; int y; t_vec3f w; t_color trans; t_vec3f tmp; t_vec3f lp; trans = new_uni_color((x = 0)); while (x < 5 && !(y = 0)) { while (y < 5) { tmp = new_vec3f(x, 0, y); lp = add_vec3f(&s->store[j].pos, &tmp); if (sharp_shadows(p, r, s, normalize_vec3f(sub_vec3f(&lp, &p.phit))).x != 0) { w = new_vec3f(1 / 25., 1 / 25., 1 / 25.); trans = add_vec3f(&trans, &w); } y++; } x++; } return (trans); }
t_bool cylinder_intersection(t_ray *r, t_sphere *s, double *t0, double *t1) { t_vec3f diff; t_vec3f dir; t_f64 b; t_f64 c; t_f64 a; t_f64 y0; t_f64 y1; dir = r->dir; diff = sub_vec3f(&r->origin, &s->pos); diff.y = 0; dir.y = 0; a = dot_vec3f(&dir, &dir); b = 2 * (dot_vec3f(&diff, &dir)); c = dot_vec3f(&diff, &diff) - pow(s->radius, 2); if (!solve_quadratic(dot_vec3f(&dir, &dir), b, c, t0, t1)) return (FALSE); y0 = fabs(r->origin.y + r->dir.y * (*t0)); y1 = fabs(r->origin.y + r->dir.y * (*t1)); if (((y0 > (s->pos.y + 4)) && (y1 > (4 + s->pos.y))) || ((y0 < s->pos.y) && (y1 < s->pos.y))) return (FALSE); return (TRUE); }
t_bool plane_intersection(t_ray *r, t_sphere *s, t_f64 *t0, t_f64 *t1) { t_f64 denom; t_vec3f v_n; t_vec3f c; t_vec3f f; v_n = normal_vec3f(&s->pos); denom = dot_vec3f(&v_n, &r->dir); if (denom > 1e-6) { f = sub_vec3f(&s->pos, &r->origin); *t1 = dot_vec3f(&f, &v_n) / denom; *t0 = *t1; c = scale_vec3f(&r->dir, *t0); c = add_vec3f(&c, &r->origin); if (!((c.x > s->pos.x) && (c.x < (s->pos.x + 10)))) return (FALSE); if (!((c.y > s->pos.y) && (c.y < (s->pos.y + 10)))) return (FALSE); if (!((c.x > s->pos.z) && (c.y < (s->pos.y + 10)))) return (FALSE); return (*t0 >= 0); } return (FALSE); }
t_bool sphere_intersection(t_ray *r, t_sphere *s, double *t0, double *t1) { t_vec3f diff; float tca; float thc; float d2; diff = sub_vec3f(&s->pos, &r->origin); tca = dot_vec3f(&diff, &r->dir); if (tca < 0) return (FALSE); d2 = dot_vec3f(&diff, &diff) - tca * tca; if (d2 > (s->radius * s->radius)) return (FALSE); thc = sqrt(s->radius * s->radius - d2); *t0 = tca - thc; *t1 = tca + thc; return (TRUE); }