use crate::Arena; use crate::core::image::HostImage; use crate::utils::TextureParameterDictionary; use crate::utils::error::FileLoc; use anyhow::{Result, anyhow}; use shared::core::material::Material; use shared::materials::*; use std::collections::HashMap; use std::sync::Arc; pub trait CreateMaterial: Sized { fn create( parameters: &TextureParameterDictionary, normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, arena: &Arena, ) -> Result; } pub trait MaterialFactory { fn create( name: &str, params: &TextureParameterDictionary, normal_map: Option>, named_materials: &HashMap, loc: FileLoc, arena: &Arena, ) -> Result where Self: Sized; } impl MaterialFactory for Material { fn create( name: &str, parameters: &TextureParameterDictionary, normal_map: Option>, named_materials: &HashMap, loc: FileLoc, arena: &Arena, ) -> Result where Self: Sized, { match name { "diffuse" => { DiffuseMaterial::create(parameters, normal_map, named_materials, &loc, arena) } "coateddiffuse" => { CoatedDiffuseMaterial::create(parameters, normal_map, named_materials, &loc, arena) } "coatedconductor" => CoatedConductorMaterial::create( parameters, normal_map, named_materials, &loc, arena, ), "diffusetransmission" => DiffuseTransmissionMaterial::create( parameters, normal_map, named_materials, &loc, arena, ), "dielectric" => { DielectricMaterial::create(parameters, normal_map, named_materials, &loc, arena) } "thindielectric" => { ThinDielectricMaterial::create(parameters, normal_map, named_materials, &loc, arena) } "hair" => HairMaterial::create(parameters, normal_map, named_materials, &loc, arena), "conductor" => { ConductorMaterial::create(parameters, normal_map, named_materials, &loc, arena) } "measured" => { MeasuredMaterial::create(parameters, normal_map, named_materials, &loc, arena) } "subsurface" => { SubsurfaceMaterial::create(parameters, normal_map, named_materials, &loc, arena) } "mix" => MixMaterial::create(parameters, normal_map, named_materials, &loc, arena), _ => Err(anyhow!("Material type '{}' unknown at {}", name, &loc)), } } } pub fn default_diffuse_material(arena: &Arena) -> Material { use shared::core::texture::GPUSpectrumTexture; use shared::core::texture::SpectrumConstantTexture; use shared::core::spectrum::{ConstantSpectrum, Spectrum}; use shared::materials::DiffuseMaterial; use shared::utils::Ptr; let grey = Spectrum::Constant(ConstantSpectrum { c: 0.5 }); let tex = GPUSpectrumTexture::Constant(SpectrumConstantTexture::new(grey)); let tex_ptr = arena.alloc(tex); Material::Diffuse(DiffuseMaterial { normal_map: Ptr::null(), displacement: Ptr::null(), reflectance: tex_ptr, }) }