use crate::math_utils::{reflect}; use crate::types_defined::{Color, HitRecord, Ray, Vec3}; #[derive(Debug)] pub enum MaterialKind { Lambertian(Lambertian), Metal(Metal), } pub trait Material { fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, ray: &mut Ray) -> bool; } #[derive(Debug)] pub struct Lambertian { pub albedo: Color, } impl Clone for Lambertian { fn clone(&self) -> Self { Lambertian { albedo: self.albedo, } } } impl Material for Lambertian { fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool { let scatter_direction = r_in.direction + Vec3::random_unit_on_hemisphere(hit_record.normal); // hit_record.normal + Vec3::random_unit(); // let scatter_direction = reflect(r_in.direction, hit_record.normal); // if near_zero(scatter_direction) { // scattered.direction = r_in.direction; // } *scattered = Ray::new(hit_record.p, scatter_direction); *attenuation = self.albedo.clone(); true } } #[derive(Debug)] pub struct Metal { pub albedo: Color, } impl Clone for Metal { fn clone(&self) -> Self { Metal { albedo: self.albedo, } } } impl Material for Metal { fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool { /* vec3 reflected = reflect(r_in.direction(), rec.normal); scattered = ray(rec.p, reflected); attenuation = albedo; return true; */ let reflected = reflect(r_in.direction, hit_record.normal); *scattered = Ray::new(hit_record.p, reflected); *attenuation = self.albedo.clone(); true } }