use ash::vk::Image; use shared::cameras::{Mapping, RealisticCamera, realistic::LensElementInterface}; struct RealisticCameraData { aperture_image: Arc, element_interfaces: Vec, } pub struct RealisticCameraHost { device: RealisticCamera, data: RealisticCameraData, } impl RealisticCameraHost { pub fn new( base: CameraBase, lens_params: &[Float], focus_distance: Float, set_aperture_diameter: Float, aperture_image: Arc, ) -> Self { let film_ptr = base.film; if film_ptr.is_null() { panic!("Camera must have a film"); } let film = &*film_ptr; let aspect = film.full_resolution().x() as Float / film.full_resolution().y() as Float; let diagonal = film.diagonal(); let x = (square(diagonal) / (1.0 + square(diagonal))).sqrt(); let y = x * aspect; let physical_extent = Bounds2f::from_points(Point2f::new(-x / 2., -y / 2.), Point2f::new(x / 2., y / 2.)); let mut element_interface: Vec = Vec::new(); for i in (0..lens_params.len()).step_by(4) { let curvature_radius = lens_params[i] / 1000.0; let thickness = lens_params[i + 1] / 1000.0; let eta = lens_params[i + 2]; let mut aperture_diameter = lens_params[i + 3] / 1000.0; if curvature_radius == 0.0 { aperture_diameter /= 1000.0; if set_aperture_diameter > aperture_diameter { println!("Aperture is larger than possible") } else { aperture_diameter = set_aperture_diameter; } } let el_int = LensElementInterface { curvature_radius, thickness, eta, aperture_radius: aperture_diameter / 2.0, }; element_interface.push(el_int); } let half_diag = film.diagonal() / 2.0; let mut exit_pupil_bounds = [Bounds2f::default(); EXIT_PUPIL_SAMPLES]; for i in 0..EXIT_PUPIL_SAMPLES { let r0 = (i as Float / EXIT_PUPIL_SAMPLES as Float) * half_diag; let r1 = ((i + 1) as Float / EXIT_PUPIL_SAMPLES as Float) * half_diag; exit_pupil_bounds[i] = Self::compute_exit_pupil_bounds(&element_interface, r0, r1); } let n_elements = element_interface.len(); let element_interfaces = element_interface.as_ptr(); std::mem::forget(element_interface); let data = RealisticCameraData { element_interfaces, aperture_image, }; let device = RealisticCamera { base, focus_distance, element_interfaces: Ptr::from(element_interfaces), n_elements, physical_extent, set_aperture_diameter, aperture_image, exit_pupil_bounds, }; Self { device, data } } }