Implement manipulation (transformations)
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 6 Dec 2024 12:13:36 +0000 (13:13 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 6 Dec 2024 12:16:39 +0000 (13:16 +0100)
As I have no mechanism for selecting an element so far, the testing
element is the current camera.
I am a little suspicious of the rotation orientation, but it is easily
corrected with sign in the key handling. I may think about it later.

Makefile
inc/miniRT.h
src/main.c
src/manipulation.c [new file with mode: 0644]

index eeff37207a44a6a13aa585ef224f0923e7bbe098..ea2178a98841fb6471c1a325f0959ee0d873e73d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,7 @@ SRCDIR := src
 
 SOURCES :=     main.c                          \
                        scene.c                         \
+                       manipulation.c          \
                        parsing.c                       \
                        vec3.c                          \
 
index 62d5734e6b4a3ea1044042faa16063b1d669e39c..fd75439939d26a594bbb4d2a78dc64d45c45c518 100644 (file)
@@ -130,4 +130,7 @@ t_color     trace_ray(const t_ray *ray, const t_scene *scene);
 t_color        color_sRGB_to_lin(t_color_sRGB sRGB);
 int            parse_args(int argc, char **argv, t_session *s);
 
+int            rotate(t_element *element, t_vec3 rot_axis, double angle);
+void   translate(t_element *element, t_vec3 direction, double distance);
+
 #endif // MINIRT_H
index ff870731b479f2d9fcaf3db679dccbfaba7b3329..83c4da26efd0697a8f05cebd2f6fe57d7ab54586 100644 (file)
@@ -136,13 +136,38 @@ int       close_win(t_session *s)
 
 int    handle_key_press(int keycode, t_session *s)
 {
+       t_element       *element;
+       t_camera        *camera;
+
+       element = ft_vec_access(&s->scene.cameras, 0);
+       camera = &element->object.camera;
        if (keycode == XK_Escape)
                close_win(s);
+       else if (keycode == XK_Up)
+               translate(element, camera->orientation, 0.1);
+       else if (keycode == XK_Down)
+               translate(element, camera->orientation, -0.1);
+       else if (keycode == XK_Left)
+               translate(element, vec_vec_mul(camera->orientation, camera->up_direction), 0.1);
+       else if (keycode == XK_Right)
+               translate(element, vec_vec_mul(camera->orientation, camera->up_direction), -0.1);
+       else if (keycode == XK_space)
+               translate(element, camera->up_direction, 0.1);
+       else if (keycode == XK_Shift_L)
+               translate(element, camera->up_direction, -0.1);
+       else if (keycode == XK_w)
+               rotate(element, vec_vec_mul(camera->orientation, camera->up_direction), -0.1);
+       else if (keycode == XK_s)
+               rotate(element, vec_vec_mul(camera->orientation, camera->up_direction), 0.1);
+       else if (keycode == XK_a)
+               rotate(element, camera->up_direction, -0.1);
+       else if (keycode == XK_d)
+               rotate(element, camera->up_direction, 0.1);
+       else if (keycode == XK_e)
+               rotate(element, camera->orientation, -0.1);
+       else if (keycode == XK_q)
+               rotate(element, camera->orientation, 0.1);
        /*
-       else if (keycode == XK_Up || keycode == XK_w)
-       else if (keycode == XK_Left || keycode == XK_a)
-       else if (keycode == XK_Down || keycode == XK_s)
-       else if (keycode == XK_Right || keycode == XK_d)
        else if (keycode == XK_KP_Add)
        else if (keycode == XK_KP_Subtract)
        */
diff --git a/src/manipulation.c b/src/manipulation.c
new file mode 100644 (file)
index 0000000..e4bef9a
--- /dev/null
@@ -0,0 +1,67 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   manipulation.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/12/06 09:48:43 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/12/06 12:49:57 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "vec3.h"
+#include "miniRT.h"
+#include "libft.h"
+#include <math.h>
+
+static void    rotate_vec(t_vec3 *vec, t_vec3 rot_axis, double angle)
+{
+       *vec = vec_add(*vec, vec_add(
+                               vec_real_mul(
+                                       vec_vec_mul(rot_axis, *vec),
+                                       sin(angle)),
+                               vec_real_mul(
+                                       vec_vec_mul(rot_axis,
+                                               vec_vec_mul(rot_axis, *vec)),
+                                       1 - cos(angle))));
+       return ;
+}
+
+int    rotate(t_element *element, t_vec3 rot_axis, double angle)
+{
+       if (element->type == PLANE)
+               rotate_vec(&element->object.plane.normal, rot_axis, angle);
+       else if (element->type == CYLINDER)
+               rotate_vec(&element->object.cylinder.rot_axis, rot_axis, angle);
+       else if (element->type == CAMERA)
+       {
+               rotate_vec(&element->object.camera.orientation, rot_axis, angle);
+               rotate_vec(&element->object.camera.up_direction, rot_axis, angle);
+       }
+       else
+               return (0);
+       return (1);
+}
+
+void   translate(t_element *element, t_vec3 direction, double distance)
+{
+       const t_vec3    change = vec_real_mul(vec_normalize(direction), distance);
+       t_vec3          *element_center;
+
+       element_center = NULL;
+       if (element->type == SPHERE)
+               element_center = &element->object.sphere.center;
+       else if (element->type == PLANE)
+               element_center = &element->object.plane.point;
+       else if (element->type == CYLINDER)
+               element_center = &element->object.cylinder.center;
+       else if (element->type == LIGHT)
+               element_center = &element->object.light.position;
+       else if (element->type == CAMERA)
+               element_center = &element->object.camera.position;
+       if (!element_center)
+               return ;
+       *element_center = vec_add(*element_center, change);
+       return ;
+}