diff --git a/src/Application.cpp b/src/Application.cpp index ed43e04..ceb01c4 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -91,7 +91,6 @@ void Application::Init(int width, int height, const std::string& title) float aspectRatio = (float)width / (float)height; data->camera->Update(100.0f, aspectRatio, 0.01f, 100.0f); - data->orthoCam->Update(-3.0f * aspectRatio, 3.0f * aspectRatio, -3.0f, 3.0f, -100.0f, 100.0f); glViewport(0, 0, width, height); } @@ -121,17 +120,11 @@ void Application::Init(int width, int height, const std::string& title) ImGui::StyleColorsDark(); float aspectRatio = (float)windowWidth / (float)windowHeight; - camera = Camera(100.0f, aspectRatio); - camera.Move(glm::vec3(0.0f, 4.0f, -4.0f)); - camera.LookAt(glm::vec3(0.0f)); + camera = OrbitingCamera(glm::vec3(0.0f, 0.0f, 0.0f), 6.0f); + pitch = camera.GetAngles().x; + yaw = camera.GetAngles().y; - orthoCam = OrthogonalCamera(-3.0f * aspectRatio, 3.0f * aspectRatio, -3.0f, 3.0f); - orthoCam.Move(glm::vec3(0.0f, 4.0f, -4.0f)); - orthoCam.LookAt(glm::vec3(0.0f)); - - activeCamera = &camera; - - plot = new Plot3D({ -glm::two_pi(), -glm::two_pi(), -1.5f, glm::two_pi(), glm::two_pi(), 1.5f }, 0.5f, 0.1f, + plot = new Plot3D({ -glm::two_pi(), -1.5f * glm::two_pi(), -1.5f, glm::two_pi(), 1.5f * glm::two_pi(), 1.5f }, 0.5f, 0.1f, [](float x, float y) { return (cos(x) + cos(y)) * 0.5f; @@ -144,7 +137,6 @@ void Application::Init(int width, int height, const std::string& title) cubeScale = glm::vec3(1.0f); data.camera = &camera; - data.orthoCam = &orthoCam; glfwWindowHint(GLFW_SAMPLES, 4); @@ -162,6 +154,8 @@ void Application::Launch() plot->SetRotation(cubeOrientation); plot->SetScale(cubeScale); + camera.SetPosition(pitch, yaw); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -169,7 +163,7 @@ void Application::Launch() ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - plot->Draw(*activeCamera); + plot->Draw(camera); ImGui::Begin("Debug"); @@ -182,16 +176,8 @@ void Application::Launch() if (ImGui::CollapsingHeader("Camera")) { - ImGui::Columns(2); - ImGui::Text("Projection: "); - ImGui::NextColumn(); - if (ImGui::Button((activeCamera == &camera) ? "Perspective" : "Orthographic")) - { - if (activeCamera == &camera) - activeCamera = &orthoCam; - else - activeCamera = &camera; - } + ImGui::SliderFloat("Yaw", &yaw, 0.0f, 360.0f); + ImGui::SliderFloat("Pitch", &pitch, 1.0f, 179.0f); } ImGui::End(); diff --git a/src/Application.hpp b/src/Application.hpp index 556d194..ad110f0 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "backend/Camera.hpp" +#include "OrbitingCamera.hpp" #include "Plot3D.hpp" struct GLFWwindow; @@ -42,9 +42,8 @@ private: GLFWwindow* window = nullptr; WindowData data; - Camera camera; - OrthogonalCamera orthoCam; - CameraBase* activeCamera; + OrbitingCamera camera; + float pitch, yaw; glm::vec3 cubeOrientation, cubePosition, cubeScale; Plot3D* plot; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d7c25b5..87037f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ add_executable(visualizer "main.cpp" "Application.cpp" - "Plot3D.cpp") + "Plot3D.cpp" "OrbitingCamera.cpp") target_sources(visualizer PUBLIC ${VENDOR_DIR}/imgui/backends/imgui_impl_opengl3.cpp diff --git a/src/OrbitingCamera.cpp b/src/OrbitingCamera.cpp new file mode 100644 index 0000000..9cea28a --- /dev/null +++ b/src/OrbitingCamera.cpp @@ -0,0 +1,39 @@ +#include "OrbitingCamera.hpp" + +OrbitingCamera::OrbitingCamera(const glm::vec3& target, float distance, const glm::vec2& pitchRange) : + target(target), distance(distance), pitchRange(pitchRange) +{ + pitch = pitchRange.x + (pitchRange.y - pitchRange.x) / 2; + yaw = 0.0f; +} + +void OrbitingCamera::Pan(float amount) +{ + yaw += amount; + if (yaw < 0.0f || yaw >= 360.0f) + yaw = 0.0f; + + CalculateMatrix(); +} + +void OrbitingCamera::Tilt(float amount) +{ + pitch += amount; + if (pitch < pitchRange.x) + pitch = pitchRange.x; + else if (pitch > pitchRange.y) + pitch = pitchRange.y; + + CalculateMatrix(); +} + +void OrbitingCamera::CalculateMatrix() +{ + glm::vec3 position = distance * glm::vec3( + cos(glm::radians(yaw)) * sin(glm::radians(pitch)), + cos(glm::radians(pitch)), + sin(glm::radians(yaw)) * sin(glm::radians(pitch)) + ); + + transformation = glm::lookAt(position, target, glm::vec3(0.0f, 1.0f, 0.0f)); +} diff --git a/src/OrbitingCamera.hpp b/src/OrbitingCamera.hpp new file mode 100644 index 0000000..602e8c4 --- /dev/null +++ b/src/OrbitingCamera.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "backend/Camera.hpp" + +class OrbitingCamera : public Camera +{ +public: + OrbitingCamera() {} + OrbitingCamera(const glm::vec3& target, float distance, const glm::vec2& verticalRange = glm::vec2(1.0f, 179.0f)); + + inline void SetPosition(float pitch, float yaw) + { + this->pitch = pitch; + this->yaw = yaw; + + CalculateMatrix(); + } + + inline glm::vec2 GetAngles() + { + return glm::vec2(pitch, yaw); + } + + void Pan(float amount); + void Tilt(float amount); + +private: + void CalculateMatrix(); + +private: + float pitch, yaw; + float distance; + glm::vec3 target; + + glm::vec2 pitchRange; +}; \ No newline at end of file