improved slider approximation for osu_fast

This commit is contained in:
MaxOhn
2021-11-09 05:02:48 +01:00
parent 1ba6cfc44c
commit a01cd1f2a3
3 changed files with 27 additions and 14 deletions
+6 -2
View File
@@ -91,6 +91,7 @@ pub fn stars(
clock_rate, clock_rate,
radius, radius,
*repeats, *repeats,
*pixel_len,
control_points, control_points,
)) ))
} }
@@ -107,6 +108,7 @@ pub fn stars(
clock_rate, clock_rate,
radius, radius,
*span_count, *span_count,
*pixel_len,
*last_control_point, *last_control_point,
)) ))
} }
@@ -267,24 +269,26 @@ pub fn strains(map: &Beatmap, mods: impl Mods) -> Strains {
HitObjectKind::Slider { HitObjectKind::Slider {
repeats, repeats,
control_points, control_points,
.. pixel_len,
} => Some(OsuObject::slider( } => Some(OsuObject::slider(
h, h,
clock_rate, clock_rate,
radius, radius,
*repeats, *repeats,
*pixel_len,
control_points, control_points,
)), )),
#[cfg(not(feature = "sliders"))] #[cfg(not(feature = "sliders"))]
HitObjectKind::Slider { HitObjectKind::Slider {
span_count, span_count,
last_control_point, last_control_point,
.. pixel_len,
} => Some(OsuObject::slider( } => Some(OsuObject::slider(
h, h,
clock_rate, clock_rate,
radius, radius,
*span_count, *span_count,
*pixel_len,
*last_control_point, *last_control_point,
)), )),
HitObjectKind::Spinner { .. } => Some(OsuObject::spinner(h, clock_rate)), HitObjectKind::Spinner { .. } => Some(OsuObject::spinner(h, clock_rate)),
+20 -11
View File
@@ -27,16 +27,20 @@ impl OsuObject {
clock_rate: f32, clock_rate: f32,
radius: f32, radius: f32,
repeats: usize, repeats: usize,
pixel_len: f32,
control_points: &[crate::parse::PathControlPoint], control_points: &[crate::parse::PathControlPoint],
) -> Self { ) -> Self {
match control_points.last() { match control_points.last() {
Some(point) => { Some(point) => {
let follow_circle_radius = radius * 3.0;
let span_count = (repeats + 1) as f32;
let travel_dist = let travel_dist =
Self::approximate_travel_dist(radius, repeats + 1, h.pos, point.pos + h.pos); Self::approximate_travel_dist(follow_circle_radius, span_count, point.pos);
let mut end_pos = h.pos; let mut end_pos = h.pos;
if repeats % 2 == 0 { if repeats % 2 == 0 && pixel_len > follow_circle_radius {
end_pos += point.pos end_pos += point.pos
} }
@@ -59,11 +63,18 @@ impl OsuObject {
clock_rate: f32, clock_rate: f32,
radius: f32, radius: f32,
span_count: usize, span_count: usize,
pixel_len: f32,
last_control_point: Pos2, last_control_point: Pos2,
) -> Self { ) -> Self {
let travel_dist = Self::approximate_travel_dist(radius, span_count, h.pos, point.pos); let follow_circle_radius = radius * 3.0;
let end_pos = if span_count % 2 == 1 { let travel_dist = Self::approximate_travel_dist(
follow_circle_radius,
span_count as f32,
point.pos - h.pos,
);
let end_pos = if span_count % 2 == 1 && pixel_len > follow_circle_radius {
last_control_point last_control_point
} else { } else {
h.pos h.pos
@@ -111,15 +122,13 @@ impl OsuObject {
// Approximating lower bound for lazy travel distance // Approximating lower bound for lazy travel distance
fn approximate_travel_dist( fn approximate_travel_dist(
radius: f32, follow_circle_radius: f32,
span_count: usize, span_count: f32,
pos: Pos2,
last_control_point: Pos2, last_control_point: Pos2,
) -> f32 { ) -> f32 {
let approx_follow_circle_radius = radius * 3.0; let lazy_end_point_dist = follow_circle_radius * span_count;
let lazy_end_point_dist = approx_follow_circle_radius * (span_count + 1) as f32; let dist = last_control_point.length();
let dist = (pos - last_control_point).length();
(dist * span_count as f32 - lazy_end_point_dist).max(0.0) (dist * span_count - lazy_end_point_dist).max(0.0)
} }
} }
+1 -1
View File
@@ -94,7 +94,7 @@ fn custom_osu() {
println!("Parsing average: {:?}", accum / iters); println!("Parsing average: {:?}", accum / iters);
let start = Instant::now(); let start = Instant::now();
let result = OsuPP::new(&map).mods(1024).calculate(); let result = OsuPP::new(&map).mods(0).calculate();
let iters = 100; let iters = 100;
let accum = start.elapsed(); let accum = start.elapsed();