More parsing code cleanup and better error messages.
This commit is contained in:
parent
331b0229b0
commit
46d0ef3b28
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
parse_utils::ws_f32,
|
parse_utils::{ensure_close, ensure_subsections, ws_f32},
|
||||||
psy::{parse_color, PsyError, PsyResult},
|
psy::{parse_color, PsyError, PsyResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,7 +28,12 @@ pub fn parse_distant_disk_light<'a>(
|
||||||
let mut colors = Vec::new();
|
let mut colors = Vec::new();
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
loop {
|
let valid_subsections = &[
|
||||||
|
("Radius", true, (1..).into()),
|
||||||
|
("Direction", true, (1..).into()),
|
||||||
|
("Color", true, (1..).into()),
|
||||||
|
];
|
||||||
|
ensure_subsections(events, valid_subsections, |events| {
|
||||||
match events.next_event()? {
|
match events.next_event()? {
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
type_name: "Radius",
|
type_name: "Radius",
|
||||||
|
@ -39,7 +44,12 @@ pub fn parse_distant_disk_light<'a>(
|
||||||
radii.push(radius);
|
radii.push(radius);
|
||||||
} else {
|
} else {
|
||||||
// Found radius, but its contents is not in the right format
|
// Found radius, but its contents is not in the right format
|
||||||
return Err(PsyError::UnknownError(byte_offset));
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"Radius data isn't in the right format. It should \
|
||||||
|
contain a single floating point value."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +65,12 @@ pub fn parse_distant_disk_light<'a>(
|
||||||
directions.push(Vector::new(direction.0, direction.1, direction.2));
|
directions.push(Vector::new(direction.0, direction.1, direction.2));
|
||||||
} else {
|
} else {
|
||||||
// Found direction, but its contents is not in the right format
|
// Found direction, but its contents is not in the right format
|
||||||
return Err(PsyError::UnknownError(byte_offset));
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"Direction data isn't in the right format. It should \
|
||||||
|
contain a single floating point value."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,15 +83,12 @@ pub fn parse_distant_disk_light<'a>(
|
||||||
colors.push(parse_color(byte_offset, &contents)?);
|
colors.push(parse_color(byte_offset, &contents)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::InnerClose { .. } => {
|
_ => unreachable!(),
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
_ => {
|
ensure_close(events)?;
|
||||||
todo!(); // Return error.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(DistantDiskLight::new(arena, &radii, &directions, &colors));
|
return Ok(DistantDiskLight::new(arena, &radii, &directions, &colors));
|
||||||
}
|
}
|
||||||
|
@ -89,9 +101,12 @@ pub fn parse_sphere_light<'a>(
|
||||||
let mut colors = Vec::new();
|
let mut colors = Vec::new();
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
loop {
|
let valid_subsections = &[
|
||||||
|
("Radius", true, (1..).into()),
|
||||||
|
("Color", true, (1..).into()),
|
||||||
|
];
|
||||||
|
ensure_subsections(events, valid_subsections, |events| {
|
||||||
match events.next_event()? {
|
match events.next_event()? {
|
||||||
// Radius
|
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
type_name: "Radius",
|
type_name: "Radius",
|
||||||
contents,
|
contents,
|
||||||
|
@ -101,7 +116,12 @@ pub fn parse_sphere_light<'a>(
|
||||||
radii.push(radius);
|
radii.push(radius);
|
||||||
} else {
|
} else {
|
||||||
// Found radius, but its contents is not in the right format
|
// Found radius, but its contents is not in the right format
|
||||||
return Err(PsyError::UnknownError(byte_offset));
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"Radius data isn't in the right format. It should \
|
||||||
|
contain a single floating point value."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,15 +134,12 @@ pub fn parse_sphere_light<'a>(
|
||||||
colors.push(parse_color(byte_offset, &contents)?);
|
colors.push(parse_color(byte_offset, &contents)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::InnerClose { .. } => {
|
_ => unreachable!(),
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
_ => {
|
ensure_close(events)?;
|
||||||
todo!(); // Return error.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(SphereLight::new(arena, &radii, &colors));
|
return Ok(SphereLight::new(arena, &radii, &colors));
|
||||||
}
|
}
|
||||||
|
@ -135,7 +152,11 @@ pub fn parse_rectangle_light<'a>(
|
||||||
let mut colors = Vec::new();
|
let mut colors = Vec::new();
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
loop {
|
let valid_subsections = &[
|
||||||
|
("Dimensions", true, (1..).into()),
|
||||||
|
("Color", true, (1..).into()),
|
||||||
|
];
|
||||||
|
ensure_subsections(events, valid_subsections, |events| {
|
||||||
match events.next_event()? {
|
match events.next_event()? {
|
||||||
// Dimensions
|
// Dimensions
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
|
@ -148,7 +169,12 @@ pub fn parse_rectangle_light<'a>(
|
||||||
dimensions.push(radius);
|
dimensions.push(radius);
|
||||||
} else {
|
} else {
|
||||||
// Found dimensions, but its contents is not in the right format
|
// Found dimensions, but its contents is not in the right format
|
||||||
return Err(PsyError::UnknownError(byte_offset));
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"Dimensions data isn't in the right format. It should \
|
||||||
|
contain two space-separated floating point values."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,15 +187,12 @@ pub fn parse_rectangle_light<'a>(
|
||||||
colors.push(parse_color(byte_offset, &contents)?);
|
colors.push(parse_color(byte_offset, &contents)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::InnerClose { .. } => {
|
_ => unreachable!(),
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
_ => {
|
ensure_close(events)?;
|
||||||
todo!(); // Return error.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(RectangleLight::new(arena, &dimensions, &colors));
|
return Ok(RectangleLight::new(arena, &dimensions, &colors));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
parse_utils::{ws_f32, ws_usize},
|
parse_utils::{ensure_close, ensure_subsections, ws_f32, ws_usize},
|
||||||
psy::{PsyError, PsyResult},
|
psy::{PsyError, PsyResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,7 +34,14 @@ pub fn parse_mesh_surface<'a>(
|
||||||
let mut face_vert_counts = Vec::new();
|
let mut face_vert_counts = Vec::new();
|
||||||
let mut face_vert_indices = Vec::new();
|
let mut face_vert_indices = Vec::new();
|
||||||
|
|
||||||
loop {
|
let valid_subsections = &[
|
||||||
|
("SurfaceShaderBind", true, (1).into()),
|
||||||
|
("Vertices", true, (1..).into()),
|
||||||
|
("Normals", true, (..).into()),
|
||||||
|
("FaceVertCounts", true, (1).into()),
|
||||||
|
("FaceVertIndices", true, (1).into()),
|
||||||
|
];
|
||||||
|
ensure_subsections(events, valid_subsections, |events| {
|
||||||
match events.next_event()? {
|
match events.next_event()? {
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
type_name: "SurfaceShaderBind",
|
type_name: "SurfaceShaderBind",
|
||||||
|
@ -46,7 +53,7 @@ pub fn parse_mesh_surface<'a>(
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
type_name: "Vertices",
|
type_name: "Vertices",
|
||||||
contents,
|
contents,
|
||||||
..
|
byte_offset,
|
||||||
} => {
|
} => {
|
||||||
// Collect verts for this time sample
|
// Collect verts for this time sample
|
||||||
let mut text = contents;
|
let mut text = contents;
|
||||||
|
@ -56,13 +63,21 @@ pub fn parse_mesh_surface<'a>(
|
||||||
|
|
||||||
tverts.push(Point::new(vert.0, vert.1, vert.2));
|
tverts.push(Point::new(vert.0, vert.1, vert.2));
|
||||||
}
|
}
|
||||||
|
if !text.is_empty() {
|
||||||
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"Vertices are not in the right format. Each vertex \
|
||||||
|
must be specified by three decimal values."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
verts.push(tverts);
|
verts.push(tverts);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
type_name: "Normals",
|
type_name: "Normals",
|
||||||
contents,
|
contents,
|
||||||
..
|
byte_offset,
|
||||||
} => {
|
} => {
|
||||||
// Collect normals for this time sample
|
// Collect normals for this time sample
|
||||||
let mut text = contents;
|
let mut text = contents;
|
||||||
|
@ -72,6 +87,14 @@ pub fn parse_mesh_surface<'a>(
|
||||||
|
|
||||||
tnormals.push(Normal::new(nor.0, nor.1, nor.2).normalized());
|
tnormals.push(Normal::new(nor.0, nor.1, nor.2).normalized());
|
||||||
}
|
}
|
||||||
|
if !text.is_empty() {
|
||||||
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"Normals are not in the right format. Each normal \
|
||||||
|
must be specified by three decimal values."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
normals.push(tnormals);
|
normals.push(tnormals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,17 +103,19 @@ pub fn parse_mesh_surface<'a>(
|
||||||
contents,
|
contents,
|
||||||
byte_offset,
|
byte_offset,
|
||||||
} => {
|
} => {
|
||||||
if !face_vert_counts.is_empty() {
|
|
||||||
return Err(PsyError::WrongNodeCount(
|
|
||||||
byte_offset,
|
|
||||||
"Meshes can only have one FaceVertCounts section.".into(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let mut text = contents;
|
let mut text = contents;
|
||||||
while let IResult::Ok((remaining, count)) = ws_usize(text) {
|
while let IResult::Ok((remaining, count)) = ws_usize(text) {
|
||||||
text = remaining;
|
text = remaining;
|
||||||
face_vert_counts.push(count);
|
face_vert_counts.push(count);
|
||||||
}
|
}
|
||||||
|
if !text.is_empty() {
|
||||||
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"FaceVertCounts are not in the right format. Should be \
|
||||||
|
a simple list of space-separated integers."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
|
@ -98,28 +123,27 @@ pub fn parse_mesh_surface<'a>(
|
||||||
contents,
|
contents,
|
||||||
byte_offset,
|
byte_offset,
|
||||||
} => {
|
} => {
|
||||||
if !face_vert_indices.is_empty() {
|
|
||||||
return Err(PsyError::WrongNodeCount(
|
|
||||||
byte_offset,
|
|
||||||
"Meshes can only have one FaceVertIndices section.".into(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let mut text = contents;
|
let mut text = contents;
|
||||||
while let IResult::Ok((remaining, index)) = ws_usize(text) {
|
while let IResult::Ok((remaining, index)) = ws_usize(text) {
|
||||||
text = remaining;
|
text = remaining;
|
||||||
face_vert_indices.push(index);
|
face_vert_indices.push(index);
|
||||||
}
|
}
|
||||||
|
if !text.is_empty() {
|
||||||
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"FaceVertCounts are not in the right format. Should be \
|
||||||
|
a simple list of space-separated integers."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::InnerClose { .. } => {
|
_ => unreachable!(),
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
_ => {
|
ensure_close(events)?;
|
||||||
todo!(); // Return error.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validation: make sure all time samples have same vert count.
|
// Validation: make sure all time samples have same vert count.
|
||||||
let vert_count = verts[0].len();
|
let vert_count = verts[0].len();
|
||||||
|
@ -136,12 +160,6 @@ pub fn parse_mesh_surface<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validation: make sure we have any mesh data.
|
|
||||||
if verts.is_empty() || face_vert_counts.is_empty() || face_vert_indices.is_empty() {
|
|
||||||
todo!("Meshes must have at least one non-empty of each of the following sections: Vertices, FaceVertCounts, FaceVertIndices.");
|
|
||||||
// Return an error.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build triangle mesh
|
// Build triangle mesh
|
||||||
let mut tri_vert_indices = Vec::new();
|
let mut tri_vert_indices = Vec::new();
|
||||||
let mut ii = 0;
|
let mut ii = 0;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use data_tree::{DataTreeReader, Event};
|
||||||
use crate::shading::{SimpleSurfaceShader, SurfaceShader};
|
use crate::shading::{SimpleSurfaceShader, SurfaceShader};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
parse_utils::{ensure_close, ws_f32},
|
parse_utils::{ensure_close, ensure_subsections, ws_f32},
|
||||||
psy::{parse_color, PsyError, PsyResult},
|
psy::{parse_color, PsyError, PsyResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,7 +63,12 @@ pub fn parse_surface_shader(
|
||||||
let mut roughness = None;
|
let mut roughness = None;
|
||||||
let mut fresnel = None;
|
let mut fresnel = None;
|
||||||
|
|
||||||
loop {
|
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()? {
|
match events.next_event()? {
|
||||||
// Color
|
// Color
|
||||||
Event::Leaf {
|
Event::Leaf {
|
||||||
|
@ -83,7 +88,12 @@ pub fn parse_surface_shader(
|
||||||
if let IResult::Ok((_, rgh)) = all_consuming(ws_f32)(contents) {
|
if let IResult::Ok((_, rgh)) = all_consuming(ws_f32)(contents) {
|
||||||
roughness = Some(rgh);
|
roughness = Some(rgh);
|
||||||
} else {
|
} else {
|
||||||
return Err(PsyError::UnknownError(byte_offset));
|
return Err(PsyError::IncorrectLeafData(
|
||||||
|
byte_offset,
|
||||||
|
"Roughness data isn't in the right format. It \
|
||||||
|
should contain a single floating point value."
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,27 +106,21 @@ pub fn parse_surface_shader(
|
||||||
if let IResult::Ok((_, frs)) = all_consuming(ws_f32)(contents) {
|
if let IResult::Ok((_, frs)) = all_consuming(ws_f32)(contents) {
|
||||||
fresnel = Some(frs);
|
fresnel = Some(frs);
|
||||||
} else {
|
} else {
|
||||||
return Err(PsyError::UnknownError(byte_offset));
|
return Err(PsyError::IncorrectLeafData(
|
||||||
}
|
byte_offset,
|
||||||
}
|
"Fresnel data isn't in the right format. It \
|
||||||
|
should contain a single floating point value."
|
||||||
Event::InnerClose { .. } => {
|
.into(),
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
todo!(); // Return an error.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validation: make sure all fields are present.
|
|
||||||
if color == None || roughness == None || fresnel == None {
|
|
||||||
return Err(PsyError::MissingNode(
|
|
||||||
events.byte_offset(),
|
|
||||||
"GGX shader requires one of each field: Color, Roughness, Fresnel.".into(),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
ensure_close(events)?;
|
||||||
|
|
||||||
Box::new(SimpleSurfaceShader::GGX {
|
Box::new(SimpleSurfaceShader::GGX {
|
||||||
color: color.unwrap(),
|
color: color.unwrap(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user