From cc3c5bce0ca6b50ef0195d893d5142833c107fec Mon Sep 17 00:00:00 2001 From: Joseph Walton-Rivers <joseph@walton-rivers.uk> Date: Tue, 7 Sep 2021 20:54:04 +0100 Subject: [PATCH] enable camera scrolling --- demo/main.cpp | 100 ++++++++++++++++++++++++++++++-------------- fggl/gfx/input.cpp | 2 +- fggl/gfx/window.cpp | 5 +++ 3 files changed, 75 insertions(+), 32 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index 4394cc8..4013fa0 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -60,9 +60,10 @@ struct CameraHacks { void CameraArcball(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c); void CameraFree(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c); +void CameraEdgeScroll(fggl::gfx::Input& input, fggl::components::Transform& t, fggl::components::Camera& c); //TODO proper input system -void process_camera(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c) { +void CameraInput(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c) { CameraHacks* hacks = (CameraHacks*)( it.ctx() ); fggl::gfx::Window& window = hacks->window; fggl::gfx::Input& input = hacks->input; @@ -74,27 +75,27 @@ void process_camera(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, cam_mode = cam_arcball; } - if ( cam_mode == cam_arcball ) { + if ( cam_mode == cam_arcball || input.mouseDown( fggl::gfx::MOUSE_2 ) ) { CameraArcball(it, t, c); } else if ( cam_mode == cam_free ) { -// CameraFree(it, t, c); + CameraFree(it, t, c); } - /* - auto camTransform = ecs.getComponent<fggl::math::Transform>(cam); - auto camComp = ecs.getComponent<fggl::gfx::Camera>(cam); + // scroll wheel + auto& camTransform = t[0]; + auto& camComp = c[0]; - const glm::vec3 dir = ( camTransform->origin() - camComp->target ); - const glm::vec3 forward = glm::normalize( dir ); + CameraEdgeScroll(input, camTransform, camComp); + + const glm::vec3 dir = ( camTransform.origin() - camComp.target ); + const glm::vec3 forward = glm::normalize( dir ); - // scroll wheel glm::vec3 motion(0.0f); float delta = (float)input.scrollDeltaY(); if ( (glm::length( dir ) < 25.0f && delta < 0.0f) || (glm::length( dir ) > 2.5f && delta > 0.0f) ) - motion -= (forward * delta); + motion -= (forward * delta); - camTransform->origin( camTransform->origin() + motion ); - */ + camTransform.origin( camTransform.origin() + motion ); } void CameraArcball(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c) { @@ -102,21 +103,10 @@ void CameraArcball(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, f const fggl::gfx::Window& window = hacks->window; const fggl::gfx::Input& input = hacks->input; - auto& camTransform = t[0]; auto& camComp = c[0]; - // scroll wheel - const glm::vec3 dir = ( camTransform.origin() - camComp.target ); - const glm::vec3 forward = glm::normalize( dir ); - - glm::vec3 motion(0.0f); - float delta = (float)input.scrollDeltaY(); - if ( (glm::length( dir ) < 25.0f && delta < 0.0f) || (glm::length( dir ) > 2.5f && delta > 0.0f) ) - motion -= (forward * delta); - auto finalPos = camTransform.origin(); - if ( input.mouseDown( fggl::gfx::MOUSE_2 ) ) { // see https://asliceofrendering.com/camera/2019/11/30/ArcballCamera/ glm::vec4 position(camTransform.origin(), 1.0f); glm::vec4 pivot(camComp.target, 1.0f); @@ -143,19 +133,18 @@ void CameraArcball(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, f glm::mat4x4 rotationMatrixY(1.0f); rotationMatrixY = glm::rotate(rotationMatrixY, yAngle, rightDir ); finalPos = ( rotationMatrixY * ( position - pivot ) ) + pivot; - } - camTransform.origin( finalPos + motion ); + camTransform.origin( finalPos ); } constexpr float ROT_SPEED = 0.05f; constexpr float PAN_SPEED = 0.05f; constexpr glm::mat4 MAT_IDENTITY(1.0f); -void process_freecam(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c) { +void CameraFree(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, fggl::components::Camera* c) { CameraHacks* hacks = (CameraHacks*)( it.ctx() ); - const fggl::gfx::Window& window = hacks->window; - const fggl::gfx::Input& input = hacks->input; + fggl::gfx::Window& window = hacks->window; + fggl::gfx::Input& input = hacks->input; auto& camTransform = t[0]; auto& camComp = c[0]; @@ -164,7 +153,7 @@ void process_freecam(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, glm::vec3 translation(0.0f); // calulate rotation (user input) -/* if ( glfwGetKey(window.handle(), GLFW_KEY_Q) == GLFW_PRESS ) { + if ( glfwGetKey(window.handle(), GLFW_KEY_Q) == GLFW_PRESS ) { rotationValue = ROT_SPEED; } else if ( glfwGetKey(window.handle(), GLFW_KEY_E) == GLFW_PRESS ) { rotationValue = -ROT_SPEED; @@ -185,7 +174,7 @@ void process_freecam(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, if ( glfwGetKey(window.handle(), GLFW_KEY_A) == GLFW_PRESS ) { translation -= fggl::math::FORWARD; - }*/ + } glm::vec4 position( camTransform.origin(), 1.0f ); glm::vec4 pivot( camComp.target, 1.0f ); @@ -213,6 +202,55 @@ void process_freecam(fggl::ecs2::impl::iter& it, fggl::components::Transform* t, camComp.target = pivot; } +void CameraEdgeScroll(fggl::gfx::Input& input, fggl::components::Transform& t, fggl::components::Camera& c) { + auto cursor = input.mousePos(); + + float rotationValue = 0.0f; + glm::vec3 translation(0.0f); + + // calulate movement (user input) + if ( cursor[1] > 0.95f ) { + translation += fggl::math::RIGHT; + } + + if ( cursor[1] < -0.95f ) { + translation -= fggl::math::RIGHT; + } + + if ( cursor[0] > 0.95f ) { + translation += fggl::math::FORWARD; + } + + if ( cursor[0] < -0.95f ) { + translation -= fggl::math::FORWARD; + } + + glm::vec4 position( t.origin(), 1.0f ); + glm::vec4 pivot( c.target, 1.0f ); + + // apply movement + if ( translation != glm::vec3(0.0f) ) { + const auto rotation = (position - pivot); + const float angle = atan2( rotation.x, rotation.z ); + const auto rotationMat = glm::rotate( MAT_IDENTITY, angle, fggl::math::UP ); + + auto deltaMove = (rotationMat * glm::vec4( translation, 1.0f )) * PAN_SPEED; + deltaMove.w = 0.0f; + + position += deltaMove; + pivot += deltaMove; + } + + // apply rotation + if ( rotationValue != 0.0f ) { + glm::mat4 rotation = glm::rotate( MAT_IDENTITY, rotationValue, fggl::math::UP ); + position = ( rotation * ( position - pivot ) ) + pivot; + } + + t.origin( position ); + c.target = pivot; +} + void loadShader(fggl::gfx::ShaderCache& cache, const char* name, bool hasGeom) { fggl::gfx::ShaderConfig config; config.name = name; @@ -326,7 +364,7 @@ int main(int argc, char* argv[]) { world.ecs().system<fggl::components::Transform, fggl::components::Camera>() .ctx( &hacks ) - .iter( CameraArcball ); + .iter( CameraInput ); bool joystickWindow = true; bool gamepadWindow = true; diff --git a/fggl/gfx/input.cpp b/fggl/gfx/input.cpp index 8be1ecb..0d14108 100644 --- a/fggl/gfx/input.cpp +++ b/fggl/gfx/input.cpp @@ -52,7 +52,7 @@ double Input::cursorDeltaY() const { } const double* Input::mousePos() const { - return m_mouse_curr.scroll.data(); + return m_mouse_curr.cursor.data(); } void Input::mouseScroll(double deltaX, double deltaY) { diff --git a/fggl/gfx/window.cpp b/fggl/gfx/window.cpp index f1aa1b5..168d2df 100644 --- a/fggl/gfx/window.cpp +++ b/fggl/gfx/window.cpp @@ -22,7 +22,12 @@ static void framebuffer_resize(GLFWwindow* window, int width, int height) { } static void fggl_input_cursor(GLFWwindow* window, double x, double y) { + auto fgglWindow = reinterpret_cast<Window*>(glfwGetWindowUserPointer( window )); Input& input = Input::instance(); + + // set coords in [-1, 1] + x = ((x / fgglWindow->width()) - 0.5f) * 2; + y = ((y / fgglWindow->height()) - 0.5f) * 2; input.mousePos(x, y); } -- GitLab