csci5607/assignment-1/src/input_file.rs

85 lines
2.1 KiB
Rust
Raw Normal View History

2023-01-31 19:50:23 +00:00
use std::{fs::File, io::Read, path::Path};
2023-01-31 07:15:22 +00:00
use anyhow::Result;
2023-01-31 19:50:23 +00:00
use crate::{
2023-01-31 21:58:32 +00:00
image::Color,
2023-01-31 19:50:23 +00:00
scene_data::{Object, Scene, Sphere},
vec3::Vec3,
};
2023-01-31 07:15:22 +00:00
2023-01-31 21:19:34 +00:00
/// Parse the input file into a scene
2023-01-31 07:15:22 +00:00
pub fn parse_input_file(path: impl AsRef<Path>) -> Result<Scene> {
2023-01-31 19:50:23 +00:00
let contents = {
let mut contents = String::new();
let mut file = File::open(path.as_ref())?;
file.read_to_string(&mut contents)?;
contents
};
let mut scene = Scene::default();
let mut material_color = None;
for line in contents.lines() {
let mut parts = line.split_whitespace();
let keyword = match parts.next() {
Some(v) => v,
None => continue,
};
if keyword == "imsize" {
let parts = parts
.map(|s| s.parse::<usize>().map_err(|e| e.into()))
.collect::<Result<Vec<_>>>()?;
if let [width, height] = parts[..] {
scene.image_width = width;
scene.image_height = height;
}
}
// Do float parsing instead
else {
let parts = parts
.map(|s| s.parse::<f64>().map_err(|e| e.into()))
.collect::<Result<Vec<_>>>()?;
let read_vec3 = || {
if parts.len() < 3 {
bail!("Vec3 requires 3 components.");
}
Ok(Vec3::new(parts[0], parts[1], parts[2]))
};
2023-01-31 21:58:32 +00:00
let read_color = || {
if parts.len() < 3 {
bail!("Color requires 3 components.");
}
Ok(Color::from_01_float(parts[0], parts[1], parts[2]))
};
2023-01-31 19:50:23 +00:00
match keyword {
"eye" => scene.eye_pos = read_vec3()?,
"viewdir" => scene.view_dir = read_vec3()?,
"updir" => scene.up_dir = read_vec3()?,
"hfov" => scene.hfov = parts[0],
2023-01-31 21:58:32 +00:00
"bkgcolor" => scene.bkg_color = read_color()?,
2023-01-31 20:39:23 +00:00
"mtlcolor" => {
let idx = scene.material_colors.len();
material_color = Some(idx);
2023-01-31 21:58:32 +00:00
scene.material_colors.push(read_color()?);
2023-01-31 20:41:23 +00:00
}
2023-01-31 19:50:23 +00:00
"sphere" => scene.objects.push(Object::Sphere(Sphere {
center: read_vec3()?,
radius: parts[3],
2023-01-31 20:39:23 +00:00
material: material_color.unwrap(),
2023-01-31 19:50:23 +00:00
})),
_ => bail!("Unknown keyword {keyword}"),
}
}
}
Ok(scene)
2023-01-31 07:15:22 +00:00
}