use crate::globals::get_options; use shared::Ptr; use shared::bxdfs::DiffuseBxDF; use shared::core::bsdf::BSDF; use shared::core::bssrdf::BSSRDF; use shared::core::bxdf::BxDF; use shared::core::camera::Camera; use shared::core::geometry::Ray; use shared::core::interaction::{MediumInteraction, SimpleInteraction, SurfaceInteraction}; use shared::core::material::{Material, MaterialEvalContext, MaterialTrait}; use shared::core::sampler::{Sampler, SamplerTrait}; use shared::core::texture::UniversalTextureEvaluator; use shared::spectra::SampledWavelengths; pub trait InteractionGetter { fn get_bsdf( &mut self, r: &Ray, lambda: &SampledWavelengths, camera: &Camera, sampler: &mut Sampler, ) -> Option; fn get_bssrdf( &self, _ray: &Ray, lambda: &SampledWavelengths, _camera: &Camera, ) -> Option; } impl InteractionGetter for SurfaceInteraction { fn get_bsdf( &mut self, r: &Ray, lambda: &SampledWavelengths, camera: &Camera, sampler: &mut Sampler, ) -> Option { self.compute_differentials(r, camera, sampler.samples_per_pixel() as i32); let material = { let mut active_mat = unsafe { self.material.as_ref() }; let tex_eval = UniversalTextureEvaluator; while let Material::Mix(mix) = active_mat { let ctx = MaterialEvalContext::from(&*self); active_mat = mix.choose_material(&tex_eval, &ctx)?; } active_mat.clone() }; let ctx = MaterialEvalContext::from(&*self); let tex_eval = UniversalTextureEvaluator; let displacement = material.get_displacement(); let normal_map = material .get_normal_map() .map(Ptr::from) .unwrap_or(Ptr::null()); if !displacement.is_null() || !normal_map.is_null() { self.compute_bump_geom(&tex_eval, displacement, normal_map); } let mut bsdf = material.get_bsdf(&tex_eval, &ctx, lambda); if get_options().force_diffuse { let rho = bsdf.rho_wo(self.common.wo, &[sampler.get1d()], &[sampler.get2d()]); let diff_bxdf = BxDF::Diffuse(DiffuseBxDF::new(rho)); bsdf = BSDF::new(self.shading.n, self.shading.dpdu, Ptr::from(&diff_bxdf)); } Some(bsdf) } fn get_bssrdf( &self, _ray: &Ray, lambda: &SampledWavelengths, _camera: &Camera, ) -> Option { let mut active_mat = unsafe { self.material.as_ref() }; let tex_eval = UniversalTextureEvaluator; while let Material::Mix(mix) = active_mat { let ctx = MaterialEvalContext::from(self); active_mat = mix.choose_material(&tex_eval, &ctx)?; } let material = active_mat.clone(); let ctx = MaterialEvalContext::from(self); material.get_bssrdf(&tex_eval, &ctx, lambda) } } impl InteractionGetter for MediumInteraction { fn get_bsdf( &mut self, _r: &Ray, _lambda: &SampledWavelengths, _camera: &Camera, _sampler: &mut Sampler, ) -> Option { None } fn get_bssrdf( &self, _ray: &Ray, _lambda: &SampledWavelengths, _camera: &Camera, ) -> Option { None } } impl InteractionGetter for SimpleInteraction { fn get_bsdf( &mut self, _r: &Ray, _lambda: &SampledWavelengths, _camera: &Camera, _sampler: &mut Sampler, ) -> Option { None } fn get_bssrdf( &self, _ray: &Ray, _lambda: &SampledWavelengths, _camera: &Camera, ) -> Option { None } }