live2d_parser/cubism_v1/moc/
pivots.rs1use 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}