From f19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc Mon Sep 17 00:00:00 2001 From: Sakarias Johansson Date: Mon, 13 Mar 2023 22:00:44 +0100 Subject: =?UTF-8?q?=F0=9F=93=B8=20Add=20Camera=20defocus=20blur=20+=20Othe?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just wanted to add defocus blur but ended up changing a bunch of other this as well. - Moved scenes to a separate folder. - Updated readme with more pretty images. - Add interface for loading scenes. There is currently one for yaml and another if you want a slightly random scene. - Add image action to decide what to do with the final image once its rendered. Currently supports just showing the buffer until you press the render buffer again and saving the image as `png`. - When you use nix shell you will be dropped in the proper folder so you can just do cargo build etc without having to do `cd`. --- racer-tracer/src/scene.rs | 111 +++++++--------------------------------------- 1 file changed, 16 insertions(+), 95 deletions(-) (limited to 'racer-tracer/src/scene.rs') diff --git a/racer-tracer/src/scene.rs b/racer-tracer/src/scene.rs index c0c6bb7..12e2296 100644 --- a/racer-tracer/src/scene.rs +++ b/racer-tracer/src/scene.rs @@ -1,13 +1,10 @@ -use std::{collections::HashMap, path::Path, sync::Arc}; - -use config::File; -use serde::Deserialize; +pub mod none; +pub mod random; +pub mod yml; use crate::{ - error::TracerError, - geometry::{sphere::Sphere, Hittable}, - material::{dialectric::Dialectric, lambertian::Lambertian, metal::Metal, SharedMaterial}, - vec3::{Color, Vec3}, + config::SceneLoader as CSLoader, error::TracerError, geometry::Hittable, + scene::none::NoneLoader, scene::random::Random, scene::yml::YmlLoader, }; pub struct Scene { @@ -16,20 +13,14 @@ pub struct Scene { impl Scene { #[allow(dead_code)] - pub fn new() -> Self { - Self { - objects: Vec::new(), - } + pub fn try_new(loader: Box) -> Result { + loader.load().map(|objects| Self { objects }) } #[allow(dead_code)] pub fn add(&mut self, hittable: Box) { self.objects.push(hittable); } - - pub fn from_file>(file: P) -> Result { - SceneData::from_file(file)?.try_into() - } } impl Hittable for Scene { @@ -53,86 +44,16 @@ impl Hittable for Scene { } } -#[derive(Debug, Deserialize)] -enum MaterialData { - Lambertian { color: Color }, - Metal { color: Color, fuzz: f64 }, - Dialectric { refraction_index: f64 }, -} - -#[derive(Debug, Deserialize)] -enum GeometryData { - Sphere { - pos: Vec3, - radius: f64, - material: String, - }, -} - -#[derive(Deserialize)] -struct SceneData { - materials: HashMap, - geometry: Vec, -} - -impl SceneData { - pub fn from_file>(file: P) -> Result { - config::Config::builder() - .add_source(File::from(file.as_ref())) - .build() - .map_err(|e| { - TracerError::Configuration( - file.as_ref().to_string_lossy().into_owned(), - e.to_string(), - ) - })? - .try_deserialize() - .map_err(|e| { - TracerError::Configuration( - file.as_ref().to_string_lossy().into_owned(), - e.to_string(), - ) - }) - } +pub trait SceneLoader: Send + Sync { + fn load(&self) -> Result>, TracerError>; } -impl TryInto for SceneData { - type Error = TracerError; - fn try_into(self) -> Result { - let mut materials: HashMap = HashMap::new(); - self.materials - .into_iter() - .for_each(|(id, material)| match material { - MaterialData::Lambertian { color } => { - materials.insert(id, Arc::new(Box::new(Lambertian::new(color)))); - } - MaterialData::Metal { color, fuzz } => { - materials.insert(id, Arc::new(Box::new(Metal::new(color, fuzz)))); - } - MaterialData::Dialectric { refraction_index } => { - materials.insert(id, Arc::new(Box::new(Dialectric::new(refraction_index)))); - } - }); - - let geometry: Vec> = self - .geometry - .into_iter() - .map(|geo| match geo { - GeometryData::Sphere { - pos, - radius, - material, - } => materials - .get(&material) - .ok_or(TracerError::UnknownMaterial(material)) - .map(|mat| { - let apa: Box = - Box::new(Sphere::new(pos, radius, Arc::clone(mat))); - apa - }), - }) - .collect::>, TracerError>>()?; - - Ok(Scene { objects: geometry }) +impl From<&CSLoader> for Box { + fn from(loader: &CSLoader) -> Self { + match loader { + CSLoader::Yml { path } => Box::new(YmlLoader::new(path.clone())), + CSLoader::Random => Box::new(Random::new()), + CSLoader::None => Box::new(NoneLoader::new()), + } } } -- cgit v1.2.3