1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 04:07:25 +08:00

Fix floating point error in slider path encoding

This commit is contained in:
smoogipoo 2021-04-06 14:10:59 +09:00
parent 784552022f
commit a2544100d4

View File

@ -329,13 +329,25 @@ namespace osu.Game.Beatmaps.Formats
if (point.Type.Value != null)
{
// We've reached a new segment!
// We've reached a new (explicit) segment!
// To preserve compatibility with osu-stable as much as possible, segments with the same type are converted to use implicit segments by duplicating the control point.
// One exception to this is when the last control point of the last segment was itself a duplicate, which can't be supported by osu-stable.
bool lastPointWasDuplicate = i > 1 && pathData.Path.ControlPoints[i - 1].Position.Value == pathData.Path.ControlPoints[i - 2].Position.Value;
// Explicit segments have a new format in which the type is injected into the middle of the control point string.
// To preserve compatibility with osu-stable as much as possible, explicit segments with the same type are converted to use implicit segments by duplicating the control point.
bool needsExplicitSegment = point.Type.Value != lastType;
if (lastPointWasDuplicate || point.Type.Value != lastType)
// One exception to this is when the last two control points of the last segment were duplicated. This is not a scenario supported by osu!stable.
// Lazer does not add implicit segments for the last two control points of _any_ explicit segment, so an explicit segment is forced in order to maintain consistency with the decoder.
if (i > 1)
{
// We need to use the absolute control point position to determine equality, otherwise floating point issues may arise.
Vector2 p1 = position + pathData.Path.ControlPoints[i - 1].Position.Value;
Vector2 p2 = position + pathData.Path.ControlPoints[i - 2].Position.Value;
if ((int)p1.X == (int)p2.X && (int)p1.Y == (int)p2.Y)
needsExplicitSegment = true;
}
if (needsExplicitSegment)
{
switch (point.Type.Value)
{