From 359cb5ac6a22d13403c9eb803d6187085952cdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 9 Dec 2016 18:03:17 +0100 Subject: [PATCH 1/7] Make bezier approximator slightly more correct (without affecting its behaviour). --- osu.Game.Modes.Osu/Objects/BezierApproximator.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Modes.Osu/Objects/BezierApproximator.cs b/osu.Game.Modes.Osu/Objects/BezierApproximator.cs index 9a4be51240..f03e1c0738 100644 --- a/osu.Game.Modes.Osu/Objects/BezierApproximator.cs +++ b/osu.Game.Modes.Osu/Objects/BezierApproximator.cs @@ -13,7 +13,7 @@ namespace osu.Game.Modes.Osu.Objects private Vector2[] subdivisionBuffer1; private Vector2[] subdivisionBuffer2; - private const float TOLERANCE = 0.5f; + private const float TOLERANCE = 0.25f; private const float TOLERANCE_SQ = TOLERANCE * TOLERANCE; public BezierApproximator(List controlPoints) @@ -36,7 +36,7 @@ namespace osu.Game.Modes.Osu.Objects private static bool IsFlatEnough(Vector2[] controlPoints) { for (int i = 1; i < controlPoints.Length - 1; i++) - if ((controlPoints[i - 1] - 2 * controlPoints[i] + controlPoints[i + 1]).LengthSquared > TOLERANCE_SQ) + if ((controlPoints[i - 1] - 2 * controlPoints[i] + controlPoints[i + 1]).LengthSquared > TOLERANCE_SQ * 4) return false; return true; @@ -96,7 +96,6 @@ namespace osu.Game.Modes.Osu.Objects /// Creates a piecewise-linear approximation of a bezier curve, by adaptively repeatedly subdividing /// the control points until their approximation error vanishes below a given threshold. /// - /// The control points describing the curve. /// A list of vectors representing the piecewise-linear approximation. public List CreateBezier() { From 38968ad6d2814642eb360a49858396229d61ca10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 9 Dec 2016 18:04:02 +0100 Subject: [PATCH 2/7] Add circular arc approximator for "perfect" sliders. --- .../Objects/CircularArcApproximator.cs | 102 ++++++++++++++++++ .../Objects/OsuHitObjectParser.cs | 2 +- osu.Game.Modes.Osu/Objects/SliderCurve.cs | 51 +++++---- osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj | 1 + 4 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 osu.Game.Modes.Osu/Objects/CircularArcApproximator.cs diff --git a/osu.Game.Modes.Osu/Objects/CircularArcApproximator.cs b/osu.Game.Modes.Osu/Objects/CircularArcApproximator.cs new file mode 100644 index 0000000000..b8f84ed510 --- /dev/null +++ b/osu.Game.Modes.Osu/Objects/CircularArcApproximator.cs @@ -0,0 +1,102 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.MathUtils; +using System; +using System.Collections.Generic; + +namespace osu.Game.Modes.Osu.Objects +{ + public class CircularArcApproximator + { + private Vector2 A; + private Vector2 B; + private Vector2 C; + + private int amountPoints; + + private const float TOLERANCE = 0.1f; + + public CircularArcApproximator(Vector2 A, Vector2 B, Vector2 C) + { + this.A = A; + this.B = B; + this.C = C; + } + + /// + /// Creates a piecewise-linear approximation of a circular arc curve. + /// + /// A list of vectors representing the piecewise-linear approximation. + public List CreateArc() + { + float aSq = (B - C).LengthSquared; + float bSq = (A - C).LengthSquared; + float cSq = (A - B).LengthSquared; + + // If we have a degenerate triangle where a side-length is almost zero, then give up and fall + // back to a more numerically stable method. + if (Precision.AlmostEquals(aSq, 0) || Precision.AlmostEquals(bSq, 0) || Precision.AlmostEquals(cSq, 0)) + return new List(); + + float s = aSq * (bSq + cSq - aSq); + float t = bSq * (aSq + cSq - bSq); + float u = cSq * (aSq + bSq - cSq); + + float sum = s + t + u; + + // If we have a degenerate triangle with an almost-zero size, then give up and fall + // back to a more numerically stable method. + if (Precision.AlmostEquals(sum, 0)) + return new List(); + + Vector2 centre = (s * A + t * B + u * C) / sum; + Vector2 dA = A - centre; + Vector2 dC = C - centre; + + float r = dA.Length; + + double thetaStart = Math.Atan2(dA.Y, dA.X); + double thetaEnd = Math.Atan2(dC.Y, dC.X); + + while (thetaEnd < thetaStart) + thetaEnd += 2 * Math.PI; + + double dir = 1; + double thetaRange = thetaEnd - thetaStart; + + // Decide in which direction to draw the circle, depending on which side of + // AC B lies. + Vector2 orthoAC = C - A; + orthoAC = new Vector2(orthoAC.Y, -orthoAC.X); + if (Vector2.Dot(orthoAC, B - A) < 0) + { + dir = -dir; + thetaRange = 2 * Math.PI - thetaRange; + } + + // We select the amount of points for the approximation by requiring the discrete curvature + // to be smaller than the provided tolerance. The exact angle required to meet the tolerance + // is: 2 * Math.Acos(1 - TOLERANCE / r) + if (2 * r <= TOLERANCE) + // This 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. + amountPoints = 2; + else + amountPoints = Math.Max(2, (int)Math.Ceiling(thetaRange / (2 * Math.Acos(1 - TOLERANCE / r)))); + + List output = new List(amountPoints); + + for (int i = 0; i < amountPoints; ++i) + { + double fract = (double)i / (amountPoints - 1); + double theta = thetaStart + dir * fract * thetaRange; + Vector2 o = new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta)) * r; + output.Add(centre + o); + } + + return output; + } + } +} diff --git a/osu.Game.Modes.Osu/Objects/OsuHitObjectParser.cs b/osu.Game.Modes.Osu/Objects/OsuHitObjectParser.cs index 216c40b779..9516006c57 100644 --- a/osu.Game.Modes.Osu/Objects/OsuHitObjectParser.cs +++ b/osu.Game.Modes.Osu/Objects/OsuHitObjectParser.cs @@ -83,7 +83,7 @@ namespace osu.Game.Modes.Osu.Objects s.Curve = new SliderCurve { - Path = points, + ControlPoints = points, Length = length, CurveType = curveType }; diff --git a/osu.Game.Modes.Osu/Objects/SliderCurve.cs b/osu.Game.Modes.Osu/Objects/SliderCurve.cs index e8df4049f5..961658112f 100644 --- a/osu.Game.Modes.Osu/Objects/SliderCurve.cs +++ b/osu.Game.Modes.Osu/Objects/SliderCurve.cs @@ -4,9 +4,8 @@ using System.Collections.Generic; using OpenTK; using System.Linq; -using System.Diagnostics; using osu.Framework.MathUtils; -using System; +using System.Diagnostics; namespace osu.Game.Modes.Osu.Objects { @@ -14,21 +13,39 @@ namespace osu.Game.Modes.Osu.Objects { public double Length; - public List Path; + public List ControlPoints; public CurveTypes CurveType; private List calculatedPath = new List(); private List cumulativeLength = new List(); - private List calculateSubpath(List subpath) + private List calculateSubpath(List subControlPoints) { switch (CurveType) { case CurveTypes.Linear: - return subpath; + return subControlPoints; + case CurveTypes.PerfectCurve: + // If we have a different amount than 3 control points, use bezier for perfect curves. + if (ControlPoints.Count != 3) + return new BezierApproximator(subControlPoints).CreateBezier(); + else + { + Debug.Assert(subControlPoints.Count == 3); + + // Here we have exactly 3 control points. Attempt to fit a circular arc. + List subpath = new CircularArcApproximator(subControlPoints[0], subControlPoints[1], subControlPoints[2]).CreateArc(); + + if (subpath.Count == 0) + // For some reason a circular arc could not be fit to the 3 given points. Fall back + // to a numerically stable bezier approximation. + subpath = new BezierApproximator(subControlPoints).CreateBezier(); + + return subpath; + } default: - return new BezierApproximator(subpath).CreateBezier(); + return new BezierApproximator(subControlPoints).CreateBezier(); } } @@ -39,21 +56,19 @@ namespace osu.Game.Modes.Osu.Objects // Sliders may consist of various subpaths separated by two consecutive vertices // with the same position. The following loop parses these subpaths and computes // their shape independently, consecutively appending them to calculatedPath. - List subpath = new List(); - for (int i = 0; i < Path.Count; ++i) + List subControlPoints = new List(); + for (int i = 0; i < ControlPoints.Count; ++i) { - subpath.Add(Path[i]); - if (i == Path.Count - 1 || Path[i] == Path[i + 1]) + subControlPoints.Add(ControlPoints[i]); + if (i == ControlPoints.Count - 1 || ControlPoints[i] == ControlPoints[i + 1]) { - // If we already constructed a subpath previously, then the new subpath - // will have as starting position the end position of the previous subpath. - // Hence we can and should remove the previous endpoint to avoid a segment - // with 0 length. - if (calculatedPath.Count > 0) - calculatedPath.RemoveAt(calculatedPath.Count - 1); + List subpath = calculateSubpath(subControlPoints); + for (int j = 0; j < subpath.Count; ++j) + // Only add those vertices that add a new segment to the path. + if (calculatedPath.Count == 0 || calculatedPath.Last() != subpath[j]) + calculatedPath.Add(subpath[j]); - calculatedPath.AddRange(calculateSubpath(subpath)); - subpath.Clear(); + subControlPoints.Clear(); } } } diff --git a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj index 503fabd28d..a9a346f563 100644 --- a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj +++ b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj @@ -42,6 +42,7 @@ + From 9c4c713aa01699c0a246fa86ed9ce69b7b7c396c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 10 Dec 2016 11:30:22 +0100 Subject: [PATCH 3/7] Fix panels that are moving off-screen having an incorrect X coordinate applied. --- osu.Game/Screens/Select/CarouselContainer.cs | 52 ++++++++++++-------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Select/CarouselContainer.cs b/osu.Game/Screens/Select/CarouselContainer.cs index 069c8d8d37..2c59639ce7 100644 --- a/osu.Game/Screens/Select/CarouselContainer.cs +++ b/osu.Game/Screens/Select/CarouselContainer.cs @@ -190,18 +190,45 @@ namespace osu.Game.Screens.Select return 125 + x; } + /// + /// Update a panel's x position and multiplicative alpha based on its y position and + /// the current scroll position. + /// + /// The panel to be updated. + /// Half the draw height of the carousel container. + private void updatePanel(Panel p, float halfHeight) + { + float panelDrawY = p.Position.Y - Current + p.DrawHeight / 2; + float dist = Math.Abs(1f - panelDrawY / halfHeight); + + // Setting the origin position serves as an additive position on top of potential + // local transformation we may want to apply (e.g. when a panel gets selected, we + // may want to smoothly transform it leftwards.) + p.OriginPosition = new Vector2(-offsetX(dist, halfHeight), 0); + + // We are applying a multiplicative alpha (which is internally done by nesting an + // additional container and setting that container's alpha) such that we can + // layer transformations on top, with a similar reasoning to the previous comment. + p.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - 1.5f * dist, 0, 1)); + } + protected override void Update() { base.Update(); + // Determine which items stopped being on screen for future removal from the lifetimelist. float drawHeight = DrawHeight; + float halfHeight = drawHeight / 2; - Lifetime.AliveItems.ForEach(delegate (Panel p) + foreach (Panel p in Lifetime.AliveItems) { float panelPosY = p.Position.Y; p.IsOnScreen = panelPosY >= Current - p.DrawHeight && panelPosY <= Current + drawHeight; - }); + updatePanel(p, halfHeight); + } + // Determine range of indices for items that are now definitely on screen to be added + // to the lifetimelist in the future. int firstIndex = yPositions.BinarySearch(Current - Panel.MAX_HEIGHT); if (firstIndex < 0) firstIndex = ~firstIndex; int lastIndex = yPositions.BinarySearch(Current + drawHeight); @@ -210,26 +237,11 @@ namespace osu.Game.Screens.Select Lifetime.StartIndex = firstIndex; Lifetime.EndIndex = lastIndex; - float halfHeight = drawHeight / 2; - for (int i = firstIndex; i < lastIndex; ++i) { - var panel = Lifetime[i]; - - panel.IsOnScreen = true; - - float panelDrawY = panel.Position.Y - Current + panel.DrawHeight / 2; - float dist = Math.Abs(1f - panelDrawY / halfHeight); - - // Setting the origin position serves as an additive position on top of potential - // local transformation we may want to apply (e.g. when a panel gets selected, we - // may want to smoothly transform it leftwards.) - panel.OriginPosition = new Vector2(-offsetX(dist, halfHeight), 0); - - // We are applying a multiplicative alpha (which is internally done by nesting an - // additional container and setting that container's alpha) such that we can - // layer transformations on top, with a similar reasoning to the previous comment. - panel.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - 1.5f * dist, 0, 1)); + Panel p = Lifetime[i]; + p.IsOnScreen = true; + updatePanel(p, halfHeight); } } } From 2ced0a48e0343fa55a61e3615412e04a13451f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 10 Dec 2016 14:37:00 +0100 Subject: [PATCH 4/7] Update framework. --- osu-framework | 2 +- osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 1b0d7a584c..b918a5bb33 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1b0d7a584cad85efcdf25c5155e6e62a4ccb5758 +Subproject commit b918a5bb33b18e194af265d82f9011a8ea2a4f3e diff --git a/osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs b/osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs index dd0738e6e5..cdb087f6c3 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs @@ -58,7 +58,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables ScaleTo(1.6f); ScaleTo(1, 100, EasingTypes.In); - MoveToRelative(new Vector2(0, 100), 800, EasingTypes.InQuint); + MoveToOffset(new Vector2(0, 100), 800, EasingTypes.InQuint); RotateTo(40, 800, EasingTypes.InQuint); Delay(600); From 882d5edf7d582a1f564119228156ce29b0ccc5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sun, 11 Dec 2016 10:09:58 +0100 Subject: [PATCH 5/7] Fix dropped input outside of playfield. --- osu.Game/Modes/UI/Playfield.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Modes/UI/Playfield.cs b/osu.Game/Modes/UI/Playfield.cs index ec91536f29..fc042d72a0 100644 --- a/osu.Game/Modes/UI/Playfield.cs +++ b/osu.Game/Modes/UI/Playfield.cs @@ -35,6 +35,8 @@ namespace osu.Game.Modes.UI public class ScaledContainer : Container { protected override Vector2 DrawScale => new Vector2(DrawSize.X / 512); + + public override bool Contains(Vector2 screenSpacePos) => true; } public class HitObjectContainer : Container From eef697d842456c2df5753f25dc417d461985bc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sun, 11 Dec 2016 10:11:22 +0100 Subject: [PATCH 6/7] Wire up CircleSize to hitobjects. Note, that circle sizes still are wrong compared to stable osu. In order to fix this, the base radius of hitcircles needs to become 64, but it currently is 72. --- .../Tests/TestCaseGamefield.cs | 3 +- .../Objects/Drawables/DrawableHitCircle.cs | 6 ++-- .../Objects/Drawables/DrawableOsuHitObject.cs | 5 ---- .../Objects/Drawables/DrawableSlider.cs | 28 +++++++++++++------ .../Objects/Drawables/Pieces/SliderBall.cs | 6 ++-- .../Objects/Drawables/Pieces/SliderBouncer.cs | 2 +- osu.Game.Modes.Osu/Objects/OsuHitObject.cs | 10 +++++++ osu.Game.Modes.Osu/Objects/Slider.cs | 4 +-- 8 files changed, 41 insertions(+), 23 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs index 3841420dad..d77e2d135b 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs @@ -42,7 +42,8 @@ namespace osu.Desktop.VisualTests.Tests objects.Add(new HitCircle() { StartTime = time, - Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)) + Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)), + Scale = RNG.NextSingle(0.5f, 1.0f), }); time += RNG.Next(50, 500); diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs index ebb5057a49..ccbfbb1db3 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -13,7 +13,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables { public class DrawableHitCircle : DrawableOsuHitObject { - private OsuHitObject osuObject; + private HitCircle osuObject; public ApproachCircle ApproachCircle; private CirclePiece circle; @@ -23,12 +23,13 @@ namespace osu.Game.Modes.Osu.Objects.Drawables private NumberPiece number; private GlowPiece glow; - public DrawableHitCircle(OsuHitObject h) : base(h) + public DrawableHitCircle(HitCircle h) : base(h) { osuObject = h; Origin = Anchor.Centre; Position = osuObject.Position; + Scale = new Vector2(osuObject.Scale); Children = new Drawable[] { @@ -104,7 +105,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables ApproachCircle.Alpha = 0; ApproachCircle.Scale = new Vector2(2); explode.Alpha = 0; - Scale = new Vector2(0.5f); //this will probably need to be moved to DrawableHitObject at some point. } protected override void UpdatePreemptState() diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs index e6e948cf6f..9e1fb93cd5 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -1,12 +1,7 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs index e0af180e95..fcf480c384 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs @@ -27,24 +27,32 @@ namespace osu.Game.Modes.Osu.Objects.Drawables slider = s; - Origin = Anchor.TopLeft; - Position = Vector2.Zero; - RelativeSizeAxes = Axes.Both; - Children = new Drawable[] { body = new SliderBody(s) { Position = s.Position, - PathWidth = 36, + PathWidth = s.Scale * 72, + }, + bouncer1 = new SliderBouncer(s, false) + { + Position = s.Curve.PositionAt(1), + Scale = new Vector2(s.Scale), + }, + bouncer2 = new SliderBouncer(s, true) + { + Position = s.Position, + Scale = new Vector2(s.Scale), + }, + ball = new SliderBall(s) + { + Scale = new Vector2(s.Scale), }, - bouncer1 = new SliderBouncer(slider, false) { Position = slider.Curve.PositionAt(1) }, - bouncer2 = new SliderBouncer(slider, true) { Position = slider.Position }, - ball = new SliderBall(slider), initialCircle = new DrawableHitCircle(new HitCircle { StartTime = s.StartTime, Position = s.Position, + Scale = s.Scale, Colour = s.Colour, }) { @@ -58,6 +66,10 @@ namespace osu.Game.Modes.Osu.Objects.Drawables components.Add(bouncer2); } + // Since the DrawableSlider itself is just a container without a size we need to + // pass all input through. + public override bool Contains(Vector2 screenSpacePos) => true; + protected override void Update() { base.Update(); diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs index ce34ef7c22..8d31acdf4e 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -16,7 +16,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces private readonly Slider slider; private Box follow; - const float width = 70; + const float width = 140; public SliderBall(Slider slider) { @@ -25,7 +25,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces AutoSizeAxes = Axes.Both; BlendingMode = BlendingMode.Additive; Origin = Anchor.Centre; - BorderThickness = 5; + BorderThickness = 10; BorderColour = Color4.Orange; Children = new Drawable[] @@ -45,7 +45,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces AutoSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, - BorderThickness = 7, + BorderThickness = 14, BorderColour = Color4.White, Alpha = 1, CornerRadius = width / 2, diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs index 39d09e6d66..47a345bdc3 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces Icon = FontAwesome.fa_eercast, Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = 24, + TextSize = 48, } }; } diff --git a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs index 61932f80a3..12fdf1a344 100644 --- a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs @@ -5,6 +5,7 @@ using System; using osu.Game.Beatmaps.Samples; using osu.Game.Modes.Objects; using OpenTK; +using osu.Game.Beatmaps; namespace osu.Game.Modes.Osu.Objects { @@ -12,8 +13,17 @@ namespace osu.Game.Modes.Osu.Objects { public Vector2 Position { get; set; } + public float Scale { get; set; } = 1; + public virtual Vector2 EndPosition => Position; + public override void SetDefaultsFromBeatmap(Beatmap beatmap) + { + base.SetDefaultsFromBeatmap(beatmap); + + Scale = (1.0f - 0.7f * (beatmap.BeatmapInfo.BaseDifficulty.CircleSize - 5) / 5) / 2; + } + [Flags] internal enum HitObjectType { diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs index 3c11ead7e4..27210eec10 100644 --- a/osu.Game.Modes.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -1,9 +1,7 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Database; using osu.Game.Beatmaps; -using System; using OpenTK; namespace osu.Game.Modes.Osu.Objects @@ -18,6 +16,8 @@ namespace osu.Game.Modes.Osu.Objects public override void SetDefaultsFromBeatmap(Beatmap beatmap) { + base.SetDefaultsFromBeatmap(beatmap); + Velocity = 100 / beatmap.BeatLengthAt(StartTime, true) * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier; } From b94d11787e945ac956d8160249bcd3d34361d474 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2016 15:38:26 +0900 Subject: [PATCH 7/7] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index b918a5bb33..cea7e88cad 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit b918a5bb33b18e194af265d82f9011a8ea2a4f3e +Subproject commit cea7e88cad687a6a6613655ddd74be3f15bf49db