1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-23 23:33:18 +08:00

Merge pull request #31912 from bdach/more-snap-grid

Fix some more visual issues with osu! distance snap grid
This commit is contained in:
Dean Herbert 2025-02-17 21:11:17 +09:00 committed by GitHub
commit 42fb544218
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 4 deletions

View File

@ -63,7 +63,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
const float thickness = 4;
float diameter = (offset + (i + 1) * DistanceBetweenTicks + thickness / 2) * 2;
AddInternal(new Ring(StartTime, GetColourForIndexFromPlacement(i))
AddInternal(new Ring(StartTime, GetColourForIndexFromPlacement(i), SliderVelocitySource)
{
Position = StartPosition,
Origin = Anchor.Centre,
@ -128,12 +128,14 @@ namespace osu.Game.Screens.Edit.Compose.Components
private EditorClock? editorClock { get; set; }
private readonly double startTime;
private readonly IHasSliderVelocity? sliderVelocitySource;
private readonly Color4 baseColour;
public Ring(double startTime, Color4 baseColour)
public Ring(double startTime, Color4 baseColour, IHasSliderVelocity? sliderVelocitySource)
{
this.startTime = startTime;
this.sliderVelocitySource = sliderVelocitySource;
Colour = this.baseColour = baseColour;
@ -150,7 +152,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
float distanceSpacingMultiplier = (float)snapProvider.DistanceSpacingMultiplier.Value;
double timeFromReferencePoint = editorClock.CurrentTime - startTime;
float distanceForCurrentTime = snapProvider.DurationToDistance(timeFromReferencePoint, startTime)
float distanceForCurrentTime = snapProvider.DurationToDistance(timeFromReferencePoint, startTime, sliderVelocitySource)
* distanceSpacingMultiplier;
float timeBasedAlpha = 1 - Math.Clamp(Math.Abs(distanceForCurrentTime - Size.X / 2) / 30, 0, 1);

View File

@ -11,6 +11,7 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Layout;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects.Types;
@ -148,7 +149,18 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
var timingPoint = Beatmap.ControlPointInfo.TimingPointAt(StartTime);
double beatLength = timingPoint.BeatLength / beatDivisor.Value;
int beatIndex = (int)Math.Floor((StartTime - timingPoint.Time) / beatLength);
double fractionalBeatIndex = (StartTime - timingPoint.Time) / beatLength;
int beatIndex = (int)Math.Round(fractionalBeatIndex);
// `fractionalBeatIndex` could differ from `beatIndex` for two reasons:
// - rounding errors (which can be exacerbated by timing point start times being truncated by/for stable),
// - `StartTime` is not snapped to the beat.
// in case 1, we want rounding to occur to prevent an off-by-one,
// as `StartTime` *is* quantised to the beat. but it just doesn't look like it because floats do float things.
// in case 2, we want *flooring* to occur, to prevent a possible off-by-one
// because of the rounding snapping forward by a chunk of time significantly too high to be considered a rounding error.
// the tolerance margin chosen here is arbitrary and can be adjusted if more cases of this are found.
if (Precision.DefinitelyBigger(beatIndex, fractionalBeatIndex, 0.005))
beatIndex = (int)Math.Floor(fractionalBeatIndex);
var colour = BindableBeatDivisor.GetColourFor(BindableBeatDivisor.GetDivisorForBeatIndex(beatIndex + placementIndex + 1, beatDivisor.Value), Colours);