diff --git a/inc/camera.h b/inc/camera.h index 212a2d5..6a9c524 100644 --- a/inc/camera.h +++ b/inc/camera.h @@ -35,6 +35,9 @@ void camera_zoom(camera_t* camera, float amount); * pan if the button was already held down. */ void camera_set_mouse_pos(camera_t* camera, float x, float y); +/* Rotates camera's axes by specified amount of degrees. */ +void camera_rotate(camera_t* camera, float x, float y); + /* Schedules a camera animation to update projection */ void camera_anim_proj_perspective(camera_t* camera); void camera_anim_proj_orthographic(camera_t* camera); diff --git a/inc/instance.h b/inc/instance.h index 7e1d8d7..51e9d2a 100644 --- a/inc/instance.h +++ b/inc/instance.h @@ -47,4 +47,5 @@ void instance_cb_window_size(instance_t* instance, int width, int height); void instance_cb_mouse_pos(instance_t* instance, float xpos, float ypos); void instance_cb_mouse_click(instance_t* instance, int button, int action, int mods); void instance_cb_mouse_scroll(instance_t* instance, float xoffset, float yoffset); +void instance_cb_key_press(instance_t* instance, int key, int scancode, int action, int mods); void instance_cb_focus(instance_t* instance, bool focus); diff --git a/src/camera.c b/src/camera.c index d744629..bb815f7 100644 --- a/src/camera.c +++ b/src/camera.c @@ -193,6 +193,29 @@ void camera_set_mouse_pos(camera_t* camera, float x, float y) { } } +void camera_rotate(camera_t* camera, float x, float y) +{ + /* Update pitch and clamp values */ + camera->pitch += y / 360.0f * M_PI; + if (camera->pitch < -M_PI) { + camera->pitch = -M_PI; + } else if (camera->pitch > 0.0f) { + camera->pitch = 0.0f; + } + + /* Update yaw and keep it under 360 degrees */ + camera->yaw += x / 360.0f * M_PI; + while (camera->yaw < 0.0f) { + camera->yaw += 2.0f * M_PI; + } + while (camera->yaw > 2.0f * M_PI) { + camera->yaw -= 2.0f * M_PI; + } + + /* Rebuild view matrix with new values */ + camera_update_view(camera); +} + static void camera_set_anim(camera_t* camera, anim_t* anim) { if (camera->anim) { log_warn("Triggered an animation while another was running; skipping"); diff --git a/src/instance.c b/src/instance.c index 5201730..b9a67ca 100644 --- a/src/instance.c +++ b/src/instance.c @@ -134,6 +134,27 @@ void instance_cb_mouse_scroll(instance_t* instance, camera_zoom(instance->camera, yoffset); } +void instance_cb_key_press(instance_t* instance, int key, int scancode, + int action, int mods) +{ + (void)scancode; + (void)mods; + if (action == GLFW_PRESS) { + if (key == GLFW_KEY_LEFT || key == GLFW_KEY_RIGHT || + key == GLFW_KEY_UP || key == GLFW_KEY_DOWN) { + if (key == GLFW_KEY_LEFT) { + camera_rotate(instance->camera, 2.0f, 0.0f); + } else if (key == GLFW_KEY_RIGHT) { + camera_rotate(instance->camera, -2.0f, 0.0f); + } else if (key == GLFW_KEY_UP) { + camera_rotate(instance->camera, 0.0f, 2.0f); + } else { + camera_rotate(instance->camera, 0.0f, -2.0f); + } + } + } +} + void instance_cb_focus(instance_t* instance, bool focus) { instance->focused = focus; diff --git a/src/window.c b/src/window.c index dc1ea44..6c70ddb 100644 --- a/src/window.c +++ b/src/window.c @@ -26,6 +26,13 @@ static void cb_mouse_click(GLFWwindow* window, int button, instance_cb_mouse_click(instance, button, action, mods); } +static void cb_key_press(GLFWwindow* window, const int key, const int scancode, + const int action, const int mods) +{ + instance_t* instance = (instance_t*)glfwGetWindowUserPointer(window); + instance_cb_key_press(instance, key, scancode, action, mods); +} + static void cb_drop(GLFWwindow* window, int count, const char** paths) { instance_t* instance = (instance_t*)glfwGetWindowUserPointer(window); @@ -59,6 +66,7 @@ void window_bind(GLFWwindow* window, instance_t* instance) { glfwSetCursorPosCallback(window, cb_mouse_pos); glfwSetScrollCallback(window, cb_mouse_scroll); glfwSetMouseButtonCallback(window, cb_mouse_click); + glfwSetKeyCallback(window, cb_key_press); glfwSetDropCallback(window, cb_drop); glfwSetWindowFocusCallback(window, cb_focus); glfwSetWindowCloseCallback(window, cb_close);