diff options
author | Vito Caputo <vcaputo@gnugeneration.com> | 2017-02-10 07:55:51 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@gnugeneration.com> | 2017-02-10 08:18:11 -0800 |
commit | 35d8587b8e6b5a85fe0f978ff8cd5a899a8ff6a4 (patch) | |
tree | 9ec99df685acefa0df3530322bf7221c49227339 /src/modules | |
parent | a4914d40fd9e25fa4c02af8d4c02d227064c1903 (diff) |
ray: implement all orders in ray_euler_basis()
Originally I only implemented pitch->yaw->roll, and being new to all this
didn't fully appreciate the limitation that resulted in.
This adds all six permutations of pitch/yaw/roll, the scene must specify
the desired order when setting up the camera with the euler angles, see
the enum in ray_euler.h.
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/ray/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/ray/ray.c | 1 | ||||
-rw-r--r-- | src/modules/ray/ray_euler.c | 90 | ||||
-rw-r--r-- | src/modules/ray/ray_euler.h | 40 |
4 files changed, 106 insertions, 27 deletions
diff --git a/src/modules/ray/Makefile.am b/src/modules/ray/Makefile.am index 6c9a50a..7acfdd8 100644 --- a/src/modules/ray/Makefile.am +++ b/src/modules/ray/Makefile.am @@ -1,4 +1,4 @@ noinst_LIBRARIES = libray.a -libray_a_SOURCES = ray_3f.h ray.c ray_camera.c ray_camera.h ray_color.h ray_euler.h ray.h ray_light_emitter.h ray_object.c ray_object.h ray_object_light.h ray_object_plane.h ray_object_point.h ray_object_sphere.h ray_object_type.h ray_ray.h ray_scene.c ray_scene.h ray_surface.h ray_threads.c ray_threads.h +libray_a_SOURCES = ray_3f.h ray.c ray_camera.c ray_camera.h ray_color.h ray_euler.c ray_euler.h ray.h ray_light_emitter.h ray_object.c ray_object.h ray_object_light.h ray_object_plane.h ray_object_point.h ray_object_sphere.h ray_object_type.h ray_ray.h ray_scene.c ray_scene.h ray_surface.h ray_threads.c ray_threads.h libray_a_CFLAGS = @ROTOTILLER_CFLAGS@ -ffast-math libray_a_CPPFLAGS = @ROTOTILLER_CFLAGS@ -I@top_srcdir@/src diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c index 60d08cf..951b1d7 100644 --- a/src/modules/ray/ray.c +++ b/src/modules/ray/ray.c @@ -90,6 +90,7 @@ static void ray(fb_fragment_t *fragment) ray_camera_t camera = { .position = { .x = 0.0, .y = 0.0, .z = 6.0 }, .orientation = { + .order = RAY_EULER_ORDER_YPR, /* yaw,pitch,roll */ .yaw = RAY_EULER_DEGREES(0.0f), .pitch = RAY_EULER_DEGREES(0.0f), .roll = RAY_EULER_DEGREES(180.0f), diff --git a/src/modules/ray/ray_euler.c b/src/modules/ray/ray_euler.c new file mode 100644 index 0000000..8709fa3 --- /dev/null +++ b/src/modules/ray/ray_euler.c @@ -0,0 +1,90 @@ +#include <assert.h> +#include <math.h> + +#include "ray_3f.h" +#include "ray_euler.h" + +/* produce orthonormal basis vectors from euler angles, rotated in the specified order */ +void ray_euler_basis(ray_euler_t *e, ray_3f_t *forward, ray_3f_t *up, ray_3f_t *left) +{ + float cos_yaw = cosf(e->yaw); + float sin_yaw = sinf(e->yaw); + float cos_roll = cosf(e->roll); + float sin_roll = sinf(e->roll); + float cos_pitch = cosf(e->pitch); + float sin_pitch = sinf(e->pitch); + + /* Rotation matrices from http://www.songho.ca/opengl/gl_anglestoaxes.html */ + switch (e->order) { + case RAY_EULER_ORDER_PYR: + /* pitch, yaw, roll */ + up->x = -cos_yaw * sin_roll; + up->y = -sin_pitch * sin_yaw * sin_roll + cos_pitch * cos_roll; + up->z = cos_pitch * sin_yaw * sin_roll + sin_pitch * cos_roll; + + forward->x = sin_yaw; + forward->y = -sin_pitch * cos_yaw; + forward->z = cos_pitch * cos_yaw; + break; + + case RAY_EULER_ORDER_YRP: + /* yaw, roll, pitch */ + up->x = -cos_yaw * sin_roll * cos_pitch + sin_yaw * sin_pitch; + up->y = cos_roll * cos_pitch; + up->z = sin_yaw * sin_roll * cos_pitch + cos_yaw * sin_pitch; + + forward->x = cos_yaw * sin_roll * sin_pitch + sin_yaw * cos_pitch; + forward->y = -cos_roll * sin_pitch; + forward->z = -sin_yaw * sin_roll * sin_pitch + cos_yaw * cos_pitch; + break; + + case RAY_EULER_ORDER_RPY: + /* roll, pitch, yaw */ + up->x = -sin_roll * cos_pitch; + up->y = cos_roll * cos_pitch; + up->z = sin_pitch; + + forward->x = cos_roll * sin_yaw + sin_roll * sin_pitch * cos_yaw; + forward->y = sin_roll * sin_yaw - cos_roll * sin_pitch * cos_yaw; + forward->z = cos_pitch * cos_yaw; + break; + + case RAY_EULER_ORDER_PRY: + /* pitch, roll, yaw */ + up->x = -sin_roll; + up->y = cos_pitch * cos_roll; + up->z = sin_pitch * cos_roll; + + forward->x = cos_roll * sin_yaw; + forward->y = cos_pitch * sin_roll * sin_yaw - sin_pitch * cos_yaw; + forward->z = sin_pitch * sin_roll * sin_yaw + cos_pitch * cos_yaw; + break; + + case RAY_EULER_ORDER_RYP: + /* roll, yaw, pitch */ + up->x = -sin_roll * cos_pitch + cos_roll * sin_yaw * sin_pitch; + up->y = cos_roll * cos_pitch + sin_roll * sin_yaw * sin_pitch; + up->z = cos_yaw * sin_pitch; + + forward->x = sin_roll * sin_pitch + cos_roll * sin_yaw * cos_pitch; + forward->y = -cos_roll * sin_pitch + sin_roll * sin_yaw * cos_pitch; + forward->z = cos_yaw * cos_pitch; + break; + + case RAY_EULER_ORDER_YPR: + /* yaw, pitch, roll */ + up->x = -cos_yaw * sin_roll + sin_yaw * sin_pitch * cos_roll; + up->y = cos_pitch * cos_roll; + up->z = sin_yaw * sin_roll + cos_yaw * sin_pitch * cos_roll; + + forward->x = sin_yaw * cos_pitch; + forward->y = -sin_pitch; + forward->z = cos_yaw * cos_pitch; + break; + + default: + assert(0); + } + + *left = ray_3f_cross(up, forward); +} diff --git a/src/modules/ray/ray_euler.h b/src/modules/ray/ray_euler.h index 86f5221..3a74cab 100644 --- a/src/modules/ray/ray_euler.h +++ b/src/modules/ray/ray_euler.h @@ -5,12 +5,22 @@ #include "ray_3f.h" +/* Desired order to apply euler angle rotations */ +typedef enum ray_euler_order_t { + RAY_EULER_ORDER_PYR, + RAY_EULER_ORDER_YRP, + RAY_EULER_ORDER_RPY, + RAY_EULER_ORDER_PRY, + RAY_EULER_ORDER_RYP, + RAY_EULER_ORDER_YPR, +} ray_euler_order_t; /* euler angles are convenient for describing orientation */ typedef struct ray_euler_t { - float pitch; /* pitch in radiasn */ - float yaw; /* yaw in radians */ - float roll; /* roll in radians */ + ray_euler_order_t order; /* order to apply rotations in */ + float pitch; /* pitch in radiasn */ + float yaw; /* yaw in radians */ + float roll; /* roll in radians */ } ray_euler_t; @@ -18,28 +28,6 @@ typedef struct ray_euler_t { #define RAY_EULER_DEGREES(_deg) \ (_deg * (2 * M_PI / 360.0f)) - -/* produce basis vectors from euler angles */ -static inline void ray_euler_basis(ray_euler_t *e, ray_3f_t *forward, ray_3f_t *up, ray_3f_t *left) -{ - float cos_yaw = cosf(e->yaw); - float sin_yaw = sinf(e->yaw); - float cos_roll = cosf(e->roll); - float sin_roll = sinf(e->roll); - float cos_pitch = cosf(e->pitch); - float sin_pitch = sinf(e->pitch); - - forward->x = sin_yaw; - forward->y = -sin_pitch * cos_yaw; - forward->z = cos_pitch * cos_yaw; - - up->x = -cos_yaw * sin_roll; - up->y = -sin_pitch * sin_yaw * sin_roll + cos_pitch * cos_roll; - up->z = cos_pitch * sin_yaw * sin_roll + sin_pitch * cos_roll; - - left->x = cos_yaw * cos_roll; - left->y = sin_pitch * sin_yaw * cos_roll + cos_pitch * sin_roll; - left->z = -cos_pitch * sin_yaw * cos_roll + sin_pitch * sin_roll; -} +void ray_euler_basis(ray_euler_t *e, ray_3f_t *forward, ray_3f_t *up, ray_3f_t *left); #endif |