live2d_parser/cubism_v1/moc/
objects.rs

1use super::*;
2use tracing::{error, trace, warn};
3use crate::cubism_v1::moc::ObjectData::ObjectReference;
4
5impl MocObject for Vec<ObjectData> {
6    #[track_caller]
7    unsafe 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    unsafe 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    unsafe 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 = std::ptr::read(r.rest().as_ptr() as *const [u8; N]);
64        r.advance(N);
65        Ok(array)
66    }
67}
68
69impl MocObject for Vec<i32> {
70    unsafe fn read_object(reader: &MocReader) -> Result<Self, L2Error>
71    where
72        Self: Sized,
73    {
74        let count = reader.read_var()?;
75        let mut values = Vec::with_capacity(count as usize);
76        for _ in 0..count {
77            values.push(reader.read()?);
78        }
79        Ok(values)
80    }
81}
82
83impl MocObject for i32 {
84    unsafe fn read_object(r: &MocReader) -> Result<Self, L2Error>
85    where
86        Self: Sized,
87    {
88        Ok(i32::from_be_bytes(r.read()?))
89    }
90}
91
92impl MocObject for Vec<f32> {
93    unsafe fn read_object(reader: &MocReader) -> Result<Self, L2Error>
94    where
95        Self: Sized,
96    {
97        let count = reader.read_var()?;
98        let mut values = Vec::with_capacity(count as usize);
99        for _ in 0..count {
100            values.push(reader.read()?);
101        }
102        Ok(values)
103    }
104}
105
106impl MocObject for f32 {
107    unsafe fn read_object(r: &MocReader) -> Result<Self, L2Error>
108    where
109        Self: Sized,
110    {
111        Ok(f32::from_be_bytes(r.read()?))
112    }
113}
114
115impl MocObject for u8 {
116    unsafe fn read_object(r: &MocReader) -> Result<Self, L2Error>
117    where
118        Self: Sized,
119    {
120        let float = std::ptr::read(r.rest().as_ptr());
121        r.advance(1);
122        Ok(float)
123    }
124}
125impl MocObject for bool {
126    unsafe fn read_object(r: &MocReader) -> Result<Self, L2Error>
127    where
128        Self: Sized,
129    {
130        Ok(u8::read_object(r)? != 0)
131    }
132}
133
134impl ObjectData {
135    pub fn as_f32_array(self) -> Vec<f32> {
136        match self {
137            ObjectData::Null => Vec::new(),
138            // ObjectData::ObjectArray(o) => o.into_iter().map(|x| x.as_f32_array()).flatten().collect(),
139            ObjectData::F32Array(v) => v,
140            s => {
141                warn!("ObjectData::as_f32_array() called on non-pivot object {s:?}");
142                vec![]
143            }
144        }
145    }
146}
147impl MocObject for MocVersion {
148    unsafe fn read_object(reader: &MocReader) -> Result<Self, L2Error>
149    where
150        Self: Sized,
151    {
152        let v = match reader.moc.get_unchecked(3) {
153            6 => MocVersion::V1_6_INTIAL,
154            7 => MocVersion::V1_7_OPACITY,
155            8 => MocVersion::V1_8_TEX_OPTION,
156            9 => MocVersion::V1_9_AVATAR_PARTS,
157            10 => MocVersion::V1_10_SDK2_0,
158            11 => MocVersion::V1_11_SDK2_1,
159            _ => Err(L2Error::UnknownError {})?,
160        };
161        Ok(v)
162    }
163}