psychopath/src/parse/psy_surface_shader.rs

140 lines
4.4 KiB
Rust

#![allow(dead_code)]
use std::result::Result;
use nom::{combinator::all_consuming, IResult};
use kioku::Arena;
use crate::shading::{SimpleSurfaceShader, SurfaceShader};
use super::{
basics::ws_f32,
psy::{parse_color, PsyParseError},
DataTree,
};
// pub struct TriangleMesh {
// time_samples: usize,
// geo: Vec<(Point, Point, Point)>,
// indices: Vec<usize>,
// accel: BVH,
// }
pub fn parse_surface_shader<'a>(
arena: &'a Arena,
tree: &'a DataTree,
) -> Result<&'a dyn SurfaceShader, PsyParseError> {
let type_name = if let Some((_, text, _)) = tree.iter_leaf_children_with_type("Type").nth(0) {
text.trim()
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Type field in SurfaceShader.",
));
};
let shader = match type_name {
"Lambert" => {
let color = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Color").nth(0)
{
if let Ok(color) = parse_color(contents) {
color
} else {
// Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
}
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Color field in Lambert SurfaceShader.",
));
};
arena.alloc(SimpleSurfaceShader::Lambert { color: color })
}
"GGX" => {
// Color
let color = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Color").nth(0)
{
if let Ok(color) = parse_color(contents) {
color
} else {
// Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
}
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Color field in GTR SurfaceShader.",
));
};
// Roughness
let roughness = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Roughness").nth(0)
{
if let IResult::Ok((_, roughness)) = all_consuming(ws_f32)(contents) {
roughness
} else {
return Err(PsyParseError::UnknownError(byte_offset));
}
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Roughness field in GTR SurfaceShader.",
));
};
// Fresnel
let fresnel = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Fresnel").nth(0)
{
if let IResult::Ok((_, fresnel)) = all_consuming(ws_f32)(contents) {
fresnel
} else {
return Err(PsyParseError::UnknownError(byte_offset));
}
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Fresnel field in GTR SurfaceShader.",
));
};
arena.alloc(SimpleSurfaceShader::GGX {
color: color,
roughness: roughness,
fresnel: fresnel,
})
}
"Emit" => {
let color = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Color").nth(0)
{
if let Ok(color) = parse_color(contents) {
color
} else {
// Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
}
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Color field in Emit SurfaceShader.",
));
};
arena.alloc(SimpleSurfaceShader::Emit { color: color })
}
_ => unimplemented!(),
};
Ok(shader)
}