Timewarp: hold Block Size to its declared range and the matching window to a cap (#3024)

This commit is contained in:
Dylan M. Taylor authored and GitHub committed 2026-11-10 18:00:27 -05:00
1 parent 8d46e1df7f
commit e2afb4b17c
2 files changed
+11 -2

No files matched your search

+2 -1
View File
@@ -565,7 +565,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
@@ -118,7 +118,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);
@@ -295,6 +296,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);