1use crate::*;
2
3#[cfg(feature = "nalgebra")]
4use nalgebra::Matrix4;
5
6#[derive(Clone, Default, Debug)]
9pub struct Scene {
10 pub instance_physics_scene: Vec<Instance<PhysicsScene>>,
13 pub instance_visual_scene: Option<Instance<VisualScene>>,
15 pub extra: Vec<Extra>,
17}
18
19impl Scene {
20 pub fn new(instance_visual_scene: Instance<VisualScene>) -> Self {
22 Self {
23 instance_physics_scene: vec![],
24 instance_visual_scene: Some(instance_visual_scene),
25 extra: vec![],
26 }
27 }
28}
29
30impl XNode for Scene {
31 const NAME: &'static str = "scene";
32 fn parse(element: &Element) -> Result<Self> {
33 debug_assert_eq!(element.name(), Self::NAME);
34 let mut it = element.children().peekable();
35 Ok(Scene {
36 instance_physics_scene: Instance::parse_list(&mut it)?,
37 instance_visual_scene: Instance::parse_opt(&mut it)?,
38 extra: Extra::parse_many(it)?,
39 })
40 }
41}
42
43impl XNodeWrite for Scene {
44 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
45 let e = Self::elem().start(w)?;
46 self.instance_physics_scene.write_to(w)?;
47 self.instance_visual_scene.write_to(w)?;
48 self.extra.write_to(w)?;
49 e.end(w)
50 }
51}
52
53#[derive(Clone, Debug)]
56pub struct VisualScene {
57 pub id: Option<String>,
59 pub name: Option<String>,
61 pub asset: Option<Box<Asset>>,
63 pub nodes: Vec<Node>,
65 pub evaluate_scene: Vec<EvaluateScene>,
68 pub extra: Vec<Extra>,
70}
71
72impl VisualScene {
73 pub fn new(id: impl Into<String>, name: Option<String>) -> Self {
75 Self {
76 id: Some(id.into()),
77 name,
78 asset: None,
79 nodes: vec![],
80 evaluate_scene: vec![],
81 extra: vec![],
82 }
83 }
84}
85
86impl XNode for VisualScene {
87 const NAME: &'static str = "visual_scene";
88 fn parse(element: &Element) -> Result<Self> {
89 debug_assert_eq!(element.name(), Self::NAME);
90 let mut it = element.children().peekable();
91 Ok(VisualScene {
92 id: element.attr("id").map(Into::into),
93 name: element.attr("name").map(Into::into),
94 asset: Asset::parse_opt_box(&mut it)?,
95 nodes: Node::parse_list(&mut it)?,
96 evaluate_scene: EvaluateScene::parse_list(&mut it)?,
97 extra: Extra::parse_many(it)?,
98 })
99 }
100}
101
102impl XNodeWrite for VisualScene {
103 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
104 let mut e = Self::elem();
105 e.opt_attr("id", &self.id);
106 e.opt_attr("name", &self.name);
107 let e = e.start(w)?;
108 self.asset.write_to(w)?;
109 self.nodes.write_to(w)?;
110 self.evaluate_scene.write_to(w)?;
111 self.extra.write_to(w)?;
112 e.end(w)
113 }
114}
115
116#[derive(Clone, Debug)]
122pub struct Node {
123 pub id: Option<String>,
125 pub name: Option<String>,
127 pub sid: Option<String>,
130 pub ty: NodeType,
132 pub layer: Vec<String>,
134 pub asset: Option<Box<Asset>>,
136 pub transforms: Vec<Transform>,
138 pub instance_camera: Vec<Instance<Camera>>,
140 pub instance_controller: Vec<Instance<Controller>>,
142 pub instance_geometry: Vec<Instance<Geometry>>,
144 pub instance_light: Vec<Instance<Light>>,
146 pub instance_node: Vec<Instance<Node>>,
148 pub children: Vec<Node>,
150 pub extra: Vec<Extra>,
152}
153
154impl XNode for Node {
155 const NAME: &'static str = "node";
156 fn parse(element: &Element) -> Result<Self> {
157 debug_assert_eq!(element.name(), Self::NAME);
158 let mut it = element.children().peekable();
159 let extra;
160 Ok(Node {
161 id: element.attr("id").map(Into::into),
162 name: element.attr("name").map(Into::into),
163 sid: element.attr("sid").map(Into::into),
164 ty: parse_attr(element.attr("type"))?.unwrap_or_default(),
165 layer: element.attr("layer").map_or_else(Vec::new, |s| {
166 s.split_ascii_whitespace().map(|s| s.to_owned()).collect()
167 }),
168 asset: Asset::parse_opt_box(&mut it)?,
169 transforms: parse_list_many(&mut it, Transform::parse)?,
170 instance_camera: Instance::parse_list(&mut it)?,
171 instance_controller: Instance::parse_list(&mut it)?,
172 instance_geometry: Instance::parse_list(&mut it)?,
173 instance_light: Instance::parse_list(&mut it)?,
174 instance_node: Instance::parse_list(&mut it)?,
175 children: {
176 extra = Extra::parse_list(&mut it)?;
180 Node::parse_list(&mut it)?
181 },
182 extra: Extra::parse_append_many(extra, it)?,
183 })
184 }
185}
186
187impl XNodeWrite for Node {
188 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
189 let mut e = Self::elem();
190 e.opt_attr("id", &self.id);
191 e.opt_attr("name", &self.name);
192 e.opt_attr("sid", &self.sid);
193 e.def_print_attr("type", self.ty, Default::default());
194 if let Some(s) = arr_to_string(&self.layer) {
195 e.attr("layer", &s)
196 }
197 if self.is_empty() {
198 e.end(w)
199 } else {
200 let e = e.start(w)?;
201 self.asset.write_to(w)?;
202 self.transforms.write_to(w)?;
203 self.instance_camera.write_to(w)?;
204 self.instance_controller.write_to(w)?;
205 self.instance_geometry.write_to(w)?;
206 self.instance_light.write_to(w)?;
207 self.instance_node.write_to(w)?;
208 self.children.write_to(w)?;
209 self.extra.write_to(w)?;
210 e.end(w)
211 }
212 }
213}
214
215impl CollectLocalMaps for Node {
216 fn collect_local_maps<'a>(&'a self, maps: &mut LocalMaps<'a>) {
217 maps.insert(self);
218 self.children.collect_local_maps(maps);
219 }
220}
221
222impl Node {
223 pub fn new(id: impl Into<String>, name: Option<String>) -> Self {
225 Self {
226 id: Some(id.into()),
227 name,
228 sid: Default::default(),
229 ty: Default::default(),
230 layer: Default::default(),
231 asset: Default::default(),
232 transforms: Default::default(),
233 instance_camera: Default::default(),
234 instance_controller: Default::default(),
235 instance_geometry: Default::default(),
236 instance_light: Default::default(),
237 instance_node: Default::default(),
238 children: Default::default(),
239 extra: Default::default(),
240 }
241 }
242
243 pub fn push_transform(&mut self, transform: impl Into<Transform>) {
245 self.transforms.push(transform.into())
246 }
247
248 fn on_children<'a, E>(
249 &'a self,
250 f: &mut impl FnMut(&'a Self) -> Result<(), E>,
251 ) -> Result<(), E> {
252 f(self)?;
253 for child in &self.children {
254 child.on_children(f)?
255 }
256 Ok(())
257 }
258
259 pub fn is_empty(&self) -> bool {
261 self.asset.is_none()
262 && self.transforms.is_empty()
263 && self.instance_camera.is_empty()
264 && self.instance_controller.is_empty()
265 && self.instance_geometry.is_empty()
266 && self.instance_light.is_empty()
267 && self.instance_node.is_empty()
268 && self.children.is_empty()
269 && self.extra.is_empty()
270 }
271}
272
273impl Traversable for Node {
274 fn traverse<'a, E>(
275 doc: &'a Document,
276 mut f: impl FnMut(&'a Node) -> Result<(), E>,
277 ) -> Result<(), E> {
278 doc.library.iter().try_for_each(|elem| match elem {
279 LibraryElement::Nodes(lib) => lib.items.iter().try_for_each(|e| e.on_children(&mut f)),
280 LibraryElement::VisualScenes(lib) => lib
281 .items
282 .iter()
283 .try_for_each(|e| e.nodes.iter().try_for_each(|e| e.on_children(&mut f))),
284 _ => Ok(()),
285 })
286 }
287}
288
289#[cfg(feature = "nalgebra")]
290impl Node {
291 pub fn prepend_transforms(&self, mat: &mut Matrix4<f32>) {
296 for t in &self.transforms {
297 t.prepend_to_matrix(mat)
298 }
299 }
300
301 pub fn append_transforms(&self, mat: &mut Matrix4<f32>) {
305 for t in self.transforms.iter().rev() {
306 t.append_to_matrix(mat)
307 }
308 }
309
310 pub fn transform_as_matrix(&self) -> Matrix4<f32> {
312 let mut mat = Matrix4::identity();
313 self.prepend_transforms(&mut mat);
314 mat
315 }
316}
317
318#[derive(Clone, Copy, Debug, PartialEq, Eq)]
320pub enum NodeType {
321 Node,
323 Joint,
325}
326
327impl Default for NodeType {
328 fn default() -> Self {
329 Self::Node
330 }
331}
332
333impl FromStr for NodeType {
334 type Err = ();
335
336 fn from_str(s: &str) -> Result<Self, Self::Err> {
337 match s {
338 "NODE" => Ok(Self::Node),
339 "JOINT" => Ok(Self::Joint),
340 _ => Err(()),
341 }
342 }
343}
344
345impl NodeType {
346 pub fn to_str(self) -> &'static str {
348 match self {
349 Self::Node => "NODE",
350 Self::Joint => "JOINT",
351 }
352 }
353}
354
355impl Display for NodeType {
356 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
357 Display::fmt(self.to_str(), f)
358 }
359}
360
361#[derive(Clone, Debug)]
363pub struct EvaluateScene {
364 pub name: Option<String>,
366 pub render: Vec<Render>,
368}
369
370impl EvaluateScene {
371 pub fn new(render: Vec<Render>) -> Self {
373 assert!(!render.is_empty());
374 Self { name: None, render }
375 }
376}
377
378impl XNode for EvaluateScene {
379 const NAME: &'static str = "evaluate_scene";
380 fn parse(element: &Element) -> Result<Self> {
381 debug_assert_eq!(element.name(), Self::NAME);
382 let mut it = element.children().peekable();
383 let res = EvaluateScene {
384 name: element.attr("name").map(Into::into),
385 render: Render::parse_list_n::<1>(&mut it)?,
386 };
387 finish(res, it)
388 }
389}
390
391impl XNodeWrite for EvaluateScene {
392 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
393 let mut e = Self::elem();
394 e.opt_attr("name", &self.name);
395 let e = e.start(w)?;
396 self.render.write_to(w)?;
397 e.end(w)
398 }
399}