Add --model flag to select model to render.

This commit is contained in:
Bill Thiede 2018-09-13 21:35:39 -07:00
parent 802b4f69a8
commit 919fa5f8d5

View File

@ -3,7 +3,9 @@ extern crate rtiow;
#[macro_use]
extern crate structopt;
use std::fmt;
use std::path::PathBuf;
use std::str;
use std::time::Instant;
use rand::Rng;
@ -91,66 +93,21 @@ fn random_scene() -> Vec<Box<Hit>> {
objects
}
fn build_scene(opt: &Opt) -> Scene {
let (camera, world) = if BOOK_COVER {
let lookfrom = Vec3::new(13., 2., 3.);
let lookat = Vec3::new(0., 0., 0.);
let dist_to_focus = 10.;
let aperture = 0.1;
let cam = Camera::new(
lookfrom,
lookat,
Vec3::new(0., 1., 0.),
20.,
opt.width as f32 / opt.height as f32,
aperture,
dist_to_focus,
);
let world = HitableList::new(random_scene());
(cam, world)
} else {
let lookfrom = Vec3::new(3., 3., 2.);
let lookat = Vec3::new(0., 0., -1.);
let dist_to_focus = (lookfrom - lookat).length();
let aperture = 2.;
let cam = Camera::new(
lookfrom,
lookat,
Vec3::new(0., 1., 0.),
20.,
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(Sphere::new(
Vec3::new(0., -100.5, -1.),
100.,
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.))),
)),
Box::new(Sphere::new(
Vec3::new(1., 0., -1.),
0.5,
Box::new(Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2)),
)),
Box::new(Sphere::new(
Vec3::new(-1., 0., -1.),
0.5,
Box::new(Dielectric::new(1.5)),
)),
Box::new(Sphere::new(
Vec3::new(-1., 0., -1.),
-0.45,
Box::new(Dielectric::new(1.5)),
)),
]);
(cam, world)
};
fn build_scene_book(opt: &Opt) -> Scene {
let lookfrom = Vec3::new(13., 2., 3.);
let lookat = Vec3::new(0., 0., 0.);
let dist_to_focus = 10.;
let aperture = 0.1;
let camera = Camera::new(
lookfrom,
lookat,
Vec3::new(0., 1., 0.),
20.,
opt.width as f32 / opt.height as f32,
aperture,
dist_to_focus,
);
let world = HitableList::new(random_scene());
Scene {
camera,
world,
@ -160,8 +117,84 @@ fn build_scene(opt: &Opt) -> Scene {
}
}
fn build_scene_tutorial(opt: &Opt) -> Scene {
let lookfrom = Vec3::new(3., 3., 2.);
let lookat = Vec3::new(0., 0., -1.);
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(Sphere::new(
Vec3::new(0., -100.5, -1.),
100.,
Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.))),
)),
Box::new(Sphere::new(
Vec3::new(1., 0., -1.),
0.5,
Box::new(Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2)),
)),
Box::new(Sphere::new(
Vec3::new(-1., 0., -1.),
0.5,
Box::new(Dielectric::new(1.5)),
)),
Box::new(Sphere::new(
Vec3::new(-1., 0., -1.),
-0.45,
Box::new(Dielectric::new(1.5)),
)),
]);
Scene {
camera,
world,
subsamples: opt.subsamples,
width: opt.width,
height: opt.height,
}
}
#[derive(Debug)]
pub enum Model {
Book,
Tutorial,
}
#[derive(Debug)]
pub struct ModelParseError(String);
impl fmt::Display for ModelParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "unknown model enum type '{}'", self.0)
}
}
impl str::FromStr for Model {
type Err = ModelParseError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"book" => Ok(Model::Book),
"tutorial" => Ok(Model::Tutorial),
_ => Err(ModelParseError(s.to_owned())),
}
}
}
#[derive(Debug, StructOpt)]
#[structopt(name = "tracert", about = "An experimental ray tracer.")]
#[structopt(name = "tracer", about = "An experimental ray tracer.")]
pub struct Opt {
/// Image width
#[structopt(short = "w", long = "width", default_value = "1280")]
@ -172,6 +205,8 @@ pub struct Opt {
/// Sub-samples per pixel
#[structopt(short = "s", long = "subsample", default_value = "10")]
pub subsamples: usize,
#[structopt(long = "model")]
pub model: Model,
/// Output directory
#[structopt(parse(from_os_str))]
@ -181,7 +216,10 @@ pub struct Opt {
fn main() -> Result<(), std::io::Error> {
let start = Instant::now();
let opt = Opt::from_args();
let scene = build_scene(&opt);
let scene = match opt.model {
Model::Book => build_scene_book(&opt),
Model::Tutorial => build_scene_tutorial(&opt),
};
let res = render(scene, &opt.output);
let runtime = start.elapsed();
eprintln!(