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

Wang Tiles #1582

Merged
merged 26 commits into from
Jul 4, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
904e8bc
Created WangSet class, as well as some functions for wangIds
Bdtrotte May 28, 2017
cb8d9ae
Moved wangId into a class of its own
Bdtrotte May 29, 2017
e93cc74
Merge branch 'master' into WangTiles
Bdtrotte Jun 11, 2017
c329a97
Merge branch 'master' of https://github.com/bjorn/tiled into WangTiles
Bdtrotte Jun 21, 2017
4757fb6
Refined WangSet class, and added them into Tileset
Bdtrotte Jun 21, 2017
31689c6
Made requested changes
Bdtrotte Jun 21, 2017
e10151e
Enabled file saving and loading. (Needs testing)
Bdtrotte Jun 24, 2017
c7e67d0
Fixed some issues with saving/loading
willt Jun 23, 2017
0ef5add
Style update
Bdtrotte Jun 25, 2017
74dbae3
Foundation for adding UI support to wangTile assignment
Bdtrotte Jun 27, 2017
400d47c
merged upstream
Bdtrotte Jun 27, 2017
ff6c624
Added a couple Undo commands, and made a bit more progress on the mod…
Bdtrotte Jun 28, 2017
3916cd6
WangSets are now able to be created and edited from the ui
Bdtrotte Jun 28, 2017
acae98a
Added new files to tiled.pro
Bdtrotte Jun 28, 2017
68bd9af
adjusted reading/writting so that all the wang set info (including ti…
Bdtrotte Jun 28, 2017
52ae862
Cleaned up a few things
Bdtrotte Jun 29, 2017
4398cea
remoced references to 'addremocewangset
Bdtrotte Jun 29, 2017
7f58709
Now can assign wangsets an image, added functions for getting the wan…
Bdtrotte Jun 30, 2017
bb6b98a
Beging to store info about tile rotation and inversion
Bdtrotte Jul 2, 2017
0969d46
Wangsets now store info about rotation and flipping, mapreader/writer…
Bdtrotte Jul 2, 2017
8b959a9
Merge branch 'wip/wangtiles' into WangTiles
Bdtrotte Jul 4, 2017
1df48f5
Made requested changes
Bdtrotte Jul 4, 2017
25f8494
Merge branch 'WangTiles' of https://github.com/Bdtrotte/tiled into Wa…
Bdtrotte Jul 4, 2017
888ea7b
fixed issue in 'wangIdFromSurrounding'
Bdtrotte Jul 4, 2017
825774a
Made requested changes!
Bdtrotte Jul 4, 2017
0d3f353
Removed file that should not be in version control
bjorn Jul 4, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/libtiled/tileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "terrain.h"
#include "tile.h"
#include "tilesetformat.h"
#include "wangset.h"

#include <QBitmap>

Expand Down Expand Up @@ -62,6 +63,7 @@ Tileset::~Tileset()
{
qDeleteAll(mTiles);
qDeleteAll(mTerrainTypes);
qDeleteAll(mWangSets);
}

void Tileset::setFormat(TilesetFormat *format)
Expand Down Expand Up @@ -505,6 +507,28 @@ void Tileset::recalculateTerrainDistances()
} while (bNewConnections);
}

/**
* @brief Tileset::insertWangSet Adds a wangSet.
* @param wangSet A pointer to the wangset to add.
*/
void Tileset::insertWangSet(WangSet *wangSet)
{
Q_ASSERT(wangSet->tileset() == this);

mWangSets.append(wangSet);
}

/**
* @brief Tileset::takeWangSetAt Removes the wangset at a given index
* And returns it to the caller.
* @param index Index to take at.
* @return
*/
WangSet *Tileset::takeWangSetAt(int index)
{
return mWangSets.takeAt(index);
}

/**
* Adds a new tile to the end of the tileset.
*/
Expand Down Expand Up @@ -617,6 +641,7 @@ void Tileset::swap(Tileset &other)
std::swap(mTiles, other.mTiles);
std::swap(mNextTileId, other.mNextTileId);
std::swap(mTerrainTypes, other.mTerrainTypes);
std::swap(mWangSets, other.mWangSets);
std::swap(mTerrainDistancesDirty, other.mTerrainDistancesDirty);
std::swap(mLoaded, other.mLoaded);
std::swap(mBackgroundColor, other.mBackgroundColor);
Expand All @@ -629,11 +654,15 @@ void Tileset::swap(Tileset &other)
tile->mTileset = this;
for (auto terrain : mTerrainTypes)
terrain->mTileset = this;
for (auto wangSet : mWangSets)
wangSet->setTileset(this);

