summaryrefslogtreecommitdiff
path: root/src/camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera.c')
-rw-r--r--src/camera.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/camera.c b/src/camera.c
new file mode 100644
index 0000000..ec486d7
--- /dev/null
+++ b/src/camera.c
@@ -0,0 +1,146 @@
+#include "cglm/vec3.h"
+#include <math.h>
+
+#include "voxel.h"
+#include "window.h"
+
+Camera camera_init(void)
+{
+ Camera camera = { 0 };
+ camera.fov = 70;
+ camera.near = 0.1;
+ camera.far = 1000;
+ camera.look_speed = 100;
+ camera.move_speed = 4.317;
+ return camera;
+}
+
+void camera_proj(Camera *camera, mat4 proj)
+{
+ float aspect, tan_half_foxy;
+
+ aspect = (float)window.width / (float)window.height;
+ tan_half_foxy = tanf(camera->fov * (M_PI / 180)) / 2.0;
+
+ glm_mat4_zero(proj);
+ proj[0][0] = 1.0 / (aspect * tan_half_foxy);
+ proj[1][1] = 1.0 / tan_half_foxy;
+ proj[2][2] = camera->far / (camera->far - camera->near);
+ proj[2][3] = 1;
+ proj[3][2] = -(camera->far * camera->near) / (camera->far - camera->near);
+}
+
+void camera_view(Camera *camera, mat4 view)
+{
+ float c3, s3, c2, s2, c1, s1;
+ vec3 u, v, w;
+
+ c3 = cosf(camera->rotation[2] * (M_PI / 180));
+ s3 = sinf(camera->rotation[2] * (M_PI / 180));
+ c2 = cosf(camera->rotation[0] * (M_PI / 180));
+ s2 = sin(camera->rotation[0] * (M_PI / 180));
+ c1 = cosf(camera->rotation[1] * (M_PI / 180));
+ s1 = sinf(camera->rotation[1] * (M_PI / 180));
+
+ u[0] = c1 * c3 + s1 * s2 * s3;
+ u[1] = c2 * s3;
+ u[2] = c1 * s2 * s3 - c3 * s1;
+
+ v[0] = c3 * s1 * s2 - c1 * s3;
+ v[1] = c2 * c3;
+ v[2] = c1 * c3 * s2 + s1 * s3;
+
+ w[0] = c2 * s1;
+ w[1] = -s2;
+ w[2] = c1 * c2;
+
+ view[0][0] = u[0];
+ view[0][1] = v[0];
+ view[0][2] = w[0];
+ view[0][3] = 0;
+ view[1][0] = u[1];
+ view[1][1] = v[1];
+ view[1][2] = w[1];
+ view[1][3] = 0;
+ view[2][0] = u[2];
+ view[2][1] = v[2];
+ view[2][2] = w[2];
+ view[2][3] = 0;
+ view[3][0] = -glm_dot(u, camera->position);
+ view[3][1] = -glm_dot(v, camera->position);
+ view[3][2] = -glm_dot(w, camera->position);
+ view[3][3] = 1;
+}
+
+void camera_proj_view(Camera *camera, mat4 proj_view)
+{
+ mat4 proj, view;
+ camera_proj(camera, proj);
+ camera_view(camera, view);
+ glm_mat4_mul(proj, view, proj_view);
+}
+
+static void camera_update_rotation(Camera *camera)
+{
+ vec3 rotate;
+
+ glm_vec3_zero(rotate);
+ if (key_down(GLFW_KEY_RIGHT))
+ rotate[1] += 1;
+ if (key_down(GLFW_KEY_LEFT))
+ rotate[1] -= 1;
+ if (key_down(GLFW_KEY_UP))
+ rotate[0] -= 1;
+ if (key_down(GLFW_KEY_DOWN))
+ rotate[0] += 1;
+ glm_normalize(rotate);
+
+ camera->rotation[0] += camera->look_speed * delta_time * rotate[0];
+ camera->rotation[1] += camera->look_speed * delta_time * rotate[1];
+
+ camera->rotation[0] = glm_clamp(camera->rotation[0], -90, 90);
+ //camera->rotation[1] = camera->rotation[0] % 360.0;
+}
+
+static void camera_update_movement(Camera *camera)
+{
+ vec3 forward, left, up, move;
+ float yaw;
+
+ yaw = camera->rotation[1] * (M_PI / 180);
+
+ glm_vec3_zero(forward);
+ forward[0] = sinf(yaw);
+ forward[2] = cosf(yaw);
+
+ glm_vec3_zero(left);
+ left[0] = -forward[2];
+ left[2] = forward[0];
+
+ glm_vec3_zero(up);
+ up[1] = 1;
+
+ glm_vec3_zero(move);
+ if (key_down(GLFW_KEY_W))
+ glm_vec3_add(move, forward, move);
+ if (key_down(GLFW_KEY_S))
+ glm_vec3_sub(move, forward, move);
+ if (key_down(GLFW_KEY_A))
+ glm_vec3_add(move, left, move);
+ if (key_down(GLFW_KEY_D))
+ glm_vec3_sub(move, left, move);
+ if (key_down(GLFW_KEY_E))
+ glm_vec3_add(move, up, move);
+ if (key_down(GLFW_KEY_Q))
+ glm_vec3_sub(move, up, move);
+ glm_normalize(move);
+ glm_vec3_scale(move, camera->move_speed * delta_time, move);
+
+ glm_vec3_add(camera->position, move, camera->position);
+}
+
+void camera_update(Camera *camera)
+{
+ camera_update_rotation(camera);
+ camera_update_movement(camera);
+}