mirror of
https://github.com/osukey/osukey.git
synced 2025-07-03 01:09:57 +09:00
Refactor flow of snapping through HitObjectComposer
This commit is contained in:
@ -14,6 +14,7 @@ using osu.Framework.Logging;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Configuration;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
@ -39,6 +40,9 @@ namespace osu.Game.Rulesets.Edit
|
||||
[Resolved]
|
||||
protected IFrameBasedClock EditorClock { get; private set; }
|
||||
|
||||
[Resolved]
|
||||
private BindableBeatDivisor beatDivisor { get; set; }
|
||||
|
||||
private IWorkingBeatmap workingBeatmap;
|
||||
private Beatmap<TObject> playableBeatmap;
|
||||
private IBeatmapProcessor beatmapProcessor;
|
||||
@ -246,7 +250,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
public void BeginPlacement(HitObject hitObject)
|
||||
{
|
||||
if (distanceSnapGrid != null)
|
||||
hitObject.StartTime = GetSnappedTime(hitObject.StartTime, distanceSnapGrid.ToLocalSpace(inputManager.CurrentState.Mouse.Position));
|
||||
hitObject.StartTime = GetSnappedPosition(distanceSnapGrid.ToLocalSpace(inputManager.CurrentState.Mouse.Position), hitObject.StartTime).time;
|
||||
}
|
||||
|
||||
public void EndPlacement(HitObject hitObject)
|
||||
@ -257,11 +261,45 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
public void Delete(HitObject hitObject) => EditorBeatmap.Remove(hitObject);
|
||||
|
||||
public override Vector2 GetSnappedPosition(Vector2 position) => distanceSnapGrid?.GetSnappedPosition(position) ?? position;
|
||||
public override (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) => distanceSnapGrid?.GetSnappedPosition(position) ?? (position, time);
|
||||
|
||||
public override double GetSnappedTime(double startTime, Vector2 position) => distanceSnapGrid?.GetSnappedTime(position) ?? startTime;
|
||||
public override float GetBeatSnapDistanceAt(double referenceTime)
|
||||
{
|
||||
DifficultyControlPoint difficultyPoint = EditorBeatmap.ControlPointInfo.DifficultyPointAt(referenceTime);
|
||||
return (float)(100 * EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / beatDivisor.Value);
|
||||
}
|
||||
|
||||
public override float GetSnappedDistance(float distance) => distanceSnapGrid?.GetSnappedDistance(distance) ?? distance;
|
||||
public override float DurationToDistance(double referenceTime, double duration)
|
||||
{
|
||||
double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value;
|
||||
return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceTime));
|
||||
}
|
||||
|
||||
public override double DistanceToDuration(double referenceTime, float distance)
|
||||
{
|
||||
double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value;
|
||||
return distance / GetBeatSnapDistanceAt(referenceTime) * beatLength;
|
||||
}
|
||||
|
||||
public override double GetSnappedDurationFromDistance(double referenceTime, float distance)
|
||||
=> beatSnap(referenceTime, DistanceToDuration(referenceTime, distance));
|
||||
|
||||
public override float GetSnappedDistanceFromDistance(double referenceTime, float distance)
|
||||
=> DurationToDistance(referenceTime, beatSnap(referenceTime, DistanceToDuration(referenceTime, distance)));
|
||||
|
||||
/// <summary>
|
||||
/// Snaps a duration to the closest beat of a timing point applicable at the reference time.
|
||||
/// </summary>
|
||||
/// <param name="referenceTime">The time of the timing point which <paramref name="duration"/> resides in.</param>
|
||||
/// <param name="duration">The duration to snap.</param>
|
||||
/// <returns>A value that represents <paramref name="duration"/> snapped to the closest beat of the timing point.</returns>
|
||||
private double beatSnap(double referenceTime, double duration)
|
||||
{
|
||||
double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value;
|
||||
|
||||
// A 1ms offset prevents rounding errors due to minute variations in duration
|
||||
return (int)((duration + 1) / beatLength) * beatLength;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
@ -312,10 +350,45 @@ namespace osu.Game.Rulesets.Edit
|
||||
[CanBeNull]
|
||||
protected virtual DistanceSnapGrid CreateDistanceSnapGrid([NotNull] IEnumerable<HitObject> selectedHitObjects) => null;
|
||||
|
||||
public abstract Vector2 GetSnappedPosition(Vector2 position);
|
||||
public abstract (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time);
|
||||
|
||||
public abstract double GetSnappedTime(double startTime, Vector2 screenSpacePosition);
|
||||
/// <summary>
|
||||
/// Retrieves the distance between two points within a timing point that are one beat length apart.
|
||||
/// </summary>
|
||||
/// <param name="referenceTime">The time of the timing point.</param>
|
||||
/// <returns>The distance between two points residing in the timing point that are one beat length apart.</returns>
|
||||
public abstract float GetBeatSnapDistanceAt(double referenceTime);
|
||||
|
||||
public abstract float GetSnappedDistance(float distance);
|
||||
/// <summary>
|
||||
/// Converts a duration to a distance.
|
||||
/// </summary>
|
||||
/// <param name="referenceTime">The time of the timing point which <paramref name="duration"/> resides in.</param>
|
||||
/// <param name="duration">The duration to convert.</param>
|
||||
/// <returns>A value that represents <paramref name="duration"/> as a distance in the timing point.</returns>
|
||||
public abstract float DurationToDistance(double referenceTime, double duration);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a distance to a duration.
|
||||
/// </summary>
|
||||
/// <param name="referenceTime">The time of the timing point which <paramref name="distance"/> resides in.</param>
|
||||
/// <param name="distance">The distance to convert.</param>
|
||||
/// <returns>A value that represents <paramref name="distance"/> as a duration in the timing point.</returns>
|
||||
public abstract double DistanceToDuration(double referenceTime, float distance);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a distance to a snapped duration.
|
||||
/// </summary>
|
||||
/// <param name="referenceTime">The time of the timing point which <paramref name="distance"/> resides in.</param>
|
||||
/// <param name="distance">The distance to convert.</param>
|
||||
/// <returns>A value that represents <paramref name="distance"/> as a duration snapped to the closest beat of the timing point.</returns>
|
||||
public abstract double GetSnappedDurationFromDistance(double referenceTime, float distance);
|
||||
|
||||
/// <summary>
|
||||
/// Converts an unsnapped distance to a snapped distance.
|
||||
/// </summary>
|
||||
/// <param name="referenceTime">The time of the timing point which <paramref name="distance"/> resides in.</param>
|
||||
/// <param name="distance">The distance to convert.</param>
|
||||
/// <returns>A value that represents <paramref name="distance"/> snapped to the closest beat of the timing point.</returns>
|
||||
public abstract float GetSnappedDistanceFromDistance(double referenceTime, float distance);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user