174 lines
5.2 KiB
Rust
174 lines
5.2 KiB
Rust
#![allow(dead_code)]
|
|
|
|
use std::{io::BufRead, result::Result};
|
|
|
|
use nom::{combinator::all_consuming, IResult};
|
|
|
|
use kioku::Arena;
|
|
|
|
use data_tree::{DataTreeReader, Event};
|
|
|
|
use crate::shading::{SimpleSurfaceShader, SurfaceShader};
|
|
|
|
use super::{
|
|
parse_utils::{ensure_close, ensure_subsections, ws_f32},
|
|
psy::{parse_color, PsyError, PsyResult},
|
|
};
|
|
|
|
// pub struct TriangleMesh {
|
|
// time_samples: usize,
|
|
// geo: Vec<(Point, Point, Point)>,
|
|
// indices: Vec<usize>,
|
|
// accel: BVH,
|
|
// }
|
|
|
|
pub fn parse_surface_shader(
|
|
_arena: &Arena,
|
|
events: &mut DataTreeReader<impl BufRead>,
|
|
_ident: Option<&str>,
|
|
) -> PsyResult<Box<dyn SurfaceShader>> {
|
|
// Get shader type.
|
|
let shader = match events.next_event()? {
|
|
Event::Leaf {
|
|
type_name: "Type",
|
|
contents: "Lambert",
|
|
..
|
|
} => {
|
|
let color = if let Event::Leaf {
|
|
type_name: "Color",
|
|
contents,
|
|
byte_offset,
|
|
} = events.next_event()?
|
|
{
|
|
parse_color(byte_offset, contents)?
|
|
} else {
|
|
return Err(PsyError::MissingNode(
|
|
events.byte_offset(),
|
|
"Expected a Color field in Lambert SurfaceShader.".into(),
|
|
));
|
|
};
|
|
|
|
// Close shader node.
|
|
ensure_close(events)?;
|
|
|
|
Box::new(SimpleSurfaceShader::Lambert { color: color })
|
|
}
|
|
|
|
Event::Leaf {
|
|
type_name: "Type",
|
|
contents: "GGX",
|
|
..
|
|
} => {
|
|
let mut color = None;
|
|
let mut roughness = None;
|
|
let mut fresnel = None;
|
|
|
|
let valid_subsections = &[
|
|
("Color", true, (1).into()),
|
|
("Roughness", true, (1).into()),
|
|
("Fresnel", true, (1).into()),
|
|
];
|
|
ensure_subsections(events, valid_subsections, |events| {
|
|
match events.next_event()? {
|
|
// Color
|
|
Event::Leaf {
|
|
type_name: "Color",
|
|
contents,
|
|
byte_offset,
|
|
} => {
|
|
color = Some(parse_color(byte_offset, contents)?);
|
|
}
|
|
|
|
// Roughness
|
|
Event::Leaf {
|
|
type_name: "Roughness",
|
|
contents,
|
|
byte_offset,
|
|
} => {
|
|
if let IResult::Ok((_, rgh)) = all_consuming(ws_f32)(contents) {
|
|
roughness = Some(rgh);
|
|
} else {
|
|
return Err(PsyError::IncorrectLeafData(
|
|
byte_offset,
|
|
"Roughness data isn't in the right format. It \
|
|
should contain a single floating point value."
|
|
.into(),
|
|
));
|
|
}
|
|
}
|
|
|
|
// Fresnel
|
|
Event::Leaf {
|
|
type_name: "Fresnel",
|
|
contents,
|
|
byte_offset,
|
|
} => {
|
|
if let IResult::Ok((_, frs)) = all_consuming(ws_f32)(contents) {
|
|
fresnel = Some(frs);
|
|
} else {
|
|
return Err(PsyError::IncorrectLeafData(
|
|
byte_offset,
|
|
"Fresnel data isn't in the right format. It \
|
|
should contain a single floating point value."
|
|
.into(),
|
|
));
|
|
}
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
}
|
|
Ok(())
|
|
})?;
|
|
|
|
ensure_close(events)?;
|
|
|
|
Box::new(SimpleSurfaceShader::GGX {
|
|
color: color.unwrap(),
|
|
roughness: roughness.unwrap(),
|
|
fresnel: fresnel.unwrap(),
|
|
})
|
|
}
|
|
|
|
Event::Leaf {
|
|
type_name: "Type",
|
|
contents: "Emit",
|
|
..
|
|
} => {
|
|
let color = if let Event::Leaf {
|
|
type_name: "Color",
|
|
contents,
|
|
byte_offset,
|
|
} = events.next_event()?
|
|
{
|
|
parse_color(byte_offset, contents)?
|
|
} else {
|
|
return Err(PsyError::MissingNode(
|
|
events.byte_offset(),
|
|
"Expected a Color field in Emit SurfaceShader.".into(),
|
|
));
|
|
};
|
|
|
|
// Close shader node.
|
|
ensure_close(events)?;
|
|
|
|
Box::new(SimpleSurfaceShader::Emit { color: color })
|
|
}
|
|
|
|
Event::Leaf {
|
|
type_name: "Type",
|
|
byte_offset,
|
|
..
|
|
} => {
|
|
return Err(PsyError::MissingNode(
|
|
byte_offset,
|
|
"Unknown SurfaceShader type.".into(),
|
|
));
|
|
}
|
|
_ => {
|
|
todo!(); // Return error.
|
|
}
|
|
};
|
|
|
|
Ok(shader)
|
|
}
|