Skip to content

Commit

Permalink
solve #2 by throwing in random lifetimes 💀
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy5909 committed May 1, 2024
1 parent adfdaef commit 02c2c00
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 46 deletions.
19 changes: 12 additions & 7 deletions src/hittable.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
use crate::{interval::Interval, material::EMaterial, ray::Ray, vec3::{dot, Point3, Vec3}};
use crate::{interval::Interval, material::{DefaultMaterial, Material}, ray::Ray, vec3::{dot, Point3, Vec3}};

#[derive(Clone, Default)]
pub struct HitRecord {
#[derive(Clone)]
pub struct HitRecord<'a> {
pub p: Point3,
pub normal: Vec3,
pub mat: Box<EMaterial>,
pub mat: &'a (dyn Material),
pub t: f64,
pub front_face: bool,
}
impl HitRecord {
impl<'a> Default for HitRecord<'a> {
fn default() -> Self {
Self { p: Default::default(), normal: Default::default(), mat: &DefaultMaterial, t: Default::default(), front_face: Default::default() }
}
}
impl<'a> HitRecord<'a> {
pub fn set_face_normal(&mut self, r: &Ray, outward_normal: &Vec3) {
self.front_face = dot(*r.dir(), *outward_normal) < 0.0;
self.normal = if self.front_face {*outward_normal} else {-*outward_normal}
}
}

pub trait Hittable {
fn hit(&self, r: &Ray, ray_t: Interval, rec: &mut HitRecord) -> bool;
pub trait Hittable<'a> {
fn hit(&self, r: &Ray, ray_t: Interval, rec: &mut HitRecord<'a>) -> bool;
}
8 changes: 4 additions & 4 deletions src/hittable_list.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use crate::{hittable::{HitRecord, Hittable}, interval::Interval};

pub struct HittableList<'a> {
objects: Vec<&'a dyn Hittable>,
objects: Vec<&'a dyn Hittable<'a>>,
}
impl<'a> HittableList<'a> {
pub fn new() -> Self {
HittableList{objects: Vec::new()}
}
pub fn add(&mut self, object: &'a dyn Hittable) {
pub fn add(&mut self, object: &'a dyn Hittable<'a>) {
self.objects.push(object);
}
}
impl<'a> Hittable for HittableList<'a> {
fn hit(&self, r: &crate::ray::Ray, ray_t: Interval, rec: &mut HitRecord) -> bool {
impl<'a> Hittable<'a> for HittableList<'a> {
fn hit(&self, r: &crate::ray::Ray, ray_t: Interval, rec: &mut HitRecord<'a>) -> bool {
let mut temp_rec = HitRecord::default();
let mut hit_anything = false;
let mut closest_so_far = ray_t.max;
Expand Down
16 changes: 8 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ mod camera;
mod material;

fn main() {
let ground = material::EMaterial::Lambertian(Lambertian {albedo: Color::new(0.8,0.8,0.0)});
let center = material::EMaterial::Lambertian(Lambertian {albedo: Color::new(0.1, 0.2, 0.5)});
let left = material::EMaterial::Metal(Metal {albedo: Color::new(0.8, 0.8, 0.8)});
let right = material::EMaterial::Metal(Metal {albedo: Color::new(0.8, 0.6, 0.2)});
let ground = Lambertian {albedo: Color::new(0.8,0.8,0.0)};
let center = Lambertian {albedo: Color::new(0.1, 0.2, 0.5)};
let left = Metal {albedo: Color::new(0.8, 0.8, 0.8)};
let right = Metal {albedo: Color::new(0.8, 0.6, 0.2)};

let mut world = HittableList::new();

let ground = Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0, Box::new(ground));
let center = Sphere::new(Point3::new(0.0, 0.0, -1.2), 0.5, Box::new(center));
let left = Sphere::new(Point3::new(-1.0, 0.0, -1.0), 0.5, Box::new(left));
let right = Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, Box::new(right));
let ground = Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0, &ground);
let center = Sphere::new(Point3::new(0.0, 0.0, -1.2), 0.5, &center);
let left = Sphere::new(Point3::new(-1.0, 0.0, -1.0), 0.5, &left);
let right = Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &right);

world.add(&ground);
world.add(&center);
Expand Down
27 changes: 7 additions & 20 deletions src/material.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
use crate::{color::Color, hittable::HitRecord, ray::Ray, vec3::{random_unit_vector, reflect}};

#[derive(Clone, Copy, Default)]
pub enum EMaterial {
Lambertian(Lambertian),
Metal(Metal),
#[default]
DefaultMaterial
}

impl Material for EMaterial {
fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
match self {
EMaterial::Lambertian(mat) => mat.scatter(r_in, rec, attenuation, scattered),
EMaterial::Metal(mat) => mat.scatter(r_in, rec, attenuation, scattered),
EMaterial::DefaultMaterial => false,
// Implement scatter method for other variants
}
}
}
pub trait Material {
fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool;
}
#[derive(Default, Clone, Copy)]
pub struct DefaultMaterial;
impl Material for DefaultMaterial {
fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
false
}
}

pub struct Lambertian { pub albedo: Color }
impl Material for Lambertian {
fn scatter(&self, _r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
Expand All @@ -38,7 +26,6 @@ impl Material for Lambertian {
}
}

#[derive(Default, Clone, Copy)]
pub struct Metal { pub albedo: Color }
impl Material for Metal {
fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
Expand Down
14 changes: 7 additions & 7 deletions src/sphere.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use crate::{hittable::{HitRecord, Hittable}, interval::Interval, material::EMaterial, vec3::{dot, Point3}};
use crate::{hittable::{HitRecord, Hittable}, interval::Interval, material::Material, vec3::{dot, Point3}};

pub struct Sphere {
pub struct Sphere<'a> {
center: Point3,
radius: f64,
mat: Box<EMaterial>
mat: &'a dyn Material,
}
impl Sphere {
pub fn new(center: Point3, radius: f64, mat: Box<EMaterial>) -> Self {
impl<'a> Sphere<'a> {
pub fn new(center: Point3, radius: f64, mat: &'a dyn Material) -> Self {
Sphere {center, radius, mat}
}
}
impl Hittable for Sphere {
fn hit(&self, r: &crate::ray::Ray, ray_t: Interval, rec: &mut HitRecord) -> bool {
impl<'a> Hittable<'a> for Sphere<'a> {
fn hit(&self, r: &crate::ray::Ray, ray_t: Interval, rec: &mut HitRecord<'a>) -> bool {
let oc = self.center - *r.origin();
let a = r.dir().length_squared();
let h = dot(*r.dir(), oc);
Expand Down

0 comments on commit 02c2c00

Please sign in to comment.