t_bool intersect_cone(t_ray ray, t_cone *obj, float *t) { float a; float b; float c; float tmp; t_vector3 ec; ec = vector_substract(ray.pos, obj->pos); tmp = (1 + obj->radius * obj->radius); a = vector_dotproduct(ray.dir, ray.dir); a = a - (tmp * SQUARE(vector_dotproduct(ray.dir, obj->dir))); b = vector_dotproduct(ray.dir, obj->dir) * vector_dotproduct(ec, obj->dir); b = 2 * (vector_dotproduct(ray.dir, ec) - b * tmp); c = vector_dotproduct(ec, ec); c -= tmp * SQUARE(vector_dotproduct(ec, obj->dir)); if ((*t = compute_len(a, b, c)) > 0.) { ec = vector_substract(create_intersect(ray, *t), obj->pos); if (obj->height == 0 || obj->dir.x > 0) return (TRUE); else if (obj->height > 0. && vector_dotproduct(obj->dir, ec) > 0.) if ((obj->height / cos(atan(obj->radius)) > vector_magnitude(ec))) return (TRUE); } return (FALSE); }
t_vector3 normal_sphere(t_ray ray, t_vector3 inter, t_sphere *obj) { t_vector3 v_normal; (void)ray; v_normal = vector_substract(obj->pos, inter); return (vector_unit(v_normal)); }
static t_color3 getfinalcolor(t_object *arr, t_intersect inter, t_env env) { t_color3 color; t_color3 color_tmp; float dist[2]; t_ray newray; float shade; t_vector3 l; int i; int k; int a; color_tmp = color_new(0, 0, 0); a = 0; if (inter.obj) { i = -1; while(arr[i].type != DEFAULT) { shade = 1.0; if (arr[i].light == TRUE) { l = vector_substract(arr[i].pos, inter.pos); dist[0] = vector_magnitude(l); newray.pos = vector_substract(inter.pos, vector_mul(inter.v_normal, 1e-4f)); newray.dir = vector_unit(l); k = -1; while (++k < 16 && arr[k].type != DEFAULT) if (env.fctinter[arr[k].type](newray, arr + k, &dist[1])) { if (arr[k].light != TRUE && dist[1] <= dist[0]) shade -= 0.3; } color_tmp = vector_sum(color_tmp, iter_light(inter, &arr[i], shade)); ++a; } ++i; } return (vector_div(color_tmp, a)); } return (color_new(17, 25, 37)); }
t_ray create_reflection(t_ray ray, t_intersect inter) { t_ray newray; t_vector3 norm; norm = inter.v_normal; newray.dir = vector_substract(ray.dir, vector_mul(norm, 2.0f * vector_dotproduct(ray.dir, norm))); newray.pos = inter.pos; return (newray); }
/** * Fill in the values for a ray starting in #origin and going through #point. */ void ray_from_points(struct ray *r, vector_t origin, const vector_t point){ r->origin = origin; r->direction = vector_normalize(vector_substract(point, origin)); #ifndef DISABLE_SSE r->invDirection.m = _mm_rcp_ps(r->direction.m); #else for(int i = 0; i < 3; ++i){ r->invDirection.f[i] = 1 / r->direction.f[i]; } #endif }
t_bool intersect_triangle(t_ray ray, t_triangle *obj, float *out) { t_tri tri; tri.e1 = vector_substract(obj->pos2, obj->pos); tri.e2 = vector_substract(obj->pos3, obj->pos); tri.p = vector_product(ray.dir, tri.e2); tri.det = vector_dotproduct(tri.e1, tri.p); if (tri.det > -1e-4f && tri.det < 1e-4f) return (FALSE); tri.det = 1.f / tri.det; tri.t = vector_substract(ray.pos, obj->pos); tri.u = vector_dotproduct(tri.t, tri.p) * tri.det; if (tri.u < 0. || tri.u > 1.) return (FALSE); tri.q = vector_product(tri.t, tri.e1); tri.v = vector_dotproduct(ray.dir, tri.q) * tri.det; if (tri.v < 0. || (tri.u + tri.v) > 1.) return (FALSE); *out = vector_dotproduct(tri.e2, tri.q) * tri.det; if (*out > 1e-4f) return (TRUE); return (FALSE); }
t_bool intersect_sphere(t_ray ray, t_sphere* obj, float *t) { t_vector3 etoc; float radius; float vector_radius; etoc = vector_substract(obj->pos, ray.pos); if ((vector_radius = vector_dotproduct(etoc, ray.dir)) < 0.) return (FALSE); *t = vector_dotproduct(etoc, etoc) - SQUARE(vector_radius); if (*t > (radius = SQUARE(obj->radius))) return (FALSE); *t = sqrt(radius - *t); *t = FT_MIN((vector_radius - *t), (vector_radius + *t)); return (TRUE); }
t_bool intersect_cylinder(t_ray ray, t_cylinder* obj, float *t) { float a; float b; float c; float d; t_vector3 x; a = vector_dotproduct(ray.dir, ray.dir) - SQUARE(vector_dotproduct(ray.dir, obj->dir)); x = vector_substract(ray.pos, obj->pos); b = (vector_dotproduct(ray.dir, x) - vector_dotproduct(ray.dir, obj->dir) * vector_dotproduct(x, obj->dir))* 2; c = vector_dotproduct(x, x) - SQUARE(vector_dotproduct(x, obj->dir)) - (obj->radius * obj->radius); d = b * b - 4 * a * c; if (d > 0.) { if (((-b - sqrt(d)) / (2 * a)) > 0) *t = (-b - sqrt(d)) / (2 * a); else *t = (-b + sqrt(d)) / (2 * a); return (TRUE); } return (FALSE); }