mirror of
https://github.com/osukey/osukey.git
synced 2025-06-25 05:07:59 +09:00
Pass sub-controlpoints as span slices
This commit is contained in:
parent
0c4403ef16
commit
83fd251c7b
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
@ -38,7 +37,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
beatmap.HitObjects.Add(new JuiceStream
|
beatmap.HitObjects.Add(new JuiceStream
|
||||||
{
|
{
|
||||||
X = 0.5f - width / 2,
|
X = 0.5f - width / 2,
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(width * CatchPlayfield.BASE_WIDTH, 0)
|
new Vector2(width * CatchPlayfield.BASE_WIDTH, 0)
|
||||||
|
@ -146,7 +146,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
|
|
||||||
public SliderCurve Curve { get; } = new SliderCurve();
|
public SliderCurve Curve { get; } = new SliderCurve();
|
||||||
|
|
||||||
public List<Vector2> ControlPoints
|
public Vector2[] ControlPoints
|
||||||
{
|
{
|
||||||
get { return Curve.ControlPoints; }
|
get { return Curve.ControlPoints; }
|
||||||
set { Curve.ControlPoints = value; }
|
set { Curve.ControlPoints = value; }
|
||||||
|
@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
StartTime = Time.Current + 1000,
|
StartTime = Time.Current + 1000,
|
||||||
Position = new Vector2(239, 176),
|
Position = new Vector2(239, 176),
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(154, 28),
|
new Vector2(154, 28),
|
||||||
@ -141,7 +141,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
StartTime = Time.Current + 1000,
|
StartTime = Time.Current + 1000,
|
||||||
Position = new Vector2(-(distance / 2), 0),
|
Position = new Vector2(-(distance / 2), 0),
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(distance, 0),
|
new Vector2(distance, 0),
|
||||||
@ -161,7 +161,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
StartTime = Time.Current + 1000,
|
StartTime = Time.Current + 1000,
|
||||||
Position = new Vector2(-200, 0),
|
Position = new Vector2(-200, 0),
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(200, 200),
|
new Vector2(200, 200),
|
||||||
@ -184,7 +184,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
CurveType = CurveType.Linear,
|
CurveType = CurveType.Linear,
|
||||||
StartTime = Time.Current + 1000,
|
StartTime = Time.Current + 1000,
|
||||||
Position = new Vector2(-200, 0),
|
Position = new Vector2(-200, 0),
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(150, 75),
|
new Vector2(150, 75),
|
||||||
@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
CurveType = CurveType.Bezier,
|
CurveType = CurveType.Bezier,
|
||||||
StartTime = Time.Current + 1000,
|
StartTime = Time.Current + 1000,
|
||||||
Position = new Vector2(-200, 0),
|
Position = new Vector2(-200, 0),
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(150, 75),
|
new Vector2(150, 75),
|
||||||
@ -235,7 +235,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
CurveType = CurveType.Linear,
|
CurveType = CurveType.Linear,
|
||||||
StartTime = Time.Current + 1000,
|
StartTime = Time.Current + 1000,
|
||||||
Position = new Vector2(0, 0),
|
Position = new Vector2(0, 0),
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(-200, 0),
|
new Vector2(-200, 0),
|
||||||
@ -265,7 +265,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
StartTime = Time.Current + 1000,
|
StartTime = Time.Current + 1000,
|
||||||
Position = new Vector2(-100, 0),
|
Position = new Vector2(-100, 0),
|
||||||
CurveType = CurveType.Catmull,
|
CurveType = CurveType.Catmull,
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(50, -50),
|
new Vector2(50, -50),
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -33,8 +32,9 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
slider.NestedHitObjects.OfType<RepeatPoint>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<RepeatPoint>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
|
|
||||||
var newControlPoints = new List<Vector2>();
|
var newControlPoints = new Vector2[slider.ControlPoints.Length];
|
||||||
slider.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, -c.Y)));
|
for (int i = 0; i < slider.ControlPoints.Length; i++)
|
||||||
|
newControlPoints[i] = new Vector2(slider.ControlPoints[i].X, -slider.ControlPoints[i].Y);
|
||||||
|
|
||||||
slider.ControlPoints = newControlPoints;
|
slider.ControlPoints = newControlPoints;
|
||||||
slider.Curve?.Calculate(); // Recalculate the slider curve
|
slider.Curve?.Calculate(); // Recalculate the slider curve
|
||||||
|
@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
public SliderCurve Curve { get; } = new SliderCurve();
|
public SliderCurve Curve { get; } = new SliderCurve();
|
||||||
|
|
||||||
public List<Vector2> ControlPoints
|
public Vector2[] ControlPoints
|
||||||
{
|
{
|
||||||
get { return Curve.ControlPoints; }
|
get { return Curve.ControlPoints; }
|
||||||
set { Curve.ControlPoints = value; }
|
set { Curve.ControlPoints = value; }
|
||||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
new Slider
|
new Slider
|
||||||
{
|
{
|
||||||
Position = new Vector2(128, 256),
|
Position = new Vector2(128, 256),
|
||||||
ControlPoints = new List<Vector2>
|
ControlPoints = new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(216, 0),
|
new Vector2(216, 0),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!-- Contains required properties for osu!framework projects. -->
|
<!-- Contains required properties for osu!framework projects. -->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup Label="C#">
|
<PropertyGroup Label="C#">
|
||||||
<LangVersion>7</LangVersion>
|
<LangVersion>7.2</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationManifest>..\app.manifest</ApplicationManifest>
|
<ApplicationManifest>..\app.manifest</ApplicationManifest>
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Objects
|
namespace osu.Game.Rulesets.Objects
|
||||||
{
|
{
|
||||||
public class BezierApproximator
|
public readonly ref struct BezierApproximator
|
||||||
{
|
{
|
||||||
private readonly int count;
|
private readonly int count;
|
||||||
private readonly List<Vector2> controlPoints;
|
private readonly ReadOnlySpan<Vector2> controlPoints;
|
||||||
private readonly Vector2[] subdivisionBuffer1;
|
private readonly Vector2[] subdivisionBuffer1;
|
||||||
private readonly Vector2[] subdivisionBuffer2;
|
private readonly Vector2[] subdivisionBuffer2;
|
||||||
|
|
||||||
private const float tolerance = 0.25f;
|
private const float tolerance = 0.25f;
|
||||||
private const float tolerance_sq = tolerance * tolerance;
|
private const float tolerance_sq = tolerance * tolerance;
|
||||||
|
|
||||||
public BezierApproximator(List<Vector2> controlPoints)
|
public BezierApproximator(ReadOnlySpan<Vector2> controlPoints)
|
||||||
{
|
{
|
||||||
this.controlPoints = controlPoints;
|
this.controlPoints = controlPoints;
|
||||||
count = controlPoints.Count;
|
count = controlPoints.Length;
|
||||||
|
|
||||||
subdivisionBuffer1 = new Vector2[count];
|
subdivisionBuffer1 = new Vector2[count];
|
||||||
subdivisionBuffer2 = new Vector2[count * 2 - 1];
|
subdivisionBuffer2 = new Vector2[count * 2 - 1];
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Objects
|
namespace osu.Game.Rulesets.Objects
|
||||||
{
|
{
|
||||||
public class CatmullApproximator
|
public readonly ref struct CatmullApproximator
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of pieces to calculate for each controlpoint quadruplet.
|
/// The amount of pieces to calculate for each controlpoint quadruplet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const int detail = 50;
|
private const int detail = 50;
|
||||||
|
|
||||||
private readonly List<Vector2> controlPoints;
|
private readonly ReadOnlySpan<Vector2> controlPoints;
|
||||||
|
|
||||||
public CatmullApproximator(List<Vector2> controlPoints)
|
public CatmullApproximator(ReadOnlySpan<Vector2> controlPoints)
|
||||||
{
|
{
|
||||||
this.controlPoints = controlPoints;
|
this.controlPoints = controlPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a piecewise-linear approximation of a Catmull-Rom spline.
|
/// Creates a piecewise-linear approximation of a Catmull-Rom spline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A list of vectors representing the piecewise-linear approximation.</returns>
|
/// <returns>A list of vectors representing the piecewise-linear approximation.</returns>
|
||||||
public List<Vector2> CreateCatmull()
|
public List<Vector2> CreateCatmull()
|
||||||
{
|
{
|
||||||
var result = new List<Vector2>();
|
var result = new List<Vector2>((controlPoints.Length - 1) * detail * 2);
|
||||||
|
|
||||||
for (int i = 0; i < controlPoints.Count - 1; i++)
|
for (int i = 0; i < controlPoints.Length - 1; i++)
|
||||||
{
|
{
|
||||||
var v1 = i > 0 ? controlPoints[i - 1] : controlPoints[i];
|
var v1 = i > 0 ? controlPoints[i - 1] : controlPoints[i];
|
||||||
var v2 = controlPoints[i];
|
var v2 = controlPoints[i];
|
||||||
var v3 = i < controlPoints.Count - 1 ? controlPoints[i + 1] : v2 + v2 - v1;
|
var v3 = i < controlPoints.Length - 1 ? controlPoints[i + 1] : v2 + v2 - v1;
|
||||||
var v4 = i < controlPoints.Count - 2 ? controlPoints[i + 2] : v3 + v3 - v2;
|
var v4 = i < controlPoints.Length - 2 ? controlPoints[i + 2] : v3 + v3 - v2;
|
||||||
|
|
||||||
for (int c = 0; c < detail; c++)
|
for (int c = 0; c < detail; c++)
|
||||||
{
|
{
|
||||||
|
@ -8,21 +8,15 @@ using OpenTK;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Objects
|
namespace osu.Game.Rulesets.Objects
|
||||||
{
|
{
|
||||||
public class CircularArcApproximator
|
public readonly ref struct CircularArcApproximator
|
||||||
{
|
{
|
||||||
private readonly Vector2 a;
|
|
||||||
private readonly Vector2 b;
|
|
||||||
private readonly Vector2 c;
|
|
||||||
|
|
||||||
private int amountPoints;
|
|
||||||
|
|
||||||
private const float tolerance = 0.1f;
|
private const float tolerance = 0.1f;
|
||||||
|
|
||||||
public CircularArcApproximator(Vector2 a, Vector2 b, Vector2 c)
|
private readonly ReadOnlySpan<Vector2> controlPoints;
|
||||||
|
|
||||||
|
public CircularArcApproximator(ReadOnlySpan<Vector2> controlPoints)
|
||||||
{
|
{
|
||||||
this.a = a;
|
this.controlPoints = controlPoints;
|
||||||
this.b = b;
|
|
||||||
this.c = c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -31,6 +25,10 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// <returns>A list of vectors representing the piecewise-linear approximation.</returns>
|
/// <returns>A list of vectors representing the piecewise-linear approximation.</returns>
|
||||||
public List<Vector2> CreateArc()
|
public List<Vector2> CreateArc()
|
||||||
{
|
{
|
||||||
|
Vector2 a = controlPoints[0];
|
||||||
|
Vector2 b = controlPoints[1];
|
||||||
|
Vector2 c = controlPoints[2];
|
||||||
|
|
||||||
float aSq = (b - c).LengthSquared;
|
float aSq = (b - c).LengthSquared;
|
||||||
float bSq = (a - c).LengthSquared;
|
float bSq = (a - c).LengthSquared;
|
||||||
float cSq = (a - b).LengthSquared;
|
float cSq = (a - b).LengthSquared;
|
||||||
@ -81,7 +79,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
// is: 2 * Math.Acos(1 - TOLERANCE / r)
|
// is: 2 * Math.Acos(1 - TOLERANCE / r)
|
||||||
// The special case is required for extremely short sliders where the radius is smaller than
|
// The special case is required for extremely short sliders where the radius is smaller than
|
||||||
// the tolerance. This is a pathological rather than a realistic case.
|
// the tolerance. This is a pathological rather than a realistic case.
|
||||||
amountPoints = 2 * r <= tolerance ? 2 : Math.Max(2, (int)Math.Ceiling(thetaRange / (2 * Math.Acos(1 - tolerance / r))));
|
int amountPoints = 2 * r <= tolerance ? 2 : Math.Max(2, (int)Math.Ceiling(thetaRange / (2 * Math.Acos(1 - tolerance / r))));
|
||||||
|
|
||||||
List<Vector2> output = new List<Vector2>(amountPoints);
|
List<Vector2> output = new List<Vector2>(amountPoints);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||||
{
|
{
|
||||||
newCombo |= forceNewCombo;
|
newCombo |= forceNewCombo;
|
||||||
comboOffset += extraComboOffset;
|
comboOffset += extraComboOffset;
|
||||||
|
@ -72,10 +72,18 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
|||||||
{
|
{
|
||||||
CurveType curveType = CurveType.Catmull;
|
CurveType curveType = CurveType.Catmull;
|
||||||
double length = 0;
|
double length = 0;
|
||||||
var points = new List<Vector2> { Vector2.Zero };
|
|
||||||
|
|
||||||
string[] pointsplit = split[5].Split('|');
|
string[] pointSplit = split[5].Split('|');
|
||||||
foreach (string t in pointsplit)
|
|
||||||
|
int pointCount = 1;
|
||||||
|
foreach (var t in pointSplit)
|
||||||
|
if (t.Length > 1)
|
||||||
|
pointCount++;
|
||||||
|
|
||||||
|
var points = new Vector2[pointCount];
|
||||||
|
|
||||||
|
int pointIndex = 1;
|
||||||
|
foreach (string t in pointSplit)
|
||||||
{
|
{
|
||||||
if (t.Length == 1)
|
if (t.Length == 1)
|
||||||
{
|
{
|
||||||
@ -94,16 +102,18 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
|||||||
curveType = CurveType.PerfectCurve;
|
curveType = CurveType.PerfectCurve;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] temp = t.Split(':');
|
string[] temp = t.Split(':');
|
||||||
points.Add(new Vector2((int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)) - pos);
|
points[pointIndex++] = new Vector2((int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)) - pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// osu-stable special-cased colinear perfect curves to a CurveType.Linear
|
// osu-stable special-cased colinear perfect curves to a CurveType.Linear
|
||||||
bool isLinear(List<Vector2> p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y));
|
bool isLinear(Vector2[] p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y));
|
||||||
if (points.Count == 3 && curveType == CurveType.PerfectCurve && isLinear(points))
|
|
||||||
|
if (points.Length == 3 && curveType == CurveType.PerfectCurve && isLinear(points))
|
||||||
curveType = CurveType.Linear;
|
curveType = CurveType.Linear;
|
||||||
|
|
||||||
int repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
|
int repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
|
||||||
@ -262,7 +272,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
|||||||
/// <param name="repeatCount">The slider repeat count.</param>
|
/// <param name="repeatCount">The slider repeat count.</param>
|
||||||
/// <param name="repeatSamples">The samples to be played when the repeat nodes are hit. This includes the head and tail of the slider.</param>
|
/// <param name="repeatSamples">The samples to be played when the repeat nodes are hit. This includes the head and tail of the slider.</param>
|
||||||
/// <returns>The hit object.</returns>
|
/// <returns>The hit object.</returns>
|
||||||
protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples);
|
protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a legacy Spinner-type hit object.
|
/// Creates a legacy Spinner-type hit object.
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
|||||||
/// <see cref="ConvertSlider"/>s don't need a curve since they're converted to ruleset-specific hitobjects.
|
/// <see cref="ConvertSlider"/>s don't need a curve since they're converted to ruleset-specific hitobjects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SliderCurve Curve { get; } = null;
|
public SliderCurve Curve { get; } = null;
|
||||||
public List<Vector2> ControlPoints { get; set; }
|
public Vector2[] ControlPoints { get; set; }
|
||||||
public CurveType CurveType { get; set; }
|
public CurveType CurveType { get; set; }
|
||||||
|
|
||||||
public double Distance { get; set; }
|
public double Distance { get; set; }
|
||||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||||
{
|
{
|
||||||
return new ConvertSlider
|
return new ConvertSlider
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||||
{
|
{
|
||||||
newCombo |= forceNewCombo;
|
newCombo |= forceNewCombo;
|
||||||
comboOffset += extraComboOffset;
|
comboOffset += extraComboOffset;
|
||||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
|
|||||||
return new ConvertHit();
|
return new ConvertHit();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||||
{
|
{
|
||||||
return new ConvertSlider
|
return new ConvertSlider
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
@ -13,7 +14,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
{
|
{
|
||||||
public double Distance;
|
public double Distance;
|
||||||
|
|
||||||
public List<Vector2> ControlPoints;
|
public Vector2[] ControlPoints;
|
||||||
|
|
||||||
public CurveType CurveType = CurveType.PerfectCurve;
|
public CurveType CurveType = CurveType.PerfectCurve;
|
||||||
|
|
||||||
@ -22,19 +23,17 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
private readonly List<Vector2> calculatedPath = new List<Vector2>();
|
private readonly List<Vector2> calculatedPath = new List<Vector2>();
|
||||||
private readonly List<double> cumulativeLength = new List<double>();
|
private readonly List<double> cumulativeLength = new List<double>();
|
||||||
|
|
||||||
private List<Vector2> calculateSubpath(List<Vector2> subControlPoints)
|
private List<Vector2> calculateSubpath(ReadOnlySpan<Vector2> subControlPoints)
|
||||||
{
|
{
|
||||||
switch (CurveType)
|
switch (CurveType)
|
||||||
{
|
{
|
||||||
case CurveType.Linear:
|
|
||||||
return subControlPoints;
|
|
||||||
case CurveType.PerfectCurve:
|
case CurveType.PerfectCurve:
|
||||||
//we can only use CircularArc iff we have exactly three control points and no dissection.
|
//we can only use CircularArc iff we have exactly three control points and no dissection.
|
||||||
if (ControlPoints.Count != 3 || subControlPoints.Count != 3)
|
if (ControlPoints.Length != 3 || subControlPoints.Length != 3)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Here we have exactly 3 control points. Attempt to fit a circular arc.
|
// Here we have exactly 3 control points. Attempt to fit a circular arc.
|
||||||
List<Vector2> subpath = new CircularArcApproximator(subControlPoints[0], subControlPoints[1], subControlPoints[2]).CreateArc();
|
List<Vector2> subpath = new CircularArcApproximator(subControlPoints).CreateArc();
|
||||||
|
|
||||||
// If for some reason a circular arc could not be fit to the 3 given points, fall back to a numerically stable bezier approximation.
|
// If for some reason a circular arc could not be fit to the 3 given points, fall back to a numerically stable bezier approximation.
|
||||||
if (subpath.Count == 0)
|
if (subpath.Count == 0)
|
||||||
@ -55,18 +54,32 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
// Sliders may consist of various subpaths separated by two consecutive vertices
|
// Sliders may consist of various subpaths separated by two consecutive vertices
|
||||||
// with the same position. The following loop parses these subpaths and computes
|
// with the same position. The following loop parses these subpaths and computes
|
||||||
// their shape independently, consecutively appending them to calculatedPath.
|
// their shape independently, consecutively appending them to calculatedPath.
|
||||||
List<Vector2> subControlPoints = new List<Vector2>();
|
|
||||||
for (int i = 0; i < ControlPoints.Count; ++i)
|
|
||||||
{
|
|
||||||
subControlPoints.Add(ControlPoints[i]);
|
|
||||||
if (i == ControlPoints.Count - 1 || ControlPoints[i] == ControlPoints[i + 1])
|
|
||||||
{
|
|
||||||
List<Vector2> subpath = calculateSubpath(subControlPoints);
|
|
||||||
foreach (Vector2 t in subpath)
|
|
||||||
if (calculatedPath.Count == 0 || calculatedPath.Last() != t)
|
|
||||||
calculatedPath.Add(t);
|
|
||||||
|
|
||||||
subControlPoints.Clear();
|
int start = 0;
|
||||||
|
int end = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < ControlPoints.Length; ++i)
|
||||||
|
{
|
||||||
|
end++;
|
||||||
|
|
||||||
|
if (i == ControlPoints.Length - 1 || ControlPoints[i] == ControlPoints[i + 1])
|
||||||
|
{
|
||||||
|
ReadOnlySpan<Vector2> cpSpan = ControlPoints.AsSpan().Slice(start, end - start);
|
||||||
|
|
||||||
|
if (CurveType == CurveType.Linear)
|
||||||
|
{
|
||||||
|
foreach (var t in cpSpan)
|
||||||
|
if (calculatedPath.Count == 0 || calculatedPath.Last() != t)
|
||||||
|
calculatedPath.Add(t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Vector2 t in calculateSubpath(cpSpan))
|
||||||
|
if (calculatedPath.Count == 0 || calculatedPath.Last() != t)
|
||||||
|
calculatedPath.Add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,7 +179,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// <param name="p1">End progress. Ranges from 0 (beginning of the slider) to 1 (end of the slider).</param>
|
/// <param name="p1">End progress. Ranges from 0 (beginning of the slider) to 1 (end of the slider).</param>
|
||||||
public void GetPathToProgress(List<Vector2> path, double p0, double p1)
|
public void GetPathToProgress(List<Vector2> path, double p0, double p1)
|
||||||
{
|
{
|
||||||
if (calculatedPath.Count == 0 && ControlPoints.Count > 0)
|
if (calculatedPath.Count == 0 && ControlPoints.Length > 0)
|
||||||
Calculate();
|
Calculate();
|
||||||
|
|
||||||
double d0 = progressToDistance(p0);
|
double d0 = progressToDistance(p0);
|
||||||
@ -193,7 +206,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Vector2 PositionAt(double progress)
|
public Vector2 PositionAt(double progress)
|
||||||
{
|
{
|
||||||
if (calculatedPath.Count == 0 && ControlPoints.Count > 0)
|
if (calculatedPath.Count == 0 && ControlPoints.Length > 0)
|
||||||
Calculate();
|
Calculate();
|
||||||
|
|
||||||
double d = progressToDistance(progress);
|
double d = progressToDistance(progress);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Objects.Types
|
namespace osu.Game.Rulesets.Objects.Types
|
||||||
@ -19,7 +18,7 @@ namespace osu.Game.Rulesets.Objects.Types
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The control points that shape the curve.
|
/// The control points that shape the curve.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
List<Vector2> ControlPoints { get; }
|
Vector2[] ControlPoints { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of curve.
|
/// The type of curve.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user