diff options
Diffstat (limited to 'src/camera.c')
| -rw-r--r-- | src/camera.c | 146 |
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); +} |