use crate::*;
#[derive(Clone, Debug)]
pub struct Camera {
pub id: Option<String>,
pub name: Option<String>,
pub asset: Option<Box<Asset>>,
pub optics: Optics,
pub imager: Option<Imager>,
pub extra: Vec<Extra>,
}
impl Camera {
pub fn new(ty: ProjectionType) -> Self {
Self {
id: Default::default(),
name: Default::default(),
asset: Default::default(),
optics: Optics::new(ty),
imager: Default::default(),
extra: Default::default(),
}
}
}
impl XNode for Camera {
const NAME: &'static str = "camera";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Camera {
id: element.attr("id").map(Into::into),
name: element.attr("name").map(Into::into),
asset: Asset::parse_opt_box(&mut it)?,
optics: Optics::parse_one(&mut it)?,
imager: Imager::parse_opt(&mut it)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Camera {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let mut e = Self::elem();
e.opt_attr("id", &self.id);
e.opt_attr("name", &self.name);
let e = e.start(w)?;
self.asset.write_to(w)?;
self.optics.write_to(w)?;
self.imager.write_to(w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct Imager {
pub technique: Vec<Technique>,
pub extra: Vec<Extra>,
}
impl Imager {
pub fn new(technique: Vec<Technique>) -> Self {
assert!(!technique.is_empty());
Self {
technique,
extra: vec![],
}
}
}
impl XNode for Imager {
const NAME: &'static str = "imager";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Imager {
technique: Technique::parse_list_n::<1>(&mut it)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Imager {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
self.technique.write_to(w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub struct Optics {
pub ty: ProjectionType,
pub technique: Vec<Technique>,
pub extra: Vec<Extra>,
}
impl Optics {
pub fn new(ty: ProjectionType) -> Self {
Self {
ty,
technique: Default::default(),
extra: Default::default(),
}
}
}
impl XNode for Optics {
const NAME: &'static str = "optics";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
Ok(Optics {
ty: parse_one(Technique::COMMON, &mut it, |e| {
let mut it = e.children().peekable();
finish(parse_one_many(&mut it, ProjectionType::parse)?, it)
})?,
technique: Technique::parse_list(&mut it)?,
extra: Extra::parse_many(it)?,
})
}
}
impl XNodeWrite for Optics {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
let common = ElemBuilder::new(Technique::COMMON).start(w)?;
self.ty.write_to(w)?;
common.end(w)?;
self.technique.write_to(w)?;
self.extra.write_to(w)?;
e.end(w)
}
}
#[derive(Clone, Debug)]
pub enum ProjectionType {
Orthographic(Orthographic),
Perspective(Perspective),
}
impl ProjectionType {
pub fn parse(e: &Element) -> Result<Option<Self>> {
match e.name() {
Orthographic::NAME => Ok(Some(Self::Orthographic(Orthographic::parse(e)?))),
Perspective::NAME => Ok(Some(Self::Perspective(Perspective::parse(e)?))),
_ => Ok(None),
}
}
}
impl XNodeWrite for ProjectionType {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
match self {
Self::Orthographic(e) => e.write_to(w),
Self::Perspective(e) => e.write_to(w),
}
}
}
#[derive(Clone, Debug)]
pub struct Orthographic {
pub xmag: Option<f32>,
pub ymag: Option<f32>,
pub extra: Vec<Extra>,
pub aspect_ratio: Option<f32>,
pub znear: f32,
pub zfar: f32,
}
impl Orthographic {
pub fn new(xmag: Option<f32>, ymag: Option<f32>, znear: f32, zfar: f32) -> Self {
Self {
xmag,
ymag,
extra: Default::default(),
aspect_ratio: Default::default(),
znear,
zfar,
}
}
}
impl XNode for Orthographic {
const NAME: &'static str = "orthographic";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
let res = Orthographic {
xmag: parse_opt("xmag", &mut it, parse_elem)?,
ymag: parse_opt("ymag", &mut it, parse_elem)?,
extra: Extra::parse_list(&mut it)?,
aspect_ratio: parse_opt("aspect_ratio", &mut it, parse_elem)?,
znear: parse_one("znear", &mut it, parse_elem)?,
zfar: parse_one("zfar", &mut it, parse_elem)?,
};
finish(res, it)
}
}
impl XNodeWrite for Orthographic {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::opt_print("xmag", &self.xmag, w)?;
ElemBuilder::opt_print("ymag", &self.ymag, w)?;
self.extra.write_to(w)?;
ElemBuilder::opt_print("aspect_ratio", &self.aspect_ratio, w)?;
ElemBuilder::print("znear", &self.znear, w)?;
ElemBuilder::print("zfar", &self.zfar, w)?;
e.end(w)
}
}
#[derive(Clone, Copy, Debug)]
pub struct Perspective {
pub xfov: Option<f32>,
pub yfov: Option<f32>,
pub aspect_ratio: Option<f32>,
pub znear: f32,
pub zfar: f32,
}
impl Perspective {
pub fn new(xfov: Option<f32>, yfov: Option<f32>, znear: f32, zfar: f32) -> Self {
Self {
xfov,
yfov,
aspect_ratio: Default::default(),
znear,
zfar,
}
}
}
impl XNode for Perspective {
const NAME: &'static str = "perspective";
fn parse(element: &Element) -> Result<Self> {
debug_assert_eq!(element.name(), Self::NAME);
let mut it = element.children().peekable();
let res = Perspective {
xfov: parse_opt("xfov", &mut it, parse_elem)?,
yfov: parse_opt("yfov", &mut it, parse_elem)?,
aspect_ratio: parse_opt("aspect_ratio", &mut it, parse_elem)?,
znear: parse_one("znear", &mut it, parse_elem)?,
zfar: parse_one("zfar", &mut it, parse_elem)?,
};
finish(res, it)
}
}
impl XNodeWrite for Perspective {
fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
let e = Self::elem().start(w)?;
ElemBuilder::opt_print("xfov", &self.xfov, w)?;
ElemBuilder::opt_print("yfov", &self.yfov, w)?;
ElemBuilder::opt_print("aspect_ratio", &self.aspect_ratio, w)?;
ElemBuilder::print("znear", &self.znear, w)?;
ElemBuilder::print("zfar", &self.zfar, w)?;
e.end(w)
}
}