From ca4a3854380ba01b3c316fc13b5dcb310fba1eca Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Fri, 14 Sep 2018 11:33:19 -0700 Subject: [PATCH] Stub cube impl. --- rtiow/src/bin/tracer.rs | 44 +++++++++++++++++++++++++++++++++ rtiow/src/cube.rs | 55 +++++++++++++++++++++++++++++++++++++++++ rtiow/src/lib.rs | 1 + 3 files changed, 100 insertions(+) create mode 100644 rtiow/src/cube.rs diff --git a/rtiow/src/bin/tracer.rs b/rtiow/src/bin/tracer.rs index a7f2224..6eefec5 100644 --- a/rtiow/src/bin/tracer.rs +++ b/rtiow/src/bin/tracer.rs @@ -12,6 +12,7 @@ use rand::Rng; use structopt::StructOpt; use rtiow::camera::Camera; +use rtiow::cube::Cube; use rtiow::hitable::Hit; use rtiow::hitable_list::HitableList; use rtiow::material::Dielectric; @@ -172,10 +173,51 @@ fn build_scene_tutorial(opt: &Opt) -> Scene { } } +fn build_scene_cube(opt: &Opt) -> Scene { + let lookfrom = Vec3::new(3., 3., 2.); + let lookat = Vec3::new(0., 0., 0.); + let dist_to_focus = (lookfrom - lookat).length(); + let aperture = 0.1; + let camera = Camera::new( + lookfrom, + lookat, + Vec3::new(0., 1., 0.), + 45., + opt.width as f32 / opt.height as f32, + aperture, + dist_to_focus, + ); + let world = HitableList::new(vec![ + Box::new(Sphere::new( + Vec3::new(0., 0., -1.), + 0.5, + Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))), + )), + Box::new(Cube::new( + Vec3::new(0., 0., 0.), + 0.5, + Box::new(Lambertian::new(Vec3::new(0.5, 0.2, 0.1))), + )), + Box::new(Sphere::new( + Vec3::new(0., -100.5, -1.), + 100., + Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))), + )), + ]); + Scene { + camera, + world, + subsamples: opt.subsamples, + width: opt.width, + height: opt.height, + } +} + #[derive(Debug)] pub enum Model { Book, Tutorial, + Cube, } #[derive(Debug)] @@ -193,6 +235,7 @@ impl str::FromStr for Model { match s { "book" => Ok(Model::Book), "tutorial" => Ok(Model::Tutorial), + "cube" => Ok(Model::Cube), _ => Err(ModelParseError(s.to_owned())), } } @@ -223,6 +266,7 @@ fn main() -> Result<(), std::io::Error> { let opt = Opt::from_args(); let scene = match opt.model { Model::Book => build_scene_book(&opt), + Model::Cube => build_scene_cube(&opt), Model::Tutorial => build_scene_tutorial(&opt), }; let res = render(scene, &opt.output); diff --git a/rtiow/src/cube.rs b/rtiow/src/cube.rs new file mode 100644 index 0000000..b127e46 --- /dev/null +++ b/rtiow/src/cube.rs @@ -0,0 +1,55 @@ +use hitable::Hit; +use hitable::HitRecord; +use material::Material; +use ray::Ray; +use vec3::dot; +use vec3::Vec3; + +pub struct Cube { + center: Vec3, + length: f32, + material: Box, +} + +impl Cube { + pub fn new(center: Vec3, length: f32, material: Box) -> Cube { + Cube { + center, + length, + material, + } + } +} + +impl Hit for Cube { + fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option { + let oc = r.origin() - self.center; + let a = dot(r.direction(), r.direction()); + let b = dot(oc, r.direction()); + let c = dot(oc, oc) - self.length * self.length; + let discriminant = b * b - a * c; + if discriminant > 0. { + let temp = (-b - (b * b - a * c).sqrt()) / a; + if temp < t_max && temp > t_min { + let point = r.point_at_parameter(temp); + return Some(HitRecord { + t: temp, + p: point, + normal: (point - self.center) / self.length, + material: &*self.material, + }); + } + let temp = (-b + (b * b - a * c).sqrt()) / a; + if temp < t_max && temp > t_min { + let point = r.point_at_parameter(temp); + return Some(HitRecord { + t: temp, + p: point, + normal: (point - self.center) / self.length, + material: &*self.material, + }); + } + } + None + } +} diff --git a/rtiow/src/lib.rs b/rtiow/src/lib.rs index 58db044..d3a55ac 100644 --- a/rtiow/src/lib.rs +++ b/rtiow/src/lib.rs @@ -1,4 +1,5 @@ pub mod camera; +pub mod cube; pub mod hitable; pub mod hitable_list; pub mod material;