use crate::core::filter::CreateFilterSampler; use shared::Float; use shared::core::filter::FilterSampler; use shared::core::geometry::{Point2f, Vector2f}; use shared::filters::MitchellFilter; #[derive(Clone, Debug, Device)] #[device(name = "MitchellFilter")] pub struct MitchellFilterHost { pub radius: Vector2f, pub b: Float, pub c: Float, #[device(flatten)] pub sampler: FilterSampler, } impl MitchellFilterHost { pub fn new(radius: Vector2f, b: Float, c: Float) -> Self { let sampler = FilterSampler::new(radius, move |p: Point2f| { mitchell_1d(p.x() / radius.x(), b, c) * mitchell_1d(p.y() / radius.y(), b, c) }); Self { radius, b, c, sampler } } } fn mitchell_1d(x: Float, b: Float, c: Float) -> Float { let x = (2.0 * x).abs(); if x <= 1.0 { ((12.0 - 9.0 * b - 6.0 * c) * x * x * x + (-18.0 + 12.0 * b + 6.0 * c) * x * x + (6.0 - 2.0 * b)) / 6.0 } else if x <= 2.0 { ((-b - 6.0 * c) * x * x * x + (6.0 * b + 30.0 * c) * x * x + (-12.0 * b - 48.0 * c) * x + (8.0 * b + 24.0 * c)) / 6.0 } else { 0.0 } }