diff --git a/src/game/scenes/flight/FlightScene.cpp b/src/game/scenes/flight/FlightScene.cpp index 993793c2..b2070996 100644 --- a/src/game/scenes/flight/FlightScene.cpp +++ b/src/game/scenes/flight/FlightScene.cpp @@ -41,8 +41,6 @@ void FlightScene::load() }, this)); get_osp()->renderer->cam = &camera; - camera.speed = 20.0; - auto vehicle_toml = SerializeUtil::load_file("udata/vehicles/Test Vehicle.toml"); Vehicle* n_vehicle = VehicleLoader(*vehicle_toml).get_vehicle(); @@ -57,6 +55,7 @@ void FlightScene::load() st.cartesian.vel = stt.cartesian.vel; st.rotation = stt.rotation; st.cartesian.pos += stt.rotation * glm::dvec3(0, 0, 1) * 10.0; + camera.init(stt.rotation * glm::dvec3(0, 0, 1)); n_vehicle->packed_veh.set_world_state(st); n_vehicle->unpack(); diff --git a/src/renderer/camera/SimpleCamera.cpp b/src/renderer/camera/SimpleCamera.cpp index c9ee1909..f9a3d342 100644 --- a/src/renderer/camera/SimpleCamera.cpp +++ b/src/renderer/camera/SimpleCamera.cpp @@ -1,149 +1,258 @@ #include "SimpleCamera.h" #include "../../util/InputUtil.h" #include +#include "../../util/Logger.h" void SimpleCamera::update(double dt) { - keyboard_blocked = false; - - if (!ImGui::IsAnyItemFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsAnyWindowFocused()) - { - bool moved = false; - // Motion - - - if (glfwGetMouseButton(input->window, GLFW_MOUSE_BUTTON_2)) - { - keyboard_blocked = true; - - if (glfwGetKey(input->window, GLFW_KEY_W) == GLFW_PRESS) - { - forwards(dt); - moved = true; - } - - if (glfwGetKey(input->window, GLFW_KEY_S) == GLFW_PRESS) - { - backwards(dt); - moved = true; - } - - if (glfwGetKey(input->window, GLFW_KEY_A) == GLFW_PRESS) - { - leftwards(dt); - moved = true; - } - - if (glfwGetKey(input->window, GLFW_KEY_D) == GLFW_PRESS) - { - rightwards(dt); - moved = true; - } - - if (glfwGetKey(input->window, GLFW_KEY_R) == GLFW_PRESS) - { - upwards(dt); - moved = true; - } - - if (glfwGetKey(input->window, GLFW_KEY_F) == GLFW_PRESS) - { - downwards(dt); - moved = true; - } - - if (glfwGetKey(input->window, GLFW_KEY_Q) == GLFW_PRESS) - { - tilt(dt, -1.0f); - } - - if (glfwGetKey(input->window, GLFW_KEY_E) == GLFW_PRESS) - { - tilt(dt, 1.0f); - } - - glfwSetInputMode(input->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - if (input->mouse_delta != glm::dvec2(0.0, 0.0)) - { - mouse(input->mouse_delta, dt); - } - - if (input->mouse_scroll_delta != 0) - { - speed += speed * input->mouse_scroll_delta * 0.05; - } - } - else - { - glfwSetInputMode(input->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - } - - } - else - { - keyboard_blocked = true; - glfwSetInputMode(input->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - } + keyboard_blocked = false; + + if (!ImGui::IsAnyItemFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsAnyWindowFocused()) + { + bool moved = false; + // Motion + if (glfwGetMouseButton(input->window, GLFW_MOUSE_BUTTON_2)) + { + keyboard_blocked = true; + + if (glfwGetKey(input->window, GLFW_KEY_W) == GLFW_PRESS) + { + forwards(dt); + moved = true; + } + + if (glfwGetKey(input->window, GLFW_KEY_S) == GLFW_PRESS) + { + backwards(dt); + moved = true; + } + if (mode==CAMERA_FREE_MODE) + { + if (glfwGetKey(input->window, GLFW_KEY_A) == GLFW_PRESS) + { + leftwards(dt); + moved = true; + } + + if (glfwGetKey(input->window, GLFW_KEY_D) == GLFW_PRESS) + { + rightwards(dt); + moved = true; + } + + if (glfwGetKey(input->window, GLFW_KEY_R) == GLFW_PRESS) + { + upwards(dt); + moved = true; + } + + if (glfwGetKey(input->window, GLFW_KEY_F) == GLFW_PRESS) + { + downwards(dt); + moved = true; + } + + if (glfwGetKey(input->window, GLFW_KEY_Q) == GLFW_PRESS) + { + tilt(dt, -1.0f); + } + + if (glfwGetKey(input->window, GLFW_KEY_E) == GLFW_PRESS) + { + tilt(dt, 1.0f); + } + } + glfwSetInputMode(input->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + if (input->mouse_delta != glm::dvec2(0.0, 0.0)) + { + mouse(input->mouse_delta, dt); + } + + if (input->mouse_scroll_delta != 0) + { + speed += speed * input->mouse_scroll_delta * 0.05; + } + } + else + { + glfwSetInputMode(input->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } + } + else + { + keyboard_blocked = true; + glfwSetInputMode(input->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } } std::pair SimpleCamera::get_camera_pos_dir() { - return std::make_pair(pos + center, fw); + return std::make_pair(pos + center, fw); } -CameraUniforms SimpleCamera::get_camera_uniforms(int w, int h) +void SimpleCamera::forwards(double dt) { - CameraUniforms out; + switch(mode) + { + case CAMERA_FREE_MODE: + pos += speed * glm::normalize(fw) * (double)dt; + break; + case CAMERA_CIRCLE_MODE: + distance-=speed * (double)dt; + toSphere(); + break; + } +} - auto[camera_pos, camera_dir] = get_camera_pos_dir(); - // ~1 light year - float far_plane = 1e16f; +void SimpleCamera::backwards(double dt) +{ + switch(mode) + { + case CAMERA_FREE_MODE: + pos -= speed * glm::normalize(fw) * (double)dt; + break; + case CAMERA_CIRCLE_MODE: + distance+=speed * (double)dt; + toSphere(); + break; + } +} +void SimpleCamera::leftwards(double dt) +{ + pos -= speed * glm::normalize(glm::cross(fw, up)) * (double)dt; +} - glm::dmat4 proj = glm::perspective(glm::radians(fov), (double)w / (double)h, NEAR_PLANE, (double)far_plane); - glm::dmat4 view = glm::lookAt(glm::dvec3(0.0, 0.0, 0.0), camera_dir, up); - glm::dmat4 proj_view = proj * view; +void SimpleCamera::rightwards(double dt) +{ + pos += speed * glm::normalize(glm::cross(fw, up)) * (double)dt; +} - out.proj = proj; - out.view = view; - out.proj_view = proj_view; - out.c_model = glm::translate(glm::dmat4(1.0), -camera_pos); - out.tform = proj * view * out.c_model; - out.far_plane = far_plane; - out.cam_pos = camera_pos; +void SimpleCamera::tilt(double dt, double dir) +{ + glm::mat4 f = glm::rotate(glm::dmat4(1.0), (double)dir * (double)dt, fw); + up = f * glm::dvec4(up, 1.0); +} - out.screen_size = glm::vec2((float)w, (float)h); - out.iscreen_size = glm::ivec2(w, h); +void SimpleCamera::upwards(double dt) +{ + pos += speed * glm::normalize(up) * (double)dt; +} - return out; +void SimpleCamera::downwards(double dt) +{ + pos -= speed * glm::normalize(up) * (double)dt; } +glm::dmat4 SimpleCamera::get_cmodel() +{ + return glm::translate(glm::dmat4(1.0), -get_camera_pos_dir().first); +} -glm::dmat4 SimpleCamera::get_proj_view(int width, int height) +void SimpleCamera::set_mode(unsigned char mode) +{ + this->mode=mode; +} + +void SimpleCamera::init(glm::dvec3 up) +{ + fov = 60.0; + speed = 20.0; + center_fw = glm::dvec3(0.0, 0.0, 0.0); + distance=10.0; + this->up=up; + pos = glm::normalize(glm::dvec3(0.0, distance, 0.0)+up*5.0)*distance; + fw = glm::normalize(-pos); +} + +void SimpleCamera::toSphere() +{ + fw=glm::normalize(-pos); + pos=fw*-distance; +} + +void SimpleCamera::mouse(glm::dvec2 deltas, double dt) { - auto[camera_pos, camera_dir] = get_camera_pos_dir(); - // ~1 light year - float far_plane = 1e16f; + switch(mode) + { + case CAMERA_FREE_MODE: + { + glm::dvec3 or_forward = fw; + glm::dvec3 or_up = up; + // Rotate forward original up + glm::mat4 hor = glm::rotate(glm::dmat4(1.0), -deltas.x * (double)dt * 0.45, or_up); - glm::dmat4 proj = glm::perspective(glm::radians(fov), (double)width / (double)height, NEAR_PLANE, (double)far_plane); - glm::dmat4 view = glm::lookAt(glm::dvec3(0.0, 0.0, 0.0), camera_dir, up); - glm::dmat4 proj_view = proj * view; + glm::dvec3 right = glm::cross(or_forward, or_up); - return proj_view; + glm::mat4 vert = glm::rotate(glm::dmat4(1.0), -deltas.y * (double)dt * 0.45, right); + fw = vert * hor * glm::dvec4(fw, 1.0); + break; + } + case CAMERA_CIRCLE_MODE: + pos += speed * glm::normalize(up) * deltas.y * (double)dt * 0.2 - speed * glm::cross(fw, up) * deltas.x * (double)dt * 0.2; + toSphere(); + break; + } } -glm::dmat4 SimpleCamera::get_cmodel() +void SimpleCamera::key_callback(GLFWwindow* , int key, int , int action, int ) +{ + if (glfwGetKey(input->window, GLFW_KEY_C) == GLFW_PRESS) { mode=!mode; } +} + +void key_callback_bounce(GLFWwindow* window, int key, int scancode, int action, int mods) { - return glm::translate(glm::dmat4(1.0), -get_camera_pos_dir().first); + ((SimpleCamera *)glfwGetWindowUserPointer(window))->key_callback(window,key,scancode,action,mods); } SimpleCamera::SimpleCamera() { - fov = 60.0; - pos = glm::dvec3(0.0, 0.0, 0.0); - fw = glm::dvec3(1.0, 0.0, 0.0); - speed = 1.0; - up = glm::dvec3(0.0, 1.0, 0.0); + keyboard_blocked=false; + set_mode(CAMERA_CIRCLE_MODE); + glfwSetWindowUserPointer(input->window,this); + glfwSetKeyCallback(input->window,&key_callback_bounce); +} + +glm::dmat4 SimpleCamera::get_proj_view(int width, int height) +{ + auto[camera_pos, camera_dir] = get_camera_pos_dir(); + + // ~1 light year + float far_plane = 1e16f; + + + glm::dmat4 proj = glm::perspective(glm::radians(fov), (double)width / (double)height, NEAR_PLANE, (double)far_plane); + glm::dmat4 view = glm::lookAt(glm::dvec3(0.0, 0.0, 0.0), camera_dir, up); + glm::dmat4 proj_view = proj * view; + + return proj_view; } +CameraUniforms SimpleCamera::get_camera_uniforms(int w, int h) +{ + CameraUniforms out; + + auto[camera_pos, camera_dir] = get_camera_pos_dir(); + + // ~1 light year + float far_plane = 1e16f; + + glm::dmat4 proj = glm::perspective(glm::radians(fov), (double)w / (double)h, NEAR_PLANE, (double)far_plane); + glm::dmat4 view = glm::lookAt(glm::dvec3(0.0, 0.0, 0.0), camera_dir, up); + //glm::dmat4 view = glm::lookAt(-camera_pos, camera_dir, up); + glm::dmat4 proj_view = proj * view; + + out.proj = proj; + out.view = view; + out.proj_view = proj_view; + out.c_model = glm::translate(glm::dmat4(1.0), -camera_pos); + out.tform = proj * view * out.c_model; + out.far_plane = far_plane; + out.cam_pos = camera_pos; + + out.screen_size = glm::vec2((float)w, (float)h); + out.iscreen_size = glm::ivec2(w, h); + + return out; +} diff --git a/src/renderer/camera/SimpleCamera.h b/src/renderer/camera/SimpleCamera.h index c87238ce..e040ede4 100644 --- a/src/renderer/camera/SimpleCamera.h +++ b/src/renderer/camera/SimpleCamera.h @@ -2,32 +2,42 @@ #include #include #include +#include +#include #include "CameraUniforms.h" #include "Camera.h" +typedef struct GLFWwindow GLFWwindow; + +#define CAMERA_FREE_MODE 0 +#define CAMERA_CIRCLE_MODE 1 class SimpleCamera : public Camera { private: + static SimpleCamera *instance; + glm::dmat4 get_proj_view(int w, int h); glm::dmat4 get_cmodel(); - public: constexpr static double NEAR_PLANE = 1e-6; - bool keyboard_blocked; + bool keyboard_blocked; + unsigned char mode; // In degrees double fov; double speed; + double distance; glm::dvec3 pos; glm::dvec3 up; glm::dvec3 fw; glm::dvec3 center; + glm::dvec3 center_fw; void update(double dt); @@ -35,59 +45,17 @@ class SimpleCamera : public Camera std::pair get_camera_pos_dir(); virtual CameraUniforms get_camera_uniforms(int w, int h) override; - - void forwards(double dt) - { - pos += speed * glm::normalize(fw) * (double)dt; - } - - void backwards(double dt) - { - pos -= speed * glm::normalize(fw) * (double)dt; - } - - void leftwards(double dt) - { - pos -= speed * glm::normalize(glm::cross(fw, up)) * (double)dt; - } - - void rightwards(double dt) - { - pos += speed * glm::normalize(glm::cross(fw, up)) * (double)dt; - } - - void tilt(double dt, double dir) - { - glm::mat4 f = glm::rotate(glm::dmat4(1.0), (double)dir * (double)dt, fw); - up = f * glm::dvec4(up, 1.0); - } - - void upwards(double dt) - { - pos += speed * glm::normalize(up) * (double)dt; - } - - void downwards(double dt) - { - pos -= speed * glm::normalize(up) * (double)dt; - } - - void mouse(glm::dvec2 deltas, double dt) - { - glm::dvec3 or_forward = fw; - glm::dvec3 or_up = up; - - // Rotate forward original up - glm::mat4 hor = glm::rotate(glm::dmat4(1.0), -deltas.x * (double)dt * 0.45, or_up); - - glm::dvec3 right = glm::cross(or_forward, or_up); - - glm::mat4 vert = glm::rotate(glm::dmat4(1.0), -deltas.y * (double)dt * 0.45, right); - up = vert * glm::dvec4(or_up, 1.0); - fw = vert * hor * glm::dvec4(fw, 1.0); - - } - + void forwards(double dt); + void backwards(double dt); + void leftwards(double dt); + void rightwards(double dt); + void tilt(double dt, double dir); + void upwards(double dt); + void downwards(double dt); + void toSphere(); + void mouse(glm::dvec2 deltas, double dt); + void set_mode(unsigned char mode); + void init(glm::dvec3 up); SimpleCamera(); - + void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); };