diff --git a/ray-tracing-pbrt-scene/src/either.rs b/ray-tracing-pbrt-scene/src/either.rs
new file mode 100644
index 0000000..9faabf7
--- /dev/null
+++ b/ray-tracing-pbrt-scene/src/either.rs
@@ -0,0 +1,30 @@
+#[derive(Debug)]
+pub enum Either {
+ A(A),
+ B(B),
+}
+
+impl Either {
+ pub fn map_a(self, f: impl FnOnce(A) -> C) -> Either {
+ match self {
+ Either::A(a) => Either::A(f(a)),
+ Either::B(b) => Either::B(b),
+ }
+ }
+ pub fn map_b(self, f: impl FnOnce(B) -> C) -> Either {
+ match self {
+ Either::A(a) => Either::A(a),
+ Either::B(b) => Either::B(f(b)),
+ }
+ }
+}
+
+impl Either> {
+ pub fn transpose_b(self) -> Result, E> {
+ match self {
+ Either::A(a) => Ok(Either::A(a)),
+ Either::B(Ok(b)) => Ok(Either::B(b)),
+ Either::B(Err(e)) => Err(e),
+ }
+ }
+}
diff --git a/ray-tracing-pbrt-scene/src/lib.rs b/ray-tracing-pbrt-scene/src/lib.rs
index efab7b8..584f2e4 100644
--- a/ray-tracing-pbrt-scene/src/lib.rs
+++ b/ray-tracing-pbrt-scene/src/lib.rs
@@ -1,7 +1,6 @@
use crate::tokenizer::Tokenizer;
-use error::SourceFile;
use material::PbrtMaterial;
-use miette::{Diagnostic, IntoDiagnostic, Result, SourceSpan, bail, miette};
+use miette::{IntoDiagnostic, Result, bail, miette};
use ray_tracing_core::{
affine_transform::AffineTransform,
math::{Dir3, Pos3},
@@ -13,10 +12,11 @@ use std::{
sync::Arc,
};
use texture::PbrtTexture;
-use thiserror::Error;
#[macro_use]
mod tokenizer;
+
+mod either;
mod error;
mod material;
mod texture;
@@ -372,10 +372,7 @@ fn parse_camera(tokenizer: &mut Tokenizer) -> Result {
}
impl Lexer {
- fn next(
- &mut self,
- textures: &HashMap>,
- ) -> Option> {
+ fn next(&mut self, context: &PbrtContext) -> Option> {
match self.input.next() {
Some(Ok(s)) => match s.as_str() {
"AttributeBegin" => Some(Ok(Statement::AttributeBegin)),
@@ -400,14 +397,14 @@ impl Lexer {
"Rotate" => Some(parse_rotate(&mut self.input)),
"Transform" => Some(parse_transform(&mut self.input).map(Statement::Transform)),
"Texture" => Some(
- texture::parse_texture(&mut self.input, textures)
+ texture::parse_texture(&mut self.input, context)
.map(|(name, texture)| Statement::Texture(name, texture)),
),
"Material" => Some(
- material::parse_material(&mut self.input, textures).map(Statement::Material),
+ material::parse_material(&mut self.input, context).map(Statement::Material),
),
"MakeNamedMaterial" => Some(
- material::parse_make_named_material(&mut self.input, textures)
+ material::parse_make_named_material(&mut self.input, context)
.map(|(name, material)| Statement::MakeNamedMaterial(name, material)),
),
"NamedMaterial" => Some(self.input.parse_parameter().map(Statement::NamedMaterial)),
@@ -575,23 +572,20 @@ impl Parser {
}
impl Parser {
- fn next(
- &mut self,
- textures: &HashMap>,
- ) -> Option> {
+ fn next(&mut self, context: &PbrtContext) -> Option> {
if let Some(iter) = &mut self.inner {
- if let Some(statement) = iter.next(textures) {
+ if let Some(statement) = iter.next(context) {
return Some(statement);
}
self.inner = None;
}
- match self.iter.next(textures) {
+ match self.iter.next(context) {
Some(Ok(Statement::Include(s))) => {
let path = self.path.parent().unwrap().join(s);
self.inner = Some(Box::new(Parser::new(path, self.base_path.clone()).unwrap()));
- self.next(textures)
+ self.next(context)
}
Some(s) => Some(s),
None => None,
@@ -679,9 +673,65 @@ struct PbrtScene {
shapes: Vec,
}
+#[derive(Debug)]
+pub struct PbrtContext {
+ ctm: Vec,
+ textures: HashMap>,
+ material: Vec>,
+ materials: HashMap>,
+}
+
+impl PbrtContext {
+ fn new() -> Self {
+ Self {
+ ctm: vec![AffineTransform::identity()],
+ textures: HashMap::new(),
+ material: Vec::new(),
+ materials: HashMap::new(),
+ }
+ }
+
+ pub fn get_ctm(&self) -> AffineTransform {
+ *self.ctm.last().unwrap()
+ }
+
+ pub fn get_texture(&self, name: &String) -> Option<&Arc> {
+ self.textures.get(name)
+ }
+
+ pub fn get_named_material(&self, name: &String) -> Option<&Arc> {
+ self.materials.get(name)
+ }
+
+ pub fn get_material(&self) -> Option<&Arc> {
+ self.material.last()
+ }
+
+ fn push(&mut self) {
+ self.ctm.push(*self.ctm.last().unwrap());
+
+ if !self.material.is_empty() {
+ self.material
+ .push(Arc::clone(self.material.last().unwrap()));
+ }
+ }
+
+ fn pop(&mut self) -> Result<()> {
+ self.ctm.pop();
+
+ if self.ctm.is_empty() {
+ return Err(miette!("Attributes do not matcch"));
+ }
+
+ self.material.pop();
+
+ Ok(())
+ }
+}
+
fn inner_parse_pbrt(path: impl AsRef + std::fmt::Debug) -> Result {
// unwrap on context.last() ok because context is never empty
- let mut context_ctm = vec![AffineTransform::identity()];
+ let mut context = PbrtContext::new();
let mut parser = Parser::new(
path.as_ref().to_path_buf(),
@@ -697,25 +747,20 @@ fn inner_parse_pbrt(path: impl AsRef + std::fmt::Debug) -> Result {
let mut named_transforms = HashMap::new();
- let mut textures = HashMap::new();
-
loop {
- let p = parser.next(&textures).ok_or_else(|| miette!(""))??;
+ let p = parser.next(&context).ok_or_else(|| miette!(""))??;
// dbg!(&p);
match p {
- Statement::AttributeBegin => context_ctm.push(*context_ctm.last().unwrap()),
+ Statement::AttributeBegin => context.push(),
Statement::AttributeEnd => {
- context_ctm.pop();
- if context_ctm.is_empty() {
- return Err(miette!("Attribute end does not match."));
- }
+ context.pop()?;
}
Statement::Include(_) => unreachable!(),
Statement::ConcatTransform(affine_transform) => {
- *context_ctm.last_mut().unwrap() *= affine_transform
+ *context.ctm.last_mut().unwrap() *= affine_transform
}
Statement::Transform(affine_transform) => {
- *context_ctm.last_mut().unwrap() = affine_transform
+ *context.ctm.last_mut().unwrap() = affine_transform
}
Statement::Unknown(s, _items) => {
eprintln!("Unknown statement: {s}")
@@ -724,14 +769,14 @@ fn inner_parse_pbrt(path: impl AsRef + std::fmt::Debug) -> Result {
if camera.is_some() {
return Err(miette!("The camera can only be set once."));
}
- camera = Some((c, *context_ctm.last().unwrap()));
- named_transforms.insert(String::from("\"camera\""), *context_ctm.last().unwrap());
+ camera = Some((c, context.get_ctm()));
+ named_transforms.insert(String::from("\"camera\""), context.get_ctm());
}
Statement::CoordinateSystem(s) => {
- named_transforms.insert(s, *context_ctm.last().unwrap());
+ named_transforms.insert(s, context.get_ctm());
}
Statement::CoordSysTransform(s) => {
- *context_ctm.last_mut().unwrap() = *named_transforms
+ *context.ctm.last_mut().unwrap() = *named_transforms
.get(&s)
.ok_or_else(|| miette!("unknown transform"))?;
}
@@ -744,50 +789,72 @@ fn inner_parse_pbrt(path: impl AsRef + std::fmt::Debug) -> Result {
let mut pbrt = Pbrt::new(PbrtWorldSettings { camera, camera_ctm });
- let mut context_ctm = vec![AffineTransform::identity()];
+ context.ctm = vec![AffineTransform::identity()];
// let mut context_material = vec![];
- while let Some(p) = parser.next(&textures).transpose()? {
+ while let Some(p) = parser.next(&context).transpose()? {
match p {
- Statement::AttributeBegin => context_ctm.push(*context_ctm.last().unwrap()),
+ Statement::AttributeBegin => context.push(),
Statement::AttributeEnd => {
- context_ctm.pop();
+ context.pop();
}
Statement::Include(_) => unreachable!(),
Statement::ConcatTransform(affine_transform) => {
- *context_ctm.last_mut().unwrap() *= affine_transform
+ *context.ctm.last_mut().unwrap() *= affine_transform
}
Statement::Transform(affine_transform) => {
- *context_ctm.last_mut().unwrap() = affine_transform
+ *context.ctm.last_mut().unwrap() = affine_transform
}
Statement::Shape(shape_type, shape_alpha) => {
pbrt.scene.shapes.push(Shape {
- ctm: *context_ctm.last().unwrap(),
+ ctm: context.get_ctm(),
material: 0,
obj: shape_type,
alpha: shape_alpha,
});
}
Statement::CoordinateSystem(s) => {
- named_transforms.insert(s, *context_ctm.last().unwrap());
+ named_transforms.insert(s, context.get_ctm());
}
Statement::CoordSysTransform(s) => {
- *context_ctm.last_mut().unwrap() = *named_transforms
+ *context.ctm.last_mut().unwrap() = *named_transforms
.get(&s)
.ok_or_else(|| miette!("unknown transform"))?;
}
+ Statement::Material(m) => {
+ if context.material.is_empty() {
+ context.material.push(m);
+ } else {
+ *context.material.last_mut().unwrap() = m;
+ }
+ }
+ Statement::MakeNamedMaterial(n, m) => {
+ context.materials.insert(n, m);
+ }
+ Statement::NamedMaterial(n) => {
+ let m = Arc::clone(
+ context
+ .get_named_material(&n)
+ .ok_or_else(|| miette!("Unknown named material {n}"))?,
+ );
+ if context.material.is_empty() {
+ context.material.push(m);
+ } else {
+ *context.material.last_mut().unwrap() = m;
+ }
+ }
Statement::Unknown(s, _items) => {
eprintln!("Unknown statement: {s}")
}
Statement::Texture(name, texture) => {
- textures.insert(name, texture);
+ context.textures.insert(name, texture);
}
s => bail!("unexpected statemnet in world settings: {s:?}"),
}
}
- dbg!(textures);
+ dbg!(context);
Ok(pbrt)
}
diff --git a/ray-tracing-pbrt-scene/src/material.rs b/ray-tracing-pbrt-scene/src/material.rs
index 1c71cac..93834c3 100644
--- a/ray-tracing-pbrt-scene/src/material.rs
+++ b/ray-tracing-pbrt-scene/src/material.rs
@@ -1,10 +1,17 @@
+use ray_tracing_core::color::Color;
+
+use crate::{
+ either::Either,
+ texture::{Pbrt_2d_float_texture, Pbrt_2d_spectrum_texture},
+};
+
use super::*;
pub trait PbrtMaterial: std::fmt::Debug + Send + Sync {}
pub fn parse_make_named_material(
input: &mut Tokenizer,
- textures: &HashMap>,
+ context: &PbrtContext,
) -> Result<(String, Arc)> {
let name = input.parse_next()?;
@@ -13,16 +20,202 @@ pub fn parse_make_named_material(
"first element of make named material dict has to be type"
));
}
- Ok((name, parse_material(input, textures)?))
+ Ok((name, parse_material(input, context)?))
}
+#[derive(Debug)]
+struct PbrtCoatedDiffuseMaterial {
+ albedo: Either>,
+ g: Either>,
+ maxdetph: usize,
+ nsamples: usize,
+ thickness: Float,
+ roughness: Either>,
+ uroughness: Either>,
+ vroughness: Either>,
+ reflectance: Either>,
+}
+
+impl PbrtMaterial for PbrtCoatedDiffuseMaterial {}
+
+#[derive(Debug)]
+struct PbrtDielectricMaterial {
+ eta: Either<
+ Either>,
+ Either>,
+ >,
+ roughness: Either>,
+ uroughness: Either>,
+ vroughness: Either>,
+}
+
+impl PbrtMaterial for PbrtDielectricMaterial {}
+
pub fn parse_material(
input: &mut Tokenizer,
- textures: &HashMap>,
+ context: &PbrtContext,
) -> Result> {
let material: String = input.parse_parameter()?;
- dbg!(material);
+ match material.as_str() {
+ "\"coateddiffuse\"" => {
+ let t = parse_dict!(input=>
+ albedo, Either, Either::A(Color::black());
+ g, Either, Either::A(0.0);
+ maxdepth, usize, 10;
+ nsamples, usize, 1;
+ thickness, Float, 0.01;
+ roughness, Either, Either::A(0.0);
+ uroughness, Either, Either::A(0.0);
+ vroughness, Either, Either::A(0.0);
+ reflectance, Either, Either::A(Color::black())
+ =>
+ albedo, "\"rgb albedo\"", Either::A(texture::parse_rgb(input)?);
+ albedo, "\"spectrum albedo\"", Either::A(texture::parse_spectrum(input)?);
+ albedo, "\"texture albedo\"", Either::B(input.parse_parameter()?);
+ g, "\"float g\"", Either::A(input.parse_parameter()?);
+ g, "\"texture g\"", Either::B(input.parse_parameter()?);
+ maxdepth, "\"integer maxdepth\"", input.parse_parameter()?;
+ nsamples, "\"integer nsamples\"", input.parse_parameter()?;
+ thickness, "\"float thickness\"", input.parse_parameter()?;
+ roughness, "\"float roughness\"", Either::A(input.parse_parameter()?);
+ roughness, "\"texture roughness\"", Either::B(input.parse_parameter()?);
+ uroughness, "\"float uroughness\"", Either::A(input.parse_parameter()?);
+ uroughness, "\"texture uroughness\"", Either::B(input.parse_parameter()?);
+ vroughness, "\"float vroughness\"", Either::A(input.parse_parameter()?);
+ vroughness, "\"texture vroughness\"", Either::B(input.parse_parameter()?);
+ reflectance, "\"rgb reflectance\"", Either::A(texture::parse_rgb(input)?);
+ reflectance, "\"spectrum reflectance\"", Either::A(texture::parse_spectrum(input)?);
+ reflectance, "\"texture reflectance\"", Either::B(input.parse_parameter()?)
+ );
- todo!()
+ Ok(Arc::new(PbrtCoatedDiffuseMaterial {
+ albedo: t
+ .albedo
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_spectrum_texture())
+ })
+ .transpose_b()?,
+ g: t.g
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_float_texture())
+ })
+ .transpose_b()?,
+ maxdetph: t.maxdepth,
+ nsamples: t.nsamples,
+ thickness: t.thickness,
+ roughness: t
+ .roughness
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_float_texture())
+ })
+ .transpose_b()?,
+ uroughness: t
+ .uroughness
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_float_texture())
+ })
+ .transpose_b()?,
+ vroughness: t
+ .vroughness
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_float_texture())
+ })
+ .transpose_b()?,
+ reflectance: t
+ .reflectance
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_spectrum_texture())
+ })
+ .transpose_b()?,
+ }))
+ }
+ "\"dielectric\"" => {
+ let t = parse_dict!(input=>
+ eta, Either<
+ Either>,
+ Either>,
+ >, Either::A(Either::A(1.5));
+ roughness, Either, Either::A(0.0);
+ uroughness, Either, Either::A(0.0);
+ vroughness, Either, Either::A(0.0)
+ =>
+ eta, "\"float eta\"", Either::A(Either::A(input.parse_parameter()?));
+ roughness, "\"float roughness\"", Either::A(input.parse_parameter()?);
+ roughness, "\"texture roughness\"", Either::B(input.parse_parameter()?);
+ uroughness, "\"float uroughness\"", Either::A(input.parse_parameter()?);
+ uroughness, "\"texture uroughness\"", Either::B(input.parse_parameter()?);
+ vroughness, "\"float vroughness\"", Either::A(input.parse_parameter()?);
+ vroughness, "\"texture vroughness\"", Either::B(input.parse_parameter()?)
+ );
+
+ Ok(Arc::new(PbrtDielectricMaterial {
+ eta: Either::A(Either::A(1.5)),
+ roughness: t
+ .roughness
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_float_texture())
+ })
+ .transpose_b()?,
+ uroughness: t
+ .uroughness
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_float_texture())
+ })
+ .transpose_b()?,
+ vroughness: t
+ .vroughness
+ .map_b(|n| {
+ context
+ .get_texture(&n)
+ .ok_or_else(|| {
+ miette!("Unknown texture for coateddiffuse material {n}")
+ })
+ .and_then(|t| Arc::clone(t).get_2d_float_texture())
+ })
+ .transpose_b()?,
+ }))
+ }
+ _ => Err(miette!("Unknown material {material}")),
+ }
}
diff --git a/ray-tracing-pbrt-scene/src/texture.rs b/ray-tracing-pbrt-scene/src/texture.rs
index 2991344..5d495d8 100644
--- a/ray-tracing-pbrt-scene/src/texture.rs
+++ b/ray-tracing-pbrt-scene/src/texture.rs
@@ -4,7 +4,7 @@ use ray_tracing_core::{affine_transform::AffineTransform, color::Color, prelude:
use scale::SpectrumScaleTexture2d;
use std::{collections::HashMap, ops::Deref, sync::Arc};
-use crate::tokenizer::Tokenizer;
+use crate::{PbrtContext, either::Either, tokenizer::Tokenizer};
mod checkerboard;
mod imagemap;
@@ -56,18 +56,18 @@ impl TextureMapping {
}
}
-fn parse_spectrum(input: &mut Tokenizer) -> Result {
+pub fn parse_spectrum(input: &mut Tokenizer) -> Result {
todo!()
}
-fn parse_rgb(input: &mut Tokenizer) -> Result {
+pub fn parse_rgb(input: &mut Tokenizer) -> Result {
let t = input.parse_list()?;
Ok(Color::new(t[0], t[1], t[2]))
}
fn parse_float_texture(
input: &mut Tokenizer,
- textures: &HashMap>,
+ context: &PbrtContext,
) -> Result> {
let texture_class: String = input.parse_next()?;
@@ -77,7 +77,7 @@ fn parse_float_texture(
fn parse_spectrum_texture(
input: &mut Tokenizer,
- textures: &HashMap>,
+ context: &PbrtContext,
) -> Result> {
let texture_class: String = input.parse_next()?;
match texture_class.as_str() {
@@ -89,8 +89,8 @@ fn parse_spectrum_texture(
udelta, Float, 0.0;
vdelta, Float, 0.0;
dimension, TextureDimension, TextureDimension::D2;
- tex1, ValueTexture, ValueTexture::Value(Color::white());
- tex2, ValueTexture, ValueTexture::Value(Color::black())
+ tex1, Either, Either::A(Color::white());
+ tex2, Either, Either::A(Color::black())
=>
mapping, "\"string mapping\"", TextureMapping::new(input.parse_parameter()?)?;
uscale, "\"float uscale\"", input.parse_parameter()?;
@@ -98,12 +98,12 @@ fn parse_spectrum_texture(
udelta, "\"float udelta\"", input.parse_parameter()?;
vdelta, "\"float vdelta\"", input.parse_parameter()?;
dimension, "\"integer dimension\"", TextureDimension::new(input.parse_parameter()?)?;
- tex1, "\"rgb tex1\"", ValueTexture::Value(parse_rgb(input)?);
- tex1, "\"spectrum tex1\"", ValueTexture::Value(parse_spectrum(input)?);
- tex1, "\"texture tex1\"", ValueTexture::Texture(input.parse_parameter()?);
- tex2, "\"rgb tex2\"", ValueTexture::Value(parse_rgb(input)?);
- tex2, "\"spectrum tex2\"", ValueTexture::Value(parse_spectrum(input)?);
- tex2, "\"texture tex2\"", ValueTexture::Texture(input.parse_parameter()?)
+ tex1, "\"rgb tex1\"", Either::A(parse_rgb(input)?);
+ tex1, "\"spectrum tex1\"", Either::A(parse_spectrum(input)?);
+ tex1, "\"texture tex1\"", Either::B(input.parse_parameter()?);
+ tex2, "\"rgb tex2\"", Either::A(parse_rgb(input)?);
+ tex2, "\"spectrum tex2\"", Either::A(parse_spectrum(input)?);
+ tex2, "\"texture tex2\"", Either::B(input.parse_parameter()?)
);
@@ -114,22 +114,22 @@ fn parse_spectrum_texture(
mapping,
tex: [
match t.tex1 {
- ValueTexture::Value(v) => ValueTexture::Value(v),
- ValueTexture::Texture(name) => ValueTexture::Texture(
+ Either::A(v) => Either::A(v),
+ Either::B(name) => Either::B(
Arc::clone(
- textures
- .get(&name)
+ context
+ .get_texture(&name)
.ok_or_else(|| miette!("unable to find texture"))?,
)
.get_2d_spectrum_texture()?,
),
},
match t.tex2 {
- ValueTexture::Value(v) => ValueTexture::Value(v),
- ValueTexture::Texture(name) => ValueTexture::Texture(
+ Either::A(v) => Either::A(v),
+ Either::B(name) => Either::B(
Arc::clone(
- textures
- .get(&name)
+ context
+ .get_texture(&name)
.ok_or_else(|| miette!("unable to find texture"))?,
)
.get_2d_spectrum_texture()?,
@@ -182,34 +182,34 @@ fn parse_spectrum_texture(
}
"\"scale\"" => {
let t = parse_dict!(input =>
- tex, ValueTexture, ValueTexture::Value(Color::white());
- scale, ValueTexture, ValueTexture::Value(1.0)
+ tex, Either, Either::A(Color::white());
+ scale, Either, Either::A(1.0)
=>
- tex, "\"rgb tex\"", ValueTexture::Value(parse_rgb(input)?);
- tex, "\"spectrum tex\"", ValueTexture::Value(parse_spectrum(input)?);
- tex, "\"texture tex\"", ValueTexture::Texture(input.parse_parameter()?);
- scale, "\"float scale\"", ValueTexture::Value(input.parse_parameter()?);
- scale, "\"texture scale\"", ValueTexture::Texture(input.parse_parameter()?)
+ tex, "\"rgb tex\"", Either::A(parse_rgb(input)?);
+ tex, "\"spectrum tex\"", Either::A(parse_spectrum(input)?);
+ tex, "\"texture tex\"", Either::B(input.parse_parameter()?);
+ scale, "\"float scale\"", Either::A(input.parse_parameter()?);
+ scale, "\"texture scale\"", Either::B(input.parse_parameter()?)
);
Ok(Arc::new(SpectrumScaleTexture2d {
tex: match t.tex {
- ValueTexture::Value(v) => ValueTexture::Value(v),
- ValueTexture::Texture(t) => ValueTexture::Texture(
+ Either::A(v) => Either::A(v),
+ Either::B(t) => Either::B(
Arc::clone(
- textures
- .get(&t)
+ context
+ .get_texture(&t)
.ok_or_else(|| miette!("Unable to find texture scale"))?,
)
.get_2d_spectrum_texture()?,
),
},
scale: match t.scale {
- ValueTexture::Value(v) => ValueTexture::Value(v),
- ValueTexture::Texture(t) => ValueTexture::Texture(
+ Either::A(v) => Either::A(v),
+ Either::B(t) => Either::B(
Arc::clone(
- textures
- .get(&t)
+ context
+ .get_texture(&t)
.ok_or_else(|| miette!("Unable to find texture scale"))?,
)
.get_2d_float_texture()?,
@@ -223,14 +223,14 @@ fn parse_spectrum_texture(
pub fn parse_texture(
input: &mut Tokenizer,
- textures: &HashMap>,
+ context: &PbrtContext,
) -> Result<(String, Arc)> {
let texture_name: String = input.parse_next()?;
let texture_type: String = input.parse_next()?;
match texture_type.as_str() {
- "\"spectrum\"" => parse_spectrum_texture(input, textures).map(|t| (texture_name, t)),
- "\"float\"" => parse_float_texture(input, textures).map(|t| (texture_name, t)),
+ "\"spectrum\"" => parse_spectrum_texture(input, context).map(|t| (texture_name, t)),
+ "\"float\"" => parse_float_texture(input, context).map(|t| (texture_name, t)),
_ => Err(miette!("Texture type has to be spectrum or float")),
}
}
@@ -267,9 +267,3 @@ impl UVMapping {
}
}
}
-
-#[derive(Debug)]
-enum ValueTexture {
- Value(V),
- Texture(T),
-}
diff --git a/ray-tracing-pbrt-scene/src/texture/checkerboard.rs b/ray-tracing-pbrt-scene/src/texture/checkerboard.rs
index 13f988a..7fd5e3c 100644
--- a/ray-tracing-pbrt-scene/src/texture/checkerboard.rs
+++ b/ray-tracing-pbrt-scene/src/texture/checkerboard.rs
@@ -3,7 +3,7 @@ use super::*;
#[derive(Debug)]
pub(super) struct FloatCheckerboardTexture2d {
pub(super) mapping: UVMapping,
- pub(super) tex: [ValueTexture>; 2],
+ pub(super) tex: [Either>; 2],
}
impl Pbrt_2d_float_texture for FloatCheckerboardTexture2d {
@@ -21,8 +21,8 @@ impl Pbrt_2d_float_texture for FloatCheckerboardTexture2d {
};
match &self.tex[even as usize] {
- ValueTexture::Value(v) => *v,
- ValueTexture::Texture(t) => t.get(u, v),
+ Either::A(v) => *v,
+ Either::B(t) => t.get(u, v),
}
}
}
@@ -43,7 +43,7 @@ impl PbrtTexture for FloatCheckerboardTexture2d {
#[derive(Debug)]
pub(super) struct SpectrumCheckerboardTexture2d {
pub(super) mapping: UVMapping,
- pub(super) tex: [ValueTexture>; 2],
+ pub(super) tex: [Either>; 2],
}
impl Pbrt_2d_spectrum_texture for SpectrumCheckerboardTexture2d {
@@ -61,8 +61,8 @@ impl Pbrt_2d_spectrum_texture for SpectrumCheckerboardTexture2d {
};
match &self.tex[even as usize] {
- ValueTexture::Value(v) => *v,
- ValueTexture::Texture(t) => t.get(u, v),
+ Either::A(v) => *v,
+ Either::B(t) => t.get(u, v),
}
}
}
diff --git a/ray-tracing-pbrt-scene/src/texture/scale.rs b/ray-tracing-pbrt-scene/src/texture/scale.rs
index 88ac284..ab3189f 100644
--- a/ray-tracing-pbrt-scene/src/texture/scale.rs
+++ b/ray-tracing-pbrt-scene/src/texture/scale.rs
@@ -2,8 +2,8 @@ use super::*;
#[derive(Debug)]
pub(super) struct SpectrumScaleTexture2d {
- pub(super) tex: ValueTexture>,
- pub(super) scale: ValueTexture>,
+ pub(super) tex: Either>,
+ pub(super) scale: Either>,
}
impl PbrtTexture for SpectrumScaleTexture2d {
@@ -23,13 +23,13 @@ impl PbrtTexture for SpectrumScaleTexture2d {
impl Pbrt_2d_spectrum_texture for SpectrumScaleTexture2d {
fn get(&self, u: Float, v: Float) -> Color {
let x = match &self.tex {
- ValueTexture::Value(x) => *x,
- ValueTexture::Texture(t) => t.get(u, v),
+ Either::A(x) => *x,
+ Either::B(t) => t.get(u, v),
};
let s = match &self.scale {
- ValueTexture::Value(s) => *s,
- ValueTexture::Texture(t) => t.get(u, v),
+ Either::A(s) => *s,
+ Either::B(t) => t.get(u, v),
};
x * s
diff --git a/ray-tracing-pbrt-scene/src/tokenizer.rs b/ray-tracing-pbrt-scene/src/tokenizer.rs
index 1984032..b0187bf 100644
--- a/ray-tracing-pbrt-scene/src/tokenizer.rs
+++ b/ray-tracing-pbrt-scene/src/tokenizer.rs
@@ -1,4 +1,5 @@
-use miette::{Diagnostic, Error, IntoDiagnostic, Report, Result, SourceSpan, bail, miette};
+use crate::{BytesToChar, error::SourceFile};
+use miette::{Diagnostic, Error, IntoDiagnostic, Report, Result, SourceSpan};
use std::{
fs::File,
io::{BufReader, Bytes, Read},
@@ -7,8 +8,6 @@ use std::{
};
use thiserror::Error;
-use crate::{BytesToChar, SourceFile};
-
pub struct Tokenizer {
inner: InnerTokenizer,
path: PathBuf,
@@ -446,6 +445,16 @@ macro_rules! parse_dict {
};
}
+// macro_rules! parse_dict2_internal {
+// () => {};
+// }
+
+// macro_rules! parse_dict2 {
+// ($tokenizer:expr, $struct:expr; $($name:ident, [$($parse_name:expr, $parsing:expr);*]);+) => {
+
+// };
+// }
+
#[derive(Error, Debug, Diagnostic)]
#[error("Duplicate dict entry error")]
#[diagnostic(help("multiple dict entries with the same key"))]