1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 00:53:22 +08:00

Expand the selection movement limiting code with detailed comments

This commit is contained in:
ekrctb 2021-07-09 12:58:08 +09:00
parent c937c45360
commit 7e14679606

View File

@ -27,10 +27,9 @@ namespace osu.Game.Rulesets.Catch.Edit
var blueprint = moveEvent.Blueprint;
Vector2 originalPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint);
Vector2 targetPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint + moveEvent.ScreenSpaceDelta);
float deltaX = targetPosition.X - originalPosition.X;
foreach (float x in EditorBeatmap.SelectedHitObjects.SelectMany(getOriginalPositions))
deltaX = Math.Clamp(deltaX, -x, CatchPlayfield.WIDTH - x);
float deltaX = targetPosition.X - originalPosition.X;
deltaX = limitMovement(deltaX, EditorBeatmap.SelectedHitObjects);
if (deltaX == 0)
{
@ -52,6 +51,36 @@ namespace osu.Game.Rulesets.Catch.Edit
return true;
}
/// <summary>
/// Limit positional movement of the objects by the constraint that moved objects should stay in bounds.
/// </summary>
/// <param name="deltaX">The positional movement.</param>
/// <param name="movingObjects">The objects to be moved.</param>
/// <returns>The positional movement with the restriction applied.</returns>
private float limitMovement(float deltaX, IEnumerable<HitObject> movingObjects)
{
float minX = float.PositiveInfinity;
float maxX = float.NegativeInfinity;
foreach (float x in movingObjects.SelectMany(getOriginalPositions))
{
minX = Math.Min(minX, x);
maxX = Math.Max(maxX, x);
}
// To make an object with position `x` stay in bounds after `deltaX` movement, `0 <= x + deltaX <= WIDTH` should be satisfied.
// Subtracting `x`, we get `-x <= deltaX <= WIDTH - x`.
// We only need to apply the inequality to extreme values of `x`.
float lowerBound = -minX;
float upperBound = CatchPlayfield.WIDTH - maxX;
// The inequality may be unsatisfiable if the objects were already out of bounds.
// In that case, don't move objects at all.
if (!(lowerBound <= upperBound))
return 0;
return Math.Clamp(deltaX, lowerBound, upperBound);
}
/// <summary>
/// Enumerate X positions that should be contained in-bounds after move offset is applied.
/// </summary>