static inline t_color recursive_tracer(t_params p, t_ray *ray, t_objects *sp) { t_f64 inside; t_f64 facingratio; t_f64 fresneleffect; t_vec3f refldir; t_vec3f refdir; t_color reflection; t_color refrac; t_ray rx; if ((inside = dot_vec3f(&ray->dir, &p.nhit) > 0)) p.nhit = scale_vec3f(&p.nhit, -1); facingratio = -dot_vec3f(&ray->dir, &p.nhit); fresneleffect = mix(pow(1 - facingratio, 3), 1, .1); refldir = get_reflection_dir(&p.nhit, &ray->dir); rx = reflected_ray(ray, &refldir, &p.nhit, &p.phit); reflection = trace_ray(&rx, sp, ++p.depth); if (p.sphere->transparency > 0) { refdir = compute_ideal_refractions(ray, inside, p); rx = refracted_ray(ray, &refdir, &p.nhit, &p.phit); refrac = trace_ray(&rx, sp, ++p.depth); } return (defualt_glossy_shading(&reflection, &refrac, fresneleffect, p.sphere)); }
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_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)); }
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); }
t_vec3f normal_vec3f(t_vec3f *vec) { t_vec3f norm; float len; float inv_norm; len = dot_vec3f(vec, vec); if (len > 0) { inv_norm = 1.0f / sqrtf(len); norm.x = vec->x * inv_norm; norm.y = vec->y * inv_norm; norm.z = vec->z * inv_norm; return (norm); } return (*vec); }
double length_vec3f(t_vec3f *vec) { return (sqrtf(dot_vec3f(vec, vec))); }