live2d_parser/cubism_v1/moc/
mod.rs

1mod deformers;
2mod objects;
3mod params;
4mod parts;
5mod pivots;
6
7use self::parts::Part;
8use crate::{
9    cubism_v1::moc::{deformers::RotationDeformer, params::Parameter},
10    L2Error,
11};
12use integer_encoding::VarInt;
13use std::{cell::RefCell, ops::AddAssign, slice::SliceIndex};
14use tracing::debug;
15use crate::cubism_v1::moc::pivots::PivotManager;
16
17pub struct Moc {
18    /// The version of the moc file
19    version: u8,
20    /// Parameter list
21    pub parameter: Vec<Parameter>,
22    /// Parts list
23    pub parts: Vec<Part>,
24    /// Canvas width
25    pub canvas_width: i32,
26    /// Canvas height
27    pub canvas_height: i32,
28}
29
30#[derive(Debug)]
31pub enum ObjectData {
32    ObjectArray(Vec<ObjectData>),
33    RotationDeformer(RotationDeformer),
34    PivotManager(PivotManager),
35    Unknown { type_id: u64 },
36}
37
38impl Moc {
39    /// Parse moc data from a byte array
40    ///
41    /// ## Safety
42    /// The input data must be a valid moc file
43    pub unsafe fn new(data: &[u8]) -> Result<Moc, L2Error> {
44        // Parse parameters and parts
45        let reader = MocReader { moc: data, ptr: RefCell::new(0) };
46        reader.advance(9);
47        Ok(Self { version: 0, parameter: reader.read()?, parts: reader.read()?, canvas_width: 0, canvas_height: 0 })
48    }
49
50    /// Get the version of the moc file
51    pub fn version(&self) -> u8 {
52        self.version
53    }
54}
55
56struct MocReader<'i> {
57    moc: &'i [u8],
58    ptr: RefCell<usize>,
59}
60
61trait MocObject {
62    unsafe fn read_object(reader: &MocReader) -> Result<Self, L2Error>
63    where
64        Self: Sized;
65}
66
67impl<'i> MocReader<'i> {
68    pub unsafe fn new(moc: &'i [u8]) -> Self {
69        Self { moc, ptr: RefCell::new(0) }
70    }
71    pub unsafe fn rest(&self) -> &[u8] {
72        let offset = self.ptr.borrow();
73        self.moc.get_unchecked(*offset..)
74    }
75    pub unsafe fn view(&self, slice: impl SliceIndex<[u8], Output = [u8]>) -> &[u8] {
76        self.rest().get_unchecked(slice)
77    }
78    pub fn advance(&self, n: usize) {
79        self.ptr.borrow_mut().add_assign(n)
80    }
81    pub unsafe fn read_var(&self) -> Result<usize, L2Error> {
82        match usize::decode_var(self.rest()) {
83            Some((s, delta)) => {
84                self.advance(delta);
85                Ok(s)
86            }
87            None => Err(L2Error::UnknownError {}),
88        }
89    }
90    pub unsafe fn read<T: MocObject>(&self) -> Result<T, L2Error> {
91        T::read_object(self)
92    }
93}