From f01deae42819902b0b1920c3caa5070243a6a9ac Mon Sep 17 00:00:00 2001 From: vun Date: Tue, 24 May 2022 17:38:52 +0800 Subject: [PATCH] Colour compression preprocessing implementation --- .../TaikoDifficultyHitObjectColour.cs | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs new file mode 100644 index 0000000000..425f5a16a9 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObjectColour.cs @@ -0,0 +1,78 @@ +namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing +{ + /// + /// Stores colour compression information for a . + /// + public class TaikoDifficultyHitObjectColour + { + const int max_repetition_interval = 16; + + private TaikoDifficultyHitObjectColour previous; + + /// + /// True if the current colour is different from the previous colour. + /// + public bool Delta { get; private set; } + + /// + /// How many notes are Delta repeated + /// + public int DeltaRunLength { get; private set; } + + /// + /// How many notes between the current and previous identical . + /// Negative number means that there is no repetition in range. + /// + public int RepetitionInterval { get; private set; } + + /// + /// Get the instance for the given hitObject. This is implemented + /// as a static function instead of constructor to allow for reusing existing instances. + /// TODO: findRepetitionInterval needs to be called a final time after all hitObjects have been processed. + /// + public static TaikoDifficultyHitObjectColour GetInstanceFor( + TaikoDifficultyHitObject hitObject, TaikoDifficultyHitObject lastObject, TaikoDifficultyHitObjectColour previous) + { + bool delta = lastObject == null || hitObject.HitType != lastObject.HitType; + if (delta == previous.Delta) + { + previous.DeltaRunLength += 1; + return previous; + } + else + { + // Calculate RepetitionInterval for previous + previous.RepetitionInterval = findRepetitionInterval(previous); + + return new TaikoDifficultyHitObjectColour() + { + Delta = delta, + DeltaRunLength = 1, + RepetitionInterval = -1, + previous = previous + }; + } + } + + /// + /// Finds the closest previous that has the identical delta value + /// and run length to target, and returns the amount of notes between them. + /// + private static int findRepetitionInterval(TaikoDifficultyHitObjectColour target) { + if (target.previous == null || target.previous.previous == null) + return -1; + + int interval = target.previous.DeltaRunLength; + TaikoDifficultyHitObjectColour other = target.previous.previous; + while(other != null && interval < max_repetition_interval) { + if (other.Delta == target.Delta && other.DeltaRunLength == target.DeltaRunLength) + return interval; + else + interval += other.DeltaRunLength; + other = other.previous; + } + + return -1; + } + } +} \ No newline at end of file