diff --git a/rtiow/renderer/src/bvh_triangles.rs b/rtiow/renderer/src/bvh_triangles.rs index 4113ab6..d02186e 100644 --- a/rtiow/renderer/src/bvh_triangles.rs +++ b/rtiow/renderer/src/bvh_triangles.rs @@ -120,7 +120,7 @@ impl BVHTriangles where M: Material, { - pub fn new(stl: &STL, material: M) -> BVHTriangles { + pub fn new(stl: &STL, material: M, scale_factor: f32) -> BVHTriangles { let now = std::time::Instant::now(); assert_eq!(std::mem::size_of::(), 32); @@ -129,9 +129,9 @@ where .triangles .iter() .map(|t| { - let v0 = t.verts[0]; - let v1 = t.verts[1]; - let v2 = t.verts[2]; + let v0 = t.verts[0] * scale_factor; + let v1 = t.verts[1] * scale_factor; + let v2 = t.verts[2] * scale_factor; let centroid = (v0 + v1 + v2) * div3; Triangle { centroid, diff --git a/rtiow/renderer/src/parser.rs b/rtiow/renderer/src/parser.rs index 6fb6a2d..ea67f08 100644 --- a/rtiow/renderer/src/parser.rs +++ b/rtiow/renderer/src/parser.rs @@ -1,5 +1,7 @@ use crate::{ + bvh_triangles::BVHTriangles, camera::Camera, + cuboid::Cuboid, hitable::Hit, hitable_list::HitableList, material::Lambertian, @@ -8,7 +10,8 @@ use crate::{ texture::{EnvMap, Texture}, }; use serde::Deserialize; -use std::path::PathBuf; +use std::{fs::File, io::BufReader, path::PathBuf, sync::Arc}; +use stl::STL; use thiserror::Error; use vec3::Vec3; @@ -16,7 +19,7 @@ use vec3::Vec3; pub struct Config { scene: SceneConfig, camera: CameraConfig, - spheres: Vec, + hitables: Vec, envmap: Option, } @@ -24,6 +27,10 @@ pub struct Config { pub enum ConfigError { #[error("failed to load image")] ImageError(#[from] image::ImageError), + #[error("failed to parser STL")] + STLError(#[from] stl::ParseError), + #[error("I/O error")] + IOError(#[from] std::io::Error), } impl TryFrom for Scene { @@ -34,15 +41,34 @@ impl TryFrom for Scene { // name in the object's config. let material = Lambertian::new([1., 0., 0.]); - let spheres: Vec> = c - .spheres - .iter() - .map(|sc| -> Box { - Box::new(Sphere::new(sc.center, sc.radius, material.clone())) + let hitables: Result>, Self::Error> = c + .hitables + .into_iter() + .map(|hc| -> Result, Self::Error> { + 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(); + let hitables = hitables?; - let world: Box = Box::new(HitableList::new(spheres)); + let world: Box = Box::new(HitableList::new(hitables)); let mut env_map: Option = None; if let Some(em) = c.envmap { @@ -92,9 +118,14 @@ struct SceneConfig { } #[derive(Debug, Deserialize)] -struct SphereConfig { - center: [f32; 3], - radius: f32, +#[serde(tag = "type")] +enum HitableConfig { + #[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 }, } #[derive(Debug, Deserialize)] diff --git a/rtiow/renderer/src/scenes/dragon.rs b/rtiow/renderer/src/scenes/dragon.rs index 97f98db..7c2d47d 100644 --- a/rtiow/renderer/src/scenes/dragon.rs +++ b/rtiow/renderer/src/scenes/dragon.rs @@ -87,7 +87,7 @@ pub fn new(opt: &Opt) -> Scene { // STL Mesh Box::new(crate::debug_hit::DebugHit::new(RotateY::new( Translate::new( - Scale::new(BVHTriangles::new(&stl_cube, dragon_material), 250.), + BVHTriangles::new(&stl_cube, dragon_material, 250.), [0., -10., 0.], ), 180., diff --git a/rtiow/renderer/src/scenes/stltest.rs b/rtiow/renderer/src/scenes/stltest.rs index 4a4ae65..92a4451 100644 --- a/rtiow/renderer/src/scenes/stltest.rs +++ b/rtiow/renderer/src/scenes/stltest.rs @@ -91,7 +91,7 @@ pub fn new(opt: &Opt) -> Scene { )), // STL Mesh Box::new(Translate::new( - BVHTriangles::new(&stl_cube, glass), + BVHTriangles::new(&stl_cube, glass, 1.), [0., 10., 0.], )), //Box::new(BVHTriangles::new(&stl_cube, box_material.clone())), diff --git a/rtiow/tracer/configs/test.toml b/rtiow/tracer/configs/test.toml index 20b35f2..1e8be5a 100644 --- a/rtiow/tracer/configs/test.toml +++ b/rtiow/tracer/configs/test.toml @@ -4,7 +4,7 @@ height = 768 #subsamples = 1000 [camera] -lookfrom = [0.0, 10.0, -100.0] +lookfrom = [0.0, 30.0, -100.0] lookat = [0.0, 0.0, 0.0] fov = 45 aspect = 1 @@ -13,15 +13,18 @@ focus_dist = 10.0 time_min = 0.0 time_max = 1.0 -[[spheres]] -center = [0.0, 0.0, 0.0] -radius = 10 -[[spheres]] +[[hitables]] +type = "cuboid" +min = [-10.0, -10.0, -10.0] +max = [10.0, 10.0, 10.0] +[[hitables]] +type = "sphere" center = [30.0, 0.0, 0.0] radius = 10 -[[spheres]] -center = [-30.0, 0.0, 0.0] -radius = 10 +[[hitables]] +type = "stl" +path = "/net/nasx.h.xinu.tv/x/3dprint/stl/stanford_dragon.stl" +scale = 200 [envmap] path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg"