diff --git a/src/shape/triangle.rs b/src/shape/triangle.rs index e91c09a..b5f1c8d 100644 --- a/src/shape/triangle.rs +++ b/src/shape/triangle.rs @@ -2,6 +2,7 @@ use super::Shape; use crate::{Point, Point2D, Vector}; use bvh::aabb::{Bounded, AABB}; use bvh::ray::Ray; +use serde::{Deserialize, Deserializer}; /// Represent a triangle inside the scene. #[derive(Debug, PartialEq)] @@ -89,6 +90,31 @@ impl Shape for Triangle { } } +#[derive(Debug, Deserialize)] +struct SerializedTriangle { + corners: [Point; 3], +} + +impl From for Triangle { + fn from(triangle: SerializedTriangle) -> Self { + Triangle::new( + triangle.corners[0], + triangle.corners[1], + triangle.corners[2], + ) + } +} + +impl<'de> Deserialize<'de> for Triangle { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let cam: SerializedTriangle = Deserialize::deserialize(deserializer)?; + Ok(cam.into()) + } +} + #[cfg(test)] mod test { use super::*; @@ -180,4 +206,23 @@ mod test { let ans = triangle.project_texel(&Point::origin()); assert!((ans - Point2D::new(0.5, 0.5)).norm() < 1e-5); } + + #[test] + fn deserialization_works() { + let yaml = r#" + corners: + - [0.0, 0.0, 0.0] + - [0.0, 1.0, 1.0] + - [0.0, 1.0, 0.0] + "#; + let triangle: Triangle = serde_yaml::from_str(yaml).unwrap(); + assert_eq!( + triangle, + Triangle::new( + Point::origin(), + Point::new(0., 1., 1.), + Point::new(0., 1., 0.) + ) + ) + } }