117 lines
3.1 KiB
Rust

use std::io::{BufReader, Cursor};
use stl::STL;
use crate::{
camera::Camera,
hitable::Hit,
hitable_list::HitableList,
kdtree::KDTree,
material::{DiffuseLight, Lambertian, Metal},
rect::{XYRect, XZRect},
renderer::{Opt, Scene},
sphere::Sphere,
texture::ConstantTexture,
triangles::Triangles,
vec3::Vec3,
};
pub fn new(opt: &Opt) -> Scene {
let lookfrom = Vec3::new(200., 200., 200.);
let lookat = Vec3::new(0., 1., 0.);
let dist_to_focus = 10.0;
let aperture = 0.0;
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 {
ConstantTexture::new(Vec3::new(1.0, 0.4, 0.4))
} else {
ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4))
};
let stl_cube = STL::parse(
BufReader::new(Cursor::new(include_bytes!("../../stls/20mm cube.stl"))),
false,
)
.expect("failed to parse cube");
let light_size = 50.;
let light_height = 200.;
let tri_mesh = Triangles::new(
&stl_cube,
Lambertian::new(ConstantTexture::new(Vec3::new(1., 0., 0.))),
);
dbg!(&tri_mesh);
let objects: Vec<Box<dyn Hit>> = vec![
// Light from above
Box::new(XZRect::new(
-light_size,
light_size,
-light_size,
light_size,
light_height,
DiffuseLight::new(ConstantTexture::new(Vec3::new(15., 15., 15.))),
)),
// Light from back
Box::new(XYRect::new(
-light_size,
light_size,
-light_size,
light_size,
-light_height,
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 15., 1.))),
)),
// Light from front
Box::new(XYRect::new(
-light_size,
light_size,
-light_size,
light_size,
light_height,
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 1., 15.))),
)),
// Earth sized sphere
Box::new(Sphere::new(
Vec3::new(0., -1200., 0.),
1000.,
Lambertian::new(ground_color),
)),
// Blue sphere
Box::new(Sphere::new(
Vec3::new(-40., 20., 0.),
20.,
Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))),
)),
// Shiny sphere
Box::new(Sphere::new(
Vec3::new(40., 20., 0.),
20.,
Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
)),
Box::new(tri_mesh),
];
let world: Box<dyn Hit> = if opt.use_accel {
Box::new(KDTree::new(objects, time_min, time_max))
} else {
Box::new(HitableList::new(objects))
};
Scene {
camera,
world,
subsamples: opt.subsamples,
num_threads: opt.num_threads,
width: opt.width,
height: opt.height,
..Default::default()
}
}