mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +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);
|
double progress = MathHelper.Clamp((Time.Current - slider.StartTime + TIME_PREEMPT) / TIME_FADEIN, 0, 1);
|
||||||
|
|
||||||
if (progress == drawnProgress) return false;
|
if (progress == drawnProgress) return false;
|
||||||
|
drawnProgress = progress;
|
||||||
bool madeChanges = false;
|
|
||||||
if (progress == 0)
|
|
||||||
{
|
|
||||||
//if we have gone backwards, just clear the path for now.
|
|
||||||
drawnProgress = 0;
|
|
||||||
path.ClearVertices();
|
|
||||||
madeChanges = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 startPosition = slider.Curve.PositionAt(0);
|
Vector2 startPosition = slider.Curve.PositionAt(0);
|
||||||
|
|
||||||
if (drawnProgress == null)
|
path.ClearVertices();
|
||||||
{
|
slider.Curve.FillCurveUntilProgress(p => path.AddVertex(p - startPosition), progress);
|
||||||
drawnProgress = 0;
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using OpenTK;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace osu.Game.Modes.Osu.Objects
|
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);
|
int i = cumulativeLength.BinarySearch(d);
|
||||||
if (i < 0) i = ~i;
|
if (i < 0) i = ~i;
|
||||||
|
|
||||||
if (i >= calculatedPath.Count)
|
return i;
|
||||||
return calculatedPath.Last();
|
}
|
||||||
|
|
||||||
|
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)
|
if (i <= 0)
|
||||||
return calculatedPath.First();
|
return calculatedPath.First();
|
||||||
|
else if (i >= calculatedPath.Count)
|
||||||
|
return calculatedPath.Last();
|
||||||
|
|
||||||
Vector2 p0 = calculatedPath[i - 1];
|
Vector2 p0 = calculatedPath[i - 1];
|
||||||
Vector2 p1 = calculatedPath[i];
|
Vector2 p1 = calculatedPath[i];
|
||||||
@ -91,5 +101,22 @@ namespace osu.Game.Modes.Osu.Objects
|
|||||||
double w = (d - d0) / (d1 - d0);
|
double w = (d - d0) / (d1 - d0);
|
||||||
return p0 + (p1 - p0) * (float)w;
|
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