Input parser

This commit is contained in:
Michael Zhang 2023-01-31 13:50:23 -06:00
parent 0000008083
commit 0000009017
7 changed files with 94 additions and 7 deletions

View file

@ -0,0 +1,8 @@
imsize 256 256
eye 0 0 0
viewdir 0 0 -1
hfov 90
updir 0 1 0
bkgcolor 0.1 0.1 0.1
mtlcolor 0 0 1
sphere 0 0 -5 2

View file

@ -0,0 +1,10 @@
imsize 512 256
eye 0 0 0
viewdir 0 0 -1
hfov 130
updir 0 1 1
bkgcolor 0.1 0.1 0.1
mtlcolor 0 1 0
sphere -0.5 -1 -8 3
mtlcolor 1 0 0
sphere 3 1 -3 1

View file

@ -1,9 +1,69 @@
use std::path::Path;
use std::{fs::File, io::Read, path::Path};
use anyhow::Result;
use crate::scene_data::Scene;
use crate::{
scene_data::{Object, Scene, Sphere},
vec3::Vec3,
};
pub fn parse_input_file(path: impl AsRef<Path>) -> Result<Scene> {
todo!()
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]))
};
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],
"bkgcolor" => scene.bkg_color = read_vec3()?,
"mtlcolor" => material_color = Some(read_vec3()?),
"sphere" => scene.objects.push(Object::Sphere(Sphere {
center: read_vec3()?,
radius: parts[3],
})),
_ => bail!("Unknown keyword {keyword}"),
}
}
}
Ok(scene)
}

View file

@ -1,3 +1,6 @@
#[macro_use]
extern crate anyhow;
mod input_file;
mod ray;
mod scene_data;
@ -8,12 +11,12 @@ use std::path::PathBuf;
use anyhow::Result;
use clap::Parser;
use vec3::Vec3;
use view::Rect;
use crate::input_file::parse_input_file;
use crate::vec3::Vec3;
use crate::view::Rect;
/// Noise image generator.
/// Simple raycaster.
#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
struct Opt {
@ -33,6 +36,7 @@ fn main() -> Result<()> {
let opt = Opt::parse();
let scene = parse_input_file(&opt.input_path)?;
println!("Scene: {scene:?}");
// Compute viewing directions
let u = Vec3::cross(scene.view_dir, scene.up_dir).unit();

View file

@ -1,10 +1,12 @@
use crate::vec3::Vec3;
#[derive(Debug)]
pub struct Sphere {
pub center: Vec3,
pub radius: f64,
}
#[derive(Debug)]
pub enum Object {
Sphere(Sphere),
Cylinder {
@ -15,6 +17,7 @@ pub enum Object {
},
}
#[derive(Debug, Default)]
pub struct Scene {
pub eye_pos: Vec3,
pub view_dir: Vec3,

View file

@ -2,7 +2,7 @@ use std::ops::{Add, Mul};
use num::Float;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
pub struct Vec3<T = f64> {
pub x: T,
pub y: T,
@ -25,6 +25,7 @@ impl<T: Float> Vec3<T> {
)
}
/// Vector L2-norm
pub fn norm(&self) -> T {
(self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt()
}

View file

@ -1,5 +1,6 @@
use crate::vec3::Vec3;
#[derive(Debug)]
pub struct Rect {
pub upper_left: Vec3,
pub upper_right: Vec3,