diff options
Diffstat (limited to 'src/camera')
-rw-r--r-- | src/camera/camera.c | 137 | ||||
-rw-r--r-- | src/camera/camera.h | 132 |
2 files changed, 269 insertions, 0 deletions
diff --git a/src/camera/camera.c b/src/camera/camera.c new file mode 100644 index 0000000..44f480d --- /dev/null +++ b/src/camera/camera.c @@ -0,0 +1,137 @@ +#include "camera.h" + +void honey_camera_new(honey_camera* camera, + vec3 position, + vec3 angle, + enum honey_camera_projection projection_type, + float aspect_ratio, + float near, float far, + float fov, + float left, float right, float top, float bottom) { + glm_vec3_copy(position, camera->position); + glm_vec3_copy(angle, camera->angle); + + camera->projection_type = projection_type; + + camera->aspect_ratio = aspect_ratio; + camera->near = near; + camera->far = far; + + if (projection_type == HONEY_PERSPECTIVE) { + camera->fov = fov; + } + else if (projection_type == HONEY_ORTHOGRAPHIC) { + camera->ortho_left = left; + camera->ortho_right = right; + camera->ortho_top = top; + camera->ortho_bottom = bottom; + } + + honey_camera_calculate_view(camera); + honey_camera_calculate_projection(camera); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_camera_new_perspective(honey_camera* camera, + vec3 position, + vec3 angle, + float aspect_ratio, + float near, float far, + float fov) { + honey_camera_new(camera, + position, angle, + HONEY_PERSPECTIVE, + aspect_ratio, near, far, fov, + 0, 0, 0, 0); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_camera_new_orthographic(honey_camera* camera, + vec3 position, + vec3 angle, + float near, float far, + float left, float right, float top, float bottom) { + honey_camera_new(camera, + position, angle, + HONEY_ORTHOGRAPHIC, + 0, + near, far, + 0, + left, right, top, bottom); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_camera_calculate_look_direction(honey_camera* camera) { + float pitch = camera->angle[0]; + float yaw = camera->angle[1]; + + float x = cos(pitch) * cos(yaw); + float y = sin(pitch); + float z = cos(pitch) * sin(yaw); + + camera->look_direction[0] = x; + camera->look_direction[1] = y; + camera->look_direction[2] = z; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_camera_calculate_up(honey_camera* camera) { + float pitch = camera->angle[0]; + float yaw = camera->angle[1]; + float roll = camera->angle[2]; + + camera->up[0] = 0; + camera->up[1] = 1; + camera->up[2] = 0; + + mat3 rot3; + mat4 rot4; + glm_mat4_identity(rot4); + glm_rotate(rot4, roll, camera->look_direction); + glm_mat4_pick3(rot4, rot3); + + glm_mat3_mulv(rot3, camera->up, camera->up); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_camera_calculate_right(honey_camera* camera) { + glm_vec3_cross(camera->up, camera->look_direction, camera->right); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_camera_calculate_view(honey_camera* camera) { + honey_camera_calculate_look_direction(camera); + honey_camera_calculate_up(camera); + honey_camera_calculate_right(camera); + + glm_look(camera->position, camera->look_direction, camera->up, camera->view); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_camera_calculate_projection(honey_camera* camera) { + if (camera->projection_type == HONEY_PERSPECTIVE) { + glm_mat4_identity(camera->projection); + glm_perspective(camera->fov, + camera->aspect_ratio, + camera->near, + camera->far, + camera->projection); + } + else if (camera->projection_type == HONEY_ORTHOGRAPHIC) { + glm_mat4_identity(camera->projection); + glm_ortho(camera->ortho_left, + camera->ortho_right, + camera->ortho_bottom, + camera->ortho_top, + camera->near, + camera->far, + camera->projection); + } +} diff --git a/src/camera/camera.h b/src/camera/camera.h new file mode 100644 index 0000000..b8d3b61 --- /dev/null +++ b/src/camera/camera.h @@ -0,0 +1,132 @@ +#ifndef HONEY_CAMERA_H +#define HONEY_CAMERA_H + +/** @file camera.h + * + * @brief Define the basic honey_camera struct, associated functions, + * and common camera variants. + */ + +#include "../common.h" + +enum honey_camera_projection { + HONEY_PERSPECTIVE, + HONEY_ORTHOGRAPHIC, +}; + +typedef struct { + vec3 position; + vec3 angle; /* pitch, yaw, roll */ + vec3 look_direction; + vec3 up; + vec3 right; + mat4 view; + mat4 projection; + enum honey_camera_projection projection_type; + float aspect_ratio; + float near, far; + float fov; + float ortho_left; + float ortho_right; + float ortho_top; + float ortho_bottom; +} honey_camera; + +/** @brief Create a new camera. + * + * The full camera creation function. Most of the time, you will probably use either + * honey_camera_new_perspective() or honey_camera_new_projection() instead. + * + * @param[out] camera Pointer to the destination honey_camera. + * @param[in] position The position of the camera. + * @param[in] angle The Euler angles (pitch, yaw, roll) of the camera. + * @param[in] projection_type The type of projection to use. + * @param[in] aspect_ratio The aspect ratio of the camera. Set to zero if using orthographic projection. + * @param[in] near The distance of the near plane. + * @param[in] far The distance of the far plane. + * @param[in] fov The field of view. Set to zero if using orthographic projection. + * @param[in] left The leftmost distance. Set to zero if using perspective projection. + * @param[in] right The rightmost distance. Set to zero if using perspective projection. + * @param[in] top The uppermost distance. Set to zero if using perspective projection. + * @param[in] bottom The lowest distance. Set to zero if using perspective projection. + */ +void honey_camera_new(honey_camera* camera, + vec3 position, + vec3 angle, + enum honey_camera_projection projection_type, + float aspect_ratio, + float near, float far, + float fov, + float left, float right, float top, float bottom); + +/** @brief Create a camera with a perspective projection matrix. + * + * @param[out] camera Pointer to the destination honey_camera. + * @param[in] position The position of the camera. + * @param[in] angle The Euler angles (pitch, yaw, roll) of the camera. + * @param[in] aspect_ratio The aspect ratio of the camera. + * @param[in] near The distance of the near plane. + * @param[in] far The distance of the far plane. + * @param[in] fov The field of view. + */ +void honey_camera_new_perspective(honey_camera* camera, + vec3 position, + vec3 angle, + float aspect_ratio, + float near, float far, + float fov); + +/** @brief Create a camera with an orthographic projection matrix. + * + * @param[out] camera Pointer to the destination honey_camera. + * @param[in] position The position of the camera. + * @param[in] angle The Euler angles (pitch, yaw, roll) of the camera. + * @param[in] near The distance of the near plane. + * @param[in] far The distance of the far plane. + * @param[in] left The leftmost distance. + * @param[in] right The rightmost distance. + * @param[in] top The uppermost distance. + * @param[in] bottom The lowest distance. + */ +void honey_camera_new_orthographic(honey_camera* camera, + vec3 position, + vec3 angle, + float near, float far, + float left, float right, float top, float bottom); + +/** @brief (Re-)Calculate a camera's look_direction. + * + * @param[in] Pointer to the camera to re-calculate. + */ +void honey_camera_calculate_look_direction(honey_camera* camera); + +/** @brief (Re-)Calculate a camera's up vector. + * + * @param[in] Pointer to the camera to re-calculate. + */ +void honey_camera_calculate_up(honey_camera* camera); + +/** @brief (Re-)Calculate a camera's right vector. + * + * @param[in] Pointer to the camera to re-calculate. + */ +void honey_camera_calculate_right(honey_camera* camera); + +/** @brief (Re-)Calculate a camera's view matrix. + * + * This function need only be called when the camera has been moved in some way. + * + * @param[in] camera Pointer to the camera to re-calculate. + */ +void honey_camera_calculate_view(honey_camera* camera); + +/** @brief (Re-)Calculate a camera's projection matrix. + * + * This function need only be called when the projection has changes in some way. + * Most commonly, this would be changing the FOV. + * + * @param[in] camera Pointer to the camera to re-calculate. + */ +void honey_camera_calculate_projection(honey_camera* camera); + +#endif |