Basic zoom implemented

This commit is contained in:
Jan Mrna 2025-10-05 21:20:30 +02:00 committed by Mrna
parent f5304d045d
commit 71e6bdb904
6 changed files with 70 additions and 30 deletions

View File

@ -8,25 +8,26 @@
void Camera::Pan(const WorldPos& delta) void Camera::Pan(const WorldPos& delta)
{ {
LOG_DEBUG("m_Pan before: ", m_Pan, " delta ", delta);
m_Pan += delta; m_Pan += delta;
LOG_DEBUG("m_Pan after: ", m_Pan);
} }
void Camera::Zoom(const WorldPos&) void Camera::Zoom(float delta)
{ {
constexpr float ZOOM_SCALE = 0.1f;
m_Zoom += delta * ZOOM_SCALE;
LOG_DEBUG("Zoom: ", m_Zoom);
} }
WindowPos Camera::WorldToWindow(WorldPos world) const WindowPos Camera::WorldToWindow(WorldPos world) const
{ {
const auto& v = world + m_Pan; const auto& v = world + m_Pan;
return WindowPos{v[0], v[1]}; return WindowPos{v[0], v[1]} * m_Zoom;
} }
WorldPos Camera::WindowToWorld(WindowPos window) const WorldPos Camera::WindowToWorld(WindowPos window) const
{ {
return WorldPos{window[0], window[1]} - m_Pan; window /= m_Zoom;
return WorldPos{window[0], window[1]} - m_Pan;
} }

View File

@ -6,7 +6,7 @@ class Camera
{ {
public: public:
void Pan(const WorldPos& delta); void Pan(const WorldPos& delta);
void Zoom(const WorldPos& delta); void Zoom(float delta);
WindowPos WorldToWindow(WorldPos) const; WindowPos WorldToWindow(WorldPos) const;
WorldPos WindowToWorld(WindowPos) const; WorldPos WindowToWorld(WindowPos) const;
@ -15,6 +15,6 @@ public:
private: private:
// TODO this should be replaced with a matrix // TODO this should be replaced with a matrix
float m_Zoom; float m_Zoom = 1.0f;
WorldPos m_Pan; WorldPos m_Pan;
}; };

View File

@ -127,6 +127,15 @@ public:
return a; return a;
} }
vec& operator/=(float scalar)
{
vec& a = *this;
auto b = std::views::repeat(scalar);
std::ranges::transform(a.m_Array, b, a.m_Array.begin(), std::divides{});
// TODO check all of this, could be done better with views instead of ranges?
return a;
}
// //
// Utility functions // Utility functions
// //

View File

@ -93,7 +93,8 @@ void PathFindingDemo::UpdatePlayerVelocity() {
double tile_velocity_coeff = m_Map.GetTileVelocityCoeff(current_pos); double tile_velocity_coeff = m_Map.GetTileVelocityCoeff(current_pos);
auto next_pos = GetMoveTarget(); auto next_pos = GetMoveTarget();
WorldPos velocity = WorldPos{}; WorldPos velocity = WorldPos{};
if (next_pos) { if (next_pos)
{
velocity = next_pos.value() - current_pos; velocity = next_pos.value() - current_pos;
velocity.Normalize(); velocity.Normalize();
//LOG_DEBUG("I want to move to: ", next_pos.value(), //LOG_DEBUG("I want to move to: ", next_pos.value(),
@ -104,26 +105,40 @@ void PathFindingDemo::UpdatePlayerVelocity() {
player->Update(time_delta); player->Update(time_delta);
} }
void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions) { void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions)
for (const auto &action : actions) { {
if (action.type == UserAction::Type::EXIT) { for (const auto &action : actions)
{
if (action.type == UserAction::Type::EXIT)
{
LOG_INFO("Exit requested"); LOG_INFO("Exit requested");
m_ExitRequested = true; m_ExitRequested = true;
} else if (action.type == UserAction::Type::SET_MOVE_TARGET) { }
else if (action.type == UserAction::Type::SET_MOVE_TARGET)
{
WorldPos wp = m_Camera.WindowToWorld(action.Argument.position); WorldPos wp = m_Camera.WindowToWorld(action.Argument.position);
LOG_INFO("Calculating path to target: ", wp); LOG_INFO("Calculating path to target: ", wp);
m_Path = m_PathFinder->CalculatePath(m_Player->GetPosition(), wp); m_Path = m_PathFinder->CalculatePath(m_Player->GetPosition(), wp);
LOG_INFO("Done, path node count: ", m_Path.size()); LOG_INFO("Done, path node count: ", m_Path.size());
} else if (action.type == UserAction::Type::SELECT_PATHFINDER) { }
else if (action.type == UserAction::Type::SELECT_PATHFINDER)
{
using namespace pathfinder; using namespace pathfinder;
PathFinderType type = static_cast<PathFinderType>(action.Argument.number); PathFinderType type = static_cast<PathFinderType>(action.Argument.number);
m_PathFinder = pathfinder::utils::create(type, (const Map*)&m_Map); m_PathFinder = pathfinder::utils::create(type, (const Map*)&m_Map);
LOG_INFO("Switched to path finding method: ", m_PathFinder->GetName()); LOG_INFO("Switched to path finding method: ", m_PathFinder->GetName());
} else if (action.type == UserAction::Type::CAMERA_PAN) { }
else if (action.type == UserAction::Type::CAMERA_PAN)
{
const auto& window_pan = action.Argument.position; const auto& window_pan = action.Argument.position;
WorldPos world_pan{window_pan.x(), window_pan.y()}; WorldPos world_pan{window_pan.x(), window_pan.y()};
m_Camera.Pan(world_pan); m_Camera.Pan(world_pan);
LOG_INFO("Camera pan delta: ", world_pan); LOG_INFO("Camera pan delta: ", world_pan);
} }
else if (action.type == UserAction::Type::CAMERA_ZOOM)
{
m_Camera.Zoom(action.Argument.float_number);
LOG_INFO("Camera zoom: ", action.Argument.float_number);
}
}; };
} }

View File

@ -24,30 +24,43 @@ void UserInput::GetActions_mouse(const SDL_Event& event)
{ {
static bool mouse_pan = false; static bool mouse_pan = false;
if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { SDL_MouseButtonEvent mouse_event = event.button;
SDL_MouseButtonEvent mouse_event = event.button; MouseButton button = static_cast<MouseButton>(mouse_event.button);
MouseButton button = static_cast<MouseButton>(mouse_event.button);
if (button == MouseButton::LEFT) { if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
{
if (button == MouseButton::LEFT)
{
LOG_DEBUG("Mouse down: ", mouse_event.x, ", ", mouse_event.y); LOG_DEBUG("Mouse down: ", mouse_event.x, ", ", mouse_event.y);
m_Actions.emplace_back(UserAction::Type::SET_MOVE_TARGET, m_Actions.emplace_back(UserAction::Type::SET_MOVE_TARGET,
WindowPos{mouse_event.x, mouse_event.y}); WindowPos{mouse_event.x, mouse_event.y});
} else if (button == MouseButton::MIDDLE) { }
else if (button == MouseButton::MIDDLE)
{
mouse_pan = true; mouse_pan = true;
} }
} else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP) { }
SDL_MouseButtonEvent mouse_event = event.button; else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP)
MouseButton button = static_cast<MouseButton>(mouse_event.button); {
if (button == MouseButton::MIDDLE) { if (button == MouseButton::MIDDLE)
{
mouse_pan = false; mouse_pan = false;
} }
} else if (event.type == SDL_EVENT_MOUSE_MOTION) { }
else if (event.type == SDL_EVENT_MOUSE_MOTION)
{
SDL_MouseMotionEvent motion_event = event.motion; SDL_MouseMotionEvent motion_event = event.motion;
if (mouse_pan) { if (mouse_pan)
{
m_Actions.emplace_back(UserAction::Type::CAMERA_PAN, m_Actions.emplace_back(UserAction::Type::CAMERA_PAN,
WindowPos{motion_event.xrel, motion_event.yrel}); WindowPos{motion_event.xrel, motion_event.yrel});
} }
} }
else if(event.type == SDL_EVENT_MOUSE_WHEEL)
{
SDL_MouseWheelEvent mouse_wheel = event.wheel;
m_Actions.emplace_back(UserAction::Type::CAMERA_ZOOM, mouse_wheel.y);
}
} }
void UserInput::GetActions_keyboard(const SDL_Event& event) void UserInput::GetActions_keyboard(const SDL_Event& event)

View File

@ -18,7 +18,8 @@ public:
UserAction(Type t) : type(t), Argument{.number = 0} {} UserAction(Type t) : type(t), Argument{.number = 0} {}
UserAction(Type t, char key) : type(t), Argument{.key = key} {} UserAction(Type t, char key) : type(t), Argument{.key = key} {}
UserAction(Type t, WindowPos v) : type(t), Argument{.position = v} {} UserAction(Type t, WindowPos v) : type(t), Argument{.position = v} {}
UserAction(Type t, int arg) : type(t), Argument{.number = arg} {} UserAction(Type t, int32_t arg) : type(t), Argument{.number = arg} {}
UserAction(Type t, float arg) : type(t), Argument{.float_number = arg} {}
~UserAction() = default; ~UserAction() = default;
Type type; Type type;
@ -26,7 +27,8 @@ public:
union { union {
WindowPos position; WindowPos position;
char key; char key;
int number; int32_t number;
float float_number;
} Argument; } Argument;
// TODO use std::variant // TODO use std::variant