live2d_parser/cubism_v1/moc/
objects.rs

1use super::*;
2use crate::cubism_v1::moc::ObjectData::ObjectReference;
3use tracing::{error, trace, warn};
4
5impl MocObject for Vec<ObjectData> {
6    #[track_caller]
7    fn read_object(r: &MocReader) -> Result<Self, L2Error>
8    where
9        Self: Sized,
10    {
11        let count = r.read_var()?;
12        let mut objects = Vec::with_capacity(count as usize);
13        trace!("Find objects: {}", count);
14        for _ in 0..count {
15            objects.push(r.read()?);
16        }
17        Ok(objects)
18    }
19}
20
21impl MocObject for ObjectData {
22    #[track_caller]
23    fn read_object(r: &MocReader) -> Result<Self, L2Error>
24    where
25        Self: Sized,
26    {
27        let caller = std::panic::Location::caller();
28        let type_id = r.read_var()?;
29        // trace!("preview: {type_id}@{:?}\n    {:?}", r.view(..8), caller);
30        let data = match type_id {
31            0 => ObjectData::Null,
32            15 => ObjectData::ObjectArray(r.read()?),
33            25 => ObjectData::I32Array(r.read()?),
34            27 => ObjectData::F32Array(r.read()?),
35            33 => {
36                let object_id: i32 = r.read()?;
37                error!("ObjectData::read_object() called on non-pivot object {object_id}");
38                return Ok(ObjectReference(object_id));
39            }
40            65 => ObjectData::CurvedSurfaceDeformer(r.read()?),
41            66 => ObjectData::PivotManager(r.read()?),
42            67 => ObjectData::Pivot(r.read()?),
43            68 => ObjectData::RotationDeformer(r.read()?),
44            69 => ObjectData::Affine(r.read()?),
45            70 => ObjectData::Texture(Box::new(r.read()?)),
46            131 => ObjectData::Parameter(r.read()?),
47            133 => ObjectData::Part(Box::new(r.read()?)),
48            // _ => Err(L2Error::UnknownType { type_id: type_id as u32 })?,
49            _ => panic!("unknown type: {type_id}"),
50        };
51        Ok(data)
52    }
53}
54
55impl<const N: usize> MocObject for [u8; N] {
56    fn read_object(r: &MocReader) -> Result<Self, L2Error>
57    where
58        Self: Sized,
59    {
60        if r.rest().len() < N {
61            return Err(L2Error::OutOfBounds { rest: r.rest().len(), request: N });
62        }
63        let array = unsafe {
64            std::ptr::read(r.rest().as_ptr() as *const [u8; N])
65        };
66        r.advance(N);
67        Ok(array)
68    }
69}
70
71impl MocObject for Vec<i32> {
72    fn read_object(reader: &MocReader) -> Result<Self, L2Error>
73    where
74        Self: Sized,
75    {
76        let count = reader.read_var()?;
77        let mut values = Vec::with_capacity(count as usize);
78        for _ in 0..count {
79            values.push(reader.read()?);
80        }
81        Ok(values)
82    }
83}
84
85impl MocObject for i32 {
86    fn read_object(r: &MocReader) -> Result<Self, L2Error>
87    where
88        Self: Sized,
89    {
90        Ok(i32::from_be_bytes(r.read()?))
91    }
92}
93
94impl MocObject for Vec<f32> {
95    fn read_object(reader: &MocReader) -> Result<Self, L2Error>
96    where
97        Self: Sized,
98    {
99        let count = reader.read_var()?;
100        let mut values = Vec::with_capacity(count as usize);
101        for _ in 0..count {
102            values.push(reader.read()?);
103        }
104        Ok(values)
105    }
106}
107
108impl MocObject for f32 {
109    fn read_object(r: &MocReader) -> Result<Self, L2Error>
110    where
111        Self: Sized,
112    {
113        Ok(f32::from_be_bytes(r.read()?))
114    }
115}
116
117impl MocObject for u8 {
118    fn read_object(r: &MocReader) -> Result<Self, L2Error>
119    where
120        Self: Sized,
121    {
122        let float = unsafe {
123            std::ptr::read(r.rest().as_ptr())
124        };
125        r.advance(1);
126        Ok(float)
127    }
128}
129impl MocObject for bool {
130    fn read_object(r: &MocReader) -> Result<Self, L2Error>
131    where
132        Self: Sized,
133    {
134        Ok(u8::read_object(r)? != 0)
135    }
136}
137
138impl ObjectData {
139    pub fn as_f32_array(self) -> Vec<f32> {
140        match self {
141            ObjectData::Null => Vec::new(),
142            // ObjectData::ObjectArray(o) => o.into_iter().map(|x| x.as_f32_array()).flatten().collect(),
143            ObjectData::F32Array(v) => v,
144            s => {
145                warn!("ObjectData::as_f32_array() called on non-pivot object {s:?}");
146                vec![]
147            }
148        }
149    }
150}