for (auto tile : other.mTiles)
tile->mTileset = &other;
for (auto terrain : other.mTerrainTypes)
terrain->mTileset = &other;
for (auto wangSet : other.mWangSets)
wangSet->setTileset(&other);
}

SharedTileset Tileset::clone() const
Expand Down Expand Up @@ -669,6 +698,10 @@ SharedTileset Tileset::clone() const
for (Terrain *terrain : mTerrainTypes)
c->mTerrainTypes.append(terrain->clone(c.data()));

c->mWangSets.reserve(mWangSets.size());
for (WangSet *wangSet : mWangSets)
c->mWangSets.append(wangSet->clone(c.data()));

return c;
}

Expand Down
24 changes: 24 additions & 0 deletions src/libtiled/tileset.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Tile;
class Tileset;
class TilesetFormat;
class Terrain;
class WangSet;

typedef QSharedPointer<Tileset> SharedTileset;

Expand Down Expand Up @@ -184,6 +185,13 @@ class TILEDSHARED_EXPORT Tileset : public Object

int terrainTransitionPenalty(int terrainType0, int terrainType1) const;

const QList<WangSet*> &wangSets() const;
int wangSetCount() const;
WangSet *wangSet(int index) const;

void insertWangSet(WangSet *wangSet);
WangSet *takeWangSetAt(int index);

Tile *addTile(const QPixmap &image, const QString &source = QString());
void addTiles(const QList<Tile*> &tiles);
void removeTiles(const QList<Tile *> &tiles);
Expand Down Expand Up @@ -246,6 +254,7 @@ class TILEDSHARED_EXPORT Tileset : public Object
QMap<int, Tile*> mTiles;
int mNextTileId;
QList<Terrain*> mTerrainTypes;
QList<WangSet*> mWangSets;
bool mTerrainDistancesDirty;
bool mLoaded;
QColor mBackgroundColor;
Expand Down Expand Up @@ -553,6 +562,21 @@ inline Terrain *Tileset::terrain(int index) const
return index >= 0 ? mTerrainTypes[index] : nullptr;
}

inline const QList<WangSet*> &Tileset::wangSets() const
{
return mWangSets;
}

inline int Tileset::wangSetCount() const
{
return mWangSets.size();
}

inline WangSet *Tileset::wangSet(int index) const
{
return index >= 0 ? mWangSets[index] : nullptr;
}

/**
* Sets the next id to be used for tiles in this tileset.
*/
Expand Down
80 changes: 49 additions & 31 deletions src/libtiled/wangset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ WangSet::WangSet(Tileset *tileset,
int imageTileId):
Object(Object::TerrainType), //for now, will add unique type soon
mTileSet(tileset),
mEdgeColors(edgeColors),
mCornerColors(cornerColors),
mName(std::move(name)),
mImageTileId(imageTileId),
mWangIdToTile(QMultiMap<WangId, Tile*>()),
mTileIdToWangId(QMap<int, WangId>())
mEdgeColors(edgeColors),
mCornerColors(cornerColors)/*,
mWangIdToTile(QMultiHash<WangId, Tile*>()),
mTileIdToWangId(QHash<int, WangId>())*/
Copy link
Member

Choose a reason for hiding this comment

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

Just remove these lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Knew I forgot something...

{
}

Expand All @@ -53,58 +53,69 @@ void WangSet::addTile(Tile *tile, WangId wangId)
Q_ASSERT(tile->tileset() == mTileSet);

for (int i = 0; i < 4; ++i) {
Q_ASSERT(wangId.getColor(i,true) <= mEdgeColors);
Q_ASSERT(wangId.edgeColor(i) <= mEdgeColors);
}

for (int i = 0; i < 4; ++i) {
Q_ASSERT(wangId.getColor(i,false) <= mCornerColors);
Q_ASSERT(wangId.cornerColor(i) <= mCornerColors);
}

mWangIdToTile.insert(wangId, tile);
mTileIdToWangId.insert(tile->id(), wangId);
}

Tile *WangSet::getMatchingTile(WangId wangId) const
Tile *WangSet::findMatchingTile(WangId wangId) const
{
auto potentials = getAllTiles(wangId);
auto potentials = findMatchingTiles(wangId);

if (potentials.length() > 0)
return potentials[qrand() % potentials.length()];
else
return NULL;
}

QList<Tile*> WangSet::getAllTiles(WangId wangId) const
typedef struct WangWildCard
{
int index, colorCount;
} WangWildCard;
Copy link
Member

Choose a reason for hiding this comment

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

This way of defining a struct was necessary in C times, to avoid needing to repeat the struct keyword whenever you would use WangWildCard. In C++, we can just write:

