From ff625f576fefcbfd62dace5d75aadaff437d8f28 Mon Sep 17 00:00:00 2001 From: bijan2005 Date: Mon, 30 Nov 2020 09:41:15 -0500 Subject: [PATCH] Add generic trait Surface --- src/main.rs | 5 ++--- src/object.rs | 25 ++++++++----------------- src/object/base.rs | 14 ++++++++++++++ src/object/plane.rs | 11 +++++++---- src/object/sphere.rs | 17 +++++++++-------- 5 files changed, 40 insertions(+), 32 deletions(-) create mode 100644 src/object/base.rs diff --git a/src/main.rs b/src/main.rs index 8bdd402..e2fe974 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,11 +52,10 @@ fn render(camera: &Camera, scene: &Scene, filename: &str) -> std::io::Result<()> fn main() -> std::io::Result<()> { - let camera = Camera::new(Point3::new(0.0,0.0,0.0), Vector3::new(0.0,0.0,-1.0), 1.0, 2.0, 2.0, 400, 400); + let camera = Camera::new(Point3::new(0.0,0.0,0.0), Vector3::new(0.0,0.0,-1.0), 1.0, 2.0, 2.0, 500, 500); let scene = vec![ - Object::Sphere(Sphere::new_solid(0.0,0.0,-5.0,2.0, Color::white())), - Object::Sphere(Sphere::new_solid(-3.0,0.0,-8.0,2.5, Color::white())) + Object::new(Sphere::new(0.0,0.0,-3.0,2.0, |x, y| Color::new(x, 0.0, y * 2.0))) ]; render(&camera, &scene, "out.ppm") diff --git a/src/object.rs b/src/object.rs index 9be2ca6..6b7d272 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,4 +1,5 @@ +mod base; pub use base::*; mod sphere; pub use sphere::*; mod plane; pub use plane::*; mod triangle; pub use triangle::*; @@ -7,28 +8,18 @@ use na::*; use crate::types::*; -pub enum Object { - Sphere(Sphere) +pub struct Object { + pub surface: Box } impl Object { - pub fn intersect(&self, ray: Ray) -> Option { - match *self { - Object::Sphere(ref sphere) => sphere.intersect(ray) - } + pub fn new(surface: S) -> Self { + Object { surface: Box::new(surface) } } - pub fn getcolor(&self, point: Point3) -> Color { - match *self { - Object::Sphere(ref sphere) => sphere.getcolor(point) - } - } - - pub fn normal(&self, point: Point3) -> Unit> { - match *self { - Object::Sphere(ref sphere) => sphere.normal(point) - } - } + pub fn intersect(&self, ray: Ray) -> Option { self.surface.intersect(ray) } + pub fn normal(&self, point: Point3) -> Unit> { self.surface.normal(point) } + pub fn getcolor(&self, point: Point3) -> Color { self.surface.getcolor(point) } } pub type Scene = Vec; diff --git a/src/object/base.rs b/src/object/base.rs new file mode 100644 index 0000000..c8489ce --- /dev/null +++ b/src/object/base.rs @@ -0,0 +1,14 @@ +extern crate nalgebra as na; + +use na::*; +use na::geometry::Point3; + +use crate::types::*; + +pub trait Surface { + fn intersect(&self, ray: Ray) -> Option; + + fn normal(&self, point: Point3) -> Unit>; + + fn getcolor(&self, point: Point3) -> Color; +} diff --git a/src/object/plane.rs b/src/object/plane.rs index 8e50e51..a32a039 100644 --- a/src/object/plane.rs +++ b/src/object/plane.rs @@ -4,6 +4,7 @@ use na::*; use na::geometry::Point3; use crate::types::*; +use super::base::*; pub struct Plane { pub center: Point3, @@ -25,8 +26,10 @@ impl Plane { pub fn new_solid(center: Point3, normal: Vector3, color: Color) -> Self { Plane::new(center, normal, move |_, _| color) } +} - pub fn intersect(&self, ray: Ray) -> Option { +impl Surface for Plane { + fn intersect(&self, ray: Ray) -> Option { let d = self.normal.dot(&ray.direction); if d < 1e-6 { return None; } @@ -37,9 +40,9 @@ impl Plane { else { None } } - pub fn getcolor(&self, point: Point3) -> Color { + fn normal(&self, _point: Point3) -> Unit> { self.normal } + + fn getcolor(&self, point: Point3) -> Color { unimplemented!() } - - pub fn normal(&self, point: Point3) -> Unit> { self.normal } } diff --git a/src/object/sphere.rs b/src/object/sphere.rs index 42e19fe..b91848d 100644 --- a/src/object/sphere.rs +++ b/src/object/sphere.rs @@ -6,6 +6,7 @@ use na::*; use na::geometry::Point3; use crate::types::*; +use super::base::*; pub struct Sphere { pub center: Point3, @@ -27,10 +28,10 @@ impl Sphere { pub fn new_solid(x: f32, y: f32, z: f32, radius: f32, color: Color) -> Self { Sphere::new(x, y, z, radius, move |_, _| color) } +} - // Determines if a ray intersects the circle. - // If so, returns the distance to the intersection point. - pub fn intersect(&self, ray: Ray) -> Option { +impl Surface for Sphere { + fn intersect(&self, ray: Ray) -> Option { fn solve_quadratic(a: f32, b: f32, c: f32) -> Option<(f32, f32)> { let discr = b * b - 4.0 * a * c; @@ -58,7 +59,11 @@ impl Sphere { else { None } } - pub fn getcolor(&self, point: Point3) -> Color { + fn normal(&self, point: Point3) -> Unit> { + Unit::new_normalize(point - self.center) + } + + fn getcolor(&self, point: Point3) -> Color { let normal = self.normal(point); // In this particular case, the normal is simular to a point on a unit sphere @@ -71,8 +76,4 @@ impl Sphere { (*self.texture)(x, y) } - - pub fn normal(&self, point: Point3) -> Unit> { - Unit::new_normalize(point - self.center) - } }