Skip to content
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

WangTiles: WangColor now have properties including name, color, image, and probability... #1670

Merged
merged 15 commits into from
Aug 15, 2017

Conversation

Bdtrotte
Copy link
Contributor

Also to be in this pr:

  • Right click to choose a wangcolor from the map
  • Add/remove buttons for wangColors
  • Any other fixes/features before 1.1

@Bdtrotte
Copy link
Contributor Author

Bdtrotte commented Aug 5, 2017

For assignment purposes in regards to staggered maps, one can think of the assignment being rotated 45 degrees clock wise. At some point this should be reflected graphically. The wang brush now supports staggered maps, (other tools to come shortly), except when working with edges. Because edges are very dependent on which edge they are closest to, the mouse moved function must be changed to take staggered into account. This is a fairly big effort at the moment, and will be saved for later.

@bjorn
Copy link
Member

bjorn commented Aug 6, 2017

For assignment purposes in regards to staggered maps, one can think of the assignment being rotated 45 degrees clock wise. At some point this should be reflected graphically.

Did you notice that the overlay used for terrain assignment is already able to handle isometric tilesets? Check out the usages of tilesetGridTransform.

@Bdtrotte
Copy link
Contributor Author

Bdtrotte commented Aug 6, 2017

Did you notice that the overlay used for terrain assignment is already able to handle isometric tilesets? Check out the usages of tilesetGridTransform.

I did not! Transforms will be very useful in supporting edges as well, thanks for pointing that out

@Bdtrotte
Copy link
Contributor Author

Bdtrotte commented Aug 7, 2017

