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

Objects have inconsistent origins #68

Closed
PatrickHoward opened this issue Jun 7, 2020 · 2 comments
Closed

Objects have inconsistent origins #68

PatrickHoward opened this issue Jun 7, 2020 · 2 comments

Comments

@PatrickHoward
Copy link
Contributor

So a couple weeks ago one of my colleagues was working in Tiled and upon creating a level he noticed something strange: Object origins in tiled are inconsistent.

Capture

All of the generic objects (excluding points) have an origin in the top left, whereas objects instantiated from Tiles have origins in the bottom left. I talked to the Tiled devs and they said that they will be adding ways to manually set the origin of a given object in the next dev release... It doesn't seem to be in the latest beta (1.4 at the time of this issue).

Currently in tmxlite, tile objects and rectangles are treated the exact same. It makes sense (as tiles are rectangles, no doubt). However this leads to having to write code such as this...

newObject.dimensions = Vector2i(tilemapObject.getAABB().width, tilemapObject.getAABB().height);
newObject.position = Vector2i(tilemapObject.getPosition().x, tilemapObject.getPosition().y - newObject.dimensions.y + 1);

(For context, I use tmxlite to preprocess maps)

The above code places objects in their expected places if the object is a tile object. However what happens if the object is a generic rectangle? Its impossible to tell if the object is a generic rectangle object or a tile object.

So my proposal is this: add a Tile shape to the Shape enumeration in Object.hpp:

        enum class Shape
        {
            Rectangle,
            Ellipse,
            Point,
            Polygon,
            Polyline,
            Text,
            Tile
        };

That way, one can handle the ambiguity ..

newObject.dimensions = Vector2i(tilemapObject.getAABB().width, tilemapObject.getAABB().height);
if (tilemapObject.getShape() == tmx::Object::Shape::Tile)
{
    newObject.position = Vector2i(tilemapObject.getPosition().x, tilemapObject.getPosition().y - newObject.dimensions.y + 1);
}
else
{
    newObject.position = Vector2i(tilemapObject.getPosition().x, tilemapObject.getPosition().y);
}

Of course, the problem with this is that one needs to know about Tiled's strange exception to Tile objects. Tmxlite could handle this excpetion silently by subtracting the Y and placing the origin in the top left, but that might break some folk's applications.

Thoughts? Suggestions?

@fallahn
Copy link
Owner

fallahn commented Jun 7, 2020

Hi! I had indeed noticed this pecularity some time ago when working on one of my own projects. The inconsistency sadly runs a bit deeper than this - objects in the tmx file which aren't a rectangle contain a child node describing their shape, which the Shape enum is designed to represent. On the other hand rectangular objects have no child nodes (in which case tmxlite just assumes the object is rectangular) but they may or may not have a tile gid attribute if they are a tile object. sigh. I've always tried to maintain a 1:1 match for the data structures as closely as possible without making any assumptions on the end user's behalf, and this is already slightly skewed by the fact that I've had to introduce a Rectangle shape type which doesn't technically exist, at least not as a tmx node. For this reason I'm not keen on introducing a new member to the enum and, as you point out, it may break existing user's projects when Rectangle type objects suddenly become exclusively non-tile objects. However as an object may potentially have a tile ID Object::getTileID() exists, which can be used to determine if an object is a tile type. By default this returns 0 so it can be used something like:

if(object.getTileID())
{
    //must be a tile object
}
else {}

Which I believe is the intended (albeit slightly confusing) use. Of course should the tiled devs add support for modifying object origins I'll endeavour to support any new properties which may be added.

@PatrickHoward
Copy link
Contributor Author

Thats a good point, I didn't think about checking the tileID, I think that will work as a temporary fix when properties in regards to origin placement come into fruition.

@fallahn fallahn closed this as completed Jun 11, 2020
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

No branches or pull requests

2 participants