use crate::calculus::calculus::{Ray, Vec3}; use crate::common::Color; use crate::object::HitRecord; #[derive(Clone)] pub enum MaterialType { Diffuse, Metal, } pub struct Material { pub material_type: MaterialType, pub albedo: Color, pub fuzz: f32, } impl Material { pub fn new(albedo: Color, material_type: MaterialType, fuzz: f32) -> Self { let fuzz = if fuzz < 1.0 { fuzz } else { 1.0 }; Self { albedo, material_type, fuzz } } pub fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool { scattered.direction = match self.material_type { MaterialType::Diffuse => { let scatter_direction = rec.normal.add(&Vec3::random_unit()); if scatter_direction.is_near_zero() { rec.normal.clone() } else { scatter_direction } } MaterialType::Metal => { let mut reflected = r_in.reflect(&rec.normal); reflected.unit().add(&Vec3::random_unit().scalar_mul(self.fuzz)) } }; scattered.origin = rec.position; attenuation.r = self.albedo.r; attenuation.g = self.albedo.g; attenuation.b = self.albedo.b; true } }