From c03f68413a11770c6d59f3d363dc7d16f21ebdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 20 May 2024 09:43:25 +0200 Subject: [PATCH 1/2] Fix skin editor closest origin selection spazzing out on scaled sprites Closes https://github.com/ppy/osu/issues/28215. `drawable.Position` is a location in the parent's coordinate space, and `drawable.OriginPosition` is in the drawable's local space and additionally does not take scale into account. --- osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs index 75bb77fa73..28b2435346 100644 --- a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs @@ -425,9 +425,9 @@ namespace osu.Game.Overlays.SkinEditor { if (origin == drawable.Origin) return; - var previousOrigin = drawable.OriginPosition; + var previousOrigin = drawable.ToParentSpace(drawable.OriginPosition); drawable.Origin = origin; - drawable.Position += drawable.OriginPosition - previousOrigin; + drawable.Position += drawable.ToParentSpace(drawable.OriginPosition) - previousOrigin; } private static void adjustScaleFromAnchor(ref Vector2 scale, Anchor reference) From 3da3b91be51526c1d40e016ddf9002134f9d788c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 20 May 2024 10:14:08 +0200 Subject: [PATCH 2/2] Improve closest origin selection to include effects of rotation/flip Closes https://github.com/ppy/osu/issues/28237. Solution as proposed here: https://github.com/ppy/osu/pull/28089#issuecomment-2095372157 For flips and rotations by 90 degrees this does what you would expect it to. For arbitrary rotations it *sort of kind of* attempts to do this but the results are a bit wonky - probably still better than what was there before, though? --- .../SkinEditor/SkinSelectionHandler.cs | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs index 28b2435346..21909cdc10 100644 --- a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -421,12 +422,41 @@ namespace osu.Game.Overlays.SkinEditor drawable.Position -= drawable.AnchorPosition - previousAnchor; } - private static void applyOrigin(Drawable drawable, Anchor origin) + private static void applyOrigin(Drawable drawable, Anchor screenSpaceOrigin) { - if (origin == drawable.Origin) return; + var boundingBox = drawable.ScreenSpaceDrawQuad.AABBFloat; + + var targetScreenSpacePosition = screenSpaceOrigin.PositionOnQuad(boundingBox); + + Anchor localOrigin = Anchor.TopLeft; + float smallestDistanceFromTargetPosition = float.PositiveInfinity; + + void checkOrigin(Anchor originToTest) + { + Vector2 positionToTest = drawable.ToScreenSpace(originToTest.PositionOnQuad(drawable.DrawRectangle)); + float testedDistance = Vector2.Distance(targetScreenSpacePosition, positionToTest); + + if (testedDistance < smallestDistanceFromTargetPosition) + { + localOrigin = originToTest; + smallestDistanceFromTargetPosition = testedDistance; + } + } + + checkOrigin(Anchor.TopLeft); + checkOrigin(Anchor.TopCentre); + checkOrigin(Anchor.TopRight); + + checkOrigin(Anchor.CentreLeft); + checkOrigin(Anchor.Centre); + checkOrigin(Anchor.CentreRight); + + checkOrigin(Anchor.BottomLeft); + checkOrigin(Anchor.BottomCentre); + checkOrigin(Anchor.BottomRight); var previousOrigin = drawable.ToParentSpace(drawable.OriginPosition); - drawable.Origin = origin; + drawable.Origin = localOrigin; drawable.Position += drawable.ToParentSpace(drawable.OriginPosition) - previousOrigin; }