From 076bcc7155be919e400a64ed78636966072d4e35 Mon Sep 17 00:00:00 2001 From: djairoh Date: Sun, 26 Apr 2026 23:49:03 +0200 Subject: [PATCH] ft: deserialization --- scenes/failsMatBounds.json | 22 ++++++++++++++++++++++ scenes/scene.json | 11 ++++++----- src/main.rs | 5 +++-- src/scenes/raw_camera.rs | 12 ++++-------- src/scenes/scene.rs | 32 ++++++++++++++++++++------------ 5 files changed, 55 insertions(+), 27 deletions(-) create mode 100644 scenes/failsMatBounds.json diff --git a/scenes/failsMatBounds.json b/scenes/failsMatBounds.json new file mode 100644 index 0000000..b7d0a37 --- /dev/null +++ b/scenes/failsMatBounds.json @@ -0,0 +1,22 @@ +{ + "camera": { + "image_width": 1920, + "image_height": 1080, + "anti_alias_rate": 1, + "max_depth": 10, + "fov": 90.0, + "look_from": { "x": -10, "y": 5, "z": 10 }, + "look_at": { "x": 0.0, "y": 0.0, "z": -1.0 }, + "vup": { "x": 0.0, "y": 1.0, "z": 0.0 } + }, + "materials": [ + { "type": "metal", "albedo": { "x": 0.2, "y": 0.4, "z": 0.8 }, "prob": 1.0, "fuzz": 0.1 } + + ], + "objects": [ + { "type": "sphere", "center": { "x": 0, "y": 0.7, "z": -0.4 }, "radius": 0.2, "material": 1} + ] +} + + + diff --git a/scenes/scene.json b/scenes/scene.json index 3f9b7af..8ea1af0 100644 --- a/scenes/scene.json +++ b/scenes/scene.json @@ -2,10 +2,10 @@ "camera": { "image_width": 1920, "image_height": 1080, - "anti_alias_rate": 3, - "max_depth": 50, - "fov": 90.0, - "look_from": { "x": 0, "y": 0, "z": 0 }, + "anti_alias_rate": 23, + "max_depth": 100, + "fov": 40.0, + "look_from": { "x": -10, "y": 5, "z": 10 }, "look_at": { "x": 0.0, "y": 0.0, "z": -1.0 }, "vup": { "x": 0.0, "y": 1.0, "z": 0.0 } }, @@ -25,7 +25,8 @@ { "type": "sphere", "center": { "x": 0.0, "y": -100.5, "z": -1.0 }, "radius": 100.0, "material": 2}, { "type": "sphere", "center": { "x": 0.0, "y": 0.0, "z": -1.2 }, "radius": 0.5, "material": 3}, { "type": "sphere", "center": { "x": -1, "y": 0, "z": -1 }, "radius": 0.4, "material": 5}, - { "type": "sphere", "center": { "x": 1, "y": 0, "z": -1 }, "radius": 0.5, "material": 6} + { "type": "sphere", "center": { "x": 1, "y": 0, "z": -1 }, "radius": 0.5, "material": 6}, + { "type": "sphere", "center": { "x": 20, "y": 7, "z": -15 }, "radius": 10.5, "material": 0} ] } diff --git a/src/main.rs b/src/main.rs index 6470ffd..ca4423a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -72,14 +72,15 @@ fn random_sphere_on_floor( sphere } -// FIXME: bunch of unwraps/expects in deserialization code // TODO: implement scene serialization fn main() { dotenv().ok(); pretty_env_logger::init(); // TODO: use cli arg for scenefile - let json_str = fs::read_to_string("./scenes/scene.json").expect("waddehell!"); + let json_file = "./scenes/scenes.json"; + // let json_file = "./scenes/failsMatBounds.json"; + let json_str = fs::read_to_string(json_file).expect("Reading specified scene file failed!"); let mut scene: Scene = serde_json::from_str(&json_str).unwrap(); scene.render(); diff --git a/src/scenes/raw_camera.rs b/src/scenes/raw_camera.rs index df69abb..2833a4e 100644 --- a/src/scenes/raw_camera.rs +++ b/src/scenes/raw_camera.rs @@ -41,11 +41,9 @@ impl Default for RawCamera { } } -impl TryFrom for Camera { - type Error = String; - - fn try_from(raw: RawCamera) -> Result { - let c = Camera::new_full( +impl From for Camera { + fn from(raw: RawCamera) -> Self { + Camera::new_full( raw.image_width, raw.image_height, raw.anti_alias_rate, @@ -54,8 +52,6 @@ impl TryFrom for Camera { raw.look_from, raw.look_at, raw.vup, - ); - - Ok(c) + ) } } diff --git a/src/scenes/scene.rs b/src/scenes/scene.rs index adbe888..4a5739d 100644 --- a/src/scenes/scene.rs +++ b/src/scenes/scene.rs @@ -1,8 +1,6 @@ -use std::{ - fmt::{self, Debug}, - sync::Arc, -}; +use std::sync::Arc; +use log::warn; use serde::Deserialize; use crate::{ @@ -53,10 +51,10 @@ impl<'de> Deserialize<'de> for Scene { let objs: Vec> = conc .objects .into_iter() - .map(|h| h.into_arc(&mats)) + .filter_map(|h| h.into_arc(&mats)) .collect(); Ok(Self { - camera: Camera::try_from(conc.camera).unwrap(), + camera: Camera::from(conc.camera), materials: mats, objects: objs, }) @@ -77,13 +75,23 @@ enum HittableDef { } impl HittableDef { - fn into_arc(self, materials: &Vec>) -> Arc { + fn into_arc(self, materials: &Vec>) -> Option> { + // THOUGHT: i think this can be done better; in the map/filter call up there? match self { - HittableDef::Sphere(s) => Arc::new(Sphere::new( - s.center, - s.radius, - materials.get(s.material as usize).unwrap().clone(), - )), + HittableDef::Sphere(s) => { + if s.material as usize >= materials.len() { + warn!( + "Sphere specified nonexistent material {}; skipping...", + s.material + ); + return None; + } + Some(Arc::new(Sphere::new( + s.center, + s.radius, + materials.get(s.material as usize).unwrap().clone(), + ))) + } } } }