2018-09-22 12:08:26 -07:00

121 lines
3.5 KiB
Rust

use rand;
use rand::Rng;
use camera::Camera;
use hitable::Hit;
use hitable_list::HitableList;
use kdtree::KDTree;
use material::Dielectric;
use material::Lambertian;
use material::Metal;
use renderer::Opt;
use renderer::Scene;
use sphere::Sphere;
use vec3::Vec3;
pub fn new(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 time_min = 0.;
let time_max = 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,
time_min,
time_max,
);
let ground_color = if opt.use_accel {
Vec3::new(1.0, 0.4, 0.4)
} else {
Vec3::new(0.4, 1.0, 0.4)
};
let world: Box<Hit> = if opt.use_accel {
Box::new(KDTree::new(random_scene(ground_color), time_min, time_max))
} else {
Box::new(HitableList::new(random_scene(ground_color)))
};
Scene {
camera,
world,
subsamples: opt.subsamples,
width: opt.width,
height: opt.height,
}
}
fn random_scene(background_color: Vec3) -> Vec<Box<Hit>> {
let mut rng = rand::thread_rng();
let mut objects: Vec<Box<Hit>> = vec![Box::new(Sphere::new(
Vec3::new(0., -1000., 0.),
1000.,
Box::new(Lambertian::new(background_color)),
))];
let mut random = || rng.gen_range::<f32>(0., 1.);
for a in -11..11 {
for b in -11..11 {
let choose_mat = random();
let center = Vec3::new(a as f32 + 0.9 * random(), 0.2, b as f32 + 0.9 * random());
if (center - Vec3::new(4., 0.2, 0.)).length() > 0.9 {
let sphere = if choose_mat < 0.8 {
// diffuse
Box::new(Sphere::new(
center,
0.2,
Box::new(Lambertian::new(Vec3::new(
random() * random(),
random() * random(),
random() * random(),
))),
))
} else if choose_mat < 0.95 {
// metal
Box::new(Sphere::new(
center,
0.2,
Box::new(Metal::new(
Vec3::new(
0.5 * (1. + random()),
0.5 * (1. + random()),
0.5 * (1. + random()),
),
0.5 * random(),
)),
))
} else {
// glass
Box::new(Sphere::new(center, 0.2, Box::new(Dielectric::new(1.5))))
};
objects.push(sphere);
};
}
}
let more: Vec<Box<Hit>> = vec![
Box::new(Sphere::new(
Vec3::new(0., 1., 0.),
1.0,
Box::new(Dielectric::new(1.5)),
)),
Box::new(Sphere::new(
Vec3::new(-4., 1., 0.),
1.0,
Box::new(Lambertian::new(Vec3::new(0.4, 0.2, 0.1))),
)),
Box::new(Sphere::new(
Vec3::new(4., 1., 0.),
1.0,
Box::new(Metal::new(Vec3::new(0.7, 0.6, 0.5), 0.0)),
)),
];
objects.extend(more);
objects
}