live2d_parser/cubism_v3/moc3/
params.rs

1use super::*;
2
3#[derive(Copy, Clone, Debug)]
4pub(crate) struct ParametersOffsets {
5    // since v3.0
6    name: u32,
7    max_value: u32,
8    min_value: u32,
9    default_value: u32,
10    is_repeat: u32,
11    decimal_places: u32,
12    binding_sources_begin: u32,
13    binding_sources_count: u32,
14    // since v4.0
15    key_source_begin_indices: u32,
16    key_source_counts: u32,
17    // since v4.2
18    r#type: u32,
19    blend_shape_parameter_binding_sources_begin_indices: u32,
20    blend_shape_parameter_binding_sources_counts: u32,
21}
22
23pub struct Parameters<'i> {
24    moc3: &'i Moc3,
25    index: u32,
26}
27
28#[derive(Clone, Debug)]
29pub struct Parameter<'i> {
30    pub name: &'i str,
31    pub min_value: f32,
32    pub max_value: f32,
33    pub default_value: f32,
34    pub is_repeat: bool,
35    pub decimal_places: u32,
36    pub binding_sources_begin: i32,
37    pub binding_sources_count: i32,
38}
39
40impl ParametersOffsets {
41    pub unsafe fn read(moc3: *const u8) -> Self {
42        Self {
43            r#type: std::ptr::read(moc3.add(0x208) as *const u32),
44            name: std::ptr::read(moc3.add(0x108) as *const u32),
45            max_value: std::ptr::read(moc3.add(0x10C) as *const u32),
46            min_value: std::ptr::read(moc3.add(0x110) as *const u32),
47            default_value: std::ptr::read(moc3.add(0x114) as *const u32),
48            is_repeat: std::ptr::read(moc3.add(0x118) as *const u32),
49            decimal_places: std::ptr::read(moc3.add(0x11C) as *const u32),
50            binding_sources_begin: std::ptr::read(moc3.add(0x120) as *const u32),
51            binding_sources_count: std::ptr::read(moc3.add(0x124) as *const u32),
52            key_source_begin_indices: std::ptr::read(moc3.add(0x1DC) as *const u32),
53            key_source_counts: std::ptr::read(moc3.add(0x1E0) as *const u32),
54            blend_shape_parameter_binding_sources_begin_indices: std::ptr::read(moc3.add(0x20C) as *const u32),
55            blend_shape_parameter_binding_sources_counts: std::ptr::read(moc3.add(0x210) as *const u32),
56        }
57    }
58}
59
60impl Moc3 {
61    pub fn parameters(&self) -> Parameters {
62        Parameters { moc3: self, index: 0 }
63    }
64}
65
66impl<'i> Parameters<'i> {
67    pub fn get_parameter(&self, index: u32) -> Option<Parameter> {
68        if index >= self.moc3.counter.parameters {
69            return None;
70        }
71        unsafe { Some(self.get_unchecked(index)) }
72    }
73    pub unsafe fn get_unchecked(&self, index: u32) -> Parameter<'i> {
74        self.moc3.params.get_unchecked(self.moc3, index)
75    }
76}
77
78impl ParametersOffsets {
79    unsafe fn get_unchecked<'i>(&self, moc3: &'i Moc3, index: u32) -> Parameter<'i> {
80        Parameter {
81            name: moc3.read_cstr::<64>(self.name, index),
82            max_value: moc3.read(self.max_value, index),
83            min_value: moc3.read(self.min_value, index),
84            default_value: moc3.read(self.default_value, index),
85            is_repeat: moc3.read_b32(self.is_repeat, index),
86            decimal_places: moc3.read(self.decimal_places, index),
87            binding_sources_begin: moc3.read(self.binding_sources_begin, index),
88            binding_sources_count: moc3.read(self.binding_sources_count, index),
89        }
90    }
91}
92
93impl<'i> Iterator for Parameters<'i> {
94    type Item = Parameter<'i>;
95
96    fn next(&mut self) -> Option<Self::Item> {
97        if self.index >= self.moc3.counter.parameters {
98            return None;
99        }
100        let result = unsafe { self.get_unchecked(self.index) };
101        self.index.add_assign(1);
102        Some(result)
103    }
104}