What is wrong with axis of objects?

(Gotenxds) #1

Hello, I think I’m getting something vary wrong or tiled is completely stupid when it comes to objects.

First of all object pivot point is 0,1 instead of the traditional 0,0 or .5,.5
What this means is that tiled is positioning point for images is from their bottom left corner which is vary wired considering tiled axis is 0,0 from the TOP left corner.

Secondly this pivot point is only taken into account in the numbers but not visually in the program so if you position an
image at position 0,0 with size of 100,100 and then filp it verticly it wont move in tiled but once a different program/game engine tries to load it and it sets the anchor point to 0,1 the image will move to 0,-100 it has to because of the anchor point.
Thats why you usually set anchor points to (0.5,0.5) so rotations and flips wont change position.

This also kills any rotation.

There is also a bug where if you change to rotation via the ui the image wont change position (it will automatically change its position to match the new rotation) but if you change the rotation via the textInput it wont change the position accordingly and completely fuck up the image position on the view…

All of this can easily be fixed if the programmer would just follow the conventions and set the pivot/anchor point to the middle of the image.

(Epsilon Alexey) #2

Hello. You can simple change pivot point to the centre of object by yourself and put it to your engine rotation formula. This is not an issue at all. For example here is rotation formula for Unity3D:

float x_center = (mo.x * ppu + mo.width * Mathf.Cos (Mathf.Deg2Rad * mo.rotation) / 2 + mo.height * Mathf.Sin (Mathf.Deg2Rad * mo.rotation) / 2) / ppu;
float y_center = (mo.y * ppu + mo.height * Mathf.Cos (Mathf.Deg2Rad * mo.rotation) / 2 - mo.width * Mathf.Sin (Mathf.Deg2Rad * mo.rotation) / 2) / ppu;
sm.GetComponent<Transform> ().position = new Vector3 (x_center, y_center, layerZ);
sm.GetComponent<Transform> ().localRotation = Quaternion.AngleAxis(- mo.rotation, new Vector3(0f, 0f, 1f));
sm.GetComponent<Transform>().transform.localScale = new Vector3(mo.width / tile.width, mo.height / tile.height, 1f);

Here “mo” is an object read from TMX map, it contains width, height, rotation.
“tile” is an object, contains tile properties from TSX spriteset (width, height).

Have a nice day.

(Thorbjørn Lindeijer) #3

I totally agree it is weird, but changing it would break compatibility. My idea is to make the object origin configurable and eventually to change the default to top-left. Even worse than the bottom-left origin is the fact that tile objects and rectangle/ellipse objects have different origin points. The reason is that tile objects were implemented to render the same way as tiles on a tile layer, where they are also bottom-left aligned.

In Tiled the flipping applies directly to the image, not the object. Hence it does not affect the object position. I realize the documentation is lacking on this point. In OpenGL it can be implemented by swapping texture coordinates (as well as some vertex coordinates in case of diagonal flip with non-square images)

That’s not a bug. If you want visual rotation, use the view. Changing the rotation property directly will apply the rotation around the object’s origin. In the future, you will be able to set the origin to center if that’s what you prefer.

See also the following issue on GitHub:

(Gotenxds) #4

Hi alexey and bjorn, thanks for the answer, I think is is a problom if the end user need to come up with a formula to correct the data given by tiled, but maybe that’s just me, as for your answer, Ive come up with similer code and its working - kinda I have slight deviation in the positions can you take a look? also what is the ppu in your code ?

private static transformFromTiledData(image, imgData) {

    imgData.rotation = Phaser.Math.degToRad(imgData.rotation || 0);
    image.anchor.set(.5, .5);

    let centerX = imgData.width /2 ;
    let centerY = imgData.height /2 ;

    let cosRotation = Math.cos(image.rotation);
    let sinRotation = Math.sin(image.rotation);

    imgData.x += centerX * cosRotation - centerY * sinRotation;
    imgData.y += centerX * sinRotation + centerY * cosRotation;

    if (imgData.gid & ObjectLayer.FLIPPED_HORIZONTALLY_FLAG) {
        image.scale.x = -1;
    if (imgData.gid & ObjectLayer.FLIPPED_VERTICALLY_FLAG) {
        image.scale.y = -1;

Could my error be because of the missing diagonal flip ?
Bjron can you explain what is it for me, Ive never heard of such a thing.

(Epsilon Alexey) #5

Sorry, ppu = 100 is a default “points per unit” value for sprites in Unity3d.

(George Kurelic) #6

@bjorn, what is the status of configurable origin points on objects? Is there a Github issue I can enable notifications for? Has there been a proposition for the interface and backwards compatibility of this feature?