diff --git a/crates/effects/src/perspective.rs b/crates/effects/src/perspective.rs index 69c63caf9..2aa9fe69d 100644 --- a/crates/effects/src/perspective.rs +++ b/crates/effects/src/perspective.rs @@ -394,7 +394,7 @@ pub fn specs() -> Vec { }; let render = || popup(&["Full", "Outside", "Inside"]); let mut cyl = vec![ - p("radius", "Radius", num(100.0), slider(0.0, 400.0, 0.0, 200.0, 1)), + p("radius", "Radius", num(100.0), slider(0.0, 30000.0, 0.0, 200.0, 1)), p("position", "Position", pt(0.5, 0.5), ParamUi::Point), p("rotation", "Rotation", num(0.0), ParamUi::Angle), p("rotationX", "Rotation X", num(0.0), ParamUi::Angle), @@ -565,6 +565,19 @@ mod tests { assert_eq!(out.get(50 + 18, 10)[3], 0.0); } + /// #3368: Radius takes the range After Effects' CC Cylinder has, up to 30000 %, and a cylinder + /// that large still renders (nearly flat, fully opaque) instead of clamping to 400 %. + #[test] + fn cylinder_radius_goes_up_to_thirty_thousand_percent() { + let spec = find("ec.perspective.cccylinder").unwrap(); + let radius = spec.params.iter().find(|p| p.id == "radius").unwrap(); + assert!(matches!(radius.ui, ParamUi::Slider { min, max, .. } if min == 0.0 && max == 30000.0), "{:?}", radius.ui); + let img = Image::filled(100, 20, [0.5, 0.5, 0.5, 1.0]); + let out = run("ec.perspective.cccylinder", &img, &[("radius", num(30000.0))]).img; + let px = out.get(50 + 40, 10); + assert!(px.iter().all(|v| v.is_finite()) && px[3] > 0.99, "{px:?}"); + } + #[test] fn cylinder_axis_rotations_affect_geometry_and_texture() { let img = Image::filled(100, 100, [0.5, 0.5, 0.5, 1.0]);