1use crate::*;
2
3#[derive(Clone, Debug)]
5pub struct Controller {
6 pub id: Option<String>,
8 pub name: Option<String>,
10 pub asset: Option<Box<Asset>>,
12 pub element: ControlElement,
14 pub extra: Vec<Extra>,
16}
17
18impl Controller {
19 pub fn new(element: ControlElement) -> Self {
21 Self {
22 id: None,
23 name: None,
24 asset: None,
25 element,
26 extra: vec![],
27 }
28 }
29}
30
31impl XNode for Controller {
32 const NAME: &'static str = "controller";
33 fn parse(element: &Element) -> Result<Self> {
34 debug_assert_eq!(element.name(), Self::NAME);
35 let mut it = element.children().peekable();
36 Ok(Controller {
37 id: element.attr("id").map(Into::into),
38 name: element.attr("name").map(Into::into),
39 asset: Asset::parse_opt_box(&mut it)?,
40 element: parse_one_many(&mut it, ControlElement::parse)?,
41 extra: Extra::parse_many(it)?,
42 })
43 }
44}
45
46impl XNodeWrite for Controller {
47 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
48 let mut e = Self::elem();
49 e.opt_attr("id", &self.id);
50 e.opt_attr("name", &self.name);
51 let e = e.start(w)?;
52 self.asset.write_to(w)?;
53 self.element.write_to(w)?;
54 self.extra.write_to(w)?;
55 e.end(w)
56 }
57}
58
59#[derive(Clone, Debug, Default)]
61pub struct InstanceControllerData {
62 pub skeleton: Vec<Url>,
65 pub bind_material: Option<BindMaterial>,
67}
68
69impl XNodeWrite for InstanceControllerData {
70 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
71 many(&self.skeleton, |e| ElemBuilder::print("skeleton", e, w))?;
72 self.bind_material.write_to(w)
73 }
74}
75
76impl Instantiate for Controller {
77 const INSTANCE: &'static str = "instance_controller";
78 type Data = InstanceControllerData;
79 fn parse_data(_: &Element, it: &mut ElementIter<'_>) -> Result<Self::Data> {
80 Ok(InstanceControllerData {
81 skeleton: parse_list("skeleton", it, parse_elem)?,
82 bind_material: BindMaterial::parse_opt(it)?,
83 })
84 }
85 fn is_empty(data: &Self::Data) -> bool {
86 data.skeleton.is_empty() && data.bind_material.is_none()
87 }
88}
89
90#[derive(Clone, Debug)]
92pub enum ControlElement {
93 Skin(Skin),
95 Morph(Morph),
97}
98
99impl ControlElement {
100 pub fn parse(e: &Element) -> Result<Option<Self>> {
102 match e.name() {
103 Skin::NAME => Ok(Some(Self::Skin(Skin::parse(e)?))),
104 Morph::NAME => Ok(Some(Self::Morph(Morph::parse(e)?))),
105 _ => Ok(None),
106 }
107 }
108
109 pub fn source(&self) -> &Url {
111 match self {
112 ControlElement::Skin(skin) => &skin.source,
113 ControlElement::Morph(morph) => &morph.source,
114 }
115 }
116
117 pub fn sources(&self) -> &[Source] {
119 match self {
120 ControlElement::Skin(skin) => &skin.sources,
121 ControlElement::Morph(morph) => &morph.sources,
122 }
123 }
124}
125
126impl XNodeWrite for ControlElement {
127 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
128 match self {
129 Self::Skin(e) => e.write_to(w),
130 Self::Morph(e) => e.write_to(w),
131 }
132 }
133}
134
135#[derive(Clone, Debug)]
137pub struct Joints {
138 pub inputs: Vec<Input>,
140 pub joint: usize,
146 pub extra: Vec<Extra>,
148}
149
150impl Joints {
151 pub fn new(inputs: Vec<Input>) -> Self {
154 Self {
155 joint: inputs
156 .iter()
157 .position(|i| i.semantic == Semantic::Joint)
158 .expect("joints: missing JOINT input"),
159 inputs,
160 extra: vec![],
161 }
162 }
163}
164
165impl XNode for Joints {
166 const NAME: &'static str = "joints";
167 fn parse(element: &Element) -> Result<Self> {
168 debug_assert_eq!(element.name(), Self::NAME);
169 let mut it = element.children().peekable();
170 let inputs = Input::parse_list_n::<2>(&mut it)?;
171 Ok(Joints {
172 joint: inputs
173 .iter()
174 .position(|i| i.semantic == Semantic::Joint)
175 .ok_or("joints: missing JOINT input")?,
176 inputs,
177 extra: Extra::parse_many(it)?,
178 })
179 }
180}
181
182impl XNodeWrite for Joints {
183 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
184 let e = Self::elem().start(w)?;
185 self.inputs.write_to(w)?;
186 self.extra.write_to(w)?;
187 e.end(w)
188 }
189}
190
191impl Joints {
192 pub fn joint_input(&self) -> &Input {
194 &self.inputs[self.joint]
195 }
196}
197
198#[derive(Clone, Debug)]
200pub struct Morph {
201 pub source: UrlRef<Geometry>,
203 pub method: MorphMethod,
205 pub sources: Vec<Source>,
207 pub targets: Targets,
209 pub extra: Vec<Extra>,
211}
212
213impl Morph {
214 pub fn new(source: Url, sources: Vec<Source>, targets: Vec<Input>) -> Self {
220 assert!(sources.len() >= 2);
221 Self {
222 source: Ref::new(source),
223 method: Default::default(),
224 sources,
225 targets: Targets::new(targets),
226 extra: vec![],
227 }
228 }
229}
230
231impl XNode for Morph {
232 const NAME: &'static str = "morph";
233 fn parse(element: &Element) -> Result<Self> {
234 debug_assert_eq!(element.name(), Self::NAME);
235 let mut it = element.children().peekable();
236 Ok(Morph {
237 source: parse_attr(element.attr("source"))?.ok_or("missing source attr")?,
238 method: parse_attr(element.attr("method"))?.unwrap_or_default(),
239 sources: Source::parse_list_n::<2>(&mut it)?,
240 targets: Targets::parse_one(&mut it)?,
241 extra: Extra::parse_many(it)?,
242 })
243 }
244}
245
246impl XNodeWrite for Morph {
247 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
248 let mut e = Self::elem();
249 e.print_attr("source", &self.source);
250 e.print_attr("method", self.method);
251 let e = e.start(w)?;
252 self.sources.write_to(w)?;
253 self.targets.write_to(w)?;
254 self.extra.write_to(w)?;
255 e.end(w)
256 }
257}
258
259#[derive(Clone, Copy, Debug, PartialEq, Eq)]
261pub enum MorphMethod {
262 Normalized,
267 Relative,
272}
273
274impl Default for MorphMethod {
275 fn default() -> Self {
276 Self::Normalized
277 }
278}
279
280impl FromStr for MorphMethod {
281 type Err = ();
282
283 fn from_str(s: &str) -> Result<Self, Self::Err> {
284 match s {
285 "NORMALIZED" => Ok(Self::Normalized),
286 "RELATIVE" => Ok(Self::Relative),
287 _ => Err(()),
288 }
289 }
290}
291
292impl MorphMethod {
293 pub fn to_str(self) -> &'static str {
295 match self {
296 Self::Normalized => "NORMALIZED",
297 Self::Relative => "RELATIVE",
298 }
299 }
300}
301
302impl Display for MorphMethod {
303 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
304 Display::fmt(self.to_str(), f)
305 }
306}
307
308#[derive(Clone, Debug)]
310pub struct Skin {
311 pub source: UrlRef<Mesh>,
314 pub bind_shape_matrix: Option<Box<[f32; 16]>>,
320 pub sources: Vec<Source>,
322 pub joints: Joints,
324 pub weights: VertexWeights,
329 pub extra: Vec<Extra>,
331}
332
333impl Skin {
334 pub fn new(
339 source: Url,
340 sources: Vec<Source>,
341 joints: Vec<Input>,
342 weights: VertexWeights,
343 ) -> Self {
344 assert!(sources.len() >= 3);
345 Self {
346 source: Ref::new(source),
347 bind_shape_matrix: None,
348 sources,
349 joints: Joints::new(joints),
350 weights,
351 extra: vec![],
352 }
353 }
354}
355
356impl XNode for Skin {
357 const NAME: &'static str = "skin";
358 fn parse(element: &Element) -> Result<Self> {
359 debug_assert_eq!(element.name(), Self::NAME);
360 let mut it = element.children().peekable();
361 Ok(Skin {
362 source: parse_attr(element.attr("source"))?.ok_or("missing source attr")?,
363 bind_shape_matrix: parse_opt("bind_shape_matrix", &mut it, parse_array_n)?,
364 sources: Source::parse_list_n::<3>(&mut it)?,
365 joints: Joints::parse_one(&mut it)?,
366 weights: VertexWeights::parse_one(&mut it)?,
367 extra: Extra::parse_many(it)?,
368 })
369 }
370}
371
372impl XNodeWrite for Skin {
373 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
374 let mut e = Self::elem();
375 e.print_attr("source", &self.source);
376 let e = e.start(w)?;
377 opt(&self.bind_shape_matrix, |e| {
378 ElemBuilder::print_arr("bind_shape_matrix", &**e, w)
379 })?;
380 self.sources.write_to(w)?;
381 self.joints.write_to(w)?;
382 self.weights.write_to(w)?;
383 self.extra.write_to(w)?;
384 e.end(w)
385 }
386}
387
388#[derive(Clone, Debug)]
390pub struct Targets {
391 pub inputs: Vec<Input>,
393 pub morph_target: usize,
395 pub morph_weight: usize,
397 pub extra: Vec<Extra>,
399}
400
401impl Targets {
402 pub fn new(inputs: Vec<Input>) -> Self {
406 Self {
407 morph_target: inputs
408 .iter()
409 .position(|i| i.semantic == Semantic::MorphTarget)
410 .expect("targets: missing MORPH_TARGET input"),
411 morph_weight: inputs
412 .iter()
413 .position(|i| i.semantic == Semantic::MorphWeight)
414 .expect("targets: missing MORPH_WEIGHT input"),
415 inputs,
416 extra: vec![],
417 }
418 }
419}
420
421impl XNode for Targets {
422 const NAME: &'static str = "targets";
423 fn parse(element: &Element) -> Result<Self> {
424 debug_assert_eq!(element.name(), Self::NAME);
425 let mut it = element.children().peekable();
426 let inputs = Input::parse_list(&mut it)?;
427 Ok(Targets {
428 morph_target: inputs
429 .iter()
430 .position(|i| i.semantic == Semantic::MorphTarget)
431 .ok_or("targets: missing MORPH_TARGET input")?,
432 morph_weight: inputs
433 .iter()
434 .position(|i| i.semantic == Semantic::MorphWeight)
435 .ok_or("targets: missing MORPH_WEIGHT input")?,
436 inputs,
437 extra: Extra::parse_many(it)?,
438 })
439 }
440}
441
442impl XNodeWrite for Targets {
443 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
444 let e = Self::elem().start(w)?;
445 self.inputs.write_to(w)?;
446 self.extra.write_to(w)?;
447 e.end(w)
448 }
449}
450
451impl Targets {
452 pub fn morph_target_input(&self) -> &Input {
454 &self.inputs[self.morph_target]
455 }
456
457 pub fn morph_weight_input(&self) -> &Input {
459 &self.inputs[self.morph_weight]
460 }
461}
462
463#[derive(Clone, Debug)]
465pub struct VertexWeights {
466 pub count: usize,
468 pub inputs: InputList,
470 pub joint: usize,
472 pub vcount: Box<[u32]>,
475 pub prim: Box<[i32]>,
480 pub extra: Vec<Extra>,
482}
483
484impl XNode for VertexWeights {
485 const NAME: &'static str = "vertex_weights";
486 fn parse(element: &Element) -> Result<Self> {
487 debug_assert_eq!(element.name(), Self::NAME);
488 let mut it = element.children().peekable();
489 let inputs = InputList::parse::<2>(&mut it)?;
490 let res = VertexWeights {
491 count: parse_attr(element.attr("count"))?.ok_or("expected 'count' attr")?,
492 joint: inputs
493 .iter()
494 .position(|i| i.semantic == Semantic::Joint)
495 .ok_or("vertex_weights: missing JOINT input")?,
496 inputs,
497 vcount: parse_opt("vcount", &mut it, parse_array)?.unwrap_or_default(),
498 prim: parse_opt("v", &mut it, parse_array)?.unwrap_or_default(),
499 extra: Extra::parse_many(it)?,
500 };
501 validate_vcount(res.count, res.inputs.stride, &res.vcount, &res.prim)?;
502 Ok(res)
503 }
504}
505
506impl XNodeWrite for VertexWeights {
507 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
508 let mut e = Self::elem();
509 e.print_attr("count", self.count);
510 let e = e.start(w)?;
511 self.inputs.write_to(w)?;
512 ElemBuilder::print_arr("vcount", &self.vcount, w)?;
513 ElemBuilder::print_arr("v", &self.prim, w)?;
514 self.extra.write_to(w)?;
515 e.end(w)
516 }
517}
518
519impl VertexWeights {
520 pub fn new(inputs: Vec<InputS>, vcount: Box<[u32]>, prim: Box<[i32]>) -> Self {
523 let inputs = InputList::new(inputs);
524 assert!(
525 inputs.stride * vcount.iter().sum::<u32>() as usize == prim.len(),
526 "vcount does not match prim"
527 );
528 Self {
529 count: vcount.len(),
530 joint: inputs
531 .iter()
532 .position(|i| i.semantic == Semantic::Joint)
533 .expect("vertex_weights: missing JOINT input"),
534 inputs,
535 vcount,
536 prim,
537 extra: vec![],
538 }
539 }
540
541 pub fn joint_input(&self) -> &Input {
543 &self.inputs[self.joint]
544 }
545}