0
\$\begingroup\$

I used TexturePacker to create an atlas for me and I've read it into my game. I can use unrotated and untrimmed sprites and it works fine. Now I would like to support trimmed sprites and I'm running into a conceptual issue.

I'm not sure how to do the untrimming. What do you do with the trim information?

My sprite is rendered as a quad with 4 vertices and 4 uv's.

Let's say the original sprite was:

size.width = 100;
size.height = 100;

Let's say that it exists in the atlas at:

location.x = 0;
location.y = 0;
location.width = 100;
location.height = 100;

To draw this untrimmed image, I do the following.

  1. Compute 4 vertices for the sprite. I use the height/width ratio to adjust the top right and bottom right vertices. That way the sprite's aspect ratio is what you would expect
  2. Compute 4 UV for the sprite. In the above case, if the atlas is 1024 pixels square, then the UVs would form a box between the points (0.0, 0.0) to (0.1, 0.1)

And this works fine. I can see an untrimmed image exactly as you would expect.

Enter trimming....

Let's say the original sprite was:

size.width = 100;
size.height = 100;

Let's say that it was trimmed in the atlas too:

trim.x = 5; // it was trimmed "in" from the left by 5 pixels
trim.y = 5; // it was trimmed "down" from the top by 5 pixels
trim.width = 15; // it was trimmed "in" from the right by 15 pixels
trim.height = 15; // it was trimmed "up" from the bottom by 15 pixels

So now the final location in the atlas is:

location.x = 0;
location.y = 0;
location.width = 80;
location.height = 80;

What I'm confused about is how to "untrim" the image when it is drawn. I tried:

  • Moving the UV's by the amount that was trimmed. This resulted in a stretched image and in other tests, I saw parts of the adjacent sprites. You can't really move a UV.
  • Moving the vertices by the amount that was trimmed. Some of my sprites are actually animations. This causes some frames to have different heights and widths -- sprite appears to "bounce". It's bounding box shifts around too with the trimming. (Currently, I have AABB's formed tightly around the vertices of the sprite -- which is what you would expect when the sprite is not trimmed.)

I clearly am missing the concept here. How does one "untrim" the sprite during a render? (I'm using OpenGL) Am I supposed to move around the vertices, but not the bounding box?

\$\endgroup\$
2
\$\begingroup\$

What you have to do is roughly the following:

  1. Pretend that your sprite has the original size in your game. This is important to keep animations aligned.

  2. Instead of rendering the original sprites' quad you have to

    • use the quad of the trimmed sprite: Trim offset with trimmed sprite size
    • apply the scene transformations (rotation, scale , translation)
  3. Don't modify the UVs.

I can't give you an exact formula because this depends on several other factors (scene coordinate system orientation, pivot point / anchor point on your sprite, your sprite coordinate system,...) but I hope this gives you an idea.

Trimmed sprite in a game scene

This image shows you the trimmed sprite inside the virtual "full" sprite. The trim offset is shown as a green line from the sprite's origin (black circle). The blue line stands for the sprite's transform (calculated from translation, scale and rotation).

Another option for you would be to use the Polygon Trim Mode. The difference here is that you get a list of triangles instead of a quad with the original coordinates in the source sprite.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.