Tile flipping issue

Hello.

I’ve been using tiled for years now but i’m just starting to use flipping.

I am doing a square map and i just mapped the first top left corner then copy / paste / flipped the other corners. The result looks good on Tiled.

However, i am having trouble to implement the antidiag flipping. I’ve read Stuck implementing antidiagonal flipping of tiles · Issue #2119 · mapeditor/tiled · GitHub and posts from bjørn and i understood that the ad flipping is just -90 degree rotation + vertical flipping, but it dont work in my case.

Does someone has a precise algorithm to implement all cases of flipping?

Actually what i did was simply X mirroring if horizontal flipping, Y mirroring if vertical flipping then apply a -90 degree + x mirroring if the AD flipping was on.

Thanks !

Not an answer, but just to avoid future edge cases: make sure you clear the hexagonal 120-degree rotation flag (0x10000000) too. It’s unlikely to creep into your map data if you never mess with hexagonals, but it does stick around if you switch data from hex to orthogonal, and it’s easy to miss that it’s there. Better safe than sorry. If it gets into your data and doesn’t get cleared, you’ll end up with invalid tile IDs.

Here’s the C++ code from my project that handles flips and rotations.

//hflip, vdlip, and dflip are bools obtained by checking the flags
//topLeft, topRight, botLeft, botRight are vectors containing texture coordinates for the current tile. They're initialised to the untransformed tile's coordinates.

if(dflip) {
	temp = topRight;
	topRight = botLeft;
	botLeft = temp;
}
if(hflip) {
	temp = topLeft;
	topLeft = topRight;
	topRight = temp;
	temp = botLeft;
	botLeft = botRight;
	botRight = temp;
}
if(vflip) {
	temp = topLeft;
	topLeft = botLeft;
	botLeft = temp;
	temp = topRight;
	topRight = botRight;
	botRight = temp;
}

As you can see, in mine, I’m not applying transformations, I’m swapping texture coords around, since I use a fairly low-level representation of tiles (to make drawing faster). I find it easier to think about in terms of flips than rotations.

The diagonal flip should be done first. Otherwise, the coordinates you need to swap will change based on the combination of vertical and horizontal flips.

If rotations are the only thing you have access to and can’t just move the texture coordinates around to flip stuff, then the mistake you’re making might be the order. First, do the diagonal check, rotate and THEN flip*. After that, do the horizontal and vertical flips.

init currentTransform
if(dflip)
	currentTransform.rotate(90) //90 degrees clockwise. If in your engine y points up, then this may need to be 270 instead of 90.
	currentTransform.scale(-1, 1)
if(hflip)
	currentTransform.scale(-1, 1)
if(vflip)
	currentTransform.scale(1, -1)

* in this example, I rotated 90 degrees clockwise and a horizontal flip. 90 degrees counterclockwise and a vertical flip also works. Just make sure the order is correct.

2 Likes

Wow thanks a lot !

I was doing the rotation trick exactly the way you are doing it but your code helped me understand my problem.

I was doing something like this (openGL, if you’re familiar with)

	    glTexCoord2f(o.isXMirrored() ? topRightX : topLeftX, o.isYMirrored() ? bottomLeftY : topLeftY);
		glVertex3f(o.getX(), o.getY(), o.getZ());

		glTexCoord2f(o.isXMirrored() ? topLeftX : topRightX, o.isYMirrored() ? bottomRightY : topRightY);
		glVertex3f(o.getX() + o.getWidth(), o.getY(), o.getZ());

		glTexCoord2f(o.isXMirrored() ? bottomLeftX : bottomRightX, o.isYMirrored() ? topRightY : bottomRightY);
		glVertex3f(o.getX() + o.getWidth(), o.getY() + o.getHeight(), o.getZ());

		glTexCoord2f(o.isXMirrored() ? bottomRightX : bottomLeftX, o.isYMirrored() ? topLeftY : bottomLeftY);
		glVertex3f(o.getX(), o.getY() + o.getHeight(), o.getZ());

Which doesn’t work if the texture is X + Y mirrored at the same time. (in your code, if X mirrored then topLeftX = topRightX but also if y mirrored topLeftX = bottomLeftX)…

If it can help someone else !

Thanks :grinning: