use std::sync::Arc; use crate::{Aabb, Color, Material, Ray, Vec3}; use crate::hittable::{HitRecord, Hittable}; use crate::isotropic::Isotropic; use crate::texture::Texture; /* #[derive(Clone, Copy)] pub struct HitRecord<'material> { pub point: Point3, pub normal: Vec3, pub t: f64, pub u: f64, pub v: f64, pub front_face: bool, pub material: &'material Arc } */ pub struct ConstantMedium { boundary: H, phase_function: Arc, neg_inv_density: f64 } impl ConstantMedium { pub fn new(boundary: H, phase_function: Arc, density: f64) -> Self { Self { boundary, phase_function, neg_inv_density: -1.0 / density } } pub fn textured(boundary: H, texture: Arc, density: f64) -> Self { Self { boundary, phase_function: Arc::new(Material::Isotropic(Isotropic::from(texture))), neg_inv_density: -1.0 / density } } pub fn colored(boundary: H, color: Color, density: f64) -> Self { Self { boundary, phase_function: Arc::new(Material::Isotropic(Isotropic::from(color))), neg_inv_density: -1.0 / density } } } implHittable for ConstantMedium{ fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option { let rec1 = self.boundary.hit(ray, f64::NEG_INFINITY, f64::INFINITY); if rec1.is_none() { return None; } let mut rec1 = rec1.unwrap(); let rec2 = self.boundary.hit(ray, rec1.t+0.0001, f64::INFINITY); if rec2.is_none() { return None; } let mut rec2 = rec2.unwrap(); if rec1.t < t_min { rec1.t = t_min; } if rec2.t > t_max { rec2.t = t_max; } if rec1.t > rec2.t { return None; } if rec1.t < t_min { rec1.t = 0.0; } let ray_length = ray.direction().length(); let distance_inside_boundary = (rec2.t - rec1.t) * ray_length; let hit_distance = self.neg_inv_density * rand::random::().ln(); if hit_distance > distance_inside_boundary { return None; } let t = rec1.t + hit_distance / ray_length; Some(HitRecord { point: ray.at(t), normal: Vec3::new(1.0, 0.0, 0.0), // arbitrary t, u: 0.0, v: 0.0, front_face: true, // also arbitrary material: &self.phase_function }) } fn bounding_box(&self, time0: f64, time1: f64) -> Option { self.boundary.bounding_box(time0, time1) } }