psychopath/src/parse/psy_surface_shader.rs

231 lines
8.3 KiB
Rust

#![allow(dead_code)]
use std::result::Result;
use nom::IResult;
use mem_arena::MemArena;
use color::{rec709_e_to_xyz, XYZ};
use shading::{SimpleSurfaceShader, SurfaceShader};
use super::basics::ws_f32;
use super::psy::PsyParseError;
use super::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 MemArena,
tree: &'a DataTree,
) -> Result<&'a 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 {
"Emit" => {
let color = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Color").nth(0)
{
if let IResult::Done(_, color) =
closure!(tuple!(ws_f32, ws_f32, ws_f32))(contents.as_bytes())
{
// TODO: handle color space conversions properly.
// Probably will need a special color type with its
// own parser...?
XYZ::from_tuple(rec709_e_to_xyz(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 })
}
"Lambert" => {
let color = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Color").nth(0)
{
if let IResult::Done(_, color) =
closure!(tuple!(ws_f32, ws_f32, ws_f32))(contents.as_bytes())
{
// TODO: handle color space conversions properly.
// Probably will need a special color type with its
// own parser...?
XYZ::from_tuple(rec709_e_to_xyz(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 })
}
"GTR" => {
// Color
let color = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Color").nth(0)
{
if let IResult::Done(_, color) =
closure!(tuple!(ws_f32, ws_f32, ws_f32))(contents.as_bytes())
{
// TODO: handle color space conversions properly.
// Probably will need a special color type with its
// own parser...?
XYZ::from_tuple(rec709_e_to_xyz(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::Done(_, roughness) = ws_f32(contents.as_bytes()) {
roughness
} else {
return Err(PsyParseError::UnknownError(byte_offset));
}
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Roughness field in GTR SurfaceShader.",
));
};
// TailShape
let tail_shape = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("TailShape").nth(0)
{
if let IResult::Done(_, tail_shape) = ws_f32(contents.as_bytes()) {
tail_shape
} else {
return Err(PsyParseError::UnknownError(byte_offset));
}
} else {
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a TailShape 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::Done(_, fresnel) = ws_f32(contents.as_bytes()) {
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::GTR {
color: color,
roughness: roughness,
tail_shape: tail_shape,
fresnel: fresnel,
})
}
"GGX" => {
// Color
let color = if let Some((_, contents, byte_offset)) =
tree.iter_leaf_children_with_type("Color").nth(0)
{
if let IResult::Done(_, color) =
closure!(tuple!(ws_f32, ws_f32, ws_f32))(contents.as_bytes())
{
// TODO: handle color space conversions properly.
// Probably will need a special color type with its
// own parser...?
XYZ::from_tuple(rec709_e_to_xyz(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::Done(_, roughness) = ws_f32(contents.as_bytes()) {
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::Done(_, fresnel) = ws_f32(contents.as_bytes()) {
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,
})
}
_ => unimplemented!(),
};
Ok(shader)
}