rtiow: make hitables an enum of various types.

This commit is contained in:
Bill Thiede 2023-02-15 19:44:17 -08:00
parent 5f0e7a26dd
commit 35071b06ac
5 changed files with 59 additions and 25 deletions

View File

@ -120,7 +120,7 @@ impl<M> BVHTriangles<M>
where where
M: Material, M: Material,
{ {
pub fn new(stl: &STL, material: M) -> BVHTriangles<M> { pub fn new(stl: &STL, material: M, scale_factor: f32) -> BVHTriangles<M> {
let now = std::time::Instant::now(); let now = std::time::Instant::now();
assert_eq!(std::mem::size_of::<BVHNode>(), 32); assert_eq!(std::mem::size_of::<BVHNode>(), 32);
@ -129,9 +129,9 @@ where
.triangles .triangles
.iter() .iter()
.map(|t| { .map(|t| {
let v0 = t.verts[0]; let v0 = t.verts[0] * scale_factor;
let v1 = t.verts[1]; let v1 = t.verts[1] * scale_factor;
let v2 = t.verts[2]; let v2 = t.verts[2] * scale_factor;
let centroid = (v0 + v1 + v2) * div3; let centroid = (v0 + v1 + v2) * div3;
Triangle { Triangle {
centroid, centroid,

View File

@ -1,5 +1,7 @@
use crate::{ use crate::{
bvh_triangles::BVHTriangles,
camera::Camera, camera::Camera,
cuboid::Cuboid,
hitable::Hit, hitable::Hit,
hitable_list::HitableList, hitable_list::HitableList,
material::Lambertian, material::Lambertian,
@ -8,7 +10,8 @@ use crate::{
texture::{EnvMap, Texture}, texture::{EnvMap, Texture},
}; };
use serde::Deserialize; use serde::Deserialize;
use std::path::PathBuf; use std::{fs::File, io::BufReader, path::PathBuf, sync::Arc};
use stl::STL;
use thiserror::Error; use thiserror::Error;
use vec3::Vec3; use vec3::Vec3;
@ -16,7 +19,7 @@ use vec3::Vec3;
pub struct Config { pub struct Config {
scene: SceneConfig, scene: SceneConfig,
camera: CameraConfig, camera: CameraConfig,
spheres: Vec<SphereConfig>, hitables: Vec<HitableConfig>,
envmap: Option<EnvMapConfig>, envmap: Option<EnvMapConfig>,
} }
@ -24,6 +27,10 @@ pub struct Config {
pub enum ConfigError { pub enum ConfigError {
#[error("failed to load image")] #[error("failed to load image")]
ImageError(#[from] image::ImageError), ImageError(#[from] image::ImageError),
#[error("failed to parser STL")]
STLError(#[from] stl::ParseError),
#[error("I/O error")]
IOError(#[from] std::io::Error),
} }
impl TryFrom<Config> for Scene { impl TryFrom<Config> for Scene {
@ -34,15 +41,34 @@ impl TryFrom<Config> for Scene {
// name in the object's config. // name in the object's config.
let material = Lambertian::new([1., 0., 0.]); let material = Lambertian::new([1., 0., 0.]);
let spheres: Vec<Box<dyn Hit>> = c let hitables: Result<Vec<Box<dyn Hit>>, Self::Error> = c
.spheres .hitables
.iter() .into_iter()
.map(|sc| -> Box<dyn Hit> { .map(|hc| -> Result<Box<dyn Hit>, Self::Error> {
Box::new(Sphere::new(sc.center, sc.radius, material.clone())) match hc {
HitableConfig::Sphere { center, radius } => {
Ok(Box::new(Sphere::new(center, radius, material.clone())))
}
HitableConfig::Cuboid { min, max } => Ok(Box::new(Cuboid::new(
min.into(),
max.into(),
Arc::new(material.clone()),
))),
HitableConfig::STL { path, scale } => {
let r = BufReader::new(File::open(path)?);
let stl = STL::parse(r, false)?;
Ok(Box::new(BVHTriangles::new(
&stl,
material.clone(),
scale.unwrap_or(1.),
)))
}
}
}) })
.collect(); .collect();
let hitables = hitables?;
let world: Box<dyn Hit> = Box::new(HitableList::new(spheres)); let world: Box<dyn Hit> = Box::new(HitableList::new(hitables));
let mut env_map: Option<EnvMap> = None; let mut env_map: Option<EnvMap> = None;
if let Some(em) = c.envmap { if let Some(em) = c.envmap {
@ -92,9 +118,14 @@ struct SceneConfig {
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct SphereConfig { #[serde(tag = "type")]
center: [f32; 3], enum HitableConfig {
radius: f32, #[serde(rename = "sphere")]
Sphere { center: [f32; 3], radius: f32 },
#[serde(rename = "cuboid")]
Cuboid { min: [f32; 3], max: [f32; 3] },
#[serde(rename = "stl")]
STL { path: PathBuf, scale: Option<f32> },
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]

View File

@ -87,7 +87,7 @@ pub fn new(opt: &Opt) -> Scene {
// STL Mesh // STL Mesh
Box::new(crate::debug_hit::DebugHit::new(RotateY::new( Box::new(crate::debug_hit::DebugHit::new(RotateY::new(
Translate::new( Translate::new(
Scale::new(BVHTriangles::new(&stl_cube, dragon_material), 250.), BVHTriangles::new(&stl_cube, dragon_material, 250.),
[0., -10., 0.], [0., -10., 0.],
), ),
180., 180.,

View File

@ -91,7 +91,7 @@ pub fn new(opt: &Opt) -> Scene {
)), )),
// STL Mesh // STL Mesh
Box::new(Translate::new( Box::new(Translate::new(
BVHTriangles::new(&stl_cube, glass), BVHTriangles::new(&stl_cube, glass, 1.),
[0., 10., 0.], [0., 10., 0.],
)), )),
//Box::new(BVHTriangles::new(&stl_cube, box_material.clone())), //Box::new(BVHTriangles::new(&stl_cube, box_material.clone())),

View File

@ -4,7 +4,7 @@ height = 768
#subsamples = 1000 #subsamples = 1000
[camera] [camera]
lookfrom = [0.0, 10.0, -100.0] lookfrom = [0.0, 30.0, -100.0]
lookat = [0.0, 0.0, 0.0] lookat = [0.0, 0.0, 0.0]
fov = 45 fov = 45
aspect = 1 aspect = 1
@ -13,15 +13,18 @@ focus_dist = 10.0
time_min = 0.0 time_min = 0.0
time_max = 1.0 time_max = 1.0
[[spheres]] [[hitables]]
center = [0.0, 0.0, 0.0] type = "cuboid"
radius = 10 min = [-10.0, -10.0, -10.0]
[[spheres]] max = [10.0, 10.0, 10.0]
[[hitables]]
type = "sphere"
center = [30.0, 0.0, 0.0] center = [30.0, 0.0, 0.0]
radius = 10 radius = 10
[[spheres]] [[hitables]]
center = [-30.0, 0.0, 0.0] type = "stl"
radius = 10 path = "/net/nasx.h.xinu.tv/x/3dprint/stl/stanford_dragon.stl"
scale = 200
[envmap] [envmap]
path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg" path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg"