mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
Merge pull request #1265
This commit is contained in:
@@ -164,7 +164,10 @@ fn wave_warp(ctx: &EffectCtx, mut b: Buf) -> Buf {
|
||||
let kind = ctx.params.e("waveType");
|
||||
let pin = ctx.params.e("pinning");
|
||||
let seed = ctx.seed ^ 0x3a7e;
|
||||
let (dx, dy) = (dir.sin(), -dir.cos());
|
||||
// Cardinal directions must not acquire a tiny perpendicular slope: at a square-wave
|
||||
// boundary cos(90°)'s rounding residue can flip a whole column on CPU but not GPU.
|
||||
let axis = |v: f64| if v.abs() < 4.0 * f64::EPSILON { 0.0 } else { v };
|
||||
let (dx, dy) = (axis(dir.sin()), -axis(dir.cos()));
|
||||
if !ctx.adjustment {
|
||||
b.pad(h.abs().ceil() as u32 + 1);
|
||||
}
|
||||
@@ -556,8 +559,21 @@ mod tests {
|
||||
let (a, b) = (o.img.get(pad, y + pad), im.get(0, y));
|
||||
assert!((0..4).all(|i| (a[i] - b[i]).abs() < 0.01), "row {y}: {a:?} vs {b:?}");
|
||||
}
|
||||
let free = run("ec.distort.wavewarp", &[("direction", num(0.0)), ("height", num(5.0))], im);
|
||||
let free = run("ec.distort.wavewarp", &[("direction", num(0.0)), ("height", num(5.0))], im.clone());
|
||||
assert!(free.img.data.iter().zip(&o.img.data).any(|(a, b)| differs(*a, *b)));
|
||||
// #1181: direction 90° → vertical displacement. Top Edge (4) holds the first row,
|
||||
// Bottom Edge (6) the last, and the rest of the layer still moves.
|
||||
for (pin, edge_row) in [(Value::Enum(4), 0i64), (Value::Enum(6), 29i64)] {
|
||||
let set = [("direction", num(90.0)), ("height", num(5.0)), ("pinning", pin)];
|
||||
let o = run("ec.distort.wavewarp", &set, im.clone());
|
||||
let pad = ((o.img.width - im.width) / 2) as i64;
|
||||
for x in 0..40 {
|
||||
let (a, b) = (o.img.get(x + pad, edge_row + pad), im.get(x, edge_row));
|
||||
assert!((0..4).all(|i| (a[i] - b[i]).abs() < 0.01), "pin {edge_row} col {x}: {a:?} vs {b:?}");
|
||||
}
|
||||
let mid = 15;
|
||||
assert!((0..40).any(|x| differs(o.img.get(x + pad, mid + pad), im.get(x, mid))), "pin {edge_row}: the middle of the layer must still distort");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -111,7 +111,10 @@ fn wave_warp(e: &mut Enc, ctx: &EffectCtx, mut b: GBuf) -> Option<GBuf> {
|
||||
let dir = ctx.params.f("direction").to_radians();
|
||||
let speed = ctx.params.f("speed");
|
||||
let phase = ctx.params.f("phase").to_radians() + ctx.time * speed * TAU;
|
||||
let (dx, dy) = (dir.sin(), -dir.cos());
|
||||
// Cardinal directions must not acquire a tiny perpendicular slope: at a square-wave
|
||||
// boundary cos(90°)'s rounding residue can flip a whole column on CPU but not GPU.
|
||||
let axis = |v: f64| if v.abs() < 4.0 * f64::EPSILON { 0.0 } else { v };
|
||||
let (dx, dy) = (axis(dir.sin()), -axis(dir.cos()));
|
||||
if !ctx.adjustment {
|
||||
b.pad(e, h.abs().ceil() as u32 + 1)?;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,11 @@ fn twirl_bulge_ripple_wave_warp() {
|
||||
effect_case("ec.distort.wavewarp", &[("waveType", e(2)), ("pinning", e(1)), ("phase", n(400.0)), ("speed", n(-2.0))]);
|
||||
effect_case("ec.distort.wavewarp", &[("waveType", e(8)), ("pinning", e(2)), ("height", n(-5.0)), ("direction", n(200.0))]);
|
||||
effect_case("ec.distort.wavewarp", &[("waveType", e(4)), ("pinning", e(7)), ("width", n(33.0))]);
|
||||
// #1181: the single-edge pinning paths, with the default vertical displacement direction.
|
||||
effect_case("ec.distort.wavewarp", &[("direction", n(90.0)), ("height", n(7.0)), ("width", n(25.0)), ("pinning", e(4))]);
|
||||
effect_case("ec.distort.wavewarp", &[("direction", n(90.0)), ("height", n(7.0)), ("width", n(19.0)), ("pinning", e(6)), ("waveType", e(1))]);
|
||||
effect_case("ec.distort.wavewarp", &[("direction", n(45.0)), ("height", n(-6.0)), ("pinning", e(4)), ("speed", n(2.0))]);
|
||||
effect_case("ec.distort.wavewarp", &[("direction", n(45.0)), ("height", n(-6.0)), ("pinning", e(6)), ("speed", n(2.0))]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -79,6 +84,9 @@ fn shape_case(id: &str, vals: &[(&str, Value)]) {
|
||||
fn edge_pinning_on_a_shape_layer() {
|
||||
shape_case("ec.distort.turbulentdisplace", &[("size", n(30.0)), ("amount", n(20.0))]);
|
||||
shape_case("ec.distort.wavewarp", &[("pinning", e(1)), ("height", n(6.0)), ("width", n(25.0))]);
|
||||
// #1181: single-edge pinning over the layer rect, not just All Edges.
|
||||
shape_case("ec.distort.wavewarp", &[("pinning", e(4)), ("direction", n(90.0)), ("height", n(6.0)), ("width", n(25.0))]);
|
||||
shape_case("ec.distort.wavewarp", &[("pinning", e(6)), ("direction", n(90.0)), ("height", n(6.0)), ("width", n(25.0))]);
|
||||
shape_case(
|
||||
"ec.distort.bulge",
|
||||
&[("pinAllEdges", on()), ("height", n(2.0)), ("hradius", n(40.0)), ("vradius", n(30.0)), ("center", Value::Vec2([28.5, 20.5]))],
|
||||
|
||||
Reference in New Issue
Block a user