1use crate::xml;
2use crate::Result;
3use roxmltree::Node;
4
5#[derive(Clone, Debug)]
7pub struct Quaternion {
8 pub w: f64,
10 pub x: f64,
12 pub y: f64,
14 pub z: f64,
16}
17
18impl Quaternion {
19 pub(crate) fn from_node(node: &Node) -> Result<Self> {
20 let w = xml::req_f64(node, "w")?;
21 let x = xml::req_f64(node, "x")?;
22 let y = xml::req_f64(node, "y")?;
23 let z = xml::req_f64(node, "z")?;
24 Ok(Self { w, x, y, z })
25 }
26}
27
28impl Default for Quaternion {
29 fn default() -> Self {
30 Self {
31 w: 1.0,
32 x: 0.0,
33 y: 0.0,
34 z: 0.0,
35 }
36 }
37}
38
39#[derive(Clone, Debug)]
41pub struct Translation {
42 pub x: f64,
44 pub y: f64,
46 pub z: f64,
48}
49
50impl Translation {
51 pub(crate) fn from_node(node: &Node) -> Result<Self> {
52 let x = xml::req_f64(node, "x")?;
53 let y = xml::req_f64(node, "y")?;
54 let z = xml::req_f64(node, "z")?;
55 Ok(Self { x, y, z })
56 }
57}
58
59impl Default for Translation {
60 fn default() -> Self {
61 Self {
62 x: 0.0,
63 y: 0.0,
64 z: 0.0,
65 }
66 }
67}
68
69#[derive(Clone, Debug, Default)]
71pub struct Transform {
72 pub rotation: Quaternion,
74 pub translation: Translation,
76}
77
78impl Transform {
79 pub(crate) fn from_node(node: &Node) -> Result<Self> {
80 let translation = match node.children().find(|n| n.has_tag_name("translation")) {
81 Some(node) => Translation::from_node(&node)?,
82 None => Translation::default(),
83 };
84 let rotation = match node.children().find(|n| n.has_tag_name("rotation")) {
85 Some(node) => Quaternion::from_node(&node)?,
86 None => Quaternion::default(),
87 };
88 Ok(Self {
89 rotation,
90 translation,
91 })
92 }
93
94 pub(crate) fn xml_string(&self, tag_name: &str) -> String {
95 let w = xml::gen_float("w", self.rotation.w);
96 let x = xml::gen_float("x", self.rotation.x);
97 let y = xml::gen_float("y", self.rotation.y);
98 let z = xml::gen_float("z", self.rotation.z);
99 let quat = format!("<rotation type=\"Structure\">\n{w}{x}{y}{z}</rotation>\n");
100
101 let x = xml::gen_float("x", self.translation.x);
102 let y = xml::gen_float("y", self.translation.y);
103 let z = xml::gen_float("z", self.translation.z);
104 let trans = format!("<translation type=\"Structure\">\n{x}{y}{z}</translation>\n");
105
106 format!("<{tag_name} type=\"Structure\">\n{quat}{trans}</{tag_name}>\n")
107 }
108}