live2d_parser/cubism_v1/moc/
meshes.rs

1use crate::{
2    cubism_v1::moc::{MocObject, MocReader, ObjectData},
3    L2Error,
4};
5use serde::{Deserialize, Serialize};
6use tracing::{debug, error, info, trace, warn};
7
8#[derive(Debug, Serialize, Deserialize, Default)]
9pub struct Mesh {
10    pub id: String,
11    pub target_id: String,
12    pub average_draw_order: i32,
13    pub pivot_draw_order: Vec<i32>,
14    pub pivot_opacity: Vec<f32>,
15    pub clip_id: Vec<String>,
16    pub values: ObjectData,
17    pub texture_id: i32,
18    pub point_count: i32,
19    pub polygon_count: i32,
20    pub index_array: ObjectData,
21    pub pivot_points: ObjectData,
22    pub uv_maps: ObjectData,
23    pub mesh_flags: i32,
24    pub color_composition_type: i32,
25    pub color_group_id: i32,
26    pub culling: bool,
27}
28
29impl MocObject for Vec<Mesh> {
30    fn read_object(reader: &MocReader) -> Result<Self, L2Error>
31    where
32        Self: Sized,
33    {
34        let count = reader.read_var()?;
35        let mut pivots = Vec::with_capacity(count as usize);
36        debug!("Find texutre: {}", count);
37        for _ in 0..count {
38            pivots.push(reader.read()?);
39        }
40        Ok(pivots)
41    }
42}
43
44impl MocObject for Mesh {
45    fn read_object(reader: &MocReader) -> Result<Self, L2Error>
46    where
47        Self: Sized,
48    {
49        let mut output = Mesh::default();
50        output.id = reader.read()?;
51        output.target_id = reader.read()?;
52        output.values = reader.read()?;
53        output.average_draw_order = reader.read()?;
54        output.pivot_draw_order = reader.read()?;
55        output.pivot_opacity = reader.read()?;
56        if reader.version() >= 11 {
57            let draw_id: String = reader.read()?;
58            if draw_id.is_empty() {} else if draw_id.contains(",") {
59                output.clip_id = draw_id.split(',').map(|s| s.to_string()).collect();
60            } else {
61                output.clip_id.push(draw_id)
62            }
63        }
64        output.texture_id = reader.read()?;
65        output.point_count = reader.read()?;
66        output.polygon_count = reader.read()?;
67        output.index_array = reader.read()?;
68        output.pivot_points = reader.read()?;
69        output.uv_maps = reader.read()?;
70        if reader.version() >= 8 {
71            output.mesh_flags = reader.read()?;
72            if output.mesh_flags != 0 {
73                if (output.mesh_flags & 1) != 0 {
74                    output.color_group_id = reader.read()?;
75                }
76                output.color_composition_type = if (output.mesh_flags & 30) != 0 { (output.mesh_flags & 30) >> 1 } else { 0 };
77                if (output.mesh_flags & 1 << 5) != 0 {
78                    output.culling = false;
79                }
80            }
81        }
82        Ok(output)
83    }
84}
85
86impl ObjectData {
87    pub fn as_texture(self) -> Vec<Mesh> {
88        match self {
89            ObjectData::Null => Vec::new(),
90            ObjectData::ObjectArray(o) => o.into_iter().map(|x| x.as_texture()).flatten().collect(),
91            // ObjectData::Pivot(v) => vec![v],
92            // ObjectData::PivotManager(v) => v.items,
93            s => {
94                warn!("ObjectData::as_texture() called on non-pivot object {s:?}");
95                vec![]
96            }
97        }
98    }
99}