use crate::spectra::dense::DenselySampledSpectrumBuffer; use shared::core::geometry::{Bounds3f, Point3i}; use shared::core::medium::{GridMedium, HGPhaseFunction, HomogeneousMedium, RGBGridMedium}; use shared::core::spectrum::Spectrum; use shared::spectra::{DenselySampledSpectrum, RGBIlluminantSpectrum, RGBUnboundedSpectrum}; use shared::utils::Transform; use shared::utils::containers::SampledGrid; use shared::{Float, core::medium::MajorantGrid}; pub struct MajorantGridHost { pub device: MajorantGrid, voxels: Vec, } impl MajorantGridHost { pub fn new(bounds: Bounds3f, res: Point3i) -> Self { let n = (res.x() * res.y() * res.z()) as usize; let voxels = vec![0.0; n]; let device = MajorantGrid { bounds, res, voxels: std::ptr::null_mut(), n_voxels: n as u32, }; Self { device, voxels } } } pub trait RGBGridMediumCreator { fn new( bounds: &Bounds3f, render_from_medium: &Transform, g: Float, sigma_a_grid: SampledGrid, sigma_s_grid: SampledGrid, sigma_scale: Float, le_grid: SampledGrid, le_scale: Float, ) -> Self; } impl RGBGridMediumCreator for RGBGridMedium { #[allow(clippy::too_many_arguments)] fn new( bounds: &Bounds3f, render_from_medium: &Transform, g: Float, sigma_a_grid: SampledGrid, sigma_s_grid: SampledGrid, sigma_scale: Float, le_grid: SampledGrid, le_scale: Float, ) -> Self { let majorant_grid = MajorantGrid::new(*bounds, Point3i::new(16, 16, 16)); for z in 0..majorant_grid.res.x() { for y in 0..majorant_grid.res.y() { for x in 0..majorant_grid.res.x() { let bounds = majorant_grid.voxel_bounds(x, y, z); let convert = |s: &RGBUnboundedSpectrum| s.max_value(); let max_sigma_t = sigma_a_grid.max_value_convert(bounds, convert) + sigma_s_grid.max_value_convert(bounds, convert); majorant_grid.set(x, y, z, sigma_scale * max_sigma_t); } } } Self { bounds: *bounds, render_from_medium: *render_from_medium, le_grid, le_scale, phase: HGPhaseFunction::new(g), sigma_a_grid, sigma_s_grid, sigma_scale, majorant_grid, } } } pub trait GridMediumCreator { fn new( bounds: &Bounds3f, render_from_medium: &Transform, sigma_a: &Spectrum, sigma_s: &Spectrum, sigma_scale: Float, g: Float, density_grid: SampledGrid, temperature_grid: SampledGrid, le: &Spectrum, le_scale: SampledGrid, ) -> Self; } impl GridMediumCreator for GridMedium { #[allow(clippy::too_many_arguments)] fn new( bounds: &Bounds3f, render_from_medium: &Transform, sigma_a: &Spectrum, sigma_s: &Spectrum, sigma_scale: Float, g: Float, density_grid: SampledGrid, temperature_grid: SampledGrid, le: &Spectrum, le_scale: SampledGrid, ) -> Self { let mut sigma_a_spec = DenselySampledSpectrum::from_spectrum(sigma_a); let mut sigma_s_spec = DenselySampledSpectrum::from_spectrum(sigma_s); let le_spec = DenselySampledSpectrum::from_spectrum(le); sigma_a_spec.scale(sigma_scale); sigma_s_spec.scale(sigma_scale); let mut majorant_grid = MajorantGrid::new(*bounds, Point3i::new(16, 16, 16)); let is_emissive = if temperature_grid.is_some() { true } else { le_spec.max_value() > 0. }; for z in 0..majorant_grid.res.z() { for y in 0..majorant_grid.res.y() { for x in 0..majorant_grid.res.x() { let bounds = majorant_grid.voxel_bounds(x, y, z); majorant_grid.set(x, y, z, density_grid.max_value(bounds)); } } } Self { bounds: *bounds, render_from_medium: *render_from_medium, sigma_a_spec, sigma_s_spec, density_grid, phase: HGPhaseFunction::new(g), temperature_grid, le_spec, le_scale, is_emissive, majorant_grid, } } } pub trait HomogeneousMediumCreator { fn new( sigma_a: Spectrum, sigma_s: Spectrum, sigma_scale: Float, le: Spectrum, le_scale: Float, g: Float, ) -> Self; } impl HomogeneousMediumCreator for HomogeneousMedium { fn new( sigma_a: Spectrum, sigma_s: Spectrum, sigma_scale: Float, le: Spectrum, le_scale: Float, g: Float, ) -> Self { let mut sigma_a_spec = DenselySampledSpectrumBuffer::from_spectrum(&sigma_a); let mut sigma_s_spec = DenselySampledSpectrumBuffer::from_spectrum(&sigma_s); let mut le_spec = DenselySampledSpectrum::from_spectrum(&le); sigma_a_spec.scale(sigma_scale); sigma_s_spec.scale(sigma_scale); le_spec.scale(le_scale); Self { sigma_a_spec, sigma_s_spec, le_spec, phase: HGPhaseFunction::new(g), } } }