live2d_parser/cubism_v1/moc/
pivots.rs

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