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 = 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> { let mut rng = rand::thread_rng(); let mut objects: Vec> = vec![Box::new(Sphere::new( Vec3::new(0., -1000., 0.), 1000., Box::new(Lambertian::new(background_color)), ))]; let mut random = || rng.gen_range::(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> = 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 }