Timewarp: hold Block Size to its declared range and the matching window to a cap

This commit is contained in:
Dylan M. Taylor
2026-11-03 18:38:08 +00:00
parent b7dee07cf4
commit d0469f9fdf
2 changed files with 11 additions and 2 deletions
+2 -1
View File
@@ -552,7 +552,8 @@ impl PixelMotion {
let px = |id: &str| (g(id, 0.0).max(0.0) * scale).round() as u32;
PixelMotion {
tile,
window: ((g("tuning/blockSize", 8.0).max(4.0)) * scale).round().max(4.0) as u32,
// Block Size is declared 4..64; a project can store any number.
window: ((g("tuning/blockSize", 8.0).clamp(4.0, 64.0)) * scale).round().max(4.0) as u32,
global_smoothness: g("tuning/smoothing/globalSmoothness", 0.5).clamp(0.0, 1.0) as f32,
local_smoothness: g("tuning/smoothing/localSmoothness", 0.5).clamp(0.0, 1.0) as f32,
iterations: g("tuning/smoothing/smoothingIterations", 20.0).clamp(0.0, 200.0) as u32,
+9 -1
View File
@@ -103,7 +103,8 @@ pub fn block_flow(a: &Image, b: &Image, block: u32, radius: i32) -> Flow {
/// (Timewarp's Vector Detail and Block Size).
pub fn block_flow_window(a: &Image, b: &Image, tile: u32, window: u32, radius: i32) -> Flow {
let bs = tile.max(2) as usize;
let win = window.max(4) as i64;
// The matching cost per vector grows with the window's area; 512 is far above any block size the effects offer.
let win = i64::from(window.clamp(4, 512));
// Window origin relative to the tile origin.
let wo = bs as i64 / 2 - win / 2;
let (w, h) = (a.width as usize, a.height as usize);
@@ -280,6 +281,13 @@ mod tests {
s / n as f32
}
#[test]
fn a_huge_matching_window_is_held_to_the_cap() {
let (a, b) = (texture(520, 520, 0.0), texture(520, 520, 2.0));
let capped = block_flow_window(&a, &b, 260, 512, 2);
assert_eq!(block_flow_window(&a, &b, 260, u32::MAX, 2).v, capped.v);
}
#[test]
fn flow_finds_translation() {
let a = texture(128, 96, 0.0);