vec3 collide_sphere_sphere(struct sphere_hitbox player, struct sphere_hitbox sphere) { if (vec3_distance(player.pos, sphere.pos) >= player.r + sphere.r) { return player.pos; } return add_vec3(sphere.pos, mult_vec3(normalize(sub(player.pos, sphere.pos)), player.r + sphere.r)); }
static void get_lum(double *col, t_scene *s, t_intersect *inter, int m) { t_vec3 l; t_vec3 r; double ln; int i; double is; double id; double dist; double rv; double tmp; t_ray ray; t_intersect shadow; i = -1; if (s->lights[m].light.type == DIRECTIONNAL) { while (++i < 3) { ln = dot_vec3(inter->norm, s->lights[m].light.dir); col[i] = MAX(ln, 0) * s->lights[m].light.color.argb[i] / 255.0 * s->lights[m].light.power; } return ; } l = sub_vec3(s->lights[m].pos, inter->pos); dist = vec3_len(l); l = div_vec3(l, dist); dist -= s->lights[m].light.radius; ln = dot_vec3(l, inter->norm); ln = MAX(ln, 0.0); r = vec3_normalize(sub_vec3(mult_vec3(inter->norm, 2 * ln), l)); is = s->lights[m].light.power / dist; id = s->lights[m].light.radius * is; rv = -dot_vec3(r, inter->dir); rv = MAX(rv, 0.0); ray.pos = add_vec3(inter->pos, mult_vec3(inter->norm, 0.00001)); ray.dir = l; ray.env = NULL; scene_intersect(s, &ray, &shadow); if (shadow.dist < dist - 0.0001) return ; while (++i < 3) { tmp = inter->mat->diffuse * MAX(ln, 0) * id * s->lights[m].light.color.argb[i] / 255.0; col[i] += MAX(tmp, 0); tmp = inter->mat->specular * pow(rv, inter->mat->shininess) * is * s->lights[m].light.color.argb[i] / 255.0; col[i] += MAX(tmp, 0); } }
t_intersect get_intersect_tore(t_obj *obj, t_ray *ray) { t_intersect inter; t_vec3 u; inter.dir = ray->dir; inter.mat = obj->mat; if (!check_box(obj, ray)) return (inter); get_dist_tore(ray, &inter, obj); if (inter.dist < 0.0 || inter.dist == NOT_A_SOLUTION) { inter.dist = -1.0; return (inter); } inter.pos = add_vec3(mult_vec3(ray->dir, inter.dist), ray->pos); u = sub_vec3(inter.pos, obj->pos); u.z = 0.0; u = mult_vec3(vec3_normalize(u), obj->torus.radius_hole); u = add_vec3(u, obj->pos); inter.norm = vec3_normalize(sub_vec3(inter.pos, u)); return (inter); }
t_intersect get_intersect_bohemian_star(t_obj *obj, t_ray *ray) { t_intersect inter; inter.dir = ray->dir; inter.mat = obj->mat; inter.dist = -1.0; get_dist_bohemian_star(ray, &inter, ray->pos); if (inter.dist <= 0.0) return (inter); inter.pos = add_vec3(mult_vec3(ray->dir, inter.dist), ray->pos); calc_normale_bohemian_star(&inter); return (inter); }
t_intersect get_intersect_duplin(t_obj *obj, t_ray *ray) { t_intersect inter; inter.dir = ray->dir; inter.mat = obj->mat; inter.dist = -1.0; get_dist_duplin(ray, &inter, ray->pos); if (inter.dist <= 0.0) return (inter); inter.pos = add_vec3(mult_vec3(ray->dir, inter.dist), ray->pos); inter.norm = vec3(0, 0, 0); return (inter); }
/** Add a sample to a tile using the AO algorithm * @param state global renderer state * @param pixels pixel buffer to add sample to * @param isect_buffer intersection buffer from samples generated by kernel_ao_gen_samples * @param mask_buffer the mask bitmap * @param n_pixels number of pixels in buffer * @param n_samples number of samples already in the buffer */ void kernel_ao_add_sample(state_t state, vec3* pixels, hit_t* isect_buffer, int* mask_buffer, sample_t* sample_buffer, int n_samples, int i) { //compute the sample float l; if(mask_buffer[i] == 1) { l = 0.f; } else if(isect_buffer[i].t == -1) { l = 1.f; } else { l = minf(1.f,isect_buffer[i].t/state.ao_params.length); } vec3 p = make_vec3(l,l,l); if(isnan(p.x) || isnan(p.y) || isnan(p.z)) { p = make_vec3(0.f,1.f,0.f); } pixels[i] = div_vec3_scalar(add_vec3(mul_vec3_scalar(pixels[i], n_samples+(1-sample_buffer[i].weight)), mul_vec3_scalar(p, sample_buffer[i].weight)),(n_samples+1)); }