From 9aaada79fefd82ac635f70c05d3e2da25ff4fb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Mon, 20 Mar 2023 12:44:43 +0100 Subject: [PATCH] Improved Terrain Brush for Hexagonal (Staggered) maps with side length 0 Now Hexagonal (Staggered) maps are treated the same way as Isometric (Staggered) maps, which might be better than treating them as orthogonal maps. It at least fixes the behavior when "hex side length" is 0, but it does not mean hexagonal maps are actually supported by the Terrain Brush. Closes #3617 --- NEWS.md | 1 + src/tiled/bucketfilltool.cpp | 7 ++---- src/tiled/stampbrush.cpp | 12 +++------ src/tiled/wangbrush.cpp | 49 ++++++++++++++++++------------------ src/tiled/wangfiller.cpp | 27 ++++++++++---------- src/tiled/wangfiller.h | 5 ++-- 6 files changed, 47 insertions(+), 54 deletions(-) diff --git a/NEWS.md b/NEWS.md index d9a15ed9d5..c968c259ab 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ ### Unreleased * Fixed object labels to adjust to application font changes +* Improved Terrain Brush for Hexagonal (Staggered) maps with side length 0 (#3617) * Qt 6: Increased the image allocation limit from 128 MB to 1 GB (#3616) ### Tiled 1.10.0 (10 March 2023) diff --git a/src/tiled/bucketfilltool.cpp b/src/tiled/bucketfilltool.cpp index 875fd2e0ae..05a35c685c 100644 --- a/src/tiled/bucketfilltool.cpp +++ b/src/tiled/bucketfilltool.cpp @@ -23,17 +23,14 @@ #include "bucketfilltool.h" -#include "addremovetileset.h" #include "brushitem.h" #include "tilepainter.h" -#include "tile.h" #include "tilelayer.h" #include "mapdocument.h" -#include "painttilelayer.h" -#include "staggeredrenderer.h" #include "stampactions.h" -#include +#include +#include #include diff --git a/src/tiled/stampbrush.cpp b/src/tiled/stampbrush.cpp index ad6cd77dc3..f2e20b7072 100644 --- a/src/tiled/stampbrush.cpp +++ b/src/tiled/stampbrush.cpp @@ -21,15 +21,11 @@ #include "stampbrush.h" -#include "addremovelayer.h" -#include "addremovetileset.h" #include "brushitem.h" #include "geometry.h" #include "map.h" #include "mapdocument.h" #include "mapscene.h" -#include "painttilelayer.h" -#include "staggeredrenderer.h" #include "stampactions.h" #include "tile.h" #include "tilestamp.h" @@ -59,13 +55,13 @@ StampBrush::StampBrush(QObject *parent) connect(mStampActions->random(), &QAction::toggled, this, &StampBrush::randomChanged); connect(mStampActions->wangFill(), &QAction::toggled, this, &StampBrush::wangFillChanged); - connect(mStampActions->flipHorizontal(), &QAction::triggered, + connect(mStampActions->flipHorizontal(), &QAction::triggered, this, [this] { emit stampChanged(mStamp.flipped(FlipHorizontally)); }); - connect(mStampActions->flipVertical(), &QAction::triggered, + connect(mStampActions->flipVertical(), &QAction::triggered, this, [this] { emit stampChanged(mStamp.flipped(FlipVertically)); }); - connect(mStampActions->rotateLeft(), &QAction::triggered, + connect(mStampActions->rotateLeft(), &QAction::triggered, this, [this] { emit stampChanged(mStamp.rotated(RotateLeft)); }); - connect(mStampActions->rotateRight(), &QAction::triggered, + connect(mStampActions->rotateRight(), &QAction::triggered, this, [this] { emit stampChanged(mStamp.rotated(RotateRight)); }); } diff --git a/src/tiled/wangbrush.cpp b/src/tiled/wangbrush.cpp index 788a71a154..90d43dff5b 100644 --- a/src/tiled/wangbrush.cpp +++ b/src/tiled/wangbrush.cpp @@ -24,13 +24,12 @@ #include "brushitem.h" #include "containerhelpers.h" #include "geometry.h" +#include "hexagonalrenderer.h" #include "map.h" #include "mapdocument.h" #include "maprenderer.h" #include "mapscene.h" #include "painttilelayer.h" -#include "randompicker.h" -#include "staggeredrenderer.h" #include "tilelayer.h" #include "wangfiller.h" @@ -279,11 +278,11 @@ void WangBrush::mouseMoved(const QPointF &pos, Qt::KeyboardModifiers modifiers) case Idle: // can't happen due to check above return; case PaintCorner: - if (StaggeredRenderer *staggeredRenderer = dynamic_cast(mapDocument()->renderer())) { + if (auto hexagonalRenderer = dynamic_cast(mapDocument()->renderer())) { if (tileLocalPos.x() >= 0.5) - tilePos = staggeredRenderer->bottomRight(tilePos.x(), tilePos.y()); + tilePos = hexagonalRenderer->bottomRight(tilePos.x(), tilePos.y()); if (tileLocalPos.y() >= 0.5) - tilePos = staggeredRenderer->bottomLeft(tilePos.x(), tilePos.y()); + tilePos = hexagonalRenderer->bottomLeft(tilePos.x(), tilePos.y()); } else { if (tileLocalPos.x() >= 0.5) tilePos.rx() += 1; @@ -324,19 +323,19 @@ void WangBrush::mouseMoved(const QPointF &pos, Qt::KeyboardModifiers modifiers) break; } case PaintEdgeAndCorner: - if (StaggeredRenderer *staggeredRenderer = dynamic_cast(mapDocument()->renderer())) { + if (auto hexagonalRenderer = dynamic_cast(mapDocument()->renderer())) { switch (wangIndex) { case WangId::BottomRight: - tilePos = staggeredRenderer->bottomRight(tilePos.x(), tilePos.y()); - tilePos = staggeredRenderer->bottomLeft(tilePos.x(), tilePos.y()); + tilePos = hexagonalRenderer->bottomRight(tilePos.x(), tilePos.y()); + tilePos = hexagonalRenderer->bottomLeft(tilePos.x(), tilePos.y()); wangIndex = WangId::TopLeft; break; case WangId::BottomLeft: - tilePos = staggeredRenderer->bottomLeft(tilePos.x(), tilePos.y()); + tilePos = hexagonalRenderer->bottomLeft(tilePos.x(), tilePos.y()); wangIndex = WangId::TopLeft; break; case WangId::TopRight: - tilePos = staggeredRenderer->bottomRight(tilePos.x(), tilePos.y()); + tilePos = hexagonalRenderer->bottomRight(tilePos.x(), tilePos.y()); wangIndex = WangId::TopLeft; break; default: @@ -645,7 +644,7 @@ void WangBrush::updateBrush() void WangBrush::updateBrushAt(FillRegion &fill, QPoint pos) { - auto staggeredRenderer = dynamic_cast(mapDocument()->renderer()); + auto hexgonalRenderer = dynamic_cast(mapDocument()->renderer()); Grid &grid = fill.grid; QRegion ®ion = fill.region; @@ -654,11 +653,11 @@ void WangBrush::updateBrushAt(FillRegion &fill, QPoint pos) if (mIsTileMode || (mBrushBehavior == Line && mBrushMode == PaintEdgeAndCorner)) { //array of adjacent positions which is assigned based on map orientation. QPoint adjacentPositions[WangId::NumIndexes]; - if (staggeredRenderer) { - adjacentPositions[0] = staggeredRenderer->topRight(pos.x(), pos.y()); - adjacentPositions[2] = staggeredRenderer->bottomRight(pos.x(), pos.y()); - adjacentPositions[4] = staggeredRenderer->bottomLeft(pos.x(), pos.y()); - adjacentPositions[6] = staggeredRenderer->topLeft(pos.x(), pos.y()); + if (hexgonalRenderer) { + adjacentPositions[0] = hexgonalRenderer->topRight(pos.x(), pos.y()); + adjacentPositions[2] = hexgonalRenderer->bottomRight(pos.x(), pos.y()); + adjacentPositions[4] = hexgonalRenderer->bottomLeft(pos.x(), pos.y()); + adjacentPositions[6] = hexgonalRenderer->topLeft(pos.x(), pos.y()); if (mapDocument()->map()->staggerAxis() == Map::StaggerX) { adjacentPositions[1] = pos + QPoint(2, 0); @@ -742,11 +741,11 @@ void WangBrush::updateBrushAt(FillRegion &fill, QPoint pos) case PaintCorner: { QPoint adjacentPoints[WangId::NumCorners]; - if (staggeredRenderer) { - adjacentPoints[0] = staggeredRenderer->topRight(pos.x(), pos.y()); + if (hexgonalRenderer) { + adjacentPoints[0] = hexgonalRenderer->topRight(pos.x(), pos.y()); adjacentPoints[1] = pos; - adjacentPoints[2] = staggeredRenderer->topLeft(pos.x(), pos.y()); - adjacentPoints[3] = staggeredRenderer->topRight(adjacentPoints[2].x(), adjacentPoints[2].y()); + adjacentPoints[2] = hexgonalRenderer->topLeft(pos.x(), pos.y()); + adjacentPoints[3] = hexgonalRenderer->topRight(adjacentPoints[2].x(), adjacentPoints[2].y()); } else { for (int i = 0; i < WangId::NumCorners; ++i) adjacentPoints[i] = pos + aroundVertexPoints[i]; @@ -768,19 +767,19 @@ void WangBrush::updateBrushAt(FillRegion &fill, QPoint pos) } case PaintEdge: { QPoint dirPoint; - if (staggeredRenderer) { + if (hexgonalRenderer) { switch (mWangIndex) { case WangId::Top: - dirPoint = staggeredRenderer->topRight(pos.x(), pos.y()); + dirPoint = hexgonalRenderer->topRight(pos.x(), pos.y()); break; case WangId::Right: - dirPoint = staggeredRenderer->bottomRight(pos.x(), pos.y()); + dirPoint = hexgonalRenderer->bottomRight(pos.x(), pos.y()); break; case WangId::Bottom: - dirPoint = staggeredRenderer->bottomLeft(pos.x(), pos.y()); + dirPoint = hexgonalRenderer->bottomLeft(pos.x(), pos.y()); break; case WangId::Left: - dirPoint = staggeredRenderer->topLeft(pos.x(), pos.y()); + dirPoint = hexgonalRenderer->topLeft(pos.x(), pos.y()); break; default: // Other color indexes not handled when painting edges break; diff --git a/src/tiled/wangfiller.cpp b/src/tiled/wangfiller.cpp index 3c2b8f5ffc..58c01da466 100644 --- a/src/tiled/wangfiller.cpp +++ b/src/tiled/wangfiller.cpp @@ -21,8 +21,9 @@ #include "wangfiller.h" #include "grid.h" +#include "hexagonalrenderer.h" +#include "map.h" #include "randompicker.h" -#include "staggeredrenderer.h" #include "tilelayer.h" #include "wangset.h" @@ -43,21 +44,21 @@ WangFiller::WangFiller(const WangSet &wangSet, const MapRenderer *mapRenderer) : mWangSet(wangSet) , mMapRenderer(mapRenderer) - , mStaggeredRenderer(dynamic_cast(mapRenderer)) + , mHexagonalRenderer(dynamic_cast(mapRenderer)) { } static void getSurroundingPoints(QPoint point, - const StaggeredRenderer *staggeredRenderer, + const HexagonalRenderer *hexagonalRenderer, QPoint *points) { - if (staggeredRenderer) { - points[0] = staggeredRenderer->topRight(point.x(), point.y()); - points[2] = staggeredRenderer->bottomRight(point.x(), point.y()); - points[4] = staggeredRenderer->bottomLeft(point.x(), point.y()); - points[6] = staggeredRenderer->topLeft(point.x(), point.y()); + if (hexagonalRenderer) { + points[0] = hexagonalRenderer->topRight(point.x(), point.y()); + points[2] = hexagonalRenderer->bottomRight(point.x(), point.y()); + points[4] = hexagonalRenderer->bottomLeft(point.x(), point.y()); + points[6] = hexagonalRenderer->topLeft(point.x(), point.y()); - if (staggeredRenderer->map()->staggerAxis() == Map::StaggerX) { + if (hexagonalRenderer->map()->staggerAxis() == Map::StaggerX) { points[1] = point + QPoint(2, 0); points[3] = point + QPoint(0, 1); points[5] = point + QPoint(-2, 0); @@ -155,7 +156,7 @@ void WangFiller::fillRegion(TileLayer &target, // Determine the bounds of the affected area QRect bounds = region.boundingRect(); - int margin = mWangSet.maximumColorDistance() + (mStaggeredRenderer != nullptr); + int margin = mWangSet.maximumColorDistance() + (mHexagonalRenderer != nullptr); bounds.adjust(-margin, -margin, margin, margin); // Don't try to make corrections outside of a fixed map @@ -185,7 +186,7 @@ void WangFiller::fillRegion(TileLayer &target, // Adjust the desired WangIds for the surrounding tiles based on the placed one QPoint adjacentPoints[WangId::NumIndexes]; - getSurroundingPoints(QPoint(x, y), mStaggeredRenderer, adjacentPoints); + getSurroundingPoints(QPoint(x, y), mHexagonalRenderer, adjacentPoints); for (int i = 0; i < WangId::NumIndexes; ++i) { const QPoint p = adjacentPoints[i]; @@ -237,7 +238,7 @@ WangId WangFiller::wangIdFromSurroundings(const TileLayer &back, { Cell surroundingCells[8]; QPoint adjacentPoints[8]; - getSurroundingPoints(point, mStaggeredRenderer, adjacentPoints); + getSurroundingPoints(point, mHexagonalRenderer, adjacentPoints); for (int i = 0; i < 8; ++i) { if (!region.contains(adjacentPoints[i])) @@ -324,7 +325,7 @@ bool WangFiller::findBestMatch(const TileLayer &target, // Adjust the desired WangIds for the surrounding tiles based on // the to be placed one. QPoint adjacentPoints[WangId::NumIndexes]; - getSurroundingPoints(position, mStaggeredRenderer, adjacentPoints); + getSurroundingPoints(position, mHexagonalRenderer, adjacentPoints); for (int i = 0; i < WangId::NumIndexes; ++i) { const QPoint p = adjacentPoints[i]; diff --git a/src/tiled/wangfiller.h b/src/tiled/wangfiller.h index b50256a3fe..6aec6f3821 100644 --- a/src/tiled/wangfiller.h +++ b/src/tiled/wangfiller.h @@ -21,7 +21,6 @@ #pragma once #include "grid.h" -#include "map.h" #include "wangset.h" #include @@ -33,7 +32,7 @@ namespace Tiled { class MapRenderer; -class StaggeredRenderer; +class HexagonalRenderer; /** * WangFiller provides functions for choosing cells based on a surrounding map @@ -87,7 +86,7 @@ class WangFiller const WangSet &mWangSet; const MapRenderer * const mMapRenderer; - const StaggeredRenderer * const mStaggeredRenderer; + const HexagonalRenderer * const mHexagonalRenderer; bool mCorrectionsEnabled = false; QPainter *mDebugPainter = nullptr;