live2d_parser/cubism_v1/moc/
mod.rs

1mod affines;
2mod deformers;
3mod objects;
4mod params;
5mod parts;
6mod pivots;
7
8use self::parts::Part;
9use crate::{
10    cubism_v1::moc::{
11        affines::Affine,
12        deformers::{CurvedSurfaceDeformer, RotationDeformer},
13        params::Parameter,
14        pivots::{Pivot, PivotManager},
15    },
16    L2Error
17    ,
18};
19use integer_encoding::VarInt;
20use std::{cell::RefCell, ops::AddAssign, slice::SliceIndex};
21use tracing::debug;
22
23pub struct Moc {
24    /// The version of the moc file
25    pub version: u8,
26    /// Parameter list
27    pub parameter: Vec<Parameter>,
28    /// Parts list
29    pub parts: Vec<Part>,
30    /// Canvas width
31    pub canvas_width: i32,
32    /// Canvas height
33    pub canvas_height: i32,
34}
35
36#[derive(Debug)]
37pub enum ObjectData {
38    Null,
39    Byte(u8),
40    ObjectArray(Vec<ObjectData>),
41    RotationDeformer(RotationDeformer),
42    CurvedSurfaceDeformer(CurvedSurfaceDeformer),
43    Pivot(Pivot),
44    PivotManager(PivotManager),
45    Affine(Affine),
46    Unknown50,
47    Unknown51,
48    Unknown60,
49    Unknown112([u8; 6]),
50    Unknown134,
51    Unknown { type_id: u64 },
52}
53
54impl Moc {
55    /// Parse moc data from a byte array
56    ///
57    /// ## Safety
58    /// The input data must be a valid moc file
59    pub unsafe fn new(data: &[u8]) -> Result<Moc, L2Error> {
60        let reader = MocReader { moc: data, ptr: RefCell::new(0) };
61        if reader.moc.get_unchecked(..3) == b"moc" {
62            // magic head
63            reader.advance(3);
64            // version
65            reader.advance(1);
66            // unknown
67            reader.advance(5);
68        }
69        else {
70            return Err(L2Error::UnknownError {});
71        }
72        Ok(Self {
73            version: reader.version(),
74            parameter: reader.read()?,
75            parts: reader.read()?,
76            canvas_width: 0,
77            canvas_height: 0,
78        })
79    }
80
81    /// Get the version of the moc file
82    pub fn version(&self) -> u8 {
83        self.version
84    }
85}
86
87struct MocReader<'i> {
88    moc: &'i [u8],
89    ptr: RefCell<usize>,
90}
91
92trait MocObject {
93    unsafe fn read_object(reader: &MocReader) -> Result<Self, L2Error>
94    where
95        Self: Sized;
96}
97
98impl<'i> MocReader<'i> {
99    pub unsafe fn new(moc: &'i [u8]) -> Self {
100        Self { moc, ptr: RefCell::new(0) }
101    }
102    pub unsafe fn version(&self) -> u8 {
103        *self.moc.get_unchecked(3)
104    }
105    pub unsafe fn rest(&self) -> &[u8] {
106        let offset = self.ptr.borrow();
107        self.moc.get_unchecked(*offset..)
108    }
109    pub unsafe fn view(&self, slice: impl SliceIndex<[u8], Output = [u8]>) -> &[u8] {
110        self.rest().get_unchecked(slice)
111    }
112    pub fn advance(&self, n: usize) {
113        self.ptr.borrow_mut().add_assign(n)
114    }
115    pub unsafe fn read_var(&self) -> Result<usize, L2Error> {
116        match usize::decode_var(self.rest()) {
117            Some((s, delta)) => {
118                self.advance(delta);
119                Ok(s)
120            }
121            None => Err(L2Error::UnknownError {}),
122        }
123    }
124    #[track_caller]
125    pub unsafe fn read<T: MocObject>(&self) -> Result<T, L2Error> {
126        T::read_object(self)
127    }
128}