From 31abb8a48f3acac6e8aa010ba592e915c4c404c9 Mon Sep 17 00:00:00 2001 From: mniip Date: Sun, 19 Feb 2023 20:15:22 +0100 Subject: [PATCH] Use integer matrices for GameSave transforms --- src/client/GameSave.cpp | 57 ++++++++++++++++----------------- src/client/GameSave.h | 6 ++-- src/gui/game/GameController.cpp | 9 +++--- src/gui/game/GameController.h | 2 +- src/gui/game/GameView.cpp | 6 ++-- 5 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 96a0c2df6..837562cb4 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -120,9 +120,8 @@ inline Vec2 lroundNegInf(Vec2 v) return Vec2(roundNegInf(v)); } -Vec2 GameSave::Translate(Vec2 translate) +Vec2 GameSave::Translate(Vec2 translate) { - Vec2 translateReal = translate; auto bounds = Rect(Vec2::Zero); // determine minimum and maximum position of all particles / signs @@ -135,18 +134,18 @@ Vec2 GameSave::Translate(Vec2 translate) bounds |= Rect(roundNegInf(Vec2(particles[i].x, particles[i].y) + translate)); } // determine whether corrections are needed. If moving in this direction would delete stuff, expand the save - auto backCorrection = Vec2( - std::max(0.0f, -std::floor(bounds.TopLeft.X / CELL)), - std::max(0.0f, -std::floor(bounds.TopLeft.Y / CELL)) + auto backCorrection = Vec2( + std::max(0, -int(std::floor(bounds.TopLeft.X / CELL))), + std::max(0, -int(std::floor(bounds.TopLeft.Y / CELL))) ); - auto frontCorrection = Vec2( - std::max(0, int(bounds.BottomRight.X / CELL) + 1 - blockDimen.X), // TODO: sus. std::floor? - std::max(0, int(bounds.BottomRight.Y / CELL) + 1 - blockDimen.Y) + auto frontCorrection = Vec2( + std::max(0, int(std::floor(bounds.BottomRight.X / CELL)) + 1 - blockDimen.X), + std::max(0, int(std::floor(bounds.BottomRight.Y / CELL)) + 1 - blockDimen.Y) ); // get new width based on corrections auto newDimen = [=]() { - return Vec2((Vec2(blockDimen) + backCorrection + frontCorrection) * CELL); + return (blockDimen + backCorrection + frontCorrection) * CELL; }; if (newDimen().X > XRES) frontCorrection.X = backCorrection.X = 0; @@ -154,38 +153,37 @@ Vec2 GameSave::Translate(Vec2 translate) frontCorrection.Y = backCorrection.Y = 0; // call Transform to do the transformation we wanted when calling this function + Vec2 translateReal = translate; translate += backCorrection * CELL; - Transform(Mat2::Identity, translate + backCorrection * CELL, translateReal, newDimen()); + Transform(Mat2::Identity, translate, translateReal, newDimen()); // return how much we corrected. This is used to offset the position of the current stamp // otherwise it would attempt to recenter it with the current size - return backCorrection * (-CELL) + frontCorrection * CELL; + return backCorrection * -CELL + frontCorrection * CELL; } - - -void GameSave::Transform(Mat2 transform, Vec2 translate) +void GameSave::Transform(Mat2 transform, Vec2 translate) { - Vec2 cornerso[4] = { - Vec2(0, 0), - Vec2(blockDimen.X * CELL - 1, 0), - Vec2(0, blockDimen.Y * CELL - 1), - Vec2(blockDimen.X * CELL - 1, blockDimen.Y * CELL - 1), + Vec2 cornerso[4] = { + Vec2(0, 0), + Vec2(blockDimen.X * CELL - 1, 0), + Vec2(0, blockDimen.Y * CELL - 1), + Vec2(blockDimen.X * CELL - 1, blockDimen.Y * CELL - 1), }; // undo any translation caused by rotation - auto bounds = Rect(transform * cornerso[0]); + auto bounds = Rect(transform * cornerso[0]); for (int i = 1; i < 4; i++) - bounds |= Rect(transform * cornerso[i]); - // casting as int doesn't quite do what we want with negative numbers, so use floor() - Vec2 translateReal = translate - roundNegInf(bounds.TopLeft); - auto newBounds = lroundNegInf(bounds.BottomRight) - lroundNegInf(bounds.TopLeft) + Vec2(1, 1); + bounds |= Rect(transform * cornerso[i]); + Vec2 translateReal = translate; + translate -= bounds.TopLeft; + auto newBounds = bounds.BottomRight - bounds.TopLeft + Vec2(1, 1); Transform(transform, translate, translateReal, newBounds); } // transform is a matrix describing how we want to rotate this save // translate can vary depending on whether the save is bring rotated, or if a normal translate caused it to expand // translateReal is the original amount we tried to translate, used to calculate wall shifting -void GameSave::Transform(Mat2 transform, Vec2 translate, Vec2 translateReal, Vec2 newDimen) +void GameSave::Transform(Mat2 transform, Vec2 translate, Vec2 translateReal, Vec2 newDimen) { newDimen.X = std::min(newDimen.X, XRES); newDimen.Y = std::min(newDimen.Y, YRES); @@ -201,15 +199,15 @@ void GameSave::Transform(Mat2 transform, Vec2 translate, Vec2 ambientHeatNew(newBlockDimen.X, newBlockDimen.Y, 0.0f); // Match these up with the matrices provided in GameView::OnKeyPress. - bool patchPipeR = transform == Mat2::CW; - bool patchPipeH = transform == Mat2::MirrorX; - bool patchPipeV = transform == Mat2::MirrorY; + bool patchPipeR = transform == Mat2::CCW; + bool patchPipeH = transform == Mat2::MirrorX; + bool patchPipeV = transform == Mat2::MirrorY; // rotate and translate signs, parts, walls auto bounds = Rect(Vec2::Zero, newDimen - Vec2(1, 1)); for (auto &sign : signs) { - auto pos = lroundNegInf(transform * Vec2(sign.x, sign.y) + translate); + auto pos = transform * Vec2(sign.x, sign.y) + translate; if (!bounds.Contains(pos)) { sign.text[0] = 0; @@ -221,6 +219,7 @@ void GameSave::Transform(Mat2 transform, Vec2 translate, Vec2(particles[i].x, particles[i].y) + translate); if (!bounds.Contains(pos)) { diff --git a/src/client/GameSave.h b/src/client/GameSave.h index 4438a407c..e44955bf5 100644 --- a/src/client/GameSave.h +++ b/src/client/GameSave.h @@ -133,9 +133,9 @@ public: void setSize(Vec2 dimen); // return value is [ fakeFromNewerVersion, gameData ] std::pair> Serialise() const; - Vec2 Translate(Vec2 translate); - void Transform(Mat2 transform, Vec2 translate); - void Transform(Mat2 transform, Vec2 translate, Vec2 translateReal, Vec2 newDimen); + Vec2 Translate(Vec2 translate); + void Transform(Mat2 transform, Vec2 translate); + void Transform(Mat2 transform, Vec2 translate, Vec2 translateReal, Vec2 newDimen); void Expand(const std::vector &data); diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index 5b7593aa0..411c3c1aa 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -422,17 +422,16 @@ void GameController::LoadStamp(GameSave *stamp) void GameController::TranslateSave(ui::Point point) { - auto translate = Vec2(point); - auto translated = gameModel->GetPlaceSave()->Translate(translate); + auto translated = gameModel->GetPlaceSave()->Translate(point); ui::Point currentPlaceSaveOffset = gameView->GetPlaceSaveOffset(); // resets placeSaveOffset to 0, which is why we back it up first gameModel->SetPlaceSave(gameModel->GetPlaceSave()); - gameView->SetPlaceSaveOffset(ui::Point(translated) + currentPlaceSaveOffset); + gameView->SetPlaceSaveOffset(translated + currentPlaceSaveOffset); } -void GameController::TransformSave(Mat2 transform) +void GameController::TransformSave(Mat2 transform) { - gameModel->GetPlaceSave()->Transform(transform, Vec2::Zero); + gameModel->GetPlaceSave()->Transform(transform, Vec2::Zero); gameModel->SetPlaceSave(gameModel->GetPlaceSave()); } diff --git a/src/gui/game/GameController.h b/src/gui/game/GameController.h index 2a2c4cbc9..3a099658f 100644 --- a/src/gui/game/GameController.h +++ b/src/gui/game/GameController.h @@ -153,7 +153,7 @@ public: void HideConsole(); void FrameStep(); void TranslateSave(ui::Point point); - void TransformSave(Mat2 transform); + void TransformSave(Mat2 transform); bool MouseInZoom(ui::Point position); ui::Point PointTranslate(ui::Point point); ui::Point PointTranslateNoClamp(ui::Point point); diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index fbf541885..134a6433e 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -1364,17 +1364,17 @@ void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, if (ctrl && shift) { //Vertical flip - c->TransformSave(Mat2::MirrorY); + c->TransformSave(Mat2::MirrorY); } else if (!ctrl && shift) { //Horizontal flip - c->TransformSave(Mat2::MirrorX); + c->TransformSave(Mat2::MirrorX); } else { //Rotate 90deg - c->TransformSave(Mat2::CW); + c->TransformSave(Mat2::CCW); } return; }