Add named transforms and camera parsing.
This commit is contained in:
parent
63a210b8b4
commit
b4d34aa6ca
2 changed files with 180 additions and 50 deletions
|
|
@ -12,7 +12,7 @@ fn main() -> Result<(), miette::Error> {
|
||||||
|
|
||||||
let t = parse_pbrt_v4(args.filename)?;
|
let t = parse_pbrt_v4(args.filename)?;
|
||||||
|
|
||||||
dbg!(t);
|
// dbg!(t);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@ use ray_tracing_core::{
|
||||||
math::{Dir3, Pos3},
|
math::{Dir3, Pos3},
|
||||||
prelude::Float,
|
prelude::Float,
|
||||||
};
|
};
|
||||||
use std::path::{Path, PathBuf};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
@ -25,13 +28,40 @@ impl Lexer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum CameraType {
|
||||||
|
Orthographic {
|
||||||
|
frame_aspect_ratio: Option<Float>,
|
||||||
|
screen_window: Option<Float>,
|
||||||
|
lens_radius: Float,
|
||||||
|
focal_distance: Float,
|
||||||
|
},
|
||||||
|
Perspective {
|
||||||
|
frame_aspect_ratio: Option<Float>,
|
||||||
|
screen_window: Option<Float>,
|
||||||
|
lens_radius: Float,
|
||||||
|
focal_distance: Float,
|
||||||
|
fov: Float,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct PbrtCamera {
|
||||||
|
camera_type: CameraType,
|
||||||
|
shutter_open: Float,
|
||||||
|
shutter_close: Float,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Statement {
|
enum Statement {
|
||||||
AttributeBegin,
|
AttributeBegin,
|
||||||
AttributeEnd,
|
AttributeEnd,
|
||||||
WorldBegin,
|
WorldBegin,
|
||||||
|
Camera(PbrtCamera),
|
||||||
Include(String),
|
Include(String),
|
||||||
ConcatTransform(AffineTransform),
|
ConcatTransform(AffineTransform),
|
||||||
|
CoordinateSystem(String),
|
||||||
|
CoordSysTransform(String),
|
||||||
Shape(ShapeType, ShapeAlpha),
|
Shape(ShapeType, ShapeAlpha),
|
||||||
Unknown(String, Vec<String>),
|
Unknown(String, Vec<String>),
|
||||||
Transform(AffineTransform),
|
Transform(AffineTransform),
|
||||||
|
|
@ -90,7 +120,7 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
n, "\"normal N\"", iter.parse_list_3(Dir3::new)?;
|
n, "\"normal N\"", iter.parse_list_3(Dir3::new)?;
|
||||||
s, "\"normal S\"", iter.parse_list_3(Dir3::new)?;
|
s, "\"normal S\"", iter.parse_list_3(Dir3::new)?;
|
||||||
uv, "\"point2 uv\"", iter.parse_list_2(|u, v| [u, v])?;
|
uv, "\"point2 uv\"", iter.parse_list_2(|u, v| [u, v])?;
|
||||||
indices, "\"interger indices\"", iter.parse_list()?;
|
indices, "\"integer indices\"", iter.parse_list()?;
|
||||||
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
||||||
);
|
);
|
||||||
|
|
@ -142,7 +172,7 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
p, "\"point3 P\"", iter.parse_list_3(Pos3::new)?;
|
p, "\"point3 P\"", iter.parse_list_3(Pos3::new)?;
|
||||||
n, "\"normal N\"", iter.parse_list_3(Dir3::new)?;
|
n, "\"normal N\"", iter.parse_list_3(Dir3::new)?;
|
||||||
uv, "\"point2 uv\"", iter.parse_list_2(|u, v| [u, v])?;
|
uv, "\"point2 uv\"", iter.parse_list_2(|u, v| [u, v])?;
|
||||||
indices, "\"interger indices\"", iter.parse_list()?;
|
indices, "\"integer indices\"", iter.parse_list()?;
|
||||||
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
||||||
);
|
);
|
||||||
|
|
@ -186,8 +216,8 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
p, Vec<Pos3>, Vec::new();
|
p, Vec<Pos3>, Vec::new();
|
||||||
alpha, ShapeAlpha, ShapeAlpha::None
|
alpha, ShapeAlpha, ShapeAlpha::None
|
||||||
=>
|
=>
|
||||||
levels, "\"float levels\"", iter.parse_parameter()?;
|
levels, "\"integer levels\"", iter.parse_parameter()?;
|
||||||
indices, "\"interger indices\"", iter.parse_list()?;
|
indices, "\"integer indices\"", iter.parse_list()?;
|
||||||
p, "\"point3 P\"", iter.parse_list_3(Pos3::new)?;
|
p, "\"point3 P\"", iter.parse_list_3(Pos3::new)?;
|
||||||
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
||||||
|
|
@ -243,8 +273,8 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
edgelength, Float, 1.0;
|
edgelength, Float, 1.0;
|
||||||
alpha, ShapeAlpha, ShapeAlpha::None
|
alpha, ShapeAlpha, ShapeAlpha::None
|
||||||
=>
|
=>
|
||||||
filename, "\"string filename\"", iter.parse_next()?;
|
filename, "\"string filename\"", iter.parse_parameter()?;
|
||||||
displacement, "\"string displacement\"", Some(iter.parse_next()?);
|
displacement, "\"string displacement\"", Some(iter.parse_parameter()?);
|
||||||
edgelength, "\"float edgelength\"", iter.parse_parameter()?;
|
edgelength, "\"float edgelength\"", iter.parse_parameter()?;
|
||||||
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
|
||||||
|
|
@ -263,8 +293,77 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_camera(tokenizer: &mut Tokenizer) -> Result<Statement> {
|
||||||
|
let camera_type = tokenizer
|
||||||
|
.next()
|
||||||
|
.ok_or(miette!("unable to get shape type"))??;
|
||||||
|
|
||||||
|
match camera_type.as_str() {
|
||||||
|
"\"orthographic\"" => {
|
||||||
|
let t = parse_dict!(tokenizer =>
|
||||||
|
shutteropen, Float, 0.0;
|
||||||
|
shutterclose, Float, 1.0;
|
||||||
|
frame_aspect_ratio, Option<Float>, None;
|
||||||
|
screen_window, Option<Float>, None;
|
||||||
|
lens_radius, Float, 0.0;
|
||||||
|
focal_distance, Float, Float::powi(10.0, 30)
|
||||||
|
=>
|
||||||
|
shutteropen, "\"float shutteropen\"", tokenizer.parse_parameter()?;
|
||||||
|
shutterclose, "\"float shutterclose\"", tokenizer.parse_parameter()?;
|
||||||
|
frame_aspect_ratio, "\"float frameaspectratio\"", Some(tokenizer.parse_parameter()?);
|
||||||
|
screen_window, "\"float screenwindow\"", Some(tokenizer.parse_parameter()?);
|
||||||
|
lens_radius, "\"float lensradius\"", tokenizer.parse_parameter()?;
|
||||||
|
focal_distance, "\"float focaldistance\"", tokenizer.parse_parameter()?
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Statement::Camera(PbrtCamera {
|
||||||
|
camera_type: CameraType::Orthographic {
|
||||||
|
frame_aspect_ratio: t.frame_aspect_ratio,
|
||||||
|
screen_window: t.screen_window,
|
||||||
|
lens_radius: t.lens_radius,
|
||||||
|
focal_distance: t.focal_distance,
|
||||||
|
},
|
||||||
|
shutter_open: t.shutteropen,
|
||||||
|
shutter_close: t.shutterclose,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
"\"perspective\"" => {
|
||||||
|
let t = parse_dict!(tokenizer =>
|
||||||
|
shutteropen, Float, 0.0;
|
||||||
|
shutterclose, Float, 1.0;
|
||||||
|
frame_aspect_ratio, Option<Float>, None;
|
||||||
|
screen_window, Option<Float>, None;
|
||||||
|
lens_radius, Float, 0.0;
|
||||||
|
focal_distance, Float, Float::powi(10.0, 30);
|
||||||
|
fov, Float, 90.0
|
||||||
|
=>
|
||||||
|
shutteropen, "\"float shutteropen\"", tokenizer.parse_parameter()?;
|
||||||
|
shutterclose, "\"float shutterclose\"", tokenizer.parse_parameter()?;
|
||||||
|
frame_aspect_ratio, "\"float frameaspectratio\"", Some(tokenizer.parse_parameter()?);
|
||||||
|
screen_window, "\"float screenwindow\"", Some(tokenizer.parse_parameter()?);
|
||||||
|
lens_radius, "\"float lensradius\"", tokenizer.parse_parameter()?;
|
||||||
|
focal_distance, "\"float focaldistance\"", tokenizer.parse_parameter()?;
|
||||||
|
fov, "\"float fov\"", tokenizer.parse_parameter()?
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Statement::Camera(PbrtCamera {
|
||||||
|
camera_type: CameraType::Perspective {
|
||||||
|
frame_aspect_ratio: t.frame_aspect_ratio,
|
||||||
|
screen_window: t.screen_window,
|
||||||
|
lens_radius: t.lens_radius,
|
||||||
|
focal_distance: t.focal_distance,
|
||||||
|
fov: t.fov,
|
||||||
|
},
|
||||||
|
shutter_open: t.shutteropen,
|
||||||
|
shutter_close: t.shutterclose,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
_ => Err(miette!("Unknown camera_type {}", camera_type)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Lexer {
|
impl Lexer {
|
||||||
fn next(&mut self, ctm: AffineTransform) -> Option<Result<Statement>> {
|
fn next(&mut self) -> Option<Result<Statement>> {
|
||||||
match self.input.next() {
|
match self.input.next() {
|
||||||
Some(Ok(s)) => match s.as_str() {
|
Some(Ok(s)) => match s.as_str() {
|
||||||
"AttributeBegin" => Some(Ok(Statement::AttributeBegin)),
|
"AttributeBegin" => Some(Ok(Statement::AttributeBegin)),
|
||||||
|
|
@ -280,6 +379,7 @@ impl Lexer {
|
||||||
|
|
||||||
Some(Ok(Statement::Include(s)))
|
Some(Ok(Statement::Include(s)))
|
||||||
}
|
}
|
||||||
|
"Camera" => Some(parse_camera(&mut self.input)),
|
||||||
"LookAt" => Some(parse_look_at(&mut self.input)),
|
"LookAt" => Some(parse_look_at(&mut self.input)),
|
||||||
"Identity" => Some(Ok(Statement::ConcatTransform(AffineTransform::identity()))),
|
"Identity" => Some(Ok(Statement::ConcatTransform(AffineTransform::identity()))),
|
||||||
"Translate" => Some(parse_translate(&mut self.input)),
|
"Translate" => Some(parse_translate(&mut self.input)),
|
||||||
|
|
@ -290,6 +390,15 @@ impl Lexer {
|
||||||
"ConcatTransform" => {
|
"ConcatTransform" => {
|
||||||
Some(parse_transform(&mut self.input).map(Statement::ConcatTransform))
|
Some(parse_transform(&mut self.input).map(Statement::ConcatTransform))
|
||||||
}
|
}
|
||||||
|
"CoordinateSystem" => Some(match self.input.parse_parameter() {
|
||||||
|
Ok(s) => Ok(Statement::CoordinateSystem(s)),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}),
|
||||||
|
"CoordSysTransform" => Some(match self.input.parse_parameter() {
|
||||||
|
Ok(s) => Ok(Statement::CoordSysTransform(s)),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}),
|
||||||
|
|
||||||
"WorldBegin" => Some(Ok(Statement::WorldBegin)),
|
"WorldBegin" => Some(Ok(Statement::WorldBegin)),
|
||||||
_ => {
|
_ => {
|
||||||
if s.chars().any(|c| !c.is_ascii_alphabetic()) {
|
if s.chars().any(|c| !c.is_ascii_alphabetic()) {
|
||||||
|
|
@ -441,20 +550,20 @@ impl<P: AsRef<Path> + std::fmt::Debug> Parser<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: AsRef<Path>> Parser<P> {
|
impl<P: AsRef<Path>> Parser<P> {
|
||||||
fn next(&mut self, context: &PbrtContext) -> Option<Result<Statement>> {
|
fn next(&mut self) -> Option<Result<Statement>> {
|
||||||
if let Some(iter) = &mut self.inner {
|
if let Some(iter) = &mut self.inner {
|
||||||
if let Some(statement) = iter.next(context) {
|
if let Some(statement) = iter.next() {
|
||||||
return Some(statement);
|
return Some(statement);
|
||||||
}
|
}
|
||||||
self.inner = None;
|
self.inner = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.iter.next(context.ctm) {
|
match self.iter.next() {
|
||||||
Some(Ok(Statement::Include(s))) => {
|
Some(Ok(Statement::Include(s))) => {
|
||||||
let path = self.path.as_ref().parent().unwrap().join(s);
|
let path = self.path.as_ref().parent().unwrap().join(s);
|
||||||
self.inner = Some(Box::new(Parser::new(path).unwrap()));
|
self.inner = Some(Box::new(Parser::new(path).unwrap()));
|
||||||
|
|
||||||
self.next(context)
|
self.next()
|
||||||
}
|
}
|
||||||
Some(s) => Some(s),
|
Some(s) => Some(s),
|
||||||
None => None,
|
None => None,
|
||||||
|
|
@ -523,104 +632,125 @@ pub struct Pbrt {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pbrt {
|
impl Pbrt {
|
||||||
fn new() -> Self {
|
fn new(settings: PbrtWorldSettings) -> Self {
|
||||||
Self {
|
Self {
|
||||||
settings: PbrtWorldSettings {},
|
settings,
|
||||||
scene: PbrtScene { shapes: Vec::new() },
|
scene: PbrtScene { shapes: Vec::new() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct PbrtWorldSettings {}
|
struct PbrtWorldSettings {
|
||||||
|
camera: PbrtCamera,
|
||||||
|
camera_ctm: AffineTransform,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct PbrtScene {
|
struct PbrtScene {
|
||||||
shapes: Vec<Shape>,
|
shapes: Vec<Shape>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
fn inner_parse_pbrt(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
||||||
struct PbrtContext {
|
|
||||||
ctm: AffineTransform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PbrtContext {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
ctm: AffineTransform::identity(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inner_parse_pbrt(
|
|
||||||
path: impl AsRef<Path> + std::fmt::Debug,
|
|
||||||
context: Option<PbrtContext>,
|
|
||||||
) -> Result<Pbrt> {
|
|
||||||
// unwrap on context.last() ok because context is never empty
|
// unwrap on context.last() ok because context is never empty
|
||||||
let mut context = vec![context.unwrap_or(PbrtContext::new())];
|
let mut context = vec![AffineTransform::identity()];
|
||||||
|
|
||||||
let mut parser = Parser::new(path)?;
|
let mut parser = Parser::new(path)?;
|
||||||
|
|
||||||
let mut pbrt = Pbrt::new();
|
|
||||||
|
|
||||||
// parse global settings
|
// parse global settings
|
||||||
|
|
||||||
|
let mut camera = None;
|
||||||
|
|
||||||
|
let mut named_transforms = HashMap::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let p = parser
|
let p = parser.next().ok_or_else(|| miette!(""))??;
|
||||||
.next(context.last().unwrap())
|
|
||||||
.ok_or_else(|| miette!(""))??;
|
|
||||||
// dbg!(&p);
|
// dbg!(&p);
|
||||||
match p {
|
match p {
|
||||||
Statement::AttributeBegin => context.push(context.last().ok_or(miette!(""))?.clone()),
|
Statement::AttributeBegin => context.push(*context.last().unwrap()),
|
||||||
Statement::AttributeEnd => {
|
Statement::AttributeEnd => {
|
||||||
context.pop();
|
context.pop();
|
||||||
|
if context.is_empty() {
|
||||||
|
return Err(miette!("Attribute end does not match."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Statement::Include(_) => unreachable!(),
|
Statement::Include(_) => unreachable!(),
|
||||||
Statement::ConcatTransform(affine_transform) => {
|
Statement::ConcatTransform(affine_transform) => {
|
||||||
context.last_mut().ok_or(miette!(""))?.ctm *= affine_transform
|
*context.last_mut().unwrap() *= affine_transform
|
||||||
}
|
}
|
||||||
Statement::Transform(affine_transform) => {
|
Statement::Transform(affine_transform) => {
|
||||||
context.last_mut().ok_or(miette!(""))?.ctm = dbg!(affine_transform)
|
*context.last_mut().unwrap() = affine_transform
|
||||||
}
|
}
|
||||||
Statement::Unknown(s, items) => {
|
Statement::Unknown(s, _items) => {
|
||||||
eprintln!("Unknown statement: {s}")
|
eprintln!("Unknown statement: {s}")
|
||||||
}
|
}
|
||||||
|
Statement::Camera(c) => {
|
||||||
|
if camera.is_some() {
|
||||||
|
return Err(miette!("The camera can only be set once."));
|
||||||
|
}
|
||||||
|
camera = Some((c, *context.last().unwrap()));
|
||||||
|
named_transforms.insert(String::from("\"camera\""), *context.last().unwrap());
|
||||||
|
}
|
||||||
|
Statement::CoordinateSystem(s) => {
|
||||||
|
named_transforms.insert(s, *context.last().unwrap());
|
||||||
|
}
|
||||||
|
Statement::CoordSysTransform(s) => {
|
||||||
|
*context.last_mut().unwrap() = *named_transforms
|
||||||
|
.get(&s)
|
||||||
|
.ok_or_else(|| miette!("unknown transform"))?;
|
||||||
|
}
|
||||||
Statement::WorldBegin => break,
|
Statement::WorldBegin => break,
|
||||||
s => bail!("unexpected statemnet in global settings: {s:?}"),
|
s => bail!("unexpected statemnet in global settings: {s:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(p) = parser.next(context.last().unwrap()).transpose()? {
|
let (camera, camera_ctm) = camera.ok_or(miette!("A camera has to be specified"))?;
|
||||||
|
|
||||||
|
let mut pbrt = Pbrt::new(PbrtWorldSettings { camera, camera_ctm });
|
||||||
|
|
||||||
|
let mut context = vec![AffineTransform::identity()];
|
||||||
|
|
||||||
|
while let Some(p) = parser.next().transpose()? {
|
||||||
match p {
|
match p {
|
||||||
Statement::AttributeBegin => context.push(context.last().ok_or(miette!(""))?.clone()),
|
Statement::AttributeBegin => context.push(*context.last().unwrap()),
|
||||||
Statement::AttributeEnd => {
|
Statement::AttributeEnd => {
|
||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
Statement::Include(_) => unreachable!(),
|
Statement::Include(_) => unreachable!(),
|
||||||
Statement::ConcatTransform(affine_transform) => {
|
Statement::ConcatTransform(affine_transform) => {
|
||||||
context.last_mut().ok_or(miette!(""))?.ctm *= affine_transform
|
*context.last_mut().unwrap() *= affine_transform
|
||||||
}
|
}
|
||||||
Statement::Transform(affine_transform) => {
|
Statement::Transform(affine_transform) => {
|
||||||
context.last_mut().ok_or(miette!(""))?.ctm = dbg!(affine_transform)
|
*context.last_mut().unwrap() = affine_transform
|
||||||
}
|
}
|
||||||
Statement::Shape(shape_type, shape_alpha) => {
|
Statement::Shape(shape_type, shape_alpha) => {
|
||||||
pbrt.scene.shapes.push(Shape {
|
pbrt.scene.shapes.push(Shape {
|
||||||
ctm: context.last().unwrap().ctm,
|
ctm: *context.last().unwrap(),
|
||||||
material: 0,
|
material: 0,
|
||||||
obj: shape_type,
|
obj: shape_type,
|
||||||
alpha: shape_alpha,
|
alpha: shape_alpha,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Statement::Unknown(s, items) => {
|
Statement::CoordinateSystem(s) => {
|
||||||
|
named_transforms.insert(s, *context.last().unwrap());
|
||||||
|
}
|
||||||
|
Statement::CoordSysTransform(s) => {
|
||||||
|
*context.last_mut().unwrap() = *named_transforms
|
||||||
|
.get(&s)
|
||||||
|
.ok_or_else(|| miette!("unknown transform"))?;
|
||||||
|
}
|
||||||
|
Statement::Unknown(s, _items) => {
|
||||||
eprintln!("Unknown statement: {s}")
|
eprintln!("Unknown statement: {s}")
|
||||||
}
|
}
|
||||||
s => bail!("unexpected statemnet in world settings: {s:?}"),
|
s => bail!("unexpected statemnet in world settings: {s:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg!(named_transforms);
|
||||||
|
|
||||||
Ok(pbrt)
|
Ok(pbrt)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_pbrt_v4(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
pub fn parse_pbrt_v4(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
||||||
inner_parse_pbrt(path, None)
|
inner_parse_pbrt(path)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue