dae_parser/fx/
material.rs1use crate::*;
2
3#[derive(Clone, Debug)]
5pub struct Material {
6 pub id: Option<String>,
8 pub name: Option<String>,
10 pub asset: Option<Box<Asset>>,
12 pub instance_effect: Instance<Effect>,
15 pub extra: Vec<Extra>,
17}
18
19impl Material {
20 pub fn new(id: impl Into<String>, name: impl Into<String>, instance_effect: Url) -> Self {
22 Self {
23 id: Some(id.into()),
24 name: Some(name.into()),
25 asset: None,
26 instance_effect: Instance::new(instance_effect),
27 extra: vec![],
28 }
29 }
30}
31
32impl XNode for Material {
33 const NAME: &'static str = "material";
34 fn parse(element: &Element) -> Result<Self> {
35 debug_assert_eq!(element.name(), Self::NAME);
36 let mut it = element.children().peekable();
37 Ok(Material {
38 id: element.attr("id").map(Into::into),
39 name: element.attr("name").map(Into::into),
40 asset: Asset::parse_opt_box(&mut it)?,
41 instance_effect: Instance::parse_one(&mut it)?,
42 extra: Extra::parse_many(it)?,
43 })
44 }
45}
46
47impl XNodeWrite for Material {
48 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
49 let mut e = Self::elem();
50 e.opt_attr("id", &self.id);
51 e.opt_attr("name", &self.name);
52 let e = e.start(w)?;
53 self.asset.write_to(w)?;
54 self.instance_effect.write_to(w)?;
55 self.extra.write_to(w)?;
56 e.end(w)
57 }
58}
59
60#[derive(Clone, Debug)]
62pub struct InstanceMaterial {
63 pub sid: Option<String>,
66 pub name: Option<String>,
68 pub symbol: String,
70 pub target: UrlRef<Material>,
78 pub bind: Vec<BindM>,
81 pub bind_vertex_input: Vec<BindVertexInput>,
83 pub extra: Vec<Extra>,
85}
86
87impl InstanceMaterial {
88 pub fn new(
90 symbol: impl Into<String>,
91 target: Url,
92 bind_vertex_input: Vec<BindVertexInput>,
93 ) -> Self {
94 Self {
95 sid: None,
96 name: None,
97 symbol: symbol.into(),
98 target: Ref::new(target),
99 bind: vec![],
100 bind_vertex_input,
101 extra: vec![],
102 }
103 }
104}
105
106impl XNode for InstanceMaterial {
107 const NAME: &'static str = "instance_material";
108 fn parse(element: &Element) -> Result<Self> {
109 debug_assert_eq!(element.name(), Self::NAME);
110 let symbol = element.attr("symbol").ok_or("expecting symbol attr")?;
111 let mut it = element.children().peekable();
112 Ok(InstanceMaterial {
113 sid: element.attr("sid").map(Into::into),
114 name: element.attr("name").map(Into::into),
115 symbol: symbol.into(),
116 target: parse_attr(element.attr("target"))?.ok_or("missing target attribute")?,
117 bind: BindM::parse_list(&mut it)?,
118 bind_vertex_input: BindVertexInput::parse_list(&mut it)?,
119 extra: Extra::parse_many(it)?,
120 })
121 }
122}
123
124impl XNodeWrite for InstanceMaterial {
125 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
126 let mut e = Self::elem();
127 e.opt_attr("sid", &self.sid);
128 e.opt_attr("name", &self.name);
129 e.attr("symbol", &self.symbol);
130 e.print_attr("target", &self.target);
131 let e = e.start(w)?;
132 self.bind.write_to(w)?;
133 self.bind_vertex_input.write_to(w)?;
134 self.extra.write_to(w)?;
135 e.end(w)
136 }
137}
138
139#[derive(Clone, Debug)]
142pub struct BindMaterial {
143 pub param: Vec<Param>,
148 pub instance_material: Vec<InstanceMaterial>,
150 pub technique: Vec<Technique>,
152 pub extra: Vec<Extra>,
154}
155
156impl BindMaterial {
157 pub fn new(instance_material: Vec<InstanceMaterial>) -> Self {
159 assert!(!instance_material.is_empty());
160 Self {
161 param: vec![],
162 instance_material,
163 technique: vec![],
164 extra: vec![],
165 }
166 }
167}
168
169impl XNode for BindMaterial {
170 const NAME: &'static str = "bind_material";
171 fn parse(element: &Element) -> Result<Self> {
172 debug_assert_eq!(element.name(), Self::NAME);
173 let mut it = element.children().peekable();
174 Ok(BindMaterial {
175 param: Param::parse_list(&mut it)?,
176 instance_material: parse_one(Technique::COMMON, &mut it, |e| {
177 let mut it = e.children().peekable();
178 finish(InstanceMaterial::parse_list_n::<1>(&mut it)?, it)
179 })?,
180 technique: Technique::parse_list(&mut it)?,
181 extra: Extra::parse_many(it)?,
182 })
183 }
184}
185
186impl XNodeWrite for BindMaterial {
187 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
188 let e = Self::elem().start(w)?;
189 self.param.write_to(w)?;
190 let common = ElemBuilder::new(Technique::COMMON).start(w)?;
191 self.instance_material.write_to(w)?;
192 common.end(w)?;
193 self.technique.write_to(w)?;
194 self.extra.write_to(w)?;
195 e.end(w)
196 }
197}
198
199#[derive(Clone, Debug)]
203pub struct BindM {
204 pub semantic: Option<String>,
206 pub target: Address,
208}
209
210impl BindM {
211 pub fn new(semantic: impl Into<String>, target: impl Into<String>) -> Self {
213 Self {
214 semantic: Some(semantic.into()),
215 target: Address(target.into()),
216 }
217 }
218}
219
220impl XNode for BindM {
221 const NAME: &'static str = "bind";
222 fn parse(element: &Element) -> Result<Self> {
223 debug_assert_eq!(element.name(), Self::NAME);
224 let target = element.attr("target").ok_or("missing target attribute")?;
225 Ok(BindM {
226 semantic: element.attr("semantic").map(Into::into),
227 target: Address(target.into()),
228 })
229 }
230}
231
232impl XNodeWrite for BindM {
233 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
234 let mut e = Self::elem();
235 e.opt_attr("semantic", &self.semantic);
236 e.print_attr("target", &self.target);
237 e.end(w)
238 }
239}