From b08f360cf92e76fabf5b762bf79032f60f751e30 Mon Sep 17 00:00:00 2001 From: Aki Date: Sun, 5 Jun 2022 12:02:17 +0200 Subject: Added cameraman to handle camera --- CMakeLists.txt | 1 + Cameraman.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ Cameraman.h | 14 ++++++++++++++ View.cpp | 18 ++++++------------ View.h | 3 ++- 5 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 Cameraman.cpp create mode 100644 Cameraman.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5afaadc..f703cc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ find_package(nlohmann_json 3.2 REQUIRED) add_executable( ${PROJECT_NAME} App.cpp + Cameraman.cpp Icons.cpp main.cpp Reader.cpp diff --git a/Cameraman.cpp b/Cameraman.cpp new file mode 100644 index 0000000..f65cb44 --- /dev/null +++ b/Cameraman.cpp @@ -0,0 +1,44 @@ +#include "Cameraman.h" + +#include +#include + +#include +#include + +#include "VectorMath.h" + + +Cameraman::Cameraman() +{ + camera.position = Vector3{10.0f, 10.0f, 10.0f}; + camera.target = Vector3{0.0f, 0.0f, 0.0f}; + camera.up = Vector3{0.0f, 1.0f, 0.0f}; + camera.fovy = 45; + camera.projection = CAMERA_PERSPECTIVE; + SetCameraMode(camera, CAMERA_CUSTOM); + m_angle.x = std::atan2(10.0f, 10.0f); + m_angle.y = std::atan2(10.0f, std::sqrt(std::pow(10.0f, 2) + std::pow(10.0f, 2))); +} + + +void +Cameraman::update(const float) +{ + const auto drag = GetMouseDelta(); + if (IsMouseButtonDown(0)) { + m_angle.x += drag.x * -0.01f; + m_angle.y = std::clamp(m_angle.y + drag.y * 0.01f, -1.483f, 1.483f); + } + const float zoom = GetMouseWheelMove(); + if (zoom != 0.0f) { + const auto offset = Vector3Subtract(camera.target, camera.position); + const float current = Vector3Length(offset); + const float expected = std::clamp(current + zoom * 0.5f, 1.0f, 30.0f); + camera.position = Vector3Add(camera.target, Vector3Scale(offset, expected / current)); + } + const float distance = dist(camera.position, camera.target); + camera.position.x = camera.target.x + distance * -std::sin(m_angle.x) * std::cos(m_angle.y); + camera.position.y = camera.target.y + distance * std::sin(m_angle.y); + camera.position.z = camera.target.z + distance * -std::cos(m_angle.x) * std::cos(m_angle.y); +} diff --git a/Cameraman.h b/Cameraman.h new file mode 100644 index 0000000..29d585c --- /dev/null +++ b/Cameraman.h @@ -0,0 +1,14 @@ +#pragma once + +#include + + +class Cameraman +{ +public: + Cameraman(); + void update(float dt); + Camera camera; +private: + Vector2 m_angle; +}; diff --git a/View.cpp b/View.cpp index 4877ba4..6f09ba5 100644 --- a/View.cpp +++ b/View.cpp @@ -19,19 +19,13 @@ const Color LINE {240, 240, 240, 160}; View::View(std::vector grids, Timeline timeline) : - m_camera {}, + m_cameraman {}, m_grids {grids}, m_labels {}, m_grid {0}, m_active {nullptr}, m_timeline {timeline} { - m_camera.position = Vector3{10.0f, 10.0f, 10.0f}; - m_camera.target = Vector3{0.0f, 0.0f, 0.0f}; - m_camera.up = Vector3{0.0f, 1.0f, 0.0f}; - m_camera.fovy = 45; - m_camera.projection = CAMERA_PERSPECTIVE; - SetCameraMode(m_camera, CAMERA_ORBITAL); } @@ -48,8 +42,8 @@ View::update(const float dt) if (m_grid >= m_grids.size()) m_grid = 0; } + m_cameraman.update(dt); m_timeline.move(dt * 60); - UpdateCamera(&m_camera); const int height = GetScreenHeight(); const int width = GetScreenWidth(); const auto& wrecks = m_grids.at(m_grid).wrecks; @@ -57,12 +51,12 @@ View::update(const float dt) m_labels.reserve(wrecks.size()); const auto mouse = GetMousePosition(); for (const auto& wreck : wrecks) { - const auto pos = GetWorldToScreen(wreck.position, m_camera); - const auto base = GetWorldToScreen({wreck.position.x, 0.0f, wreck.position.z}, m_camera); + const auto pos = GetWorldToScreen(wreck.position, m_cameraman.camera); + const auto base = GetWorldToScreen({wreck.position.x, 0.0f, wreck.position.z}, m_cameraman.camera); if (0 > pos.x || width < pos.x || 0 > pos.y || height < pos.y) if (0 > base.x || width < base.x || 0 > base.y || height < base.y) continue; - const auto depth = dist(m_camera.position, wreck.position); + const auto depth = dist(m_cameraman.camera.position, wreck.position); const auto length = dist(pos, base); const bool hover = 8.0f > dist(mouse, pos); m_labels.push_back( @@ -86,7 +80,7 @@ View::draw() const { BeginDrawing(); ClearBackground(BACKGROUND); - BeginMode3D(m_camera); + BeginMode3D(m_cameraman.camera); DrawGrid(12, 1.0f); EndMode3D(); for (const auto& point : m_labels) { diff --git a/View.h b/View.h index e98502a..8e0a1f0 100644 --- a/View.h +++ b/View.h @@ -4,6 +4,7 @@ #include +#include "Cameraman.h" #include "Grid.h" #include "Label.h" #include "Timeline.h" @@ -17,7 +18,7 @@ public: void update(float dt); void draw() const; private: - Camera m_camera; + Cameraman m_cameraman; std::vector m_grids; std::vector