From d1bde8a1a8cde0aee953ba5fe3b8c707eb358b57 Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Sun, 4 Jun 2023 09:19:25 -0500 Subject: [PATCH] Spurious crashes - Switching to enums Segfaults and stack overflows. I get overflows when running in either debug or release. Segmentation faults when hooked up to GDB. I think it may be related to the copying of uninitialized trait objects, but I don't know. I've decided the trait-based interface just isn't worth this. I'll rearrange the materials into an Enum and a big match block. --- src/hittable.rs | 7 ++++--- src/main.rs | 6 +++--- src/material.rs | 6 ++---- src/sphere.rs | 14 +++++++------- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/hittable.rs b/src/hittable.rs index 9e88cb6..cdadab6 100644 --- a/src/hittable.rs +++ b/src/hittable.rs @@ -2,16 +2,17 @@ use crate::vec3::Vec3; use crate::ray::Ray; use crate::material::Material; +use std::rc::Rc; -pub struct HitRecord<'a>{ +pub struct HitRecord{ pub p: Vec3, pub normal: Vec3, - pub material: Option<&'a Material>, + pub material: Option>, pub t: f32, pub front_face: bool, } -impl<'a> HitRecord<'a>{ +impl HitRecord{ pub fn set_face_normal(&mut self, r: Ray, outward_normal: Vec3) -> (){ self.front_face = Vec3::dot(r.dir, outward_normal) < 0.0; self.normal = if self.front_face { outward_normal } else { -outward_normal }; diff --git a/src/main.rs b/src/main.rs index 5ecee08..52c9856 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,7 @@ fn main() { (400.0 / aspect_ratio) as i32 ); let samples_per_pixel = 100; - let max_depth = 50; + let max_depth = 100; // world @@ -37,7 +37,7 @@ fn main() { Box::new( Sphere{ center: Vec3{ x: 0.0, y: 0.0, z: -1.0}, - radius: 0.5 + radius: 0.5, material: None, } ) @@ -75,7 +75,7 @@ fn main() { eprintln!("Done!"); } -fn ray_color(r: Ray, world: &HittableList, depth: u32, srng: &mut SmallRng, distrib: Uniform ) -> Vec3 { +fn ray_color(r: Ray, world: &dyn Hittable, depth: u32, srng: &mut SmallRng, distrib: Uniform ) -> Vec3 { // recursion depth guard if depth == 0 { return Vec3::new(0.0, 0.0, 0.0); diff --git a/src/material.rs b/src/material.rs index 6b1db74..d3f0cee 100644 --- a/src/material.rs +++ b/src/material.rs @@ -3,11 +3,9 @@ use crate::ray::Ray; use crate::hittable::HitRecord; use crate::Vec3; -pub struct Material; - -pub Scatter { +pub trait Material { fn scatter( - ray_in: Ray, rec: HitRecord, attenuation: Vec3, scattered: Ray + &self, ray_in: Ray, rec: HitRecord, attenuation: Vec3, scattered: Ray ) -> bool; } diff --git a/src/sphere.rs b/src/sphere.rs index 719f27d..89bff19 100644 --- a/src/sphere.rs +++ b/src/sphere.rs @@ -5,16 +5,17 @@ use crate::hittable::{ HitRecord, }; use crate::material::Material; - use crate::ray::Ray; -pub struct Sphere<'a>{ +use std::rc::Rc; + +pub struct Sphere{ pub center: Vec3, pub radius: f32, - pub material: &'a Material, + pub material: Option>, } -impl<'a> Hittable for Sphere<'a> { +impl Hittable for Sphere { fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option{ let oc = r.orig - self.center; let a = r.dir.length_squared(); @@ -26,7 +27,7 @@ impl<'a> Hittable for Sphere<'a> { return None; } let sqrtd = discriminant.sqrt(); - + // nearest root that lies within tolerance let root = (-half_b - sqrtd) / a; if root < t_min || root > t_max { @@ -35,11 +36,10 @@ impl<'a> Hittable for Sphere<'a> { return None; } } - let mut record = HitRecord{ p: r.at(root), normal: (r.at(root) - self.center) / self.radius, - material: Some(self.material), + material: self.material.clone(), t: root, front_face: false, };