live2d_parser/cubism_v1/moc/
pivots.rs1use crate::{
2 cubism_v1::moc::{MocObject, MocReader, ObjectData},
3 L2Error,
4};
5use serde::{Deserialize, Serialize};
6use tracing::{debug, info, trace, warn};
7
8#[derive(Debug, Serialize, Deserialize)]
9pub struct PivotManager {
10 pub items: Vec<Pivot>,
11}
12
13#[derive(Debug, Serialize, Deserialize)]
14pub struct Pivot {
15 pub id: String,
16 pub count: u32,
17 pub values: Vec<f32>,
18}
19
20impl MocObject for PivotManager {
21 fn read_object(reader: &MocReader) -> Result<Self, L2Error>
22 where
23 Self: Sized,
24 {
25 let o: ObjectData = reader.read()?;
26 Ok(Self { items: o.as_pivots() })
27 }
28}
29
30impl MocObject for Vec<Pivot> {
31 fn read_object(reader: &MocReader) -> Result<Self, L2Error>
32 where
33 Self: Sized,
34 {
35 let count = reader.read_var()?;
36 let mut pivots = Vec::with_capacity(count as usize);
37 for _ in 0..count {
38 pivots.push(reader.read()?);
39 }
40 Ok(pivots)
41 }
42}
43
44impl MocObject for Pivot {
45 fn read_object(reader: &MocReader) -> Result<Self, L2Error>
46 where
47 Self: Sized,
48 {
49 let id = reader.read()?;
50 let count: i32 = reader.read()?;
51 let values: ObjectData = reader.read()?;
52 Ok(Self {
53 id,
54 count: count as u32,
55 values: values.as_f32_array(),
57 })
58 }
59}
60
61impl ObjectData {
62 pub fn as_pivots(self) -> Vec<Pivot> {
63 match self {
64 ObjectData::Null => Vec::new(),
65 ObjectData::ObjectArray(o) => o.into_iter().map(|x| x.as_pivots()).flatten().collect(),
66 ObjectData::Pivot(v) => vec![v],
67 ObjectData::PivotManager(v) => v.items,
68 s => {
69 warn!("ObjectData::as_pivots() called on non-pivot object {s:?}");
70 vec![]
71 }
72 }
73 }
74}