# error "This platform does not support NAN macro!"
#endif // NAN
-static const t_color DEFAULT_COLOR = {0, 0, 0};
+static const t_color DEFAULT_COLOR = {0, 0, 0};
+
+static const double SELF_OBSTRUCTION_MULTIPLIER = 1e-8;
static int is_bounded(const t_object *object)
{
return (0 > vec_scalar_mul(ray->direction, vec_diff(point, ray->start)));
}
-int intersects_circumsphere(const t_ray *ray, const t_object *object)
+t_sphere get_circumsphere(const t_object *object)
{
- double radius;
- t_vec3 center;
- double distance;
+ t_sphere circumsphere;
if (object->type == SPHERE)
{
- radius = object->object.sphere.radius;
- center = object->object.sphere.center;
+ circumsphere.radius = object->object.sphere.radius;
+ circumsphere.center = object->object.sphere.center;
}
else if (object->type == CYLINDER)
{
- radius = get_cylinder_circumsphere_radius(&object->object.cylinder);
- center = object->object.cylinder.center;
+ circumsphere.radius = get_cylinder_circumsphere_radius(&object->object.cylinder);
+ circumsphere.center = object->object.cylinder.center;
+ }
+ else if(object->type == PLANE)
+ {
+ circumsphere.radius = INFINITY;
+ circumsphere.center = object->object.plane.point;
}
- if (is_behind_ray(ray, center))
+ return (circumsphere);
+}
+
+int intersects_circumsphere(const t_ray *ray, const t_object *object)
+{
+ t_sphere circumsphere;
+ double distance;
+
+ circumsphere = get_circumsphere(object);
+ if (is_behind_ray(ray, circumsphere.center))
return (0);
- distance = dist_point_from_line(ray, center);
- return (distance < radius);
+ distance = dist_point_from_line(ray, circumsphere.center);
+ return (distance < circumsphere.radius);
}
double get_intersection_arg_plane(const t_ray *ray, const t_plane *plane)
}
const t_object *find_nearest_object(const t_ray *ray, const t_vec *objects,
- const t_object *ignored)
+ const t_object *ignored, double ignored_dist)
{
size_t i;
const t_object *object_found;
while (i < objects->size)
{
object = ft_vec_caccess(objects, i++);
- if (object == ignored)
- continue ;
distance = get_intersection_arg(ray, object);
+ if (object == ignored && distance > 0 && distance < ignored_dist)
+ continue ;
if (0 < distance && distance < distance_found)
{
distance_found = distance;
return ((t_vec3){.x = 0, .y = 0, .z = 0});
}
+double get_self_obstruction_limit(const t_object *object)
+{
+ return (get_circumsphere(object).radius * SELF_OBSTRUCTION_MULTIPLIER);
+}
+
t_color get_light_contribution(t_ray normal, const t_object *object, const t_light *light, const t_scene *scene)
{
t_ray new_ray;
new_ray.direction = vec_diff(light->position, new_ray.start);
distance = vec_norm(new_ray.direction);
new_ray.direction = vec_real_mul(new_ray.direction, 1 / distance);
- obstruction = find_nearest_object(&new_ray, &scene->objects, object);
+ obstruction = find_nearest_object(&new_ray, &scene->objects, object, get_self_obstruction_limit(object));
angle_multiplier = vec_scalar_mul(normal.direction, new_ray.direction)
/ (vec_norm(normal.direction) * vec_norm(new_ray.direction));
if (object->type == PLANE)
{
const t_object *object_found;
- object_found = find_nearest_object(ray, &scene->objects, NULL);
+ object_found = find_nearest_object(ray, &scene->objects, NULL, 0);
if (object_found)
return (get_object_color(ray, object_found, scene));
else