use ecs::Component; use crate::color::Color; use crate::texture::Id as TextureId; #[derive(Debug, Clone, Component)] pub struct Material { ambient: Option>, diffuse: Option>, specular: Option>, ambient_map: TextureId, diffuse_map: TextureId, specular_map: TextureId, shininess: f32, } impl Material { #[must_use] pub fn ambient(&self) -> Option<&Color> { self.ambient.as_ref() } #[must_use] pub fn diffuse(&self) -> Option<&Color> { self.diffuse.as_ref() } #[must_use] pub fn specular(&self) -> Option<&Color> { self.specular.as_ref() } #[must_use] pub fn ambient_map(&self) -> &TextureId { &self.ambient_map } #[must_use] pub fn diffuse_map(&self) -> &TextureId { &self.diffuse_map } #[must_use] pub fn specular_map(&self) -> &TextureId { &self.specular_map } #[must_use] pub fn shininess(&self) -> f32 { self.shininess } } /// [`Material`] builder. #[derive(Debug, Clone)] pub struct Builder { ambient: Option>, diffuse: Option>, specular: Option>, ambient_map: Option, diffuse_map: Option, specular_map: Option, shininess: f32, } impl Builder { #[must_use] pub fn new() -> Self { Self { ambient: None, diffuse: None, specular: None, ambient_map: None, diffuse_map: None, specular_map: None, shininess: 32.0, } } #[must_use] pub fn ambient(mut self, ambient: Color) -> Self { self.ambient = Some(ambient); self } #[must_use] pub fn diffuse(mut self, diffuse: Color) -> Self { self.diffuse = Some(diffuse); self } #[must_use] pub fn specular(mut self, specular: Color) -> Self { self.specular = Some(specular); self } #[must_use] pub fn ambient_map(mut self, ambient_map: TextureId) -> Self { self.ambient_map = Some(ambient_map); self } #[must_use] pub fn diffuse_map(mut self, diffuse_map: TextureId) -> Self { self.diffuse_map = Some(diffuse_map); self } #[must_use] pub fn specular_map(mut self, specular_map: TextureId) -> Self { self.specular_map = Some(specular_map); self } #[must_use] pub fn shininess(mut self, shininess: f32) -> Self { self.shininess = shininess; self } /// Builds a new [`Material`]. /// /// # Panics /// Will panic if no ambient map, diffuse map or specular map is set. #[must_use] pub fn build(&self) -> Material { Material { ambient: self.ambient.clone(), diffuse: self.diffuse.clone(), specular: self.specular.clone(), ambient_map: self.ambient_map.unwrap(), diffuse_map: self.diffuse_map.unwrap(), specular_map: self.specular_map.unwrap(), shininess: self.shininess, } } } impl Default for Builder { fn default() -> Self { Self::new() } }