live2d_parser/cubism_v1/moc/
meshes.rs1use 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 s => {
94 warn!("ObjectData::as_texture() called on non-pivot object {s:?}");
95 vec![]
96 }
97 }
98 }
99}