live2d_parser/cubism_v1/moc/
pivots.rs

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