typedef struct s_sphere
{
+ t_color color;
t_vec3 center;
double radius;
- t_color color;
} t_sphere;
typedef struct s_plane
{
+ t_color color;
t_vec3 point;
t_vec3 normal;
- t_color color;
} t_plane;
typedef struct s_cylinder
{
+ t_color color;
t_vec3 center;
t_vec3 rot_axis;
double radius;
typedef struct s_light
{
- t_vec3 position;
- double brightness;
t_color color;
+ double brightness;
+ t_vec3 position;
} t_light;
typedef struct s_camera
typedef struct s_ambient_light
{
- double brightness;
t_color color;
+ double brightness;
} t_ambient_light;
typedef struct s_scene
} t_session;
t_ray get_camera_ray(int x, int y, const t_session *session);
-t_color get_object_color(const t_ray *ray, const t_object *object);
double get_intersection_arg_cylinder(const t_ray *ray,
const t_cylinder *cylinder);
t_color trace_ray(const t_ray *ray, const t_scene *scene);
return (v.x * u.x + v.y * u.y + v.z * u.z);
}
+t_vec3 vec_elwise_mul(t_vec3 v, t_vec3 u)
+{
+ t_vec3 res;
+
+ res.x = v.x * u.x;
+ res.y = v.y * u.y;
+ res.z = v.z * u.z;
+ return (res);
+}
+
double vec_norm(t_vec3 vec)
{
return (sqrt(vec_scalar_mul(vec, vec)));
return (get_intersection_arg_bounded(ray, object));
}
-t_color trace_ray(const t_ray *ray, const t_scene *scene)
+const t_object *find_nearest_object(const t_ray *ray, const t_vec *objects)
{
size_t i;
const t_object *object_found;
object_found = NULL;
distance_found = INFINITY;
i = 0;
- while (i < scene->objects.size)
+ while (i < objects->size)
{
- distance = get_intersection_arg(ray, ft_vec_caccess(&scene->objects, i));
+ distance = get_intersection_arg(ray, ft_vec_caccess(objects, i));
if (0 < distance && distance < distance_found)
{
distance_found = distance;
- object_found = ft_vec_caccess(&scene->objects, i);
+ object_found = ft_vec_caccess(objects, i);
}
++i;
}
+ return (object_found);
+}
+
+t_color get_ambient_color(const t_object *object, const t_ambient_light *amb)
+{
+ return (vec_real_mul(
+ vec_elwise_mul(amb->color, object->object.plane.color),
+ amb->brightness));
+}
+
+t_color get_object_color(const t_ray *ray, const t_object *object,
+ const t_scene *scene)
+{
+ t_color result;
+ const t_light *light;
+ size_t i;
+ t_ray new_ray;
+ const t_object *obstruction;
+
+ i = 0;
+ while (i < scene->lights.size)
+ {
+ light = ft_vec_caccess(&scene->lights, i);
+ new_ray.start = vec_add(ray->start, vec_real_mul(ray->direction,
+ get_intersection_arg(ray, object)));
+ new_ray.direction = vec_diff(light->position, new_ray.start);
+ obstruction = find_nearest_object(&new_ray, &scene->objects);
+ if (!obstruction || 1 < get_intersection_arg(&new_ray, obstruction)
+ || get_intersection_arg(&new_ray, obstruction) < 0)
+ result = vec_add(result, vec_real_mul(vec_elwise_mul(light->color,
+ object->object.plane.color), light->brightness));
+ ++i;
+ }
+ result = vec_add(result, get_ambient_color(object, &scene->ambient_light));
+ return (result);
+}
+
+t_color trace_ray(const t_ray *ray, const t_scene *scene)
+{
+ const t_object *object_found;
+
+ object_found = find_nearest_object(ray, &scene->objects);
if (object_found)
- return (get_object_color(ray, object_found));
+ return (get_object_color(ray, object_found, scene));
else
return (DEFAULT_COLOR);
}