First materials succesfully parsed
This commit is contained in:
parent
9a95ca8fd7
commit
c8ff77a0a9
5 changed files with 197 additions and 172 deletions
|
|
@ -10,3 +10,4 @@ miette = { version = "7.6.0", features = ["fancy"] }
|
|||
nom = "8.0.0"
|
||||
thiserror = "2.0.12"
|
||||
image = "0.25.6"
|
||||
const_format = "0.2.34"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::tokenizer::Tokenizer;
|
||||
use crate::{texture::Pbrt_2d_float_texture, tokenizer::Tokenizer};
|
||||
use error::SourceFile;
|
||||
use material::PbrtMaterial;
|
||||
use miette::{IntoDiagnostic, Result, bail, miette};
|
||||
use miette::{Diagnostic, IntoDiagnostic, Result, SourceSpan, bail, miette};
|
||||
use ray_tracing_core::{
|
||||
affine_transform::AffineTransform,
|
||||
math::{Dir3, Pos3},
|
||||
|
|
@ -12,6 +13,7 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
use texture::PbrtTexture;
|
||||
use thiserror::Error;
|
||||
|
||||
#[macro_use]
|
||||
mod tokenizer;
|
||||
|
|
@ -642,7 +644,7 @@ enum ShapeAlpha {
|
|||
#[derive(Debug)]
|
||||
struct Shape {
|
||||
ctm: AffineTransform,
|
||||
material: usize,
|
||||
material: Arc<dyn PbrtMaterial>,
|
||||
obj: ShapeType,
|
||||
alpha: ShapeAlpha,
|
||||
}
|
||||
|
|
@ -809,7 +811,12 @@ fn inner_parse_pbrt(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
|||
Statement::Shape(shape_type, shape_alpha) => {
|
||||
pbrt.scene.shapes.push(Shape {
|
||||
ctm: context.get_ctm(),
|
||||
material: 0,
|
||||
material: Arc::clone(
|
||||
context
|
||||
.material
|
||||
.last()
|
||||
.ok_or_else(|| miette!("No material specified"))?,
|
||||
),
|
||||
obj: shape_type,
|
||||
alpha: shape_alpha,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use ray_tracing_core::color::Color;
|
|||
|
||||
use crate::{
|
||||
either::Either,
|
||||
texture::{Pbrt_2d_float_texture, Pbrt_2d_spectrum_texture},
|
||||
texture::{Pbrt_2d_float_texture, Pbrt_2d_spectrum_texture, parse_rgb},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
|
@ -27,13 +27,17 @@ pub fn parse_make_named_material(
|
|||
struct PbrtCoatedDiffuseMaterial {
|
||||
albedo: Either<Color, Arc<dyn Pbrt_2d_spectrum_texture>>,
|
||||
g: Either<Float, Arc<dyn Pbrt_2d_float_texture>>,
|
||||
maxdetph: usize,
|
||||
maxdepth: usize,
|
||||
nsamples: usize,
|
||||
thickness: Float,
|
||||
roughness: Either<Float, Arc<dyn Pbrt_2d_float_texture>>,
|
||||
uroughness: Either<Float, Arc<dyn Pbrt_2d_float_texture>>,
|
||||
vroughness: Either<Float, Arc<dyn Pbrt_2d_float_texture>>,
|
||||
reflectance: Either<Color, Arc<dyn Pbrt_2d_spectrum_texture>>,
|
||||
eta: Either<
|
||||
Either<Float, Arc<dyn Pbrt_2d_float_texture>>,
|
||||
Either<Color, Arc<dyn Pbrt_2d_spectrum_texture>>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl PbrtMaterial for PbrtCoatedDiffuseMaterial {}
|
||||
|
|
@ -51,6 +55,37 @@ struct PbrtDielectricMaterial {
|
|||
|
||||
impl PbrtMaterial for PbrtDielectricMaterial {}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PbrtDiffuseMaterial {
|
||||
reflectance: Either<Color, Arc<dyn Pbrt_2d_spectrum_texture>>,
|
||||
}
|
||||
|
||||
impl PbrtMaterial for PbrtDiffuseMaterial {}
|
||||
|
||||
fn parse_2d_float_texture(
|
||||
input: &mut Tokenizer,
|
||||
context: &PbrtContext,
|
||||
) -> Result<Arc<dyn Pbrt_2d_float_texture>> {
|
||||
let n = input.parse_parameter()?;
|
||||
|
||||
context
|
||||
.get_texture(&n)
|
||||
.ok_or_else(|| miette!("Unknown texture"))
|
||||
.and_then(|t| Arc::clone(t).get_2d_float_texture())
|
||||
}
|
||||
|
||||
fn parse_2d_spectrum_texture(
|
||||
input: &mut Tokenizer,
|
||||
context: &PbrtContext,
|
||||
) -> Result<Arc<dyn Pbrt_2d_spectrum_texture>> {
|
||||
let n = input.parse_parameter()?;
|
||||
|
||||
context
|
||||
.get_texture(&n)
|
||||
.ok_or_else(|| miette!("Unknown texture"))
|
||||
.and_then(|t| Arc::clone(t).get_2d_spectrum_texture())
|
||||
}
|
||||
|
||||
pub fn parse_material(
|
||||
input: &mut Tokenizer,
|
||||
context: &PbrtContext,
|
||||
|
|
@ -58,164 +93,84 @@ pub fn parse_material(
|
|||
let material: String = input.parse_parameter()?;
|
||||
|
||||
match material.as_str() {
|
||||
"\"coateddiffuse\"" => {
|
||||
let t = parse_dict!(input=>
|
||||
albedo, Either<Color, String>, Either::A(Color::black());
|
||||
g, Either<Float, String>, Either::A(0.0);
|
||||
maxdepth, usize, 10;
|
||||
nsamples, usize, 1;
|
||||
thickness, Float, 0.01;
|
||||
roughness, Either<Float, String>, Either::A(0.0);
|
||||
uroughness, Either<Float, String>, Either::A(0.0);
|
||||
vroughness, Either<Float, String>, Either::A(0.0);
|
||||
reflectance, Either<Color, String>, 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()?)
|
||||
);
|
||||
|
||||
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<Float, Arc<dyn Pbrt_2d_float_texture>>,
|
||||
Either<Color, Arc<dyn Pbrt_2d_spectrum_texture>>,
|
||||
>, Either::A(Either::A(1.5));
|
||||
roughness, Either<Float, String>, Either::A(0.0);
|
||||
uroughness, Either<Float, String>, Either::A(0.0);
|
||||
vroughness, Either<Float, String>, 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()?,
|
||||
}))
|
||||
}
|
||||
"\"diffuse\"" => Ok(Arc::new(parse_dict2!(input, PbrtDiffuseMaterial;
|
||||
reflectance, Either::A(Color::black()), [
|
||||
"\"rgb reflectance\"", Either::A(texture::parse_rgb(input)?);
|
||||
"\"spectrum reflectance\"", Either::A(texture::parse_spectrum(input)?);
|
||||
"\"texture reflectance\"", Either::B(parse_2d_spectrum_texture(input, context)?)
|
||||
]
|
||||
))),
|
||||
"\"coateddiffuse\"" => Ok(Arc::new(parse_dict2!(input, PbrtCoatedDiffuseMaterial;
|
||||
albedo, Either::A(Color::black()), [
|
||||
"\"rgb albedo\"", Either::A(texture::parse_rgb(input)?);
|
||||
"\"spectrum albedo\"", Either::A(texture::parse_spectrum(input)?);
|
||||
"\"texture albedo\"", Either::B(parse_2d_spectrum_texture(input, context)?)
|
||||
];
|
||||
g, Either::A(0.0), [
|
||||
"\"float g\"", Either::A(input.parse_parameter()?);
|
||||
"\"texture g\"", Either::B(parse_2d_float_texture(input, context)?)
|
||||
];
|
||||
maxdepth, 10, ["\"integer maxdepth\"", input.parse_parameter()?];
|
||||
nsamples, 1, ["\"integer nsamples\"", input.parse_parameter()?];
|
||||
thickness, 0.01, ["\"float thickness\"", input.parse_parameter()?];
|
||||
roughness, Either::A(0.0), [
|
||||
"\"float roughness\"", Either::A(input.parse_parameter()?);
|
||||
"\"texture roughness\"", Either::B(parse_2d_float_texture(input, context)?)
|
||||
];
|
||||
uroughness, Either::A(0.0), [
|
||||
"\"float uroughness\"", Either::A(input.parse_parameter()?);
|
||||
"\"texture uroughness\"", Either::B(parse_2d_float_texture(input, context)?)
|
||||
];
|
||||
vroughness, Either::A(0.0), [
|
||||
"\"float vroughness\"", Either::A(input.parse_parameter()?);
|
||||
"\"texture vroughness\"", Either::B(parse_2d_float_texture(input, context)?)
|
||||
];
|
||||
reflectance, Either::A(Color::black()), [
|
||||
"\"rgb reflectance\"", Either::A(texture::parse_rgb(input)?);
|
||||
"\"spectrum reflectance\"", Either::A(texture::parse_spectrum(input)?);
|
||||
"\"texture reflectance\"", Either::B(parse_2d_spectrum_texture(input, context)?)
|
||||
];
|
||||
eta, Either::A(Either::A(1.5)), [
|
||||
"\"float eta\"", Either::A(Either::A(input.parse_parameter()?));
|
||||
"\"rgb eta\"", Either::B(Either::A(parse_rgb(input)?));
|
||||
"\"spectrum eta\"", Either::B(Either::A(texture::parse_spectrum(input)?));
|
||||
"\"texture eta\"", {
|
||||
let n = input.parse_parameter()?;
|
||||
let t = context.get_texture(&n).ok_or_else(|| miette!("Unknown texture"))?;
|
||||
match Arc::clone(t).get_2d_spectrum_texture() {
|
||||
Ok(t) => Either::B(Either::B(t)),
|
||||
Err(_) => Either::A(Either::B(Arc::clone(t).get_2d_float_texture()?))
|
||||
}
|
||||
}
|
||||
]
|
||||
))),
|
||||
"\"dielectric\"" => Ok(Arc::new(parse_dict2!(input, PbrtDielectricMaterial;
|
||||
eta, Either::A(Either::A(1.5)), [
|
||||
"\"float eta\"", Either::A(Either::A(input.parse_parameter()?));
|
||||
"\"rgb eta\"", Either::B(Either::A(parse_rgb(input)?));
|
||||
"\"spectrum eta\"", Either::B(Either::A(texture::parse_spectrum(input)?));
|
||||
"\"texture eta\"", {
|
||||
let n = input.parse_parameter()?;
|
||||
let t = context.get_texture(&n).ok_or_else(|| miette!("Unknown texture"))?;
|
||||
match Arc::clone(t).get_2d_spectrum_texture() {
|
||||
Ok(t) => Either::B(Either::B(t)),
|
||||
Err(_) => Either::A(Either::B(Arc::clone(t).get_2d_float_texture()?))
|
||||
}
|
||||
}
|
||||
];
|
||||
roughness, Either::A(0.0), [
|
||||
"\"float roughness\"", Either::A(input.parse_parameter()?);
|
||||
"\"texture roughness\"", Either::B(parse_2d_float_texture(input, context)?)
|
||||
];
|
||||
uroughness, Either::A(0.0), [
|
||||
"\"float uroughness\"", Either::A(input.parse_parameter()?);
|
||||
"\"texture uroughness\"", Either::B(parse_2d_float_texture(input, context)?)
|
||||
];
|
||||
vroughness, Either::A(0.0), [
|
||||
"\"float vroughness\"", Either::A(input.parse_parameter()?);
|
||||
"\"texture vroughness\"", Either::B(parse_2d_float_texture(input, context)?)
|
||||
]
|
||||
))),
|
||||
_ => Err(miette!("Unknown material {material}")),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
use crate::{BytesToChar, error::SourceFile};
|
||||
use crate::{
|
||||
BytesToChar, PbrtContext, either::Either, error::SourceFile, texture::Pbrt_2d_float_texture,
|
||||
};
|
||||
use const_format::concatcp;
|
||||
use miette::{Diagnostic, Error, IntoDiagnostic, Report, Result, SourceSpan};
|
||||
use ray_tracing_core::prelude::Float;
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufReader, Bytes, Read},
|
||||
iter::Peekable,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
|
|
@ -445,15 +450,45 @@ macro_rules! parse_dict {
|
|||
};
|
||||
}
|
||||
|
||||
// macro_rules! parse_dict2_internal {
|
||||
// () => {};
|
||||
// }
|
||||
macro_rules! parse_dict2 {
|
||||
($tokenizer:expr, $struct:path; $($name:ident, $default:expr, [$($parse_name:expr, $parsing:expr);*]);+) => {
|
||||
{
|
||||
$(
|
||||
#[allow(unused_mut)]
|
||||
let mut $name = None;
|
||||
)+
|
||||
|
||||
// macro_rules! parse_dict2 {
|
||||
// ($tokenizer:expr, $struct:expr; $($name:ident, [$($parse_name:expr, $parsing:expr);*]);+) => {
|
||||
while let Some(p) = $tokenizer.next_if(|p| p.starts_with('"')).transpose()? {
|
||||
match p.as_str() {
|
||||
$(
|
||||
$(
|
||||
$parse_name => {
|
||||
if $name.is_none() {
|
||||
$name = Some($parsing);
|
||||
} else {
|
||||
return Err($crate::tokenizer::DuplicateDictEntryError {bad_bit: $tokenizer.last_span(), src: $tokenizer.get_src()}.into())
|
||||
}
|
||||
}
|
||||
)*
|
||||
)+
|
||||
_ => {
|
||||
return Err($crate::tokenizer::UnknownDictEntryError {bad_bit: $tokenizer.last_span(), src: $tokenizer.get_src()}.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// };
|
||||
// }
|
||||
$struct {
|
||||
$(
|
||||
$name: match $name {
|
||||
Some(v) => v,
|
||||
None => {$default},
|
||||
},
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Diagnostic)]
|
||||
#[error("Duplicate dict entry error")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue