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

Various fixes for trimmed sprites and images #465

Merged
merged 29 commits into from
Nov 12, 2022

Conversation

ggcrunchy
Copy link
Contributor

I was doing some art for a project and this involved objects consisting of several parts, like one would have in Spine or Spriter. I used trimming so that I could choose some fixed size, e.g. 512 x 512, and in the image editor just put the individual parts in different layers and draw on those, for my own sanity.

Well, this is all well and good if you just put the sprites and (image sheet-based) images down on the center position and leave it there. But with scaling and rotation (especially with anchoring!) in the mix, problems quickly arise.

This and this, for instance, touch on issues I saw, and maybe this one as well.

@Shchvova I sent you a project I used for testing. As I told somebody else, "The rotating head is way off, the wings break, the legs aren't where their bounds show (the two rects), they "dance", and the collision rect is shifted and oversized."

Basically, the trimming offset needs to be taken into account in several more places.


I pulled the frame offset calculation out of ShapeObject::DidUpdateTransform() and into a GetTrimmedFrameOffset() function. The offset will always be retrieved by DidUpdateTransform(), to achieve the current behavior, but in the remaining cases a new flag—enabled via display.setDefault("isImageSheetFrameTrimCorrected", true), initially false for compatibility purposes—will be queried, and when not set the offset will have x and y of 0.

These offsets figure into some operations that traverse the display hierarchy, or the parent chain up to the stage, including the calculation of a display object's transform. They are omitted where the source-to-destination matrix is valid.


There are a few "unrelated" additions, though I didn't exactly know that while I was doing them.


A group's anchorChildren property won't immediately affect anything; another display property would need to be set, such as x. I've added a fix for this. Per the comment, you have to enable sprite trimming to get this behavior. This is a bit odd; maybe it should have its own default? (At the same time, if you were willing and able to enable a new default, you probably want the sprite corrections as well, in which case adding another would be superfluous. shrug)


On that same note, while making sure physics played well, I tried this case:

local physics = require("physics")

physics.start()
physics.setGravity(0,0)
physics.setDrawMode("hybrid")

local g = display.newGroup()
local r1 = display.newRect(g, 200, 200, 80, 80)
local r2 = display.newRect(g, 100, 150, 20, 70) -- extra, since one object will show the issue

physics.addBody(g, "static")

(The body and the group will be in rather different spots.)

This will address that. It's also guarded by the sprite trimming default, like anchorChildren; the same criticisms apply.


More of a general sprite thing: some of the frames would be wider or whatever than others, in the same sequence, but the sprite would just blindly use whatever anchor it had, everywhere. I added a new method: sprite:useFrameForAnchors([index]). This will make the frame at index (if omitted, the current frame) normative; any anchor computation is done as if that frame were active.

The index refers to the member of the current sequence, if one is assigned. If the sequence is changed, the sprite will stop watching the frame.


I believe that covers it.

ggcrunchy and others added 28 commits February 7, 2019 17:09
…nd buffer and assignment logic

Next up, prepare details from graphics.defineEffect()
…from Program

Slight redesign of TimeTransform with caching (to synchronize multiple invocations with a frame) and slightly less heavyweight call site
Err, was calling Modulo for sine method, heh

That said, time transform seems to work in basic test
Fixed error detection for positive number time transform inputs

Relaxed amplitude positivity requirement
Maintenance Revert Test
My mistake adding back changes made
Group anchoring not quite right (calculation pulls in offsets)

Needs testing with other rotation and scaling scenarios
Renamed GetCorrectionForOffset() to GetTrimmedFrameOffset()

Added flag to image sheets, now checked in that function

Added display default, isImageSheetFrameTrimCorrected, used to populate that and thus opt-in to the new behavior
…ling)

Physics body (automatic one) adjusted for offsets... probably still need to handle custom ones too
Also a frame trimming method for anchors, that relies on that

Seems to work in test cases, so now just needs some review
Some backward compatibility checks

Negating the offset in the physics stuff was wrong
@ggcrunchy ggcrunchy requested a review from Shchvova as a code owner October 18, 2022 02:44
Copy link
Contributor

@Shchvova Shchvova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I'll test it and merge

Copy link
Contributor

@Shchvova Shchvova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I'll test it and merge

@Shchvova Shchvova merged commit d5ebcde into coronalabs:master Nov 12, 2022
@ggcrunchy ggcrunchy deleted the SpriteSourceOffset branch December 19, 2022 21:51
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

Successfully merging this pull request may close these issues.

3 participants