1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-22 22:17:46 +08:00

Rework beatmap post-processing into HitRenderer.

This commit is contained in:
smoogipooo 2017-03-14 17:01:21 +09:00
parent 90ad2e9731
commit 7141bc86d3
24 changed files with 144 additions and 87 deletions

View File

@ -77,8 +77,6 @@ namespace osu.Desktop.VisualTests.Tests
}
};
decoder.Process(b);
beatmap = new TestWorkingBeatmap(b);
}

View File

@ -0,0 +1,16 @@
using osu.Game.Beatmaps;
using osu.Game.Modes.Catch.Objects;
namespace osu.Game.Modes.Catch.Beatmaps
{
internal class CatchBeatmapProcessor : IBeatmapProcessor<CatchBaseHit>
{
public void PostProcess(Beatmap<CatchBaseHit> beatmap)
{
}
public void SetDefaults(CatchBaseHit hitObject)
{
}
}
}

View File

@ -18,6 +18,8 @@ namespace osu.Game.Modes.Catch.UI
protected override IBeatmapConverter<CatchBaseHit> CreateBeatmapConverter() => new CatchBeatmapConverter();
protected override IBeatmapProcessor<CatchBaseHit> CreateBeatmapProcessor() => new CatchBeatmapProcessor();
protected override Playfield<CatchBaseHit> CreatePlayfield() => new CatchPlayfield();
protected override DrawableHitObject<CatchBaseHit> GetVisualRepresentation(CatchBaseHit h) => null;// new DrawableFruit(h);

View File

@ -48,6 +48,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Beatmaps\CatchBeatmapConverter.cs" />
<Compile Include="Beatmaps\CatchBeatmapProcessor.cs" />
<Compile Include="CatchDifficultyCalculator.cs" />
<Compile Include="Objects\CatchBaseHit.cs" />
<Compile Include="Objects\Drawable\DrawableFruit.cs" />

View File

@ -0,0 +1,16 @@
using osu.Game.Beatmaps;
using osu.Game.Modes.Mania.Objects;
namespace osu.Game.Modes.Mania.Beatmaps
{
internal class ManiaBeatmapProcessor : IBeatmapProcessor<ManiaBaseHit>
{
public void PostProcess(Beatmap<ManiaBaseHit> beatmap)
{
}
public void SetDefaults(ManiaBaseHit hitObject)
{
}
}
}

View File

@ -21,6 +21,8 @@ namespace osu.Game.Modes.Mania.UI
protected override IBeatmapConverter<ManiaBaseHit> CreateBeatmapConverter() => new ManiaBeatmapConverter();
protected override IBeatmapProcessor<ManiaBaseHit> CreateBeatmapProcessor() => new ManiaBeatmapProcessor();
protected override Playfield<ManiaBaseHit> CreatePlayfield() => new ManiaPlayfield(columns);
protected override DrawableHitObject<ManiaBaseHit> GetVisualRepresentation(ManiaBaseHit h)

View File

@ -48,6 +48,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Beatmaps\ManiaBeatmapConverter.cs" />
<Compile Include="Beatmaps\ManiaBeatmapProcessor.cs" />
<Compile Include="ManiaDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableNote.cs" />
<Compile Include="Objects\HoldNote.cs" />

View File

@ -8,7 +8,6 @@ using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.Objects.Drawables;
using System.Collections.Generic;
using osu.Game.Modes.Objects.Types;
using OpenTK.Graphics;
using System.Linq;
namespace osu.Game.Modes.Osu.Beatmaps
@ -17,13 +16,9 @@ namespace osu.Game.Modes.Osu.Beatmaps
{
public Beatmap<OsuHitObject> Convert(Beatmap original)
{
List<OsuHitObject> converted = convertHitObjects(original.HitObjects, original.BeatmapInfo?.StackLeniency ?? 0.7f);
converted.ForEach(c => c.SetDefaultsFromBeatmap(original));
return new Beatmap<OsuHitObject>(original)
{
HitObjects = converted
HitObjects = convertHitObjects(original.HitObjects, original.BeatmapInfo?.StackLeniency ?? 0.7f)
};
}
@ -57,8 +52,6 @@ namespace osu.Game.Modes.Osu.Beatmaps
Position = positionData?.Position ?? Vector2.Zero,
ComboColour = comboData?.ComboColour ?? Color4.White,
ComboIndex = comboData?.ComboIndex ?? 0,
NewCombo = comboData?.NewCombo ?? false,
Length = distanceData?.Distance ?? 0,
@ -76,10 +69,6 @@ namespace osu.Game.Modes.Osu.Beatmaps
Position = new Vector2(512, 384) / 2,
EndTime = endTimeData.EndTime,
ComboColour = comboData?.ComboColour ?? Color4.White,
ComboIndex = comboData?.ComboIndex ?? 0,
NewCombo = comboData?.NewCombo ?? false,
};
}
@ -90,8 +79,6 @@ namespace osu.Game.Modes.Osu.Beatmaps
Position = positionData?.Position ?? Vector2.Zero,
ComboColour = comboData?.ComboColour ?? Color4.White,
ComboIndex = comboData?.ComboIndex ?? 0,
NewCombo = comboData?.NewCombo ?? false
};
}

View File

@ -0,0 +1,33 @@
using osu.Game.Beatmaps;
using osu.Game.Modes.Osu.Objects;
namespace osu.Game.Modes.Osu.Beatmaps
{
internal class OsuBeatmapProcessor : IBeatmapProcessor<OsuHitObject>
{
public void SetDefaults(OsuHitObject hitObject)
{
}
public void PostProcess(Beatmap<OsuHitObject> beatmap)
{
if ((beatmap.ComboColors?.Count ?? 0) == 0)
return;
int comboIndex = 0;
int colourIndex = 0;
foreach (var obj in beatmap.HitObjects)
{
if (obj.NewCombo)
{
comboIndex = 0;
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
}
obj.ComboIndex = comboIndex++;
obj.ComboColour = beatmap.ComboColors[colourIndex];
}
}
}
}

View File

@ -13,6 +13,5 @@ namespace osu.Game.Modes.Osu.Objects
public override HitObjectType Type => HitObjectType.Spinner;
public override bool NewCombo => true;
}
}

View File

@ -19,6 +19,8 @@ namespace osu.Game.Modes.Osu.UI
protected override IBeatmapConverter<OsuHitObject> CreateBeatmapConverter() => new OsuBeatmapConverter();
protected override IBeatmapProcessor<OsuHitObject> CreateBeatmapProcessor() => new OsuBeatmapProcessor();
protected override Playfield<OsuHitObject> CreatePlayfield() => new OsuPlayfield();
protected override DrawableHitObject<OsuHitObject> GetVisualRepresentation(OsuHitObject h)

View File

@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Beatmaps\OsuBeatmapConverter.cs" />
<Compile Include="Beatmaps\OsuBeatmapProcessor.cs" />
<Compile Include="Objects\BezierApproximator.cs" />
<Compile Include="Objects\CircularArcApproximator.cs" />
<Compile Include="Objects\Drawables\DrawableOsuHitObject.cs" />

View File

@ -0,0 +1,16 @@
using osu.Game.Beatmaps;
using osu.Game.Modes.Taiko.Objects;
namespace osu.Game.Modes.Taiko.Beatmaps
{
internal class TaikoBeatmapProcessor : IBeatmapProcessor<TaikoBaseHit>
{
public void PostProcess(Beatmap<TaikoBaseHit> beatmap)
{
}
public void SetDefaults(TaikoBaseHit hitObject)
{
}
}
}

View File

@ -18,6 +18,8 @@ namespace osu.Game.Modes.Taiko.UI
protected override IBeatmapConverter<TaikoBaseHit> CreateBeatmapConverter() => new TaikoBeatmapConverter();
protected override IBeatmapProcessor<TaikoBaseHit> CreateBeatmapProcessor() => new TaikoBeatmapProcessor();
protected override Playfield<TaikoBaseHit> CreatePlayfield() => new TaikoPlayfield();
protected override DrawableHitObject<TaikoBaseHit> GetVisualRepresentation(TaikoBaseHit h) => null;// new DrawableTaikoHit(h);

