-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically Resize Maps - #260 #1651
Conversation
I think this will not be good for performance. Hence I was suggesting, to keep track of a bounding |
Alright, so the |
But why do you think that this won't be good for performance? In fact I think it's better now. Because earlier whenever the |
Yes, but when does the |
So instead of maintaining a |
Yes. In addition, I was suggesting that you update |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm looking forward to test this. :-)
src/libtiled/tilelayer.h
Outdated
int x = std::min(0, bound.x()); | ||
int y = std::min(0, bound.y()); | ||
int width = std::max(mWidth, bound.width()); | ||
int height = std::max(mHeight, bound.height()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this? When a layer is empty, by all means its bounds should be empty as well. That is actually a nice optimization for the code using the bounds
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried using mBounds.boundintRect()
previously, but that wasn't working for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the must have been a problem elsewhere. Please try to take it out again and find out what's going wrong.
src/libtiled/tilelayer.h
Outdated
int width = std::max(mWidth, bound.width()); | ||
int height = std::max(mHeight, bound.height()); | ||
|
||
return QRect(x, y, width, height).translated(mX, mY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since in your only usage of bounds
so far, you're translating the rectangle back to local coordinates, I wonder if it may be better to just return local coordinates instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was talking about the .translated(mX, mY)
part. Because it's there, you're doing layer->bounds().translated(-(layer->x()), -(layer->y()))
in the renderer. You could leave out both calls to translate
for the same result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But for BrushItem
it draws the selection on the basis of x()
and y()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if both the translate
are removed, then BrushItem
won't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see TileLayer::bounds
being used by BrushItem
. If you do use it there and it wants the bounds to be translated, then yes you should either leave this in there or add a translation in BrushItem
.
src/libtiled/tilelayer.h
Outdated
@@ -513,6 +515,7 @@ class TILEDSHARED_EXPORT TileLayer : public Layer | |||
int mHeight; | |||
Cell mEmptyCell; | |||
QHash<QPoint, Chunk> mChunks; | |||
QRegion mBounds; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we only care about the bounding rectangle, why is this a QRegion
instead of a QRect
? I don't currently see a use-case for using the region.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I previously tried with QRect
, but we cannot do arithmetic operations on QRect
. Although we can convert QRect
to QRegion
, then add a chunk and then use QRegion::boundingRect
but I guess that would have the same complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You only need to extend the rectangle in some cases. It's easy to do, but then, Qt even has QRect::united
. Not going through QRegion
will be a lot more efficient.
src/libtiled/tilelayer.cpp
Outdated
mBounds = mBounds.united(QRect(x - (x & CHUNK_MASK), | ||
y - (y & CHUNK_MASK), | ||
CHUNK_SIZE, | ||
CHUNK_SIZE)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the line in the else is multiple lines long please use {}
around it. And since the else
then has it, the if
-part also should have it
src/libtiled/tilelayer.h
Outdated
int x = std::min(0, mBounds.x()); | ||
int y = std::min(0, mBounds.y()); | ||
// int width = std::max(mWidth, mBounds.width()); | ||
// int height = std::max(mHeight, mBounds.height()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you want to remove those?
you broke a test apparently... Due to this the travis test failed. |
src/libtiled/tilelayer.cpp
Outdated
@@ -400,6 +410,7 @@ void TileLayer::rotate(RotateDirection direction) | |||
mWidth = newWidth; | |||
mHeight = newHeight; | |||
mChunks = newLayer->mChunks; | |||
updateBounds(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not mBounds = newLayer->mBounds;
? (and of course, passing mX
and mY
to constructor when creating newLayer
. This goes for all these functions creating a new layer.
src/libtiled/tilelayer.h
Outdated
int x = std::min(0, mBounds.x()); | ||
int y = std::min(0, mBounds.y()); | ||
int width = std::max(mWidth, mBounds.width()); | ||
int height = std::max(mHeight, mBounds.height()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this and document where it is causing issues, so that we can find a way to fix that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QRegion TilePainter::paintableRegion(const QRegion ®ion) const
{
const QRegion bounds = QRegion(mTileLayer->bounds());
QRegion intersection = bounds.intersected(region);
const QRegion &selection = mMapDocument->selectedArea();
if (!selection.isEmpty())
intersection &= selection;
return intersection;
}
Due to this, if we directly return mBounds
then we won't be able to paint the tile layer.
src/libtiled/orthogonalrenderer.cpp
Outdated
int startY = 0; | ||
int endX = layer->width() - 1; | ||
int endY = layer->height() - 1; | ||
QRect bounds = layer->bounds().translated(-(layer->x()), -(layer->y())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be written shorter as .translated(-layer->position())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting to look pretty good.
src/libtiled/hexagonalrenderer.cpp
Outdated
@@ -254,7 +254,7 @@ void HexagonalRenderer::drawTileLayer(QPainter *painter, | |||
QRect rect = exposed.toAlignedRect(); | |||
|
|||
if (rect.isNull()) | |||
rect = boundingRect(layer->bounds()); | |||
rect = boundingRect(layer->rect()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be bounds
, because there is no point in trying to draw anything outside of it.
src/libtiled/isometricrenderer.cpp
Outdated
@@ -191,7 +191,7 @@ void IsometricRenderer::drawTileLayer(QPainter *painter, | |||
|
|||
QRect rect = exposed.toAlignedRect(); | |||
if (rect.isNull()) | |||
rect = boundingRect(layer->bounds()); | |||
rect = boundingRect(layer->rect()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be bounds
, again because outside of that there are never any tiles to draw (also we need to use bounds
because when tiles were placed on an infinite map, we want to make sure to draw all of them).
src/libtiled/tilelayer.cpp
Outdated
@@ -640,7 +640,7 @@ Layer *TileLayer::mergedWith(Layer *other) const | |||
Q_ASSERT(canMergeWith(other)); | |||
|
|||
const TileLayer *o = static_cast<TileLayer*>(other); | |||
const QRect unitedBounds = bounds().united(o->bounds()); | |||
const QRect unitedBounds = rect().united(o->rect()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid confusion, this should be unitedRect
.
src/tiled/stampbrush.cpp
Outdated
if (!tileLayer->rect().intersects(QRect(preview->x(), | ||
preview->y(), | ||
preview->width(), | ||
preview->height()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I wonder why this wasn't using preview->bounds()
before. In any case, it can be changed to:
if (!tileLayer->rect().intersects(preview->bounds()))
@@ -349,7 +349,9 @@ class TILEDSHARED_EXPORT TileLayer : public Layer | |||
/** | |||
* Returns the bounds of this layer. | |||
*/ | |||
QRect bounds() const { return QRect(mX, mY, mWidth, mHeight); } | |||
QRect bounds() const { return mBounds.translated(mX, mY); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggested to use bounds
in the map renderers, but due to an assert this will currently only work if this function is implemented as:
QRect bounds() const { return mBounds.translated(mX, mY).intersected(rect()); }
That is because mBounds
may extend beyond the limits imposed by the layer size due to growing it chunk-by-chunk. I think that is a fine implementation for now, and the intersection can be taken out again when we actually allow layers to grow (and take out the assert in cellAt
).
I'm not able to understand why the build fails 😕 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments. I'm sorry it's not exhaustive.
src/plugins/csv/csvplugin.cpp
Outdated
for (int y = 0; y < tileLayer->height(); ++y) { | ||
for (int x = 0; x < tileLayer->width(); ++x) { | ||
if (x > 0) | ||
for (int y = startY; y <= endY; ++y) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you just use bounds.left()
and bounds.right()
here, then the above can be written much shorter:
QRect bounds = map->infinite() ? tileLayer->bounds() : tileLayer->rect();
bounds.translate(-layer->position());
I do wonder a little what somebody would do with multiple CSV files that cover various areas of different tile layers, especially with no way of knowing how to map them back relative to each other, but that's the way it is when exporting infinite maps in this format...
src/tiled/tilepainter.cpp
Outdated
const QRegion bounds = QRegion(mTileLayer->rect()); | ||
QRegion intersection; | ||
|
||
if (mTileLayer->map()->infinite()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just in case, please obtain the map from the mMapDocument
, since tile layers are not guaranteed to have a map but the MapDocument is.
src/tiled/tilepainter.cpp
Outdated
if (mTileLayer->map()->infinite()) | ||
intersection = region; | ||
else | ||
intersection = bounds.intersected(region);; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole thing can be written a lot shorter:
QRegion intersection = region;
if (!mMapDocument->map()->infinite())
intersection &= QRegion(mTileLayer->rect());
src/libtiled/hexagonalrenderer.h
Outdated
@@ -71,6 +71,8 @@ class TILEDSHARED_EXPORT HexagonalRenderer : public OrthogonalRenderer | |||
|
|||
QSize mapSize() const override; | |||
|
|||
QPoint mapStart() const override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider replacing mapSize
and mapStart
with a single QRect mapBoundingRect() const
function.
int startX = bounds.left(); | ||
int startY = bounds.top(); | ||
int endX = bounds.right(); | ||
int endY = bounds.bottom(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this should still have the -1:
int endX = bounds.right() - 1;
int endY = bounds.bottom() - 1;
Because the right
and bottom
of a QRect are inclusive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was previously iterating upto layer->width() - 1
. So if - 1
is added, then it doesn't render the last row/column.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right, precisely because QRect is inclusive, we should indeed not do -1.
mDarkRectangle->setRect(sceneRect); | ||
|
||
if (mMapDocument->map()->infinite()) | ||
mDarkRectangle->setRect(QRect()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to find some way to still darken the view, for the "Highlight Current Layer" feature to work on infinite maps.
src/tiled/newmapdialog.ui
Outdated
<item row="3" column="1"> | ||
<widget class="QCheckBox" name="mapInfinite"> | ||
<property name="text"> | ||
<string>Automatically Resize Map</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see if this checkbox fits in the "Map Size" box, and disable the width/height inputs and hide the pixel size display for infinite maps (I think the map size should just be 0,0).
src/tiled/stampbrush.cpp
Outdated
|
||
if (!tileLayer->map()->infinite()) | ||
captured &= QRect(tileLayer->x(), tileLayer->y(), | ||
tileLayer->width(), tileLayer->height()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this intersection at all?
a6f6c51
to
8965443
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While there is indeed the problem with the scene rect, and I have no good solution for this now, I've found a lot of small issues with the existing patch in the meantime which can be addressed.
I suggest we work towards merging this patch without trying to solve the "jumping" problem for now. It will probably take some trial and error to find a workable solution to that, but it's more important to get all the other parts of the code adjusted in the right way.
src/libtiled/mapreader.cpp
Outdated
@@ -129,6 +129,9 @@ class MapReaderPrivate | |||
bool mReadingExternalTileset; | |||
|
|||
QXmlStreamReader xml; | |||
|
|||
int startX; | |||
int startY; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming style: should be mStartX
and mStartY
.
However, I think you should anyway just pass these around as function parameters rather than having them as members.
src/libtiled/maprenderer.h
Outdated
@@ -70,10 +70,7 @@ class TILEDSHARED_EXPORT MapRenderer | |||
*/ | |||
const Map *map() const; | |||
|
|||
/** | |||
* Returns the size in pixels of the map associated with this renderer. | |||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please leave an updated comment in place.
tileLayerVariant[QLatin1String("width")] = tileLayer.width(); | ||
tileLayerVariant[QLatin1String("height")] = tileLayer.height(); | ||
tileLayerVariant[QLatin1String("startx")] = 0; | ||
tileLayerVariant[QLatin1String("starty")] = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please just leave out these values for finite maps.
src/libtiled/mapwriter.cpp
Outdated
@@ -48,6 +48,8 @@ | |||
#include <QDir> | |||
#include <QXmlStreamWriter> | |||
|
|||
#include <QDebug> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember to remove this include again.
src/libtiled/mapwriter.cpp
Outdated
w.writeAttribute(QLatin1String("startx"), | ||
QString::number(bounds.left())); | ||
w.writeAttribute(QLatin1String("starty"), | ||
QString::number(bounds.top())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too, please don't write those attributes for finite maps.
src/tiled/thumbnailrenderer.cpp
Outdated
@@ -98,7 +98,7 @@ static QRectF cellRect(const MapRenderer &renderer, | |||
static QRect computeMapRect(const MapRenderer &renderer) | |||
{ | |||
// Start with the basic map size | |||
QRectF rect(QPointF(0, 0), renderer.mapSize()); | |||
QRectF rect(QPointF(0, 0), renderer.mapBoundingRect().size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should just be initialized to renderer.mapBoundingRect()
, not just its size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How exactly do I test the Thumbnail Renderer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the thumbnail renderer renders the tiles for the tile stamp dock. So you can simply add some tiles there to test it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ThumbnailRenderer
should really be unified with MiniMapRenderer
, but that's something for another time...
src/tiled/tilepainter.cpp
Outdated
@@ -197,12 +199,26 @@ static QRegion fillRegion(const TileLayer *layer, QPoint fillOrigin, | |||
if (!layer->contains(fillOrigin)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check should be disabled for infinite maps (once contains
is back to its original form).
src/tiled/tilepainter.cpp
Outdated
const int layerHeight = layer->height(); | ||
QRect bounds = layer->bounds().translated(-layer->position()); | ||
if (!layer->map()->infinite()) | ||
bounds = layer->rect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translated by -layer->position()
as well, right?
src/tmxrasterizer/tmxrasterizer.cpp
Outdated
@@ -101,7 +101,7 @@ int TmxRasterizer::render(const QString &mapFileName, | |||
break; | |||
} | |||
|
|||
QSize mapSize = renderer->mapSize(); | |||
QSize mapSize = renderer->mapBoundingRect().size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will need to store the bounding rect and translate the painter based on the topLeft
of it.
@@ -53,10 +53,10 @@ void test_StaggeredRenderer::mapSize() | |||
StaggeredRenderer renderer(mMap); | |||
|
|||
TileLayer *tileLayer = static_cast<TileLayer*>(mMap->layerAt(0)); | |||
QSize mapSize = renderer.mapSize(); | |||
QSize mapSize = renderer.mapBoundingRect().size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make the test a little more complete, just take the bounding rect and compare it to a QRect(0, 0, 10 * 64 + 32, 10 * 16 + 16)
.
Travis seems to have a compiling issue:
|
src/libtiled/orthogonalrenderer.cpp
Outdated
map()->width() * tileWidth + 1); | ||
const int endY = qMin(qCeil(rect.bottom()), | ||
map()->height() * tileHeight + 1); | ||
int startX = ((int) (rect.x() / tileWidth - 1)) * tileWidth; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the -1 is to make it work in case of negative coordinates, but it means an extra column of tiles will be rendered in positive coordinate space. A real fix would be to use qFloor(rect.x() / tileWidth) * tileWidth
.
src/libtiled/orthogonalrenderer.cpp
Outdated
int endY = qCeil(rect.bottom()); | ||
|
||
if (!map()->infinite()) { | ||
startX = qMax(0, (int) (rect.x() / tileWidth) * tileWidth); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you should reuse the value of startX
:
startX = qMax(0, startX);
|
||
QCOMPARE(mapSize, QSize(10 * 64 + 32, 10 * 16 + 16)); | ||
QCOMPARE(renderer.boundingRect(tileLayer->bounds()), | ||
QRect(QPoint(), mapSize)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you removing the test of StaggeredRenderer::boundingRect
? It should be possible to just change it to:
QCOMPARE(renderer.boundingRect(tileLayer->rect()), mapBoundingRect);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some review feedback.
I guess the main things still open for this change would be:
-
Checking the behavior of automapping. The main thing to fix is
AutomappingManager::autoMap
taking the map size rather than calculating the combined bounds, but there may be other parts to modify. -
Implementing the alternative chunk-based storage format.
src/tiled/terrainbrush.cpp
Outdated
@@ -204,7 +204,7 @@ void TerrainBrush::capture() | |||
|
|||
const QPoint position = tilePosition() - tileLayer->position(); | |||
|
|||
if (!tileLayer->contains(position)) | |||
if (!tileLayer->contains(position) && !mapDocument()->map()->infinite()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is no longer necessary. I think capturing outside of the map can simply capture "no terrain", also for finite maps.
src/tiled/terrainbrush.cpp
Outdated
@@ -373,7 +373,7 @@ void TerrainBrush::updateBrush(QPoint cursorPos, const QVector<QPoint> *list) | |||
} | |||
|
|||
// if the cursor is outside of the map, bail out | |||
if (!currentLayer->contains(cursorPos)) { | |||
if (!currentLayer->contains(cursorPos) && !mapDocument()->map()->infinite()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Contains check should not be needed anymore even for finite maps.
src/tiled/terrainbrush.cpp
Outdated
@@ -395,7 +395,7 @@ void TerrainBrush::updateBrush(QPoint cursorPos, const QVector<QPoint> *list) | |||
transitionList.reserve(list->size()); | |||
for (QPoint p : *list) { | |||
p -= layerPosition; | |||
if (currentLayer->contains(p)) | |||
if (currentLayer->contains(p) || mapDocument()->map()->infinite()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Contains check should not be needed anymore even for finite maps.
@@ -68,7 +70,7 @@ Cell TilePainter::cellAt(int x, int y) const | |||
const int layerX = x - mTileLayer->x(); | |||
const int layerY = y - mTileLayer->y(); | |||
|
|||
if (!mTileLayer->contains(layerX, layerY)) | |||
if (!mTileLayer->contains(layerX, layerY) && !mMapDocument->map()->infinite()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check is not necessary at all anymore. If the layer does not contain this position, it will anyway return an empty cell.
Edit: GitHub seems to match this comment to a different line now. In this function it is of course still needed..
src/tiled/tilepainter.cpp
Outdated
if (!layer->contains(fillOrigin) && !layer->map()->infinite()) | ||
return fillRegion; | ||
|
||
if (layer->map()->infinite() && !layer->bounds().contains(fillOrigin)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please combine the above checks with getting the bounds below:
QRect bounds = layer->map()->infinite() ? layer->bounds() : layer->rect();
if (!bounds.contains(fillOrigin))
return fillRegion;
bounds.translate(-layer->position());
src/tmxrasterizer/tmxrasterizer.cpp
Outdated
@@ -101,7 +101,8 @@ int TmxRasterizer::render(const QString &mapFileName, | |||
break; | |||
} | |||
|
|||
QSize mapSize = renderer->mapSize(); | |||
QSize mapSize = renderer->mapBoundingRect().size(); | |||
QPoint mapOffset = renderer->mapBoundingRect().topLeft(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't call mapBoundingRect
twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll still need to adjust HexagonalRenderer::mapBoundingRect
.
src/libtiled/hexagonalrenderer.cpp
Outdated
@@ -338,14 +342,14 @@ void HexagonalRenderer::drawTileLayer(QPainter *painter, | |||
if (p.doStaggerY(startTile.y() + layer->y())) | |||
startPos.rx() -= p.columnWidth; | |||
|
|||
for (; startPos.y() < rect.bottom() && startTile.y() < layer->height(); startTile.ry()++) { | |||
for (; startPos.y() < rect.bottom() && (startTile.y() < layer->height() || map()->infinite()); startTile.ry()++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please still optimize this to use an endY
that is either layer->height()
or layer->bounds()
, same for X.
src/libtiled/isometricrenderer.cpp
Outdated
@@ -242,7 +268,7 @@ void IsometricRenderer::drawTileLayer(QPainter *painter, | |||
QPoint columnItr = rowItr; | |||
|
|||
for (int x = startPos.x(); x < rect.right(); x += tileWidth) { | |||
if (layer->contains(columnItr)) { | |||
if (map()->infinite() || layer->contains(columnItr)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can drop both these checks and rely only on !cell.isEmpty()
below.
src/libtiled/hexagonalrenderer.cpp
Outdated
@@ -289,6 +318,9 @@ void HexagonalRenderer::drawTileLayer(QPainter *painter, | |||
|
|||
CellRenderer renderer(painter, CellRenderer::HexagonalCells); | |||
|
|||
const int endX = map()->infinite() ? layer->bounds().width() : layer->width(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the endX
should be layer->bounds().right() - layer->x() + 1
in case of infinite maps. Similar for Y.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But not for layer->width()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about layer->width()
? My point is that endX
should be the right-most X coordinate (+1 because it's one beyond that), like it is for finite maps. But you just took bounds().width()
, which does not take into account that bounds().x()
isn't always 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so instead of layer->x()
, it should be layer->bounds().x()
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the - layer->x()
part is to change the bounds to local coordinates, since the bounds()
include the layer's position. Subtracting layer->bounds().x()
would defeat the point of using layer->bounds().right()
.
src/libtiled/hexagonalrenderer.cpp
Outdated
QPoint rowTile = startTile; | ||
QPoint rowPos = startPos; | ||
|
||
for (; rowPos.x() < rect.right() && (rowTile.x() < layer->width() || map()->infinite()); rowTile.rx() += 2) { | ||
for (; rowPos.x() < rect.right() && endX; rowTile.rx() += 2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦♂️ 🤦♂️ 🤦♂️
src/libtiled/hexagonalrenderer.cpp
Outdated
// The map size is the same regardless of which indexes are shifted. | ||
if (p.staggerX) { | ||
QSize size(map()->width() * p.columnWidth + p.sideOffsetX, | ||
map()->height() * (p.tileHeight + p.sideLengthY)); | ||
if (!map()->infinite()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please consider that infinite and finite maps are not so different that you couldn't use the same code for both, just using the bounds:
QRect mapBounds;
if (map()->inifinite()) {
// unite with the layer bounds
} else {
mapBounds = QRect(0, 0, map()->width(), map()->height());
}
// Calculate bounding rect based on bounds (no need for checking infinite anymore)
src/libtiled/hexagonalrenderer.cpp
Outdated
map()->height() * (p.tileHeight + p.sideLengthY)); | ||
|
||
if (map()->width() > 1) | ||
size.rheight() += p.rowHeight; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this line is also needed for infinite maps. rowHeight
needs to be added because of the staggering. Same for columnWidth
below.
src/libtiled/hexagonalrenderer.cpp
Outdated
} | ||
|
||
if (mapBounds.size() == QSize(0, 0)) | ||
mapBounds.setSize(QSize(1, 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this before. If the size is set to (0, 0) then after creating a new map, the 'weird' scrolling problem starts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we work around that problem in the MapScene
? It's not related to the renderers.
src/libtiled/hexagonalrenderer.cpp
Outdated
@@ -339,14 +365,14 @@ void HexagonalRenderer::drawTileLayer(QPainter *painter, | |||
if (p.doStaggerY(startTile.y() + layer->y())) | |||
startPos.rx() -= p.columnWidth; | |||
|
|||
for (; startPos.y() < rect.bottom() && startTile.y() < layer->height(); startTile.ry()++) { | |||
for (; startPos.y() < rect.bottom() && endY; startTile.ry()++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix all cases.
mRegion
keeps track of the non-empty region of layer. The bounds function is modified so that it calculates the bounds usingmRegion
itself.