-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Map Object resizing, v3! #593
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
Conversation
Sorry, my fixes in commit a2b030a are conflicting with these changes. Could you please rebase these commits on top of the latest master? |
@mauvecow - Hi. I'm very interested in a version of tiled that allow one to resize the images one adds to object layers, i.e. with the "Insert Tile" action on an object layer. Would version provide this? Any tips or links re how to build a Mac version for this version? Regards Greg |
@bjorn what's the next step to get this change merged in? |
@callagga Time constraints. I got a lot going on with work, family and several hobby projects. This is a big change that will take time to review in detail and will likely need some additional work before it can be considered stable. I also do not want it to delay a possible stable release further, so before merging this in I want to make a Tiled 0.10 release. Regarding compiling Tiled on Mac OS X, it should be quite straight-forward, though I'm personally having some strange issue when trying to compile it with Qt 5. I'm just happy the Qt 4 daily builds are still somewhat working, even though it warns a lot about not supporting my version of OS X during the compile. I need to look into that sometime, but meantime just try to follow the wiki page about compiling Tiled and if you get stuck somewhere, report your problem and ask for help. So start at https://github.com/bjorn/tiled/wiki/Contributing-to-Tiled. |
@bjorn - ok thanks for the background - hard to know sometimes if something that seems simply on the surface really is. I'll have a look at the build info. Mind if I ask: a) what does the green notice " All is well — The Travis CI build passed" mean? Does this imply the patch tested ok? b) follow on question from this is whether this patch/pull request works at a basic level? (i..e if you happen to know & there's issues, then I won't try to spend the time frying to build it - just if you happened to have tried it) |
That just means it compiled fine. No relevant autotests currently exist.
It's been a while since I tried it so I can't remember any exact issues right now. I think it works fine in general, though. |
Maybe I didn't merge all the changes in correctly but I'm finding some strange side effects with the resizing code. I dragged the centre right handle to size it by one tile (32pixels) but although it appeared to snap into place, the width is now 94.52 instead of 96 (64+32). When selecting multiple objects the same things happens but it also doesn't restrict the horizontal and vertical movement when using a one axis resize handle e.g. centre right, should only size on the X axis but it actually resizes on both. I rechecked the committed changes, so I think I have transposed them correctly. Thanks |
@obeea If you want to make sure they're not issues introduced by your merging efforts, then check out exactly the branch @mauvecow requested to pull (his |
I did as you suggested and can confirm that these issues remain.
Thanks. |
The reason for this is probably because it has no special-case for single items or groups of non-rotated items. Because for groups of items that have different individual rotation, this kind of resizing is not possible with Tiled because of the kind of transformation that would need to be applied. |
Yes that is a good point, it would be more complicated to check the rotation for each object in the group and resize accordingly. |
I had a play today and was able to get the singleitem resize code to snap to the grid, I really don't know if this is the best way to do it so I've included the code here for reference. void ObjectSelectionTool::updateResizingSingleItem(const QPointF &pos,
Qt::KeyboardModifiers modifiers)
{
MapObjectItem *objectItem = *mMovingItems.begin();
MapRenderer *renderer = mapDocument()->renderer();
QPointF diff = pos - mResizingOrigin;
QPointF startDiff = mStart - mResizingOrigin;
diff = snapToGrid(diff, modifiers);
// Most calculations in this function occur in object space, so
// we transform the scaling factors from world space.
qreal rotation = objectItem->rotation() * M_PI / -180;
const qreal sn = std::sin(rotation);
const qreal cs = std::cos(rotation);
if (rotation != 0) {
diff = QPointF(diff.x() * cs - diff.y() * sn, diff.x() * sn + diff.y() * cs);
startDiff = QPointF(startDiff.x() * cs - startDiff.y() * sn, startDiff.x() * sn + startDiff.y() * cs);
}
// Calculate scaling factor.
QSizeF scalingFactor(qMax((qreal)0, diff.x() / startDiff.x()),
qMax((qreal)0, diff.y() / startDiff.y()));
if (mResizingLimitHorizontal)
scalingFactor.setWidth(1);
if (mResizingLimitVertical)
scalingFactor.setHeight(1);
// Convert relative position into object space, scale,
// and then convert back to world space.
const QPointF oldRelPos = mOldObjectItemPositions.at(0) - mResizingOrigin;
const QPointF objectRelPos(oldRelPos.x() * cs - oldRelPos.y() * sn,
oldRelPos.x() * sn + oldRelPos.y() * cs);
const QPointF scaledRelPos(objectRelPos.x() * scalingFactor.width(),
objectRelPos.y() * scalingFactor.height());
const QPointF newRelPos(scaledRelPos.x() * cs + scaledRelPos.y() * sn,
scaledRelPos.x() * -sn + scaledRelPos.y() * cs);
const QPointF newScreenPos = mResizingOrigin + newRelPos;
const QPointF newPos = renderer->screenToPixelCoords(newScreenPos);
const QSizeF origSize = mOldObjectSizes.at(0);
QSizeF newSize(origSize.width() * scalingFactor.width(),
origSize.height() * scalingFactor.height());
//make sure new size aligns to grid
QPointF nSize = QPointF(newSize.width(),newSize.height());
nSize = snapToGrid(nSize, modifiers);
newSize.setWidth(nSize.x());
newSize.setHeight(nSize.y());
if (objectItem->mapObject()->polygon().isEmpty() == false) {
const QPolygonF &oldPolygon = mOldObjectPolygons.at(0);
QPolygonF newPolygon(oldPolygon.size());
for (int n = 0; n < oldPolygon.size(); ++n) {
const QPointF point(oldPolygon[n]);
const QPointF newPoint(point.x() * scalingFactor.width(),
point.y() * scalingFactor.height());
// newPolygon += newPoint;
newPolygon[n] = newPoint; // replace point
}
objectItem->mapObject()->setPolygon(newPolygon);
}
objectItem->resizeObject(newSize);
objectItem->setPos(newScreenPos);
objectItem->mapObject()->setPosition(newPos);
} |
apologies for the formatting, are there special tags I can use to format code? |
You can use
for more fancy code :) Like this: if (rotation != 0) {
diff = QPointF(diff.x() * cs - diff.y() * sn, diff.x() * sn + diff.y() * cs);
startDiff = QPointF(startDiff.x() * cs - startDiff.y() * sn, startDiff.x() * sn + startDiff.y() * cs);
} |
Will get on reviewing this over the weekend(I hope). Some notes:
It's been long enough that I've forgotten everything so it will take some time to get a good look at it. |
3b85f0d
to
98f8c83
Compare
Rebased to the current master, added the polygon vertex fix from above. Thanks, totally didn't notice. The resizing issue only exists for non-tile objects, and it is tied to the boundingRect() function causing the resizing origins to be placed. I remember this being an issue with object names being applied incorrectly as well. Waiting on feedback on this before fixing this up. And yeah I'll squash this all down next time. |
I totally think object names should not affect the bounding rect. In fact, I think the rendering of object names should be taken out of the map renderer and instead it should be done with separate items on the scene. But, this will be quite a change so it should probably be done separately. |
I've merged master into this branch and pushed the result to So far, it looks like you've done an amazing job, @mauvecow! I'm sorry it has taken me so long to finally work towards merging this. I'll document here the issues I'm aware of that I think should be looked at before merging it into master:
Either before or after merging to master, but before releasing, I'd prefer to also tackle the following:
|
This is exciting news! I just discovered tiled and have been having great fun making maps for D&D. With object resizing this will be a first-class RPG map editor! |
It's been so long I've actually sort of forgotten everything I'd done here. (the project that uses this is, uh, still underway, just taking forever) Sounds like you've got a fair degree of it handled. Is there anything you want me to review? It's kind of a bad time for me to hit this up quickly though. |
@mauvecow I may have some questions later. It'll still be one week till I really have time to work on this. Of course I understand you will have forgotten most of this patch by now, and so have I only faint memories of earlier review rounds we made. You've had this patch in progress since almost 2 years now. :-/ |
I've pushed the progress so far to the |
I pushed some mostly visual improvements in change 333df0e. Now it looks like this: I'm considering whether this looks maybe a little too much still and to put the rotation below a mode switch as done in Inkscape. |
It's merged! The isometric projection as well as the varying object origins (top-left for most objects, bottom-left for tile objects, bottom-center for tile objects on isometric maps...) made it all quite challenging, but I'm relatively happy with the resulting code (commit 42b564d). So all known issues with this patch have been resolved, but some more testing will be in order. The Windows daily build including these changes is already available and an OS X one should be coming soon, as well as rebuilds of the other daily packages. Feature-wise, it's still lacking a mode to keep the aspect ratio, which I think is quite important when working with images. |
|
woohoo! |
Glad to hear it finally made it in. Now to finish the game I was working on that used it... |
Depends on pull requests #591 and #592, so you might want to get through them first to make the comparison less unsightly. Replaces pull #485. Does the following:
Caveats: