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 unsafe 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 unsafe 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() {
59 }
60 else if draw_id.contains(",") {
61 output.clip_id = draw_id.split(',').map(|s| s.to_string()).collect();
62 }
63 else {
64 output.clip_id.push(draw_id)
65 }
66 }
67 output.texture_id = reader.read()?;
68 output.point_count = reader.read()?;
69 output.polygon_count = reader.read()?;
70 output.index_array = reader.read()?;
71 output.pivot_points = reader.read()?;
72 output.uv_maps = reader.read()?;
73 if reader.version() >= 8 {
74 output.mesh_flags = reader.read()?;
75 if output.mesh_flags != 0 {
76 if (output.mesh_flags & 1) != 0 {
77 output.color_group_id = reader.read()?;
78 }
79 output.color_composition_type = if (output.mesh_flags & 30) != 0 { (output.mesh_flags & 30) >> 1 } else { 0 };
80 if (output.mesh_flags & 1 << 5) != 0 {
81 output.culling = false;
82 }
83 }
84 }
85 Ok(output)
86 }
87}
88
89impl ObjectData {
90 pub fn as_texture(self) -> Vec<Mesh> {
91 match self {
92 ObjectData::Null => Vec::new(),
93 ObjectData::ObjectArray(o) => o.into_iter().map(|x| x.as_texture()).flatten().collect(),
94 s => {
97 warn!("ObjectData::as_texture() called on non-pivot object {s:?}");
98 vec![]
99 }
100 }
101 }
102}