struct WangWildCard
{
    int index;
    int colorCount;
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What a wonderful time we live in! Thanks for informing me


QList<Tile*> WangSet::findMatchingTiles(WangId wangId) const
{
QList<Tile*> list;

//Stores the space of a wild card, followed by how many colors that space can have.
QVector<QPoint> wildCards;
QVector<WangWildCard> wildCards;

if (mEdgeColors > 0) {
for (int i = 0; i < 4; ++i) {
if (!wangId.getColor(i,true)) {
wildCards.append(QPoint(i * 8, mEdgeColors));
if (!wangId.edgeColor(i)) {
WangWildCard w;
w.index = i * 8;
w.colorCount = mEdgeColors;

wildCards.append(w);
}
}
}

if (mCornerColors > 0) {
for (int i = 0; i < 4; ++i) {
if (!wangId.getColor(i,false)) {
wildCards.append(QPoint(i * 8 + 4, mCornerColors));
if (!wangId.cornerColor(i)) {
WangWildCard w;
w.index = i * 8 + 4;
w.colorCount = mCornerColors;

wildCards.append(w);
}
}
}

if (wildCards.isEmpty()) {
list.append(mWangIdToTile.values(wangId));
} else {
QStack<QPoint> stack;
QStack<WangWildCard> stack;

for (int i = 0; i < wildCards.size(); ++i) {
stack.push(wildCards[i]);
}
stack.append(wildCards);
Copy link
Contributor

Choose a reason for hiding this comment

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

I checked the documentation, check the following link.

http://doc.qt.io/qt-5/qvector.html#append-2

The method to append another qvector was introduced in Qt 5.5 so there is a difference in the Qt version that you are using and the one that the Travis CI uses, I would suggest you to get Qt 5.4.2 which is the officially minimal supported to build Tiled.

Copy link
Contributor

Choose a reason for hiding this comment

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

You might be able to use += or << operators instead.

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 we could also just raise the minimum Qt version to 5.5. I wanted to quickly look up if those operators would work as an alternative, but http://doc.qt.io/archives/index.html does not even host Qt 5.4 documentation anymore.

In general, it does not matter which version is used for development but I'd recommend simply using the latest version, since that is likely the version the next Tiled release is going to be made against. We can check the minimum supported version using Travis CI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So for the time being, should I change that part of the code to comply with the older version? Or just leave it as is?

Copy link
Contributor

Choose a reason for hiding this comment

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

Bjorn has more a word on this than I, he is the product owner, but I would say that if += work in older versions and in newers aswell, then just use the operator.

Copy link
Member

Choose a reason for hiding this comment

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

Right, looking at the Qt 5.4 docs in Qt Creator, the operator+= does work with another QVector, so please just use that instead of append, so we can have it in a single line without raising the Qt dependency.


int max = wildCards.size();

Expand All @@ -113,19 +124,19 @@ QList<Tile*> WangSet::getAllTiles(WangId wangId) const
int idVariation = 0;

for (int i = 0; i < max; ++i) {
idVariation |= stack[i].y() << stack[i].x();
idVariation |= stack[i].colorCount << stack[i].index;
}
Copy link
Member

Choose a reason for hiding this comment

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

Coding style: please leave out the braces for one-line bodies (also below).


list.append(mWangIdToTile.values(idVariation | wangId.id()));
list.append(mWangIdToTile.values(idVariation | wangId));

QPoint top = stack.pop();
top.setY(top.y() - 1);
if (top.y() > 0)
WangWildCard top = stack.pop();
top.colorCount -= 1;
if (top.colorCount > 0)
stack.push(top);
} else {
QPoint top = stack.pop();
top.setY(top.y() - 1);
if (top.y() > 0) {
WangWildCard top = stack.pop();
top.colorCount -= 1;
if (top.colorCount > 0) {
stack.push(top);

for (int i = stack.size(); i < max; ++i) {
Expand All @@ -139,10 +150,17 @@ QList<Tile*> WangSet::getAllTiles(WangId wangId) const
return list;
}

WangId WangSet::getWangIdOfTile(Tile *tile) const
WangId WangSet::wangIdOfTile(Tile *tile) const
{
if (tile->tileset() == mTileSet && mTileIdToWangId.contains(tile->id()))
return mTileIdToWangId.value(tile->id());
else
return WangId(0);
return mTileIdToWangId.value(tile->id());
}

WangSet *WangSet::clone(Tileset *tileset) const
{
WangSet *c = new WangSet(tileset, mEdgeColors, mCornerColors, mName, mImageTileId);

c->mWangIdToTile = mWangIdToTile;
c->mTileIdToWangId = mTileIdToWangId;

return c;
}
Loading