1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-07 16:12:55 +08:00

flip along grid axis

This commit is contained in:
OliBomby 2023-12-30 01:38:08 +01:00
parent 6bb72a9fcc
commit e803b0215f
2 changed files with 21 additions and 9 deletions

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -15,7 +16,6 @@ using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
using osu.Game.Utils; using osu.Game.Utils;
using osuTK; using osuTK;
@ -28,6 +28,9 @@ namespace osu.Game.Rulesets.Osu.Edit
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
private IDistanceSnapProvider? snapProvider { get; set; } private IDistanceSnapProvider? snapProvider { get; set; }
[Resolved]
private OsuGridToolboxGroup gridToolbox { get; set; } = null!;
/// <summary> /// <summary>
/// During a transform, the initial path types of a single selected slider are stored so they /// During a transform, the initial path types of a single selected slider are stored so they
/// can be maintained throughout the operation. /// can be maintained throughout the operation.
@ -104,13 +107,16 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
var hitObjects = selectedMovableObjects; var hitObjects = selectedMovableObjects;
var flipQuad = flipOverOrigin ? new Quad(0, 0, OsuPlayfield.BASE_SIZE.X, OsuPlayfield.BASE_SIZE.Y) : GeometryUtils.GetSurroundingQuad(hitObjects); var flipQuad = flipOverOrigin ? new Quad(gridToolbox.StartPositionX.Value, gridToolbox.StartPositionY.Value, 0, 0) : GeometryUtils.GetSurroundingQuad(hitObjects);
var flipAxis = flipOverOrigin ? new Vector2(MathF.Cos(MathHelper.DegreesToRadians(gridToolbox.GridLinesRotation.Value)), MathF.Sin(MathHelper.DegreesToRadians(gridToolbox.GridLinesRotation.Value))) : Vector2.UnitX;
flipAxis = direction == Direction.Vertical ? flipAxis.PerpendicularLeft : flipAxis;
var controlPointFlipQuad = new Quad();
bool didFlip = false; bool didFlip = false;
foreach (var h in hitObjects) foreach (var h in hitObjects)
{ {
var flippedPosition = GeometryUtils.GetFlippedPosition(direction, flipQuad, h.Position); var flippedPosition = GeometryUtils.GetFlippedPosition(flipAxis, flipQuad, h.Position);
if (!Precision.AlmostEquals(flippedPosition, h.Position)) if (!Precision.AlmostEquals(flippedPosition, h.Position))
{ {
@ -123,12 +129,7 @@ namespace osu.Game.Rulesets.Osu.Edit
didFlip = true; didFlip = true;
foreach (var cp in slider.Path.ControlPoints) foreach (var cp in slider.Path.ControlPoints)
{ cp.Position = GeometryUtils.GetFlippedPosition(flipAxis, controlPointFlipQuad, cp.Position);
cp.Position = new Vector2(
(direction == Direction.Horizontal ? -1 : 1) * cp.Position.X,
(direction == Direction.Vertical ? -1 : 1) * cp.Position.Y
);
}
} }
} }

View File

@ -70,6 +70,17 @@ namespace osu.Game.Utils
return position; return position;
} }
/// <summary>
/// Given a flip axis vector, a surrounding quad for all selected objects, and a position,
/// will return the flipped position in screen space coordinates.
/// </summary>
public static Vector2 GetFlippedPosition(Vector2 axis, Quad quad, Vector2 position)
{
var centre = quad.Centre;
return position - 2 * Vector2.Dot(position - centre, axis) * axis;
}
/// <summary> /// <summary>
/// Given a scale vector, a surrounding quad for all selected objects, and a position, /// Given a scale vector, a surrounding quad for all selected objects, and a position,
/// will return the scaled position in screen space coordinates. /// will return the scaled position in screen space coordinates.