diff --git a/rtiow/renderer/src/parser.rs b/rtiow/renderer/src/parser.rs index 2ee4f0f..6fb6a2d 100644 --- a/rtiow/renderer/src/parser.rs +++ b/rtiow/renderer/src/parser.rs @@ -8,7 +8,8 @@ use crate::{ texture::{EnvMap, Texture}, }; use serde::Deserialize; - +use std::path::PathBuf; +use thiserror::Error; use vec3::Vec3; #[derive(Debug, Deserialize)] @@ -16,38 +17,40 @@ pub struct Config { scene: SceneConfig, camera: CameraConfig, spheres: Vec, + envmap: Option, } -impl From for Scene { - fn from(c: Config) -> Scene { +#[derive(Error, Debug)] +pub enum ConfigError { + #[error("failed to load image")] + ImageError(#[from] image::ImageError), +} + +impl TryFrom for Scene { + type Error = ConfigError; + + fn try_from(c: Config) -> Result { + // TODO(wathiede): make this something that is loaded from the config and referenced by + // name in the object's config. let material = Lambertian::new([1., 0., 0.]); - let objects: Vec> = c + + let spheres: Vec> = c .spheres .iter() .map(|sc| -> Box { Box::new(Sphere::new(sc.center, sc.radius, material.clone())) }) .collect(); - let world: Box = Box::new(HitableList::new(objects)); - let env_map: Option = None; - let lookfrom = Vec3::new(0., 80., 80.); - let lookat = Vec3::new(0., 0., 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.), - 45., - c.scene.width as f32 / c.scene.height as f32, - aperture, - dist_to_focus, - time_min, - time_max, - ); + let world: Box = Box::new(HitableList::new(spheres)); + let mut env_map: Option = None; + + if let Some(em) = c.envmap { + let im = image::open(em.path)?.into_rgb(); + env_map = Some(EnvMap::new(im)); + }; + + let camera = make_camera(&c.camera, c.scene.width, c.scene.height); let scene = Scene { world, @@ -60,11 +63,24 @@ impl From for Scene { height: c.scene.height, global_illumination: c.scene.global_illumination.unwrap_or(true), }; - dbg!(&scene); - scene + Ok(scene) } } +fn make_camera(cfg: &CameraConfig, width: usize, height: usize) -> Camera { + Camera::new( + cfg.lookfrom.into(), + cfg.lookat.into(), + Vec3::new(0., 1., 0.), + cfg.fov, + width as f32 / height as f32, + cfg.aperture, + cfg.focus_dist, + cfg.time_min, + cfg.time_max, + ) +} + #[derive(Debug, Deserialize)] struct SceneConfig { subsamples: Option, @@ -92,3 +108,8 @@ pub struct CameraConfig { time_min: f32, time_max: f32, } + +#[derive(Debug, Deserialize)] +struct EnvMapConfig { + path: PathBuf, +} diff --git a/rtiow/tracer/configs/test.toml b/rtiow/tracer/configs/test.toml index 0b5ece2..20b35f2 100644 --- a/rtiow/tracer/configs/test.toml +++ b/rtiow/tracer/configs/test.toml @@ -1,12 +1,12 @@ [scene] width = 768 height = 768 -subsamples = 1000 +#subsamples = 1000 [camera] -lookfrom = [0.0, 10.0, 0.0] +lookfrom = [0.0, 10.0, -100.0] lookat = [0.0, 0.0, 0.0] -fov = 45.0 +fov = 45 aspect = 1 aperture = 0.0 focus_dist = 10.0 @@ -22,3 +22,6 @@ radius = 10 [[spheres]] center = [-30.0, 0.0, 0.0] radius = 10 + +[envmap] +path = "/home/wathiede/src/xinu.tv/raytracers/rtiow/renderer/images/52681723945_e1d94d3df9_6k.jpg" diff --git a/rtiow/tracer/src/main.rs b/rtiow/tracer/src/main.rs index 5ab9542..181d351 100644 --- a/rtiow/tracer/src/main.rs +++ b/rtiow/tracer/src/main.rs @@ -65,7 +65,7 @@ fn main() -> Result<()> { let s = std::fs::read_to_string(config)?; let cfg: Config = toml::from_str(&s)?; println!("{:#?}", cfg); - cfg.into() + cfg.try_into()? } _ => unreachable!(), };