mirror of
https://github.com/osukey/osukey.git
synced 2025-08-03 14:46:38 +09:00
Construct drawable slider paths smoothly using the optimized slider curve instead of by discrete individual re-sampled segments.
This commit is contained in:
@ -248,42 +248,13 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
|
||||
double progress = MathHelper.Clamp((Time.Current - slider.StartTime + TIME_PREEMPT) / TIME_FADEIN, 0, 1);
|
||||
|
||||
if (progress == drawnProgress) return false;
|
||||
|
||||
bool madeChanges = false;
|
||||
if (progress == 0)
|
||||
{
|
||||
//if we have gone backwards, just clear the path for now.
|
||||
drawnProgress = 0;
|
||||
path.ClearVertices();
|
||||
madeChanges = true;
|
||||
}
|
||||
drawnProgress = progress;
|
||||
|
||||
Vector2 startPosition = slider.Curve.PositionAt(0);
|
||||
|
||||
if (drawnProgress == null)
|
||||
{
|
||||
drawnProgress = 0;
|
||||
path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value) - startPosition);
|
||||
madeChanges = true;
|
||||
}
|
||||
|
||||
double segmentSize = 1 / (slider.Curve.Length / 5);
|
||||
|
||||
while (drawnProgress + segmentSize < progress)
|
||||
{
|
||||
drawnProgress += segmentSize;
|
||||
path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value) - startPosition);
|
||||
madeChanges = true;
|
||||
}
|
||||
|
||||
if (progress == 1 && drawnProgress != progress)
|
||||
{
|
||||
drawnProgress = progress;
|
||||
path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value) - startPosition);
|
||||
madeChanges = true;
|
||||
}
|
||||
|
||||
return madeChanges;
|
||||
path.ClearVertices();
|
||||
slider.Curve.FillCurveUntilProgress(p => path.AddVertex(p - startPosition), progress);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using OpenTK;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.MathUtils;
|
||||
using System;
|
||||
|
||||
namespace osu.Game.Modes.Osu.Objects
|
||||
{
|
||||
@ -64,19 +65,28 @@ namespace osu.Game.Modes.Osu.Objects
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 PositionAt(double progress)
|
||||
private int indexOfDistance(double d)
|
||||
{
|
||||
progress = MathHelper.Clamp(progress, 0, 1);
|
||||
|
||||
double d = progress * Length;
|
||||
int i = cumulativeLength.BinarySearch(d);
|
||||
if (i < 0) i = ~i;
|
||||
|
||||
if (i >= calculatedPath.Count)
|
||||
return calculatedPath.Last();
|
||||
return i;
|
||||
}
|
||||
|
||||
private double progressToDistance(double progress)
|
||||
{
|
||||
return MathHelper.Clamp(progress, 0, 1) * Length;
|
||||
}
|
||||
|
||||
private Vector2 interpolateVertices(int i, double d)
|
||||
{
|
||||
if (calculatedPath.Count == 0)
|
||||
return Vector2.Zero;
|
||||
|
||||
if (i <= 0)
|
||||
return calculatedPath.First();
|
||||
else if (i >= calculatedPath.Count)
|
||||
return calculatedPath.Last();
|
||||
|
||||
Vector2 p0 = calculatedPath[i - 1];
|
||||
Vector2 p1 = calculatedPath[i];
|
||||
@ -91,5 +101,22 @@ namespace osu.Game.Modes.Osu.Objects
|
||||
double w = (d - d0) / (d1 - d0);
|
||||
return p0 + (p1 - p0) * (float)w;
|
||||
}
|
||||
|
||||
public void FillCurveUntilProgress(Action<Vector2> action, double progress)
|
||||
{
|
||||
double d = progressToDistance(progress);
|
||||
|
||||
int i = 0;
|
||||
for (; i < calculatedPath.Count && cumulativeLength[i] <= d; ++i)
|
||||
action.Invoke(calculatedPath[i]);
|
||||
|
||||
action.Invoke(interpolateVertices(i, d));
|
||||
}
|
||||
|
||||
public Vector2 PositionAt(double progress)
|
||||
{
|
||||
double d = progressToDistance(progress);
|
||||
return interpolateVertices(indexOfDistance(d), d);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user