diff --git a/src/hittable.rs b/src/hittable.rs index 59913e0..982a59f 100644 --- a/src/hittable.rs +++ b/src/hittable.rs @@ -14,6 +14,13 @@ pub struct Sphere { pub mat_ptr: Arc, } +pub struct Triangle { + a: Point3, + b: Point3, + c: Point3, + pub mat_ptr: Arc, +} + pub trait Hittable: Sync + Send { fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool; } @@ -92,3 +99,55 @@ impl Hittable for Sphere { return true; } } + +impl Triangle { + pub fn new(a: Point3, b: Point3, c: Point3, m: Arc) -> Self { + Triangle { + a, + b, + c, + mat_ptr: m, + } + } +} + +impl Hittable for Triangle { + fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool { + let a_to_b = self.b - self.a; + let a_to_c = self.c - self.a; + + let u_vec = Vec3::cross(r.direction(), a_to_c); + + let det = Vec3::dot(a_to_b, u_vec); + + if det < 0.0 { // only positive bound + return false; + } + + let inv_det = 1.0 / det; + + let a_to_origin = r.origin() - self.a; + + let u = Vec3::dot(a_to_origin, u_vec) * inv_det; + + if u < 0.0 || u > 1.0 { //check if outside of triangle + return false; + } + + let v_vec = Vec3::cross(a_to_origin, a_to_b); + + let v = Vec3::dot(r.direction(), v_vec) * inv_det; + + if v < 0.0 || u+v > 1.0 { // intersection outside of triangle + return false; + } + + let dist = Vec3::dot(a_to_c, v_vec) * inv_det; + + if dist > 0.0 { + + } + + return true; + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ef37067..dffb2cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,23 +50,24 @@ fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color { fn random_world() -> HittableList { let mut world = HittableList::new(); - let material_ground = Arc::new(Lambertian::new(&Color::new(0.05, 0.05, 0.05))); - + let material_ground = Arc::new(Lambertian::new(&Color::new(0.05, 0.05,0.05))); world.add(Box::::new(Sphere::new( Point3::new(0.0, -50000.0, 0.0), 50000.0, material_ground.clone(), ))); + (-6..5).into_iter().for_each(|a| { (-6..5).into_iter().for_each(|b| { let choose_mat = utility::random_f64(); + let rad = utility::random_rng(0.1, 0.5); let center = Point3::new( 1.5 * a as f64 + 1.3 * utility::random_f64(), - 0.2, + rad, 1.5 * b as f64 + 1.3 * utility::random_f64(), ); - if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 { + if (center - Point3::new(4.0, rad, 0.0)).length() > 0.9 { if choose_mat < 0.8 { // diffuse let sphere_material = Arc::new(Lambertian::new( @@ -74,7 +75,7 @@ fn random_world() -> HittableList { )); world.add(Box::::new(Sphere::new( center, - 0.2, + rad, sphere_material.clone(), ))); } else if choose_mat < 0.95 { @@ -146,12 +147,12 @@ fn main() { // Image let aspect_ratio = 16.0 / 9.0; - let image_width = 1920; + let image_width = 600; let image_height = (image_width as f64 / aspect_ratio) as u32; - let samples_per_pixel = 200_u32; + let samples_per_pixel = 50_u32; let max_depth = 50; - let vfov = 25.0; + let vfov = 40.0; let lookfrom = Point3::new(10.0, 4.0, 13.0); let lookat = Point3::new(0.0, 0.0, 0.0); let vup = Vec3::new(0.0, 1.0, 0.0);