Skip to content

Commit

Permalink
Fixed Automapping of Tile Objects
Browse files Browse the repository at this point in the history
Map Objects are removed from automapping when "DeleteTiles" is used.
Code was already there for this but was comparing tile space with map
space.
Tile Objects can be added to Object Layers through automapping.

Tile Objects having a bottom-left origin and zero width and height was
problematic for automapping.
I've added a convenience function MapObject::boundsUseTile() that will
use the tile, if present, to build the boundary for a given Tile Object.
(Perhaps that function could be better named?)
Note: it's possible that the added functionaliy of
MapObject::boundsUseTile() could just be rolled into
MapObject::bounds(), but I didn't want to (potentially) break legacy
code that may have relied on Tile Objects having an empty bounds. For
instance, do we want Tile Objects to be written out to TMX with non-zero
width and height now?
  • Loading branch information
Seanba authored and bjorn committed Mar 29, 2015
1 parent 1750300 commit 521a40a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
18 changes: 18 additions & 0 deletions src/libtiled/mapobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
*/

#include "mapobject.h"
#include "tile.h"

using namespace Tiled;

Expand Down Expand Up @@ -58,6 +59,23 @@ MapObject::MapObject(const QString &name, const QString &type,
{
}

QRectF MapObject::boundsUseTile() const
{
if (mCell.isEmpty()) {
// No tile so just use regular bounds
return bounds();
}

// Using the tile for determing boundary
// Note the position given is the bottom-left corner so correct for that
QRectF rect;
rect.setLeft(mPos.x());
rect.setTop(mPos.y() - mCell.tile->height());
rect.setWidth(mCell.tile->width());
rect.setHeight(mCell.tile->height());
return rect;
}

void MapObject::flip(FlipDirection direction)
{
if (!mCell.isEmpty()) {
Expand Down
5 changes: 5 additions & 0 deletions src/libtiled/mapobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ class TILEDSHARED_EXPORT MapObject : public Object
*/
QRectF bounds() const { return QRectF(mPos, mSize); }

/**
* Shortcut to getting a QRectF from position() and size() that uses cell tile if present.
*/
QRectF boundsUseTile() const;

/**
* Sets the tile that is associated with this object. The object will
* display as the tile image.
Expand Down
20 changes: 18 additions & 2 deletions src/tiled/automappingutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "addremovemapobject.h"
#include "mapdocument.h"
#include "mapobject.h"
#include "maprenderer.h"
#include "objectgroup.h"

#include <QUndoStack>
Expand All @@ -42,7 +43,22 @@ void eraseRegionObjectGroup(MapDocument *mapDocument,
// tile objects. polygons and polylines are not covered correctly by this
// erase method (we are in fact deleting too many objects)
// TODO2: toAlignedRect may even break rects.
if (where.intersects(obj->bounds().toAlignedRect()))

// Convert the boundary of the object into tile space
const QRectF objBounds = obj->boundsUseTile();
QPointF tl = mapDocument->renderer()->pixelToTileCoords(objBounds.topLeft());
QPointF tr = mapDocument->renderer()->pixelToTileCoords(objBounds.topRight());
QPointF br = mapDocument->renderer()->pixelToTileCoords(objBounds.bottomRight());
QPointF bl = mapDocument->renderer()->pixelToTileCoords(objBounds.bottomLeft());

QRectF objInTileSpace;
objInTileSpace.setTopLeft(tl);
objInTileSpace.setTopRight(tr);
objInTileSpace.setBottomRight(br);
objInTileSpace.setBottomLeft(bl);

const QRect objAlignedRect = objInTileSpace.toAlignedRect();
if (where.intersects(objAlignedRect))
undo->push(new RemoveMapObject(mapDocument, obj));
}
}
Expand All @@ -68,7 +84,7 @@ const QList<MapObject*> objectsInRegion(ObjectGroup *layer,
// tile objects. polygons and polylines are not covered correctly by this
// erase method (we are in fact deleting too many objects)
// TODO2: toAlignedRect may even break rects.
const QRect rect = obj->bounds().toAlignedRect();
const QRect rect = obj->boundsUseTile().toAlignedRect();

// QRegion::intersects() returns false for empty regions even if they are
// contained within the region, so we also check for containment of the
Expand Down

0 comments on commit 521a40a

Please sign in to comment.