diff --git a/VulkanTest b/VulkanTest index a6d84c4..aff8aa9 100755 Binary files a/VulkanTest and b/VulkanTest differ diff --git a/first_app.cpp b/first_app.cpp index 15bc658..18d77df 100644 --- a/first_app.cpp +++ b/first_app.cpp @@ -1,6 +1,8 @@ #include "first_app.hpp" #include "simple_render_system.hpp" #include "rainbow_system.hpp" + +#include "keyboard_movement_controller.hpp" #include "hk_camera.hpp" // libs @@ -11,6 +13,7 @@ // std #include +#include #include @@ -30,18 +33,27 @@ namespace hk SimpleRenderSystem simpleRenderSystem{m_device, m_renderer.getSwapChainRenderPass()}; RainbowSystem rainbowSystem(2000.0f); Camera camera{}; - //camera.setViewDirection(glm::vec3(0.f), glm::vec3(0.5f, 0.f, 1.f)); - camera.setViewTarget(glm::vec3(-1.f, -2.f, -2.f), glm::vec3(0.f, 0.f, 2.5f)); + + auto viewerObject = GameObject::createGameObject(); + KeyboardMovementController cameraController{}; + + auto currentTime = std::chrono::high_resolution_clock::now(); while (!m_window.shouldClose()) { glfwPollEvents(); + + auto newTime = std::chrono::high_resolution_clock::now(); + float frameTime = std::chrono::duration(newTime - currentTime).count(); + currentTime = newTime; + + cameraController.moveInPlaneXZ(m_window.getWindow(), frameTime, viewerObject); + camera.setViewYXZ(viewerObject.m_transform.translation, viewerObject.m_transform.rotation); // update objects color rainbowSystem.update(5.0f, m_gameObjects); float aspect = m_renderer.getAspectRatio(); - //camera.setOrthographicProjection(-aspect, aspect, -1, 1, -1, 1); camera.setPerspectiveProjection(glm::radians(50.f), aspect, 0.1f, 10.f); if (auto commandBuffer = m_renderer.beginFrame()) { diff --git a/hk_camera.cpp b/hk_camera.cpp index 7d6191e..8ef12e7 100644 --- a/hk_camera.cpp +++ b/hk_camera.cpp @@ -43,6 +43,20 @@ namespace hk m_viewMatrix[3][0] = -glm::dot(u, position); m_viewMatrix[3][1] = -glm::dot(v, position); m_viewMatrix[3][2] = -glm::dot(w, position); + + m_inverseViewMatrix = glm::mat4{1.0f}; + m_inverseViewMatrix[0][0] = u.x; + m_inverseViewMatrix[0][1] = u.y; + m_inverseViewMatrix[0][2] = u.z; + m_inverseViewMatrix[1][0] = v.x; + m_inverseViewMatrix[1][1] = v.y; + m_inverseViewMatrix[1][2] = v.z; + m_inverseViewMatrix[2][0] = w.x; + m_inverseViewMatrix[2][1] = w.y; + m_inverseViewMatrix[2][2] = w.z; + m_inverseViewMatrix[3][0] = position.x; + m_inverseViewMatrix[3][1] = position.y; + m_inverseViewMatrix[3][2] = position.z; } void Camera::setViewTarget(glm::vec3 position, glm::vec3 target, glm::vec3 up) { @@ -73,5 +87,19 @@ namespace hk m_viewMatrix[3][0] = -glm::dot(u, position); m_viewMatrix[3][1] = -glm::dot(v, position); m_viewMatrix[3][2] = -glm::dot(w, position); + + m_inverseViewMatrix = glm::mat4{1.0f}; + m_inverseViewMatrix[0][0] = u.x; + m_inverseViewMatrix[0][1] = u.y; + m_inverseViewMatrix[0][2] = u.z; + m_inverseViewMatrix[1][0] = v.x; + m_inverseViewMatrix[1][1] = v.y; + m_inverseViewMatrix[1][2] = v.z; + m_inverseViewMatrix[2][0] = w.x; + m_inverseViewMatrix[2][1] = w.y; + m_inverseViewMatrix[2][2] = w.z; + m_inverseViewMatrix[3][0] = position.x; + m_inverseViewMatrix[3][1] = position.y; + m_inverseViewMatrix[3][2] = position.z; } } // namespace hk \ No newline at end of file diff --git a/hk_camera.hpp b/hk_camera.hpp index c9395e5..f5e66f5 100644 --- a/hk_camera.hpp +++ b/hk_camera.hpp @@ -22,8 +22,10 @@ namespace hk const glm::mat4& getProjection() const { return m_projectionMatrix; } const glm::mat4& getView() const { return m_viewMatrix; } + const glm::mat4& getInverseView() const { return m_inverseViewMatrix; } private: glm::mat4 m_projectionMatrix{1.0f}; glm::mat4 m_viewMatrix{1.0f}; + glm::mat4 m_inverseViewMatrix{1.0f}; }; } // namespace hk \ No newline at end of file diff --git a/hk_window.hpp b/hk_window.hpp index 6fb8216..c88c050 100644 --- a/hk_window.hpp +++ b/hk_window.hpp @@ -16,6 +16,8 @@ namespace hk Window(const Window&) = delete; Window &operator=(const Window&) = delete; + GLFWwindow* getWindow() { return m_window; } + bool shouldClose() { return glfwWindowShouldClose(m_window); } VkExtent2D getExtend() { return {static_cast(m_width), static_cast(m_height)}; } bool wasWindowResized() { return m_framebufferResized; } diff --git a/keyboard_movement_controller.cpp b/keyboard_movement_controller.cpp new file mode 100644 index 0000000..c5a3b10 --- /dev/null +++ b/keyboard_movement_controller.cpp @@ -0,0 +1,42 @@ +#include "keyboard_movement_controller.hpp" + +namespace hk +{ + void KeyboardMovementController::moveInPlaneXZ(GLFWwindow *window, float dt, GameObject &gameObject) + { + glm::vec3 rotate{0}; + if (glfwGetKey(window, m_keys.lookRight) == GLFW_PRESS) rotate.y += 1.f; + if (glfwGetKey(window, m_keys.lookLeft) == GLFW_PRESS) rotate.y -= 1.f; + if (glfwGetKey(window, m_keys.lookUp) == GLFW_PRESS) rotate.x += 1.f; + if (glfwGetKey(window, m_keys.lookDown) == GLFW_PRESS) rotate.x -= 1.f; + + if (glm::dot(rotate, rotate) > std::numeric_limits::epsilon()) + { + gameObject.m_transform.rotation += m_lookSpeed * dt * glm::normalize(rotate); + } + + // limit pitch values between about +/-85ish degrees + gameObject.m_transform.rotation.x = glm::clamp(gameObject.m_transform.rotation.x, -1.5f, 1.5f); + gameObject.m_transform.rotation.y = glm::mod(gameObject.m_transform.rotation.y, glm::two_pi()); + + + float yaw = gameObject.m_transform.rotation.y; + const glm::vec3 forwardDir{sin(yaw), 0.f, cos(yaw)}; + const glm::vec3 rightDir{forwardDir.z, 0.f, -forwardDir.x}; + const glm::vec3 upDir{0.f, -1.f, 0.f}; + + glm::vec3 moveDir{0.f}; + if (glfwGetKey(window, m_keys.moveForward) == GLFW_PRESS) moveDir += forwardDir; + if (glfwGetKey(window, m_keys.moveBackward) == GLFW_PRESS) moveDir -= forwardDir; + if (glfwGetKey(window, m_keys.moveRight) == GLFW_PRESS) moveDir += rightDir; + if (glfwGetKey(window, m_keys.moveLeft) == GLFW_PRESS) moveDir -= rightDir; + if (glfwGetKey(window, m_keys.moveUp) == GLFW_PRESS) moveDir += upDir; + if (glfwGetKey(window, m_keys.moveDown) == GLFW_PRESS) moveDir -= upDir; + + if (glm::dot(moveDir, moveDir) > std::numeric_limits::epsilon()) + { + gameObject.m_transform.translation += m_moveSpeed * dt * glm::normalize(moveDir); + } + } + +} \ No newline at end of file diff --git a/keyboard_movement_controller.hpp b/keyboard_movement_controller.hpp new file mode 100644 index 0000000..34883ff --- /dev/null +++ b/keyboard_movement_controller.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace hk +{ + class KeyboardMovementController + { + public: + struct KeyMappings + { + int moveLeft{ GLFW_KEY_A }; + int moveRight{ GLFW_KEY_D }; + int moveForward{ GLFW_KEY_W }; + int moveBackward{ GLFW_KEY_S }; + int moveUp{ GLFW_KEY_E }; + int moveDown{ GLFW_KEY_Q }; + int lookLeft{ GLFW_KEY_LEFT }; + int lookRight{ GLFW_KEY_RIGHT }; + int lookUp{ GLFW_KEY_UP }; + int lookDown{ GLFW_KEY_DOWN }; + }; + + void moveInPlaneXZ(GLFWwindow *window, float dt, GameObject &gameObject); + + KeyMappings m_keys{}; + float m_moveSpeed{ 3.f }; + float m_lookSpeed{ 1.5f }; + }; +} \ No newline at end of file diff --git a/simple_render_system.cpp b/simple_render_system.cpp index 166339f..8f6a5f8 100644 --- a/simple_render_system.cpp +++ b/simple_render_system.cpp @@ -70,13 +70,10 @@ namespace hk { m_pipeline->bind(commandBuffer); - auto projectionView = camera.getProjection() * camera.getView(); + auto projectionView = camera.getProjection() * camera.getInverseView(); for (auto &obj : gameObjects) { - obj.m_transform.rotation.y = glm::mod(obj.m_transform.rotation.y + 0.01f, glm::two_pi()); - obj.m_transform.rotation.x = glm::mod(obj.m_transform.rotation.x + 0.005f, glm::two_pi()); - SimplePushConstantData push{}; push.color = obj.m_color; push.transform = projectionView * obj.m_transform.mat4();