I have not tested the results of the change of the last commit at length. Map rendering and such seems fine. The terrain brush may behave a little out of sorts on staggered maps, though should likely be updated to properly follow the corner the mouse is closest to (which I'm pretty sure it did not do prior in staggered maps.) In fact this could probably be done in the AbstractTileTool for BetweenTiles mode.

Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you do a rebase and squash the "removed stray file" commit into its parent? That way, we don't have the adding and removing of this file in the history. You may also want to add some .gitignore rule to avoid adding these files in the future.


return referencePoint;
QPointF newRel = HexagonalRenderer::tileToScreenCoords(referencePoint.x(), referencePoint.y());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not be necessary to qualify this with HexagonalRenderer::.

newRel = QPointF(x - newRel.x(), y - newRel.y());
QPointF tileLocal = newRel - QPointF(p.tileWidth / 2, 0);

//Undose the adjustment done above.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it would be nicer to not modify x and y and copy them into alignedX and alignedY for example before modifying them.

Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not a full review, I think I got about halfway through.

int index = wangColorAtts.value(QLatin1String("index")).toInt();
int r = wangColorAtts.value(QLatin1String("r")).toInt();
int g = wangColorAtts.value(QLatin1String("g")).toInt();
int b = wangColorAtts.value(QLatin1String("b")).toInt();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please store color the same way as it is done for other color attributes, so in hex format like "#RRGGBB".

int r = wangColorAtts.value(QLatin1String("r")).toInt();
int g = wangColorAtts.value(QLatin1String("g")).toInt();
int b = wangColorAtts.value(QLatin1String("b")).toInt();
int imageId = wangColorAtts.value(QLatin1String("imageTile")).toInt();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the names for elements and attributes all lower-case, so that would be imagetile. However, in this case, I would match the name with that used on the terrain element, and simply call this the tile.

void removeWangColorAt(int color, bool isEdge);

WangColor *wangColorOfEdge(int index) const;
WangColor *wangColorOfCorner(int index) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could these be just called edgeColorAt and cornerColorAt?


if (n == 1) {
mEdgeColors = 1;
mEdges.clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not delete the WangColor instances (nor will the below call to removeLast). Who owns the instances?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wangSet does, bit of an oversight on my part!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ill use QSharedPointer I think


colors.insert(wangColor->colorIndex(), wangColor);

for (int i = wangColor->colorIndex() + 1; i <= (wangColor->isEdge()? mEdgeColors : mCornerColors); ++i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If for almost every other line you need to check if the color is edge or corner, please split it up into two functions. Same goes for removeWangColorAt.

@@ -52,6 +52,8 @@
<file>images/16x16/selection-subtract.png</file>
<file>images/16x16/selection-intersect.png</file>
<file>images/22x22/add.png</file>
<file>images/22x22/add-corner.png</file>
<file>images/22x22/add-edge.png</file>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid using tabs here.


if ((isEdge? wangSet->edgeColors() : wangSet->cornerColors()) == 2) {
if (isEdge)
wangSet->setEdgeColors(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please try to get rid of this special logic, or explain me why it's a good idea. :-)


QString extraInfo;
if (!static_cast<WangBrushItem*>(brushItem())->isValid())
extraInfo = QLatin1String(" (Missing wang tile transition)");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a translatable string (except for the leading space, which shouldn't be part of the translatable string).

int newColor = 0;

if (mBrushMode == PaintVertex)
newColor = wangId.cornerColor(3);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid hardcoded numbers like 3 I think we should probably have an enumeration going over the colors and edges, so that we can write something like wangId.cornerColor(WangId::TopLeft).

class ChangeWangColorProbability : public QUndoCommand
{
public:
ChangeWangColorProbability(float newProbability,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is off by one level here.

@@ -84,20 +131,25 @@ Cell WangFiller::findFittingCell(const TileLayer &back,
break;
}
}
delete adjacentPoints;
Copy link
Member

@bjorn bjorn Aug 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since getSurroundingPoints uses malloc, this should be free.

Or, preferably, use a static array in getSurroundingPoints.

@Bdtrotte Bdtrotte force-pushed the wip/wangtiles branch 4 times, most recently from fbfb52a to 126681e Compare August 10, 2017 23:05
Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's shaping up nicely, but I had some comments on the code that I'd like to be addressed before merging.

<file>images/22x22/add-corner.png</file>
<file>images/22x22/add-edge.png</file>
<file>images/22x22/add-corner.png</file>
<file>images/22x22/add-edge.png</file>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You only changed one tab to 4 spaces, but there is still a tab remaining.

|| xml.name() == QLatin1String("wangcornercolor")) {
const QXmlStreamAttributes wangColorAtts = xml.attributes();
QString name = wangColorAtts.value(QLatin1String("name")).toString();
int index = wangColorAtts.value(QLatin1String("index")).toInt();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we shouldn't store the index, since it's superfluous. We could even drop the edges amd corners attributes from wangset now, and just append the edge and corner colors we find inside.

int mEdgeColors;
int mCornerColors;
QList<QSharedPointer<WangColor>> mEdgeColors;
QList<QSharedPointer<WangColor>> mCornerColors;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use QVector, since a QSharedPointer does not fit in a pointer.

@@ -45,7 +45,8 @@ class AbstractTileTool : public AbstractTool
AbstractTileTool(const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent = nullptr);
QObject *parent = nullptr,
BrushItem *brushItem = nullptr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the parent as the last parameter.

wc = wangSet->cornerColorAt(index).data();

wc->setName(name);
wc->setColor(color);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please either avoid setting invalid colors, or update the example files to use color attributes. :-)

if (!mTemplateAndColorView->isVisible()) {
mSwitchTemplateViewButton->setEnabled(true);
mTemplateAndColorView->setVisible(true);
if (!mTemplateAndColorWidget->isVisible()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can also be removed, right?


retranslateUi();
}

void WangDock::hideTemplateColorView()
{
if (!mTemplateAndColorView->isVisible())
if (!mTemplateAndColorWidget->isVisible())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also be superfluous now.

@@ -47,26 +50,68 @@ void WangFiller::setWangSet(WangSet *wangSet)
mWangSet = wangSet;
}

static QPoint *getSurroundingPoints(QPoint point, StaggeredRenderer *staggeredRenderer, Map::StaggerAxis staggerAxis)
{
QPoint *adjacentPoints = (QPoint*)malloc(sizeof(QPoint) * 8);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's still the problem with malloc / delete mismatch. Actually, I suggested using a static array but I think it's not going to work because the function is called multiple times. But you could allocate these arrays on the stack and pass them into the function:

static void getSurroundingPoints(QPoint point, StaggeredRenderer *staggeredRenderer, Map::StaggerAxis staggerAxis, QPoint *points)

QPoint adjacentPoints[8];
getSurroundingPoints(point, staggeredRenderer, staggerAxis, adjacentPoints);

QPoint point) const;
QPoint point,
StaggeredRenderer *staggeredRenderer = nullptr,
Map::StaggerAxis staggerAxis = Map::StaggerX) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding these parameters to each WangFiller method, passing them around on each call, consider adding them to the WangFiller constructor. And to avoid having to keep a WangFiller instance up-to-date, just allocate it on the stack when you're going to call its methods. This is similar to how TilePainter is used.

@@ -89,11 +89,11 @@ void test_StaggeredRenderer::screenToTileCoords_data()
QTest::addColumn<QPointF>("screenCoords");
QTest::addColumn<QPointF>("tileCoords");

QTest::newRow("10,16") << QPointF(10, 16) << QPointF(0, 0);
QTest::newRow("5,5") << QPointF(5, 5) << QPointF(-1, -1);
QTest::newRow("10,16") << QPointF(10, 16) << QPointF(0, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these values are very hard to understand, since they rely on rounding the internal fraction in a coordinate space where rounding makes no sense at all. Please keep these values the same, and change the test_StaggeredRenderer::screenToTileCoords to truncate instead of round.

Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments.

}

int WangSet::edgeColorCount() const
{
int size = mEdgeColors.size();

if (size > 1)
return size - 1;
return size;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's shorten this to:

return qMax(1, mEdgeColors.size());

@@ -614,22 +612,18 @@ void MapReaderPrivate::readTilesetWangSets(Tileset &tileset)
} else if (xml.name() == QLatin1String("wangedgecolor")
|| xml.name() == QLatin1String("wangcornercolor")) {
const QXmlStreamAttributes wangColorAtts = xml.attributes();
QString name = wangColorAtts.value(QLatin1String("name")).toString();
int index = wangColorAtts.value(QLatin1String("index")).toInt();
QString name = wangColorAtts.value(QLatin1String("name")).toString();\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray \.

mapDocument()->map()->staggerAxis());
WangFiller wangFiller(mWangSet,
dynamic_cast<StaggeredRenderer *>(mapDocument()->renderer()),
mapDocument()->map()->staggerAxis());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the wangFiller out of the loop.

@bjorn bjorn merged commit 5f8d1a9 into mapeditor:wip/wangtiles Aug 15, 2017
@Bdtrotte Bdtrotte deleted the wip/wangtiles branch August 15, 2017 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants