Skip to content

Commit

Permalink
add ignore_smoothing
Browse files Browse the repository at this point in the history
  • Loading branch information
khanghugo committed Dec 30, 2024
1 parent bafc8b7 commit 986cf36
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/modules/tas_optimizer/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ impl Optimizer {
Line::RenderYawOverride(_) => (),
Line::PitchOverride(_) => (),
Line::RenderPitchOverride(_) => (),
Line::IgnoreSmoothing => (),
}
}

Expand Down
1 change: 1 addition & 0 deletions src/modules/tas_optimizer/simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl<'a, T: Trace> Iterator for Simulator<'a, T> {
Line::RenderYawOverride(_) => (),
Line::PitchOverride(_) => (),
Line::RenderPitchOverride(_) => (),
Line::IgnoreSmoothing => (),
}

// Advance to the next line for non-frame-bulks.
Expand Down
114 changes: 110 additions & 4 deletions src/modules/tas_studio/editor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use hltas::types::{
use hltas::HLTAS;
use itertools::Itertools;
use thiserror::Error;
use utils::get_ignore_smoothing_frames;

use self::db::{Action, ActionKind, Branch, Db};
use self::operation::{Key, Operation};
Expand Down Expand Up @@ -3512,12 +3513,15 @@ impl Editor {
let yaws = frames.iter().map(|f| f.state.prev_frame_input.yaw);
let pitches = frames.iter().map(|f| f.state.prev_frame_input.pitch);

let ignore_smoothing_frames = get_ignore_smoothing_frames(&self.script(), frames.len());

let smoothed_yaws = smoothed_views(
self.smooth_window_s,
self.smooth_small_window_s,
self.smooth_small_window_multiplier,
&frames[..frames.len()],
yaws,
ignore_smoothing_frames.as_slice(),
);

let smoothed_pitches = smoothed_views(
Expand All @@ -3526,6 +3530,7 @@ impl Editor {
self.smooth_small_window_multiplier,
&frames[..frames.len()],
pitches,
ignore_smoothing_frames.as_slice(),
);

let mut line = "target_yaw_override".to_string();
Expand Down Expand Up @@ -3583,13 +3588,16 @@ impl Editor {
));
}

let ignore_smoothing_frames = get_ignore_smoothing_frames(&self.script(), frames.len());

let yaws = frames.iter().map(|f| f.state.prev_frame_input.yaw);
let mut smoothed_yaws = smoothed_views(
self.smooth_window_s,
self.smooth_small_window_s,
self.smooth_small_window_multiplier,
&frames[start..=end],
yaws,
&ignore_smoothing_frames.as_slice(),
);

// Skip the first frame because it is the initial frame before the start of the TAS.
Expand Down Expand Up @@ -3807,19 +3815,24 @@ impl Editor {
let yaws = branch.frames.iter().map(|f| f.state.prev_frame_input.yaw);
let pitches = branch.frames.iter().map(|f| f.state.prev_frame_input.pitch);

let ignore_smoothing_frames =
get_ignore_smoothing_frames(&smoothed_script, branch.frames.len());

let mut smoothed_yaws = smoothed_views(
self.smooth_window_s,
self.smooth_small_window_s,
self.smooth_small_window_multiplier,
&branch.frames,
yaws,
&ignore_smoothing_frames.as_slice(),
);
let mut smoothed_pitches = smoothed_views(
self.smooth_window_s,
self.smooth_small_window_s,
self.smooth_small_window_multiplier,
&branch.frames,
pitches,
&ignore_smoothing_frames.as_slice(),
);

// First yaw corresponds to the initial frame, which is not controlled by the TAS.
Expand Down Expand Up @@ -4581,10 +4594,11 @@ fn forward(pitch: f32, yaw: f32) -> Vec3 {
}

fn unwrap_angles(xs: impl Iterator<Item = f32>) -> impl Iterator<Item = f32> {
use std::f32::consts::PI;
// does things in f64 to avoid imprecision
use std::f64::consts::PI;

xs.scan((0., 0.), |(prev, offset), curr| {
let mut diff = curr - *prev + *offset;
let mut diff = curr as f64 - *prev as f64 + *offset as f64;
while diff >= PI {
diff -= 2. * PI;
*offset -= 2. * PI;
Expand All @@ -4595,7 +4609,7 @@ fn unwrap_angles(xs: impl Iterator<Item = f32>) -> impl Iterator<Item = f32> {
}

*prev += diff;
Some(*prev)
Some(*prev as f32)
})
}

Expand All @@ -4605,6 +4619,7 @@ fn smoothed_views(
small_window_multiplier: f32,
frames: &[Frame],
views: impl Iterator<Item = f32>,
ignore_smoothing_frames: &[bool],
) -> Vec<f32> {
if frames.is_empty() {
return vec![];
Expand All @@ -4626,6 +4641,11 @@ fn smoothed_views(
// The smoothing window is centered at the center of each yaw.
// For pitch smoothing, every frame has both pitch and yaw so iterate over this is ok.
for i in 0..unwrapped.len() {
if ignore_smoothing_frames[i] {
rv.push(unwrapped[i]);
continue;
}

let mut total_view = 0.;
let mut total_weight = 0.;

Expand Down Expand Up @@ -4950,6 +4970,7 @@ mod tests {
input: impl IntoIterator<Item = (f32, f32)>,
small_window_size: f32,
expect: Expect,
ignore_smoothing_frames: &[bool],
) {
let frames: Vec<Frame> = input
.into_iter()
Expand All @@ -4969,7 +4990,14 @@ mod tests {
.collect();

let yaws = frames.iter().map(|f| f.state.prev_frame_input.yaw);
let smoothed = smoothed_views(1., small_window_size, 4., &frames, yaws);
let smoothed = smoothed_views(
1.,
small_window_size,
4.,
&frames,
yaws,
ignore_smoothing_frames,
);
expect.assert_debug_eq(&smoothed);
}

Expand All @@ -4985,6 +5013,7 @@ mod tests {
2.0,
]
"#]],
vec![false; 3].as_slice(),
);
}

Expand All @@ -5008,6 +5037,7 @@ mod tests {
-0.75,
]
"#]],
vec![false; 5].as_slice(),
);
}

Expand All @@ -5031,6 +5061,7 @@ mod tests {
-0.75,
]
"#]],
vec![false; 5].as_slice(),
);
}

Expand All @@ -5054,6 +5085,7 @@ mod tests {
-0.9,
]
"#]],
vec![false; 5].as_slice(),
);
}

Expand All @@ -5079,6 +5111,7 @@ mod tests {
-0.9,
]
"#]],
vec![false; 6].as_slice(),
);
}

Expand All @@ -5102,6 +5135,79 @@ mod tests {
-0.9,
]
"#]],
vec![false; 5].as_slice(),
);
}

#[test]
fn test_smoothing_ignore1() {
check_smoothing(
[
(0.25, -1.),
(0.25, -1.),
(0.4, 1.),
(0.25, -1.),
(0.25, -1.),
],
0.5,
expect![[r#"
[
-1.0,
-0.4,
0.28000003,
-0.4,
-0.9,
]
"#]],
&[true, false, false, false, false],
);
}

#[test]
fn test_smoothing_ignore2() {
check_smoothing(
[
(0.25, -1.),
(0.25, -1.),
(0.4, 1.),
(0.25, -1.),
(0.25, -1.),
],
0.5,
expect![[r#"
[
-1.0,
-0.4,
0.28000003,
-0.4,
-1.0,
]
"#]],
&[true, false, false, false, true],
);
}

#[test]
fn test_smoothing_ignore3() {
check_smoothing(
[
(0.25, -1.),
(0.25, -1.),
(0.4, 1.),
(0.25, -1.),
(0.25, -1.),
],
0.5,
expect![[r#"
[
-1.0,
-0.4,
1.0,
-0.4,
-1.0,
]
"#]],
&[true, false, true, false, true],
);
}

Expand Down
43 changes: 43 additions & 0 deletions src/modules/tas_studio/editor/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::iter;
use std::num::NonZeroU32;
use std::ops::Range;

use hltas::types::{AutoMovement, FrameBulk, Line, StrafeDir, StrafeSettings, StrafeType};
use hltas::HLTAS;
Expand Down Expand Up @@ -304,3 +305,45 @@ pub fn join_lines(prev: &mut Line, next: &Line) {

prev_bulk.frame_count = NonZeroU32::new(temp.get() + next_bulk.frame_count.get()).unwrap();
}

pub fn get_ignore_smoothing_frames(hltas: &HLTAS, frame_count: usize) -> Vec<bool> {
let line_first_frame_iter = line_first_frame_idx_and_frame_count(hltas).collect::<Vec<usize>>();

let mut numbers = vec![];
let mut get_next = false;

for (idx, line) in hltas.lines.iter().enumerate() {
// if matches `ignore_smoothing`, takes the immediate line or at the least calculate
// its affecting frame bulk
if matches!(line, Line::IgnoreSmoothing) && !get_next {
get_next = true;
numbers.push(idx);
continue;
}

// taking a framebulk immediately after `ignore_smoothing`
if matches!(line, Line::FrameBulk(_)) && get_next {
get_next = false;
numbers.push(idx);
continue;
}
}

let ranges = numbers
// by the end of this, we have
// is line idx -> framebulk idx -> is line idx -> framebulk idx
.chunks(2)
// chunking by 2 will have us range of (start..end) based on line idx and bulk idx
.map(|arr| {
// .nth `line_first_frame_iter` to get the actual frame number
// need to add 1 always to the line number just because
(line_first_frame_iter[arr[0] + 1])..(line_first_frame_iter[arr[1] + 1])
})
.collect::<Vec<Range<usize>>>();

let contains = |idx| ranges.iter().any(|range| range.contains(&idx));

(0..frame_count)
.map(|frame_idx| if contains(frame_idx) { true } else { false })
.collect::<Vec<bool>>()
}

0 comments on commit 986cf36

Please sign in to comment.