[Ohrrpgce] Slice rotation and zoom

Ralph Versteegen teeemcee at gmail.com
Fri Feb 22 14:51:33 PST 2019

I've added a rotozoomer and slice rotate/zoom options, though there
are various things that need to be addressed before I expose it to
users. And those are mostly to do with slice positioning. This email
is about that, and not anything interesting.

It's natural that changing the size of a sprite slice should stretch
its sprite to match its width and height, just like lines, rects and
The hidden "scaled" sprite slice setting (a bool), only available in
32-bit color mode, already acts like this. (I'll be getting rid of
this now-redundant setting).
Sprite slices could still have zoom/zoom x/zoom y properties, but they
could just provide an alternative way to set the size of the slice.
(But sub-pixel zoom is a nice thing to have, so I'll probably still
store the zoom separately. I need to modify the rotozoomer to support
We will need a backcompat bit to enable zooming, because you can
already change the width and height of a sprite by setting it to fill,
but it does nothing. (Even though "set slice width/height" is
disallowed, Fill Parent is a loophole)

That's all fine, but rotation is a problem. As they rotate, the size
of the axis-aligned bounding box changes. But if you want to set both
the sprite size and rotation, the slice width and height should be the
non-rotated size, not the bounding box size.

But if bounding box is used for positioning/alignment, it would mean
their position can't be calculated like other slices.
And how should child slices of the sprite be positioned, how should
the Fill Parent setting for both the sprite and its children work,
"Cover Children", "slice at pixel", and whatever else I've forgotten?

In a perfect world, perhaps all children of a rotated sprites would be
rotated too, like an OpenGL transformation matrix stack... but we
wouldn't really expect child slices of a stretched sprite to be
stretched in the same way. I think that if we ever implemented
whole-slice-tree zooming/rotating, they should actually be completely
separate slice properties, not sprite properties. Still, even if the
child slices aren't rotated, maybe the alignment points on the rotated
parent should be rotated too, for convenience when positioning? Oh,
but then child X and Y offsets would also have to be rotated for
consistency. How about we assume that in future we would add separate
settings to rotate and stretch a slice tree, so anything we add now
should be orthogonal to that instead of overlapping: we shouldn't add
transformation of child positions now, because there's a better way to
do it later.

Still, that leaves the problem that the bounding box size is not equal
to the "specified size" set in the slice editor/by scripts.
If rotated sprites always rotated around their center and we treated
the bounding box size as being equal to the specified size, even
though the drawn sprite might extend far outside it, then all the
problems can go away. "slice at pixel" could always be given special
cases for rotated sprites, ellipses, and lines anyway.

But you should be able to customise the point around which a sprite is
rotated, otherwise correctly positioning a sprite rotated around a
corner (eg a swung weapon) would require complicated calculations by
the user.
At a minimum sprites should rotate around their anchor point, but even
that's not flexible enough - for a weapon swung in an arc the point
should actually be outside the sprite. You could add blank space to
the sprite, though.
Again, if the bounding box size and position didn't change at all
there would be no problem, except the sprite is likely to be
completely outside its bounding box! That seems a tad ridiculous. If
the box size didn't change but the position did that seems reasonable
enough, and only the calculation of the anchor point would need to be
specialised. Allowing the size to change requires replacing most
occurrences of sl->Width and sl->Height in the code!

Another example: a ball rolling along the top of a surface. You might
want its anchor point to be the bottom of the slice, but to rotate
around the center.

Right now, rotating around a custom offset and specialising
SliceX/YAnchor() to compensate for that offset + rotation angle seems
preferable. Funny, I almost got rid of those functions a couple weeks
ago because they seemed unneeded.

More information about the Ohrrpgce mailing list