Use t_object (t_element) for lights and cameras
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 6 Dec 2024 11:42:30 +0000 (12:42 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 6 Dec 2024 11:42:30 +0000 (12:42 +0100)
This is because manipulation (translation and rotation) has to be
implemented not just for objects but for lights and cameras also.
It would be better to create a separate union from t_object, but I
cannot think of a way that would not be quite difficult to use.

The typedef t_element can be used for generic element, whereas t_object
should be used for objects (things casting shadow) only.

The vectors for lights and cameras was also changed to vectors of
t_element so that it is easy to pass it as a t_element pointer to change
it in place.

inc/miniRT.h
src/main.c
src/parsing.c
src/scene.c

index 650c6db4a2bbd504abcb6c7006d923cc3fa37734..62d5734e6b4a3ea1044042faa16063b1d669e39c 100644 (file)
@@ -63,6 +63,8 @@ union u_object_union
        t_sphere        sphere;
        t_plane         plane;
        t_cylinder      cylinder;
+       t_light         light;
+       t_camera        camera;
 };
 
 enum e_object_type
@@ -70,6 +72,8 @@ enum e_object_type
        SPHERE,
        PLANE,
        CYLINDER,
+       LIGHT,
+       CAMERA,
 };
 
 typedef struct s_object
@@ -78,6 +82,10 @@ typedef struct s_object
        union u_object_union    object;
 }                                                      t_object;
 
+// The t_object should be used for scene objects only while the t_element can be
+// anything in the scene (except for ambient light).
+typedef t_object t_element;
+
 typedef struct s_ambient_light
 {
        t_color color;
index d6ffc22c340074ca83495dc2e8743dc01d77e3a8..ff870731b479f2d9fcaf3db679dccbfaba7b3329 100644 (file)
@@ -198,8 +198,8 @@ void        set_defaults(t_session *s)
        s->img.width = 1920;
        s->img.height = 1011;
        ft_vec_init(&s->scene.objects, sizeof(t_object));
-       ft_vec_init(&s->scene.lights, sizeof(t_light));
-       ft_vec_init(&s->scene.cameras, sizeof(t_camera));
+       ft_vec_init(&s->scene.lights, sizeof(t_element));
+       ft_vec_init(&s->scene.cameras, sizeof(t_element));
 }
 
 int    main(int argc, char **argv)
index 6c9d1ef454f8c0c7ef7450bb7b2b4e39dd022462..9890a1a0a63f6f682a10ab2ecadac9f3f1a343bb 100644 (file)
@@ -204,70 +204,82 @@ void      set_ambient_light(
 
 int    add_light(const t_parse_tree_node *light_node, t_vec *lights)
 {
-       t_light light;
+       t_element       element;
+       t_light         *light;
 
-       light.brightness = node_to_double(ft_cget_node_child(ft_cget_node_child(light_node, 2), 0));
-       light.position = node_to_vec3(ft_cget_node_child(
+       element.type = LIGHT;
+       light = &element.object.light;
+       light->brightness = node_to_double(ft_cget_node_child(ft_cget_node_child(light_node, 2), 0));
+       light->position = node_to_vec3(ft_cget_node_child(
                                ft_cget_node_child(light_node, 1), 0));
        if (light_node->children.size == 4)
-               light.color = node_to_linear_RGB(ft_cget_node_child(light_node, 3));
+               light->color = node_to_linear_RGB(ft_cget_node_child(light_node, 3));
        else
-               light.color = (t_color){.x = 1, .y = 1, .z = 1};
-       return (ft_vec_append(lights, &light) != success);
+               light->color = (t_color){.x = 1, .y = 1, .z = 1};
+       return (ft_vec_append(lights, &element) != success);
 }
 
 int    add_camera(const t_parse_tree_node *camera_node, t_vec *cameras)
 {
-       t_camera        camera;
+       t_element       element;
+       t_camera        *camera;
 
-       camera.position = node_to_vec3(ft_cget_node_child(
+       element.type = CAMERA;
+       camera = &element.object.camera;
+       camera->position = node_to_vec3(ft_cget_node_child(
                                ft_cget_node_child(camera_node, 1), 0));
-       camera.orientation = node_to_vec3(ft_cget_node_child(camera_node, 2));
-       camera.orientation = vec_normalize(camera.orientation);
-       camera.up_direction = (t_vec3){.x = 0, .y = 0, .z = 1};
-       camera.up_direction = vec_vec_mul(camera.orientation, camera.up_direction);
-       if (vec_norm(camera.up_direction) < 1e-3)
-               camera.up_direction = (t_vec3){.x = 0, .y = 1, .z = 0};
-       camera.up_direction = vec_vec_mul(camera.up_direction, camera.orientation);
-       camera.up_direction = vec_normalize(camera.up_direction);
-       camera.field_of_view = node_to_double(ft_cget_node_child(ft_cget_node_child(camera_node, 3), 0)) * M_PI / 180;
-       return (ft_vec_append(cameras, &camera) != success);
+       camera->orientation = node_to_vec3(ft_cget_node_child(camera_node, 2));
+       camera->orientation = vec_normalize(camera->orientation);
+       camera->up_direction = (t_vec3){.x = 0, .y = 0, .z = 1};
+       camera->up_direction = vec_vec_mul(camera->orientation, camera->up_direction);
+       if (vec_norm(camera->up_direction) < 1e-3)
+               camera->up_direction = (t_vec3){.x = 0, .y = 1, .z = 0};
+       camera->up_direction = vec_vec_mul(camera->up_direction, camera->orientation);
+       camera->up_direction = vec_normalize(camera->up_direction);
+       camera->field_of_view = node_to_double(ft_cget_node_child(ft_cget_node_child(camera_node, 3), 0)) * M_PI / 180;
+       return (ft_vec_append(cameras, &element) != success);
 }
 
 int    add_plane(const t_parse_tree_node *plane_node, t_vec *objects)
 {
        t_object        object;
+       t_plane         *plane;
 
        object.type = PLANE;
-       object.object.plane.point = node_to_vec3(ft_cget_node_child(ft_cget_node_child(plane_node, 1), 0));
-       object.object.plane.normal = node_to_vec3(ft_cget_node_child(plane_node, 2));
-       object.object.plane.color = node_to_linear_RGB(ft_cget_node_child(plane_node, 3));
-       object.object.plane.normal = vec_normalize(object.object.plane.normal);
+       plane = &object.object.plane;
+       plane->point = node_to_vec3(ft_cget_node_child(ft_cget_node_child(plane_node, 1), 0));
+       plane->normal = node_to_vec3(ft_cget_node_child(plane_node, 2));
+       plane->color = node_to_linear_RGB(ft_cget_node_child(plane_node, 3));
+       plane->normal = vec_normalize(plane->normal);
        return (ft_vec_append(objects, &object) != success);
 }
 
 int    add_sphere(const t_parse_tree_node *sphere_node, t_vec *objects)
 {
        t_object        object;
+       t_sphere        *sphere;
 
        object.type = SPHERE;
-       object.object.sphere.center = node_to_vec3(ft_cget_node_child(ft_cget_node_child(sphere_node, 1), 0));
-       object.object.sphere.radius = node_to_double(ft_cget_node_child(ft_cget_node_child(sphere_node, 2), 0)) / 2;
-       object.object.sphere.color = node_to_linear_RGB(ft_cget_node_child(sphere_node, 3));
+       sphere = &object.object.sphere;
+       sphere->center = node_to_vec3(ft_cget_node_child(ft_cget_node_child(sphere_node, 1), 0));
+       sphere->radius = node_to_double(ft_cget_node_child(ft_cget_node_child(sphere_node, 2), 0)) / 2;
+       sphere->color = node_to_linear_RGB(ft_cget_node_child(sphere_node, 3));
        return (ft_vec_append(objects, &object) != success);
 }
 
 int    add_cylinder(const t_parse_tree_node *cylinder_node, t_vec *objects)
 {
        t_object        object;
+       t_cylinder      *cylinder;
 
        object.type = CYLINDER;
-       object.object.cylinder.center = node_to_vec3(ft_cget_node_child(ft_cget_node_child(cylinder_node, 1), 0));
-       object.object.cylinder.rot_axis = node_to_vec3(ft_cget_node_child(cylinder_node, 2));
-       object.object.cylinder.rot_axis = vec_normalize(object.object.cylinder.rot_axis);
-       object.object.cylinder.color = node_to_linear_RGB(ft_cget_node_child(cylinder_node, 5));
-       object.object.cylinder.radius = node_to_double(ft_cget_node_child(ft_cget_node_child(cylinder_node, 3), 0)) / 2;
-       object.object.cylinder.height = node_to_double(ft_cget_node_child(ft_cget_node_child(cylinder_node, 4), 0));
+       cylinder = &object.object.cylinder;
+       cylinder->center = node_to_vec3(ft_cget_node_child(ft_cget_node_child(cylinder_node, 1), 0));
+       cylinder->rot_axis = node_to_vec3(ft_cget_node_child(cylinder_node, 2));
+       cylinder->rot_axis = vec_normalize(cylinder->rot_axis);
+       cylinder->color = node_to_linear_RGB(ft_cget_node_child(cylinder_node, 5));
+       cylinder->radius = node_to_double(ft_cget_node_child(ft_cget_node_child(cylinder_node, 3), 0)) / 2;
+       cylinder->height = node_to_double(ft_cget_node_child(ft_cget_node_child(cylinder_node, 4), 0));
        object.object.sphere.color = node_to_linear_RGB(ft_cget_node_child(cylinder_node, 5));
        return (ft_vec_append(objects, &object) != success);
 }
@@ -340,7 +352,7 @@ int parse_rt_file(const char *filename, t_scene *scene)
                        if (parse_tree && !parse_tree_to_scene(parse_tree, scene))
                                if (scene->cameras.size > 0)
                                {
-                                       scene->current_camera = ft_vec_caccess(&scene->cameras, 0);
+                                       scene->current_camera = &((const t_element *)ft_vec_caccess(&scene->cameras, 0))->object.camera;
                                        res = 0;
                                }
                        ft_parse_tree_free(parse_tree);
index 42571c2e24b2d3ea6786ee45ba9689abfc146f7a..38e2203f24a96d0054f4abef12f37e118c2b0bdd 100644 (file)
@@ -317,7 +317,7 @@ t_color     get_object_color(const t_ray *ray, const t_object *object,
        i = 0;
        while (i < scene->lights.size)
        {
-               light = ft_vec_caccess(&scene->lights, i);
+               light = &((const t_element *)ft_vec_caccess(&scene->lights, i))->object.light;
                result = vec_add(result, get_light_contribution(
                                        ray_point(ray, get_intersection_arg(ray, object)),
                                        object, light, scene));