live2d_parser/cubism_v1/moc/
affines.rs

1use crate::{
2    cubism_v1::moc::{parts::Part, MocObject, MocReader, ObjectData},
3    L2Error,
4};
5use serde::{Deserialize, Serialize};
6use tracing::{trace, warn};
7
8#[derive(Debug, Serialize, Deserialize)]
9pub struct Affine {
10    pub origin_x: f32,
11    pub origin_y: f32,
12    pub scale_x: f32,
13    pub scale_y: f32,
14    pub rotation: f32,
15    pub reflect_x: bool,
16    pub reflect_y: bool,
17}
18
19impl MocObject for Vec<Affine> {
20    fn read_object(reader: &MocReader) -> Result<Self, L2Error>
21    where
22        Self: Sized,
23    {
24        let count = reader.read_var()?;
25        let mut pivots = Vec::with_capacity(count as usize);
26        trace!("Find affine: {}", count);
27        for _ in 0..count {
28            pivots.push(reader.read()?);
29        }
30        Ok(pivots)
31    }
32}
33
34impl MocObject for Affine {
35    fn read_object(reader: &MocReader) -> Result<Self, L2Error>
36    where
37        Self: Sized,
38    {
39        let origin_x = reader.read()?;
40        let origin_y = reader.read()?;
41        let scale_x = reader.read()?;
42        let scale_y = reader.read()?;
43        let rotation = reader.read()?;
44        let reflect_x = if reader.version() >= 10 { reader.read()? } else { false };
45        let reflect_y = if reader.version() >= 10 { reader.read()? } else { false };
46        Ok(Affine { origin_x, origin_y, scale_x, scale_y, rotation, reflect_x, reflect_y })
47    }
48}
49
50impl ObjectData {
51    pub fn as_affine(self) -> Vec<Affine> {
52        match self {
53            ObjectData::Null => Vec::new(),
54            ObjectData::Affine(o) => vec![o],
55            ObjectData::ObjectArray(o) => o.into_iter().map(|o| o.as_affine()).flatten().collect(),
56            s => {
57                warn!("ObjectData::as_affine() called on non-pivot object {s:?}");
58                vec![]
59            }
60        }
61    }
62}