Skip to content

core: Return false for shape hitTests on zero-scale graphics #10330

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

Merged
merged 5 commits into from
Mar 31, 2023

Conversation

Herschel
Copy link
Member

@Herschel Herschel commented Mar 23, 2023

If a graphic has a scaleX or scaleY of 0, a shape hitTest(x, y, true) should return false, even on the exact location of the object. Note that a bounds hitTest(x, y, false) still returns true on the exact location of the object. Bail out on the hitTest immediately when we detect no width or height.

Fix with the following changes:

  • Change Matrix::invert to Matrix::inverse and make it fallible, returning None for non-invertible matrices. (An object with zero scale will have a non-invertible matrix for its transform).
  • Change DisplayObject::global_to_local_matrix and DisplayObject::global_to_local fallible. These return None when the object has zero scale.
  • Adjust all places in core that used these to properly handle these methods returning None. All overrides of hit_test_shape will return false in this case.

Bonus:

  • Fix clip.globalToLocal(point) when the clip has zero scale: point will be unaffected.
  • Fix clip._xmouse/_ymouse/etc. when the clip has zero scale: a 1/20 scale matrix (twips-to-pixels) is used.
    • Added DisplayObject::mouse_to_local to handle these cases.

Fixes #6906.

@Herschel Herschel marked this pull request as draft March 23, 2023 08:40
@Herschel Herschel force-pushed the hit-test-zero-scale branch from 7a6e444 to 9d3a873 Compare March 31, 2023 00:59
@Herschel Herschel marked this pull request as ready for review March 31, 2023 05:06
@Herschel Herschel requested a review from Toad06 March 31, 2023 05:06
@Herschel
Copy link
Member Author

Herschel commented Mar 31, 2023

I decided on a more thorough way to solve this by making Matrix::inverse, DisplayObject::global_to_local return an Option. This way any caller has to explicitly handle the case when the object is zero scale and the matrix has no inverse.

@Herschel Herschel force-pushed the hit-test-zero-scale branch from 0edddf7 to a19940e Compare March 31, 2023 20:04
Copy link
Member

@Toad06 Toad06 left a comment

Choose a reason for hiding this comment

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

Thanks for your work on this. This looks good to me based on testing, I haven't found any issue or regression.

Mentioning that this game now works would be a nice addition to ruffle-rs/ruffle-rs.github.io#132. 😉

 * Add `Matrix::determinant`.
 * Rename `Matrix::invert` to `inverse`.
 * `Matrix::inverse` return an `Option`, with `None` returned
    for non-invertible matrices.
 * AMV `Matrix::invert` duplicates the code as the behavior is
   different (works in f64 and not twips, etc.)
This will return `None` if the object is zero scale, and callers
can handle this appropriately.
 * `global_to_local` returns `None` if the object has zero scale.
 * Adjust AVM `globalToLocal` methods to return the untransformed
   point on failure.
 * Add `DisplayObject::mouse_to_local` to handle AVM `mouseX`
   and `mouseY` coordinates. For zero scale objects, these end up
   returning values based on the twips-to-pixels scale,
   divided by 20.
@szefkaf
Copy link

szefkaf commented Apr 6, 2023

mario_63_game_speed
@Toad06 please note that the quality of this game dropped dramatically to 18-20fps sometimes after these fixes when more sprites are on the screen. In the version I fixed it stays at over 30 frames per second just like in the original Flash version. Please compare Level 1 Bob-omb Battlefield (left door in Castle) in both versions. In the new version of Ruffle, even the jump sound can't keep up with real Mario's jump on mid-range laptops. I'm a little afraid that it will have its consequences in other games that will simply be too slow to play especially on mobiles.

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.

Super Mario 63: problems when entering the castle
3 participants