use crate::core::spectrum::SPECTRUM_CACHE; use crate::core::texture::FloatTexture; use crate::spectra::DenselySampledSpectrumBuffer; use crate::utils::{Arena, FileLoc, ParameterDictionary}; use anyhow::{Result, anyhow}; use shared::core::camera::CameraTransform; use shared::core::light::Light; use shared::core::medium::Medium; use shared::core::shape::Shape; use shared::core::spectrum::Spectrum; use shared::lights::*; use shared::spectra::RGBColorSpace; use shared::utils::Transform; use std::sync::Arc; pub fn lookup_spectrum(s: &Spectrum) -> Arc { let cache = &SPECTRUM_CACHE; let dense_spectrum = DenselySampledSpectrumBuffer::from_spectrum(s); cache.lookup(dense_spectrum).into() } pub trait CreateLight { fn create( arena: &mut Arena, render_from_light: Transform, medium: Medium, parameters: &ParameterDictionary, loc: &FileLoc, shape: &Shape, alpha_text: &FloatTexture, colorspace: Option<&RGBColorSpace>, ) -> Result; } pub trait LightFactory { fn create( name: &str, arena: &mut Arena, render_from_light: Transform, medium: Medium, parameters: &ParameterDictionary, loc: &FileLoc, shape: &Shape, alpha_tex: &FloatTexture, colorspace: Option<&RGBColorSpace>, camera_transform: CameraTransform, ) -> Result; } impl LightFactory for Light { fn create( name: &str, arena: &mut Arena, render_from_light: Transform, medium: Medium, parameters: &ParameterDictionary, loc: &FileLoc, shape: &Shape, alpha_tex: &FloatTexture, colorspace: Option<&RGBColorSpace>, camera_transform: CameraTransform, ) -> Result { match name { "diffuse" => DiffuseAreaLight::create( arena, render_from_light, medium, parameters, loc, shape, alpha_tex, colorspace, ), "point" => PointLight::create( arena, render_from_light, medium, parameters, loc, shape, alpha_tex, colorspace, ), "spot" => SpotLight::create( arena, render_from_light, medium, parameters, loc, shape, alpha_tex, colorspace, ), "goniometric" => GoniometricLight::create( arena, render_from_light, medium, parameters, loc, shape, alpha_tex, colorspace, ), "projection" => ProjectionLight::create( arena, render_from_light, medium, parameters, loc, shape, alpha_tex, colorspace, ), "distant" => DistantLight::create( arena, render_from_light, medium, parameters, loc, shape, alpha_tex, colorspace, ), "infinite" => crate::lights::infinite::create( arena, render_from_light, medium.into(), camera_transform, parameters, colorspace, loc, ), _ => Err(anyhow!("{}: unknown light type: \"{}\"", loc, name)), } } }