View File

@ -48,6 +48,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Beatmaps\TaikoBeatmapConverter.cs" />
<Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" />
<Compile Include="TaikoDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableTaikoHit.cs" />
<Compile Include="Objects\TaikoBaseHit.cs" />

View File

@ -19,7 +19,13 @@ namespace osu.Game.Beatmaps
{
public BeatmapInfo BeatmapInfo;
public List<ControlPoint> ControlPoints;
public List<Color4> ComboColors;
public List<Color4> ComboColors = new List<Color4>
{
new Color4(17, 136, 170, 255),
new Color4(102, 136, 0, 255),
new Color4(204, 102, 0, 255),
new Color4(121, 9, 13, 255)
};
public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata;
@ -34,9 +40,9 @@ namespace osu.Game.Beatmaps
/// <param name="original">The original beatmap to use the parameters of.</param>
public Beatmap(Beatmap original = null)
{
BeatmapInfo = original?.BeatmapInfo;
ControlPoints = original?.ControlPoints;
ComboColors = original?.ComboColors;
BeatmapInfo = original?.BeatmapInfo ?? BeatmapInfo;
ControlPoints = original?.ControlPoints ?? ControlPoints;
ComboColors = original?.ComboColors ?? ComboColors;
}
public double BPMMaximum => 60000 / (ControlPoints?.Where(c => c.BeatLength != 0).OrderBy(c => c.BeatLength).FirstOrDefault() ?? ControlPoint.Default).BeatLength;

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using osu.Game.Modes.Objects;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
@ -31,9 +30,7 @@ namespace osu.Game.Beatmaps.Formats
public virtual Beatmap Decode(TextReader stream)
{
Beatmap b = ParseFile(stream);
Process(b);
return b;
return ParseFile(stream);
}
public virtual void Decode(TextReader stream, Beatmap beatmap)
@ -41,43 +38,12 @@ namespace osu.Game.Beatmaps.Formats
ParseFile(stream, beatmap);
}
public virtual Beatmap Process(Beatmap beatmap)
{
int comboIndex = 0;
int colourIndex = 0;
foreach (var obj in beatmap.HitObjects)
{
HitObjectWithCombo comboObject = obj as HitObjectWithCombo;
if (comboObject == null || comboObject.NewCombo)
{
comboIndex = 0;
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
}
if (comboObject != null)
{
comboObject.ComboIndex = comboIndex++;
comboObject.ComboColour = beatmap.ComboColors[colourIndex];
}
}
return beatmap;
}
protected virtual Beatmap ParseFile(TextReader stream)
{
var beatmap = new Beatmap
{
HitObjects = new List<HitObject>(),
ControlPoints = new List<ControlPoint>(),
ComboColors = new List<Color4> {
new Color4(17, 136, 170, 255),
new Color4(102, 136, 0, 255),
new Color4(204, 102, 0, 255),
new Color4(121, 9, 13, 255),
},
BeatmapInfo = new BeatmapInfo
{
Metadata = new BeatmapMetadata(),

View File

@ -0,0 +1,27 @@
using osu.Game.Modes.Objects;
namespace osu.Game.Beatmaps
{
/// <summary>
/// Processes a post-converted Beatmap.
/// </summary>
/// <typeparam name="T">The type of HitObject contained in the Beatmap.</typeparam>
public interface IBeatmapProcessor<T>
where T : HitObject
{
/// <summary>
/// Sets default values for a HitObject.
/// </summary>
/// <param name="hitObject">The HitObject to set default values for.</param>
void SetDefaults(T hitObject);
/// <summary>
/// Post-processes a Beatmap to add mode-specific components that aren't added during conversion.
/// <para>
/// An example of such a usage is for combo colours.
/// </para>
/// </summary>
/// <param name="beatmap">The Beatmap to process.</param>
void PostProcess(Beatmap<T> beatmap);
}
}

View File

@ -6,8 +6,10 @@ using OpenTK;
namespace osu.Game.Modes.Objects
{
internal class Hit : HitObjectWithCombo, IHasPosition
internal class Hit : HitObject, IHasPosition, IHasCombo
{
public Vector2 Position { get; set; }
public bool NewCombo { get; set; }
}
}

View File

@ -1,15 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects.Types;
using OpenTK.Graphics;
namespace osu.Game.Modes.Objects
{
internal class HitObjectWithCombo : HitObject, IHasCombo
{
public Color4 ComboColour { get; set; }
public bool NewCombo { get; set; }
public int ComboIndex { get; set; }
}
}

View File

@ -7,7 +7,7 @@ using OpenTK;
namespace osu.Game.Modes.Objects
{
internal class Slider : HitObjectWithCombo, IHasCurve, IHasPosition, IHasDistance, IHasRepeats
internal class Slider : HitObject, IHasCurve, IHasPosition, IHasDistance, IHasRepeats, IHasCombo
{
public List<Vector2> ControlPoints { get; set; }
public CurveType CurveType { get; set; }
@ -17,5 +17,7 @@ namespace osu.Game.Modes.Objects
public double Distance { get; set; }
public int RepeatCount { get; set; }
public bool NewCombo { get; set; }
}
}

View File

@ -1,8 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Graphics;
namespace osu.Game.Modes.Objects.Types
{
/// <summary>
@ -10,19 +8,9 @@ namespace osu.Game.Modes.Objects.Types
/// </summary>
public interface IHasCombo
{
/// <summary>
/// The colour of this HitObject in the combo.
/// </summary>
Color4 ComboColour { get; }
/// <summary>
/// Whether the HitObject starts a new combo.
/// </summary>
bool NewCombo { get; }
/// <summary>
/// The combo index.
/// </summary>
int ComboIndex { get; }
}
}

View File

@ -52,7 +52,10 @@ namespace osu.Game.Modes.UI
protected HitRenderer(WorkingBeatmap beatmap)
{
// Convert + process the beatmap
Beatmap = CreateBeatmapConverter().Convert(beatmap.Beatmap);
Beatmap.HitObjects.ForEach(CreateBeatmapProcessor().SetDefaults);
CreateBeatmapProcessor().PostProcess(Beatmap);
applyMods(beatmap.Mods.Value);
@ -70,7 +73,6 @@ namespace osu.Game.Modes.UI
AddInternal(InputManager);
}
[BackgroundDependencyLoader]
private void load()
{
@ -110,6 +112,8 @@ namespace osu.Game.Modes.UI
protected abstract DrawableHitObject<TObject> GetVisualRepresentation(TObject h);
protected abstract Playfield<TObject> CreatePlayfield();
protected abstract IBeatmapConverter<TObject> CreateBeatmapConverter();
protected abstract IBeatmapProcessor<TObject> CreateBeatmapProcessor();
}
}

View File

@ -74,6 +74,7 @@
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
<Compile Include="Beatmaps\IBeatmapCoverter.cs" />
<Compile Include="Beatmaps\IBeatmapProcessor.cs" />
<Compile Include="Database\ScoreDatabase.cs" />
<Compile Include="Graphics\Backgrounds\Triangles.cs" />
<Compile Include="Graphics\Cursor\CursorTrail.cs" />
@ -94,7 +95,6 @@
<Compile Include="Modes\Mods\IApplicableMod.cs" />
<Compile Include="Modes\Mods\ModType.cs" />
<Compile Include="Modes\Objects\Hit.cs" />
<Compile Include="Modes\Objects\HitObjectWithCombo.cs" />
<Compile Include="Modes\Objects\LegacyHitObjectParser.cs" />
<Compile Include="Modes\Objects\Slider.cs" />
<Compile Include="Modes\Objects\Spinner.cs" />