Skip to content

Commit

Permalink
Unified Wang colors
Browse files Browse the repository at this point in the history
Removed the distinction between corner colors and edge colors. A WangSet
now has just one list of colors, which can be used at any index.

The tools will need some other way of knowing whether they are operating
on corners, edges or both now.
  • Loading branch information
bjorn committed Sep 9, 2020
1 parent 7f62c3d commit 0139dda
Show file tree
Hide file tree
Showing 30 changed files with 920 additions and 1,198 deletions.
33 changes: 29 additions & 4 deletions src/libtiled/mapreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,14 +696,37 @@ void MapReaderPrivate::readTilesetWangSets(Tileset &tileset)

auto wangSet = std::make_unique<WangSet>(&tileset, name, tile);

// For backwards-compatibility
QVector<int> cornerColors;
QVector<int> edgeColors;

while (xml.readNextStartElement()) {
const bool isCorner = xml.name() == QLatin1String("wangcornercolor");
const bool isEdge = xml.name() == QLatin1String("wangedgecolor");

if (xml.name() == QLatin1String("properties")) {
wangSet->mergeProperties(readProperties());
} else if (xml.name() == QLatin1String("wangtile")) {
const QXmlStreamAttributes tileAtts = xml.attributes();
int tileId = tileAtts.value(QLatin1String("tileid")).toInt();
WangId wangId = tileAtts.value(QLatin1String("wangid")).toUInt(nullptr, 16);

// Backwards compatibility with TMX 1.4:
// If the wang set was using explicit corner and edge colors,
// map the WangId to the unified colors.
if (!cornerColors.isEmpty() || !edgeColors.isEmpty()) {
for (int i = 0; i < 4; ++i) {
int color = wangId.cornerColor(i);
if (color > 0 && color <= cornerColors.size())
wangId.setCornerColor(i, cornerColors.at(color - 1));
}
for (int i = 0; i < 4; ++i) {
int color = wangId.edgeColor(i);
if (color > 0 && color <= edgeColors.size())
wangId.setEdgeColor(i, edgeColors.at(color - 1));
}
}

if (!wangSet->wangIdIsValid(wangId)) {
xml.raiseError(QLatin1String("Invalid wangId given for tileId: ") + QString::number(tileId));
return;
Expand All @@ -723,23 +746,25 @@ void MapReaderPrivate::readTilesetWangSets(Tileset &tileset)
wangSet->addWangTile(wangTile);

xml.skipCurrentElement();
} else if (xml.name() == QLatin1String("wangedgecolor")
|| xml.name() == QLatin1String("wangcornercolor")) {
} else if (xml.name() == QLatin1String("wangcolor") || isCorner || isEdge) {
const QXmlStreamAttributes wangColorAtts = xml.attributes();
bool isEdge = xml.name() == QLatin1String("wangedgecolor");
QString name = wangColorAtts.value(QLatin1String("name")).toString();
QColor color = wangColorAtts.value(QLatin1String("color")).toString();
int imageId = wangColorAtts.value(QLatin1String("tile")).toInt();
qreal probability = wangColorAtts.value(QLatin1String("probability")).toDouble();

auto wc = QSharedPointer<WangColor>::create(0,
isEdge,
name,
color,
imageId,
probability);
wangSet->addWangColor(wc);

if (isCorner)
cornerColors.append(wc->colorIndex());
if (isEdge)
edgeColors.append(wc->colorIndex());

xml.skipCurrentElement();
} else {
readUnknownElement();
Expand Down
23 changes: 6 additions & 17 deletions src/libtiled/maptovariantconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,31 +367,20 @@ QVariant MapToVariantConverter::toVariant(const WangSet &wangSet) const
wangSetVariant[QStringLiteral("name")] = wangSet.name();
wangSetVariant[QStringLiteral("tile")] = wangSet.imageTileId();

QVariantList edgeColorVariants;
if (wangSet.edgeColorCount() > 1) {
for (int i = 1; i <= wangSet.edgeColorCount(); ++i) {
if (WangColor *wc = wangSet.edgeColorAt(i).data())
edgeColorVariants.append(toVariant(*wc));
}
}
wangSetVariant[QStringLiteral("edgecolors")] = edgeColorVariants;

QVariantList cornerColorVariants;
if (wangSet.cornerColorCount() > 1) {
for (int i = 1; i <= wangSet.cornerColorCount(); ++i) {
if (WangColor *wc = wangSet.cornerColorAt(i).data())
cornerColorVariants.append(toVariant(*wc));
}
QVariantList colorVariants;
if (wangSet.colorCount() > 1) {
for (int i = 1; i <= wangSet.colorCount(); ++i)
colorVariants.append(toVariant(*wangSet.colorAt(i)));
}
wangSetVariant[QStringLiteral("cornercolors")] = cornerColorVariants;
wangSetVariant[QStringLiteral("colors")] = colorVariants;

QVariantList wangTileVariants;
const auto wangTiles = wangSet.sortedWangTiles();
for (const WangTile &wangTile : wangTiles) {
QVariantMap wangTileVariant;

QVariantList wangIdVariant;
for (int i = 0; i < 8; ++i)
for (int i = 0; i < WangId::NumIndexes; ++i)
wangIdVariant.append(QVariant(wangTile.wangId().indexColor(i)));

wangTileVariant[QStringLiteral("wangid")] = wangIdVariant;
Expand Down
23 changes: 4 additions & 19 deletions src/libtiled/mapwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,25 +502,10 @@ void MapWriterPrivate::writeTileset(QXmlStreamWriter &w, const Tileset &tileset,
w.writeAttribute(QStringLiteral("name"), ws->name());
w.writeAttribute(QStringLiteral("tile"), QString::number(ws->imageTileId()));

if (ws->edgeColorCount() > 1) {
for (int i = 1; i <= ws->edgeColorCount(); ++i) {
if (WangColor *wc = ws->edgeColorAt(i).data()) {
w.writeStartElement(QStringLiteral("wangedgecolor"));

w.writeAttribute(QStringLiteral("name"), wc->name());
w.writeAttribute(QStringLiteral("color"), colorToString(wc->color()));
w.writeAttribute(QStringLiteral("tile"), QString::number(wc->imageId()));
w.writeAttribute(QStringLiteral("probability"), QString::number(wc->probability()));

w.writeEndElement();
}
}
}

if (ws->cornerColorCount() > 1) {
for (int i = 1; i <= ws->cornerColorCount(); ++i) {
if (WangColor *wc = ws->cornerColorAt(i).data()) {
w.writeStartElement(QStringLiteral("wangcornercolor"));
if (ws->colorCount() > 1) {
for (int i = 1; i <= ws->colorCount(); ++i) {
if (WangColor *wc = ws->colorAt(i).data()) {
w.writeStartElement(QStringLiteral("wangcolor"));

w.writeAttribute(QStringLiteral("name"), wc->name());
w.writeAttribute(QStringLiteral("color"), colorToString(wc->color()));
Expand Down
45 changes: 36 additions & 9 deletions src/libtiled/varianttomapconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,26 @@ std::unique_ptr<WangSet> VariantToMapConverter::toWangSet(const QVariantMap &var

wangSet->setProperties(extractProperties(variantMap));

const QVariantList edgeColorVariants = variantMap[QStringLiteral("edgecolors")].toList();
for (const QVariant &edgeColorVariant : edgeColorVariants)
wangSet->addWangColor(toWangColor(edgeColorVariant.toMap(), true));
const QVariantList colorVariants = variantMap[QStringLiteral("colors")].toList();
for (const QVariant &colorVariant : colorVariants)
wangSet->addWangColor(toWangColor(colorVariant.toMap()));

// For backwards-compatibility
QVector<int> cornerColors;
QVector<int> edgeColors;

const QVariantList edgeColorVariants = variantMap[QStringLiteral("edgecolors")].toList();
for (const QVariant &edgeColorVariant : edgeColorVariants) {
auto wc = toWangColor(edgeColorVariant.toMap());
wangSet->addWangColor(wc);
edgeColors.append(wc->colorIndex());
}
const QVariantList cornerColorVariants = variantMap[QStringLiteral("cornercolors")].toList();
for (const QVariant &cornerColorVariant : cornerColorVariants)
wangSet->addWangColor(toWangColor(cornerColorVariant.toMap(), false));
for (const QVariant &cornerColorVariant : cornerColorVariants) {
auto wc = toWangColor(cornerColorVariant.toMap());
wangSet->addWangColor(wc);
cornerColors.append(wc->colorIndex());
}

const QVariantList wangTileVariants = variantMap[QStringLiteral("wangtiles")].toList();
for (const QVariant &wangTileVariant : wangTileVariants) {
Expand All @@ -420,9 +433,25 @@ std::unique_ptr<WangSet> VariantToMapConverter::toWangSet(const QVariantMap &var

WangId wangId;
bool ok = true;
for (int i = 0; i < 8 && ok; ++i)
for (int i = 0; i < WangId::NumIndexes && ok; ++i)
wangId.setIndexColor(i, wangIdVariant[i].toUInt(&ok));

// Backwards compatibility with version 1.4:
// If the wang set was using explicit corner and edge colors,
// map the WangId to the unified colors.
if (!cornerColors.isEmpty() || !edgeColors.isEmpty()) {
for (int i = 0; i < 4; ++i) {
int color = wangId.cornerColor(i);
if (color > 0 && color <= cornerColors.size())
wangId.setCornerColor(i, cornerColors.at(color - 1));
}
for (int i = 0; i < 4; ++i) {
int color = wangId.edgeColor(i);
if (color > 0 && color <= edgeColors.size())
wangId.setEdgeColor(i, edgeColors.at(color - 1));
}
}

if (!ok || !wangSet->wangIdIsValid(wangId)) {
mError = QStringLiteral("Invalid wangId given for tileId: ") + QString::number(tileId);
return nullptr;
Expand All @@ -445,16 +474,14 @@ std::unique_ptr<WangSet> VariantToMapConverter::toWangSet(const QVariantMap &var
return wangSet;
}

QSharedPointer<WangColor> VariantToMapConverter::toWangColor(const QVariantMap &variantMap,
bool isEdge)
QSharedPointer<WangColor> VariantToMapConverter::toWangColor(const QVariantMap &variantMap)
{
const QString name = variantMap[QStringLiteral("name")].toString();
const QColor color = variantMap[QStringLiteral("color")].toString();
const int imageId = variantMap[QStringLiteral("tile")].toInt();
const qreal probability = variantMap[QStringLiteral("probability")].toDouble();

return QSharedPointer<WangColor>::create(0,
isEdge,
name,
color,
imageId,
Expand Down
2 changes: 1 addition & 1 deletion src/libtiled/varianttomapconverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class TILEDSHARED_EXPORT VariantToMapConverter
const QVariant &propertyTypesVariant) const;
SharedTileset toTileset(const QVariant &variant);
std::unique_ptr<WangSet> toWangSet(const QVariantMap &variantMap, Tileset *tileset);
QSharedPointer<WangColor> toWangColor(const QVariantMap &variantMap, bool isEdge);
QSharedPointer<WangColor> toWangColor(const QVariantMap &variantMap);
std::unique_ptr<ObjectTemplate> toObjectTemplate(const QVariant &variant);
std::unique_ptr<Layer> toLayer(const QVariant &variant);
std::unique_ptr<TileLayer> toTileLayer(const QVariantMap &variantMap);
Expand Down
Loading

0 comments on commit 0139dda

Please sign in to comment.