summaryrefslogtreecommitdiff
path: root/src/camera
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera')
-rw-r--r--src/camera/camera.c137
-rw-r--r--src/camera/camera.h132
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