1use crate::*;
2
3#[derive(Clone, Debug)]
6pub struct Camera {
7 pub id: Option<String>,
9 pub name: Option<String>,
11 pub asset: Option<Box<Asset>>,
13 pub optics: Optics,
15 pub imager: Option<Imager>,
17 pub extra: Vec<Extra>,
19}
20
21impl Camera {
22 pub fn new(ty: ProjectionType) -> Self {
24 Self {
25 id: Default::default(),
26 name: Default::default(),
27 asset: Default::default(),
28 optics: Optics::new(ty),
29 imager: Default::default(),
30 extra: Default::default(),
31 }
32 }
33}
34
35impl XNode for Camera {
36 const NAME: &'static str = "camera";
37 fn parse(element: &Element) -> Result<Self> {
38 debug_assert_eq!(element.name(), Self::NAME);
39 let mut it = element.children().peekable();
40 Ok(Camera {
41 id: element.attr("id").map(Into::into),
42 name: element.attr("name").map(Into::into),
43 asset: Asset::parse_opt_box(&mut it)?,
44 optics: Optics::parse_one(&mut it)?,
45 imager: Imager::parse_opt(&mut it)?,
46 extra: Extra::parse_many(it)?,
47 })
48 }
49}
50
51impl XNodeWrite for Camera {
52 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
53 let mut e = Self::elem();
54 e.opt_attr("id", &self.id);
55 e.opt_attr("name", &self.name);
56 let e = e.start(w)?;
57 self.asset.write_to(w)?;
58 self.optics.write_to(w)?;
59 self.imager.write_to(w)?;
60 self.extra.write_to(w)?;
61 e.end(w)
62 }
63}
64
65#[derive(Clone, Debug)]
67pub struct Imager {
68 pub technique: Vec<Technique>,
72 pub extra: Vec<Extra>,
74}
75
76impl Imager {
77 pub fn new(technique: Vec<Technique>) -> Self {
79 assert!(!technique.is_empty());
80 Self {
81 technique,
82 extra: vec![],
83 }
84 }
85}
86
87impl XNode for Imager {
88 const NAME: &'static str = "imager";
89 fn parse(element: &Element) -> Result<Self> {
90 debug_assert_eq!(element.name(), Self::NAME);
91 let mut it = element.children().peekable();
92 Ok(Imager {
93 technique: Technique::parse_list_n::<1>(&mut it)?,
94 extra: Extra::parse_many(it)?,
95 })
96 }
97}
98
99impl XNodeWrite for Imager {
100 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
101 let e = Self::elem().start(w)?;
102 self.technique.write_to(w)?;
103 self.extra.write_to(w)?;
104 e.end(w)
105 }
106}
107
108#[derive(Clone, Debug)]
110pub struct Optics {
111 pub ty: ProjectionType,
113 pub technique: Vec<Technique>,
115 pub extra: Vec<Extra>,
117}
118
119impl Optics {
120 pub fn new(ty: ProjectionType) -> Self {
122 Self {
123 ty,
124 technique: Default::default(),
125 extra: Default::default(),
126 }
127 }
128}
129
130impl XNode for Optics {
131 const NAME: &'static str = "optics";
132 fn parse(element: &Element) -> Result<Self> {
133 debug_assert_eq!(element.name(), Self::NAME);
134 let mut it = element.children().peekable();
135 Ok(Optics {
136 ty: parse_one(Technique::COMMON, &mut it, |e| {
137 let mut it = e.children().peekable();
138 finish(parse_one_many(&mut it, ProjectionType::parse)?, it)
139 })?,
140 technique: Technique::parse_list(&mut it)?,
141 extra: Extra::parse_many(it)?,
142 })
143 }
144}
145
146impl XNodeWrite for Optics {
147 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
148 let e = Self::elem().start(w)?;
149 let common = ElemBuilder::new(Technique::COMMON).start(w)?;
150 self.ty.write_to(w)?;
151 common.end(w)?;
152 self.technique.write_to(w)?;
153 self.extra.write_to(w)?;
154 e.end(w)
155 }
156}
157
158#[derive(Clone, Debug)]
160pub enum ProjectionType {
161 Orthographic(Orthographic),
163 Perspective(Perspective),
165}
166
167impl ProjectionType {
168 pub fn parse(e: &Element) -> Result<Option<Self>> {
170 match e.name() {
171 Orthographic::NAME => Ok(Some(Self::Orthographic(Orthographic::parse(e)?))),
172 Perspective::NAME => Ok(Some(Self::Perspective(Perspective::parse(e)?))),
173 _ => Ok(None),
174 }
175 }
176}
177
178impl XNodeWrite for ProjectionType {
179 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
180 match self {
181 Self::Orthographic(e) => e.write_to(w),
182 Self::Perspective(e) => e.write_to(w),
183 }
184 }
185}
186
187#[derive(Clone, Debug)]
189pub struct Orthographic {
190 pub xmag: Option<f32>,
192 pub ymag: Option<f32>,
194 pub extra: Vec<Extra>,
196 pub aspect_ratio: Option<f32>,
198 pub znear: f32,
200 pub zfar: f32,
202}
203
204impl Orthographic {
205 pub fn new(xmag: Option<f32>, ymag: Option<f32>, znear: f32, zfar: f32) -> Self {
207 Self {
208 xmag,
209 ymag,
210 extra: Default::default(),
211 aspect_ratio: Default::default(),
212 znear,
213 zfar,
214 }
215 }
216}
217
218impl XNode for Orthographic {
219 const NAME: &'static str = "orthographic";
220 fn parse(element: &Element) -> Result<Self> {
221 debug_assert_eq!(element.name(), Self::NAME);
222 let mut it = element.children().peekable();
223 let res = Orthographic {
224 xmag: parse_opt("xmag", &mut it, parse_elem)?,
225 ymag: parse_opt("ymag", &mut it, parse_elem)?,
226 extra: Extra::parse_list(&mut it)?,
227 aspect_ratio: parse_opt("aspect_ratio", &mut it, parse_elem)?,
228 znear: parse_one("znear", &mut it, parse_elem)?,
229 zfar: parse_one("zfar", &mut it, parse_elem)?,
230 };
231 finish(res, it)
232 }
233}
234
235impl XNodeWrite for Orthographic {
236 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
237 let e = Self::elem().start(w)?;
238 ElemBuilder::opt_print("xmag", &self.xmag, w)?;
239 ElemBuilder::opt_print("ymag", &self.ymag, w)?;
240 self.extra.write_to(w)?;
241 ElemBuilder::opt_print("aspect_ratio", &self.aspect_ratio, w)?;
242 ElemBuilder::print("znear", &self.znear, w)?;
243 ElemBuilder::print("zfar", &self.zfar, w)?;
244 e.end(w)
245 }
246}
247
248#[derive(Clone, Copy, Debug)]
250pub struct Perspective {
251 pub xfov: Option<f32>,
253 pub yfov: Option<f32>,
255 pub aspect_ratio: Option<f32>,
257 pub znear: f32,
259 pub zfar: f32,
261}
262
263impl Perspective {
264 pub fn new(xfov: Option<f32>, yfov: Option<f32>, znear: f32, zfar: f32) -> Self {
266 Self {
267 xfov,
268 yfov,
269 aspect_ratio: Default::default(),
270 znear,
271 zfar,
272 }
273 }
274}
275
276impl XNode for Perspective {
277 const NAME: &'static str = "perspective";
278 fn parse(element: &Element) -> Result<Self> {
279 debug_assert_eq!(element.name(), Self::NAME);
280 let mut it = element.children().peekable();
281 let res = Perspective {
282 xfov: parse_opt("xfov", &mut it, parse_elem)?,
283 yfov: parse_opt("yfov", &mut it, parse_elem)?,
284 aspect_ratio: parse_opt("aspect_ratio", &mut it, parse_elem)?,
285 znear: parse_one("znear", &mut it, parse_elem)?,
286 zfar: parse_one("zfar", &mut it, parse_elem)?,
287 };
288 finish(res, it)
289 }
290}
291
292impl XNodeWrite for Perspective {
293 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
294 let e = Self::elem().start(w)?;
295 ElemBuilder::opt_print("xfov", &self.xfov, w)?;
296 ElemBuilder::opt_print("yfov", &self.yfov, w)?;
297 ElemBuilder::opt_print("aspect_ratio", &self.aspect_ratio, w)?;
298 ElemBuilder::print("znear", &self.znear, w)?;
299 ElemBuilder::print("zfar", &self.zfar, w)?;
300 e.end(w)
301 }
302}