reuse path & length bufs for curves

This commit is contained in:
MaxOhn
2022-10-22 18:48:52 +02:00
parent 3a1b868a4d
commit ea23a8948b
3 changed files with 40 additions and 26 deletions
@@ -37,7 +37,7 @@ impl<'h> DistanceObjectPatternGenerator<'h> {
prev_pattern: &'h Pattern, prev_pattern: &'h Pattern,
orig: &'h Beatmap, orig: &'h Beatmap,
repeats: usize, repeats: usize,
curve: &Curve, curve: &Curve<'_>,
edge_sounds: &'h [u8], edge_sounds: &'h [u8],
) -> Self { ) -> Self {
let timing_point = orig.timing_point_at(hit_object.start_time); let timing_point = orig.timing_point_at(hit_object.start_time);
+2 -2
View File
@@ -136,7 +136,7 @@ impl Beatmap {
} }
struct SliderParams<'c> { struct SliderParams<'c> {
curve: &'c Curve, curve: &'c Curve<'c>,
duration: u32, duration: u32,
repeats: usize, repeats: usize,
start_time: f64, start_time: f64,
@@ -144,7 +144,7 @@ struct SliderParams<'c> {
} }
impl<'c> SliderParams<'c> { impl<'c> SliderParams<'c> {
fn new(start_time: f64, repeats: usize, curve: &'c Curve) -> Self { fn new(start_time: f64, repeats: usize, curve: &'c Curve<'c>) -> Self {
Self { Self {
curve, curve,
repeats, repeats,
+37 -23
View File
@@ -8,6 +8,8 @@ const CIRCULAR_ARC_TOLERANCE: f32 = 0.1;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub(crate) struct CurveBuffers { pub(crate) struct CurveBuffers {
path: Vec<Pos2>,
lengths: Vec<f64>,
vertices: Vec<Pos2>, vertices: Vec<Pos2>,
bezier: BezierBuffers, bezier: BezierBuffers,
} }
@@ -50,21 +52,24 @@ struct CircularArcProperties {
centre: Pos2, centre: Pos2,
} }
pub(crate) struct Curve { pub(crate) struct Curve<'bufs> {
path: Vec<Pos2>, path: &'bufs [Pos2],
lengths: Vec<f64>, lengths: &'bufs [f64],
} }
impl Curve { impl<'bufs> Curve<'bufs> {
pub(crate) fn new( pub(crate) fn new(
points: &[PathControlPoint], points: &[PathControlPoint],
expected_len: Option<f64>, expected_len: Option<f64>,
bufs: &mut CurveBuffers, bufs: &'bufs mut CurveBuffers,
) -> Self { ) -> Self {
let mut path = Self::calculate_path(points, bufs); Self::calculate_path(points, bufs);
let lengths = Self::calculate_length(points, &mut path, expected_len); Self::calculate_length(points, bufs, expected_len);
Self { path, lengths } Self {
path: &bufs.path,
lengths: &bufs.lengths,
}
} }
pub(crate) fn position_at(&self, progress: f64) -> Pos2 { pub(crate) fn position_at(&self, progress: f64) -> Pos2 {
@@ -117,17 +122,23 @@ impl Curve {
p0 + (p1 - p0) * w as f32 p0 + (p1 - p0) * w as f32
} }
fn calculate_path(points: &[PathControlPoint], bufs: &mut CurveBuffers) -> Vec<Pos2> { fn calculate_path(points: &[PathControlPoint], bufs: &mut CurveBuffers) {
bufs.path.clear();
if points.is_empty() { if points.is_empty() {
return Vec::new(); return;
} }
let CurveBuffers { vertices, bezier } = bufs; let CurveBuffers {
vertices,
bezier,
path,
..
} = bufs;
vertices.clear(); vertices.clear();
vertices.extend(points.iter().map(|p| p.pos)); vertices.extend(points.iter().map(|p| p.pos));
let mut path = Vec::new();
let mut start = 0; let mut start = 0;
for i in 0..points.len() { for i in 0..points.len() {
@@ -139,24 +150,29 @@ impl Curve {
let segment_vertices = &vertices[start..i + 1]; let segment_vertices = &vertices[start..i + 1];
let segment_kind = points[start].kind.unwrap_or(PathType::Linear); let segment_kind = points[start].kind.unwrap_or(PathType::Linear);
Self::calculate_subpath(&mut path, segment_vertices, segment_kind, bezier); Self::calculate_subpath(path, segment_vertices, segment_kind, bezier);
// * Start the new segment at the current vertex // * Start the new segment at the current vertex
start = i; start = i;
} }
path.dedup(); path.dedup();
path
} }
fn calculate_length( fn calculate_length(
points: &[PathControlPoint], points: &[PathControlPoint],
path: &mut Vec<Pos2>, bufs: &mut CurveBuffers,
expected_len: Option<f64>, expected_len: Option<f64>,
) -> Vec<f64> { ) {
let CurveBuffers {
path,
lengths: cumulative_len,
..
} = bufs;
cumulative_len.clear();
let mut calculated_len = 0.0; let mut calculated_len = 0.0;
let mut cumulative_len = Vec::with_capacity(path.len()); cumulative_len.reserve(path.len());
cumulative_len.push(0.0); cumulative_len.push(0.0);
let length_iter = path.iter().zip(path.iter().skip(1)).map(|(&curr, &next)| { let length_iter = path.iter().zip(path.iter().skip(1)).map(|(&curr, &next)| {
@@ -178,12 +194,12 @@ impl Curve {
if condition_opt.is_some() { if condition_opt.is_some() {
cumulative_len.push(calculated_len); cumulative_len.push(calculated_len);
return cumulative_len; return;
} }
// Shortcut when it's just (0,0) since there's nothing to do anyway // Shortcut when it's just (0,0) since there's nothing to do anyway
if cumulative_len.len() == 1 { if cumulative_len.len() == 1 {
return cumulative_len; return;
} }
// * The last length is always incorrect // * The last length is always incorrect
@@ -206,7 +222,7 @@ impl Curve {
// * Perhaps negative path lengths should be disallowed altogether // * Perhaps negative path lengths should be disallowed altogether
cumulative_len.push(0.0); cumulative_len.push(0.0);
return cumulative_len; return;
} }
} }
@@ -219,8 +235,6 @@ impl Curve {
path[end_idx] = path[prev_idx] + dir * (expected_len - cumulative_len[prev_idx]) as f32; path[end_idx] = path[prev_idx] + dir * (expected_len - cumulative_len[prev_idx]) as f32;
cumulative_len.push(expected_len); cumulative_len.push(expected_len);
} }
cumulative_len
} }
fn calculate_subpath( fn calculate_subpath(