Fix logic but + add error stuff

This commit is contained in:
Michael Zhang 2023-02-24 05:05:41 -06:00
parent 862cf9215e
commit 05462fde28
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
4 changed files with 129 additions and 44 deletions

View file

@ -2,11 +2,29 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "addr2line"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.68" version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
dependencies = [
"backtrace",
]
[[package]] [[package]]
name = "approx" name = "approx"
@ -42,6 +60,21 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "backtrace"
version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.21.0" version = "0.21.0"
@ -214,6 +247,12 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "gimli"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.4.1" version = "0.4.1"
@ -296,6 +335,12 @@ dependencies = [
"rawpointer", "rawpointer",
] ]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "memoffset" name = "memoffset"
version = "0.7.1" version = "0.7.1"
@ -305,6 +350,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "miniz_oxide"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
dependencies = [
"adler",
]
[[package]] [[package]]
name = "nalgebra" name = "nalgebra"
version = "0.32.1" version = "0.32.1"
@ -431,6 +485,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "object"
version = "0.30.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.17.0" version = "1.17.0"
@ -576,6 +639,12 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.36.7" version = "0.36.7"

View file

@ -19,7 +19,7 @@ name = "raytracer1c"
path = "src/main.rs" path = "src/main.rs"
[dependencies] [dependencies]
anyhow = "1.0.68" anyhow = { version = "1.0.68", features = ["backtrace"] }
base64 = "0.21.0" base64 = "0.21.0"
clap = { version = "4.1.4", features = ["cargo", "derive"] } clap = { version = "4.1.4", features = ["cargo", "derive"] }
derivative = "2.2.0" derivative = "2.2.0"

View file

@ -1,4 +1,4 @@
imsize 640 480 imsize 1024 768
eye 0 0 15 eye 0 0 15
viewdir 0 0 -1 viewdir 0 0 -1
hfov 60 hfov 60

View file

@ -4,7 +4,7 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use anyhow::Result; use anyhow::{Context, Result};
use itertools::Itertools; use itertools::Itertools;
use nalgebra::Vector3; use nalgebra::Vector3;
@ -40,32 +40,42 @@ impl Scene {
let mut material_color = None; let mut material_color = None;
for line in contents.lines() { for line in contents.lines() {
// Split lines into words, and identify the keyword // Split lines into words. `parts' is an iterator, which is consumed upon
// iterating, rather than collected into a Vec
let mut parts = line.split_whitespace(); let mut parts = line.split_whitespace();
// The keyword is the very first space-separated substring, and tells us
// how to interpret the rest
let keyword = match parts.next() { let keyword = match parts.next() {
Some(v) => v, Some(v) => v,
None => continue, None => continue,
}; };
/// Shortcut for reading something from the iterator and converting it /// Short for "read", macro for reading something from the iterator and
/// into the appropriate format /// converting it into the appropriate format given by $ty. For this to
/// work, $ty must implement Construct
macro_rules! r { macro_rules! r {
($ty:ty) => { ($ty:ty) => {
<$ty>::construct(&mut parts, ())? <$ty>::construct(&mut parts, ())
.with_context(|| format!("Could not parse {}", stringify!($ty)))?
}; };
($ty:ty, $($ex:expr),* $(,)?) => { ($ty:ty, $($ex:expr),* $(,)?) => {
<$ty>::construct(&mut parts, $($ex,)*)? <$ty>::construct(&mut parts, $($ex,)*)
.with_context(|| format!("Could not parse {}", stringify!($ty)))?
}; };
} }
/// Shortcut for getting material color /// Shortcut for unwrapping one of the state `Option's
macro_rules! mat { macro_rules! u {
() => { ($expr:expr) => {
match material_color { match $expr {
Some(v) => v, Some(v) => v,
None => { None => {
bail!("Each sphere must be preceded by a `mtlcolor` line") bail!(
"Each object must be preceded by a `{}` line",
stringify!($expr)
)
} }
} }
}; };
@ -90,40 +100,29 @@ impl Scene {
"bkgcolor" => scene.bkg_color = r!(Color), "bkgcolor" => scene.bkg_color = r!(Color),
// light x y z w r g b // light x y z w r g b
"light" => {
let vec3 = r!(Vector3<f64>);
let w = r!(usize);
let color = r!(Color);
let kind = match w as usize {
0 => LightKind::Directional { direction: vec3 },
1 => LightKind::Point {
location: vec3,
attenuation: None,
},
_ => bail!("Invalid w; must be either 0 or 1"),
};
let light = Light { kind, color };
scene.lights.push(light);
}
// attlight x y z w r g b c1 c2 c3 // attlight x y z w r g b c1 c2 c3
"attlight" => { "light" | "attlight" => {
let vec3 = r!(Vector3<f64>); let vec3 = r!(Vector3<f64>);
let w = r!(usize); let w = r!(usize);
let color = r!(Color); let color = r!(Color);
let c = r!(Vector3<f64>);
let kind = match w as usize { let attenuation = match keyword == "attlight" {
0 => LightKind::Directional { direction: vec3 }, true => {
1 => LightKind::Point { let c = r!(Vector3<f64>);
location: vec3, Some(Attenuation {
attenuation: Some(Attenuation {
c1: c.x, c1: c.x,
c2: c.y, c2: c.y,
c3: c.z, c3: c.z,
}), })
}
false => None,
};
let kind = match w as usize {
0 => LightKind::Directional { direction: vec3 },
1 => LightKind::Point {
location: vec3,
attenuation,
}, },
_ => bail!("Invalid w; must be either 0 or 1"), _ => bail!("Invalid w; must be either 0 or 1"),
}; };
@ -178,7 +177,7 @@ impl Scene {
scene.objects.push(Object { scene.objects.push(Object {
kind: ObjectKind::Sphere(Sphere { center, radius }), kind: ObjectKind::Sphere(Sphere { center, radius }),
material: mat!(), material: u!(material_color),
}); });
} }
@ -195,7 +194,7 @@ impl Scene {
radius, radius,
length, length,
}), }),
material: mat!(), material: u!(material_color),
}); });
} }
@ -238,7 +237,7 @@ impl Scene {
}; };
scene.objects.push(Object { scene.objects.push(Object {
kind: ObjectKind::Triangle(triangle), kind: ObjectKind::Triangle(triangle),
material: mat!(), material: u!(material_color),
}); });
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -267,13 +266,13 @@ impl Scene {
let vertex_idx: usize = parts[0].parse::<usize>()? - 1; let vertex_idx: usize = parts[0].parse::<usize>()? - 1;
let texture_idx = let texture_idx =
match parts.get(1).and_then(|s| s.is_empty().then(|| *s)) { match parts.get(1).and_then(|s| (!s.is_empty()).then(|| *s)) {
Some(s) => Some(s.parse::<usize>()? - 1), Some(s) => Some(s.parse::<usize>()? - 1),
None => None, None => None,
}; };
let normal_idx = let normal_idx =
match parts.get(2).and_then(|s| s.is_empty().then(|| *s)) { match parts.get(2).and_then(|s| (!s.is_empty()).then(|| *s)) {
Some(s) => Some(s.parse::<usize>()? - 1), Some(s) => Some(s.parse::<usize>()? - 1),
None => None, None => None,
}; };
@ -315,6 +314,23 @@ pub trait Construct: Sized {
I: Iterator<Item = &'a str>; I: Iterator<Item = &'a str>;
} }
impl<T: Construct> Construct for Option<T> {
type Args = T::Args;
fn construct<'a, I>(it: &mut I, args: Self::Args) -> Result<Self>
where
I: Iterator<Item = &'a str>,
{
let mut peeker = it.peekable();
if peeker.peek().is_none() {
return Ok(None);
}
T::construct(&mut peeker, args).map(Some)
}
}
macro_rules! impl_construct { macro_rules! impl_construct {
($ty:ty) => { ($ty:ty) => {
impl Construct for $ty { impl Construct for $ty {