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,
orig: &'h Beatmap,
repeats: usize,
curve: &Curve,
curve: &Curve<'_>,
edge_sounds: &'h [u8],
) -> Self {
let timing_point = orig.timing_point_at(hit_object.start_time);
+2 -2
View File
@@ -136,7 +136,7 @@ impl Beatmap {
}
struct SliderParams<'c> {
curve: &'c Curve,
curve: &'c Curve<'c>,
duration: u32,
repeats: usize,
start_time: f64,
@@ -144,7 +144,7 @@ struct 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 {
curve,
repeats,
+37 -23
View File
@@ -8,6 +8,8 @@ const CIRCULAR_ARC_TOLERANCE: f32 = 0.1;
#[derive(Clone, Debug, Default)]
pub(crate) struct CurveBuffers {
path: Vec<Pos2>,
lengths: Vec<f64>,
vertices: Vec<Pos2>,
bezier: BezierBuffers,
}
@@ -50,21 +52,24 @@ struct CircularArcProperties {
centre: Pos2,
}
pub(crate) struct Curve {
path: Vec<Pos2>,
lengths: Vec<f64>,
pub(crate) struct Curve<'bufs> {
path: &'bufs [Pos2],
lengths: &'bufs [f64],
}
impl Curve {
impl<'bufs> Curve<'bufs> {
pub(crate) fn new(
points: &[PathControlPoint],
expected_len: Option<f64>,
bufs: &mut CurveBuffers,
bufs: &'bufs mut CurveBuffers,
) -> Self {
let mut path = Self::calculate_path(points, bufs);
let lengths = Self::calculate_length(points, &mut path, expected_len);
Self::calculate_path(points, bufs);
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 {
@@ -117,17 +122,23 @@ impl Curve {
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() {
return Vec::new();
return;
}
let CurveBuffers { vertices, bezier } = bufs;
let CurveBuffers {
vertices,
bezier,
path,
..
} = bufs;
vertices.clear();
vertices.extend(points.iter().map(|p| p.pos));
let mut path = Vec::new();
let mut start = 0;
for i in 0..points.len() {
@@ -139,24 +150,29 @@ impl Curve {
let segment_vertices = &vertices[start..i + 1];
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 = i;
}
path.dedup();
path
}
fn calculate_length(
points: &[PathControlPoint],
path: &mut Vec<Pos2>,
bufs: &mut CurveBuffers,
expected_len: Option<f64>,
) -> Vec<f64> {
) {
let CurveBuffers {
path,
lengths: cumulative_len,
..
} = bufs;
cumulative_len.clear();
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);
let length_iter = path.iter().zip(path.iter().skip(1)).map(|(&curr, &next)| {
@@ -178,12 +194,12 @@ impl Curve {
if condition_opt.is_some() {
cumulative_len.push(calculated_len);
return cumulative_len;
return;
}
// Shortcut when it's just (0,0) since there's nothing to do anyway
if cumulative_len.len() == 1 {
return cumulative_len;
return;
}
// * The last length is always incorrect
@@ -206,7 +222,7 @@ impl Curve {
// * Perhaps negative path lengths should be disallowed altogether
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;
cumulative_len.push(expected_len);
}
cumulative_len
}
fn calculate_subpath(