use super::streaminginfo::StreamingInfo; use crate::object::{Value, parser::FromValue}; use anyhow::Result; use glam::Mat4; use serde::Serialize; #[derive(Debug, Serialize)] pub struct Mesh { pub name: String, pub bind_pose: Vec, pub bone_name_hashes: Vec, pub index_format: i32, pub index_buffer: Vec, pub sub_meshes: Vec, pub stream_data: StreamingInfo, } #[derive(Debug, Serialize)] pub struct SubMesh { pub topology: i32, pub vertex_count: u32, pub base_vertex: u32, pub first_byte: u32, pub first_vertex: u32, pub index_count: u32, } #[derive(Debug, Serialize)] pub struct VertexData { pub channels: Vec, pub data_size: Vec, pub vertex_count: u32, } #[derive(Debug, Serialize)] pub struct ChannelInfo { pub dimension: u8, pub format: u8, pub offset: u8, pub stream: u8, } impl FromValue for Mesh { fn from_value(v: Value) -> Result { let mut fields = v.as_class("Mesh").unwrap(); Ok(Mesh { name: fields.remove("m_Name").unwrap().parse().unwrap(), index_format: fields.remove("m_IndexFormat").unwrap().parse().unwrap(), index_buffer: fields .remove("m_IndexBuffer") .unwrap() .as_vector() .unwrap() .into_iter() .map(|e| e.as_u8().unwrap()) .collect(), sub_meshes: fields .remove("m_SubMeshes") .unwrap() .as_vector() .unwrap() .into_iter() .map(|e| e.parse().unwrap()) .collect(), stream_data: fields.remove("m_StreamData").unwrap().parse().unwrap(), bind_pose: fields .remove("m_BindPose") .unwrap() .as_vector() .unwrap() .into_iter() .map(|e| e.parse().unwrap()) .collect(), bone_name_hashes: fields .remove("m_BoneNameHashes") .unwrap() .as_vector() .unwrap() .into_iter() .map(|e| e.parse().unwrap()) .collect(), }) } } impl FromValue for VertexData { fn from_value(v: Value) -> Result { let mut fields = v.as_class("VertexData").unwrap(); Ok(VertexData { vertex_count: fields.remove("vertexCount").unwrap().parse().unwrap(), channels: fields .remove("m_Channels") .unwrap() .as_array() .unwrap() .into_iter() .map(|e| e.parse().unwrap()) .collect(), data_size: fields.remove("m_DataSize").unwrap().as_typeless().unwrap(), }) } } impl FromValue for ChannelInfo { fn from_value(v: Value) -> Result { let mut fields = v.as_class("ChannelInfo").unwrap(); Ok(ChannelInfo { dimension: fields.remove("dimension").unwrap().parse().unwrap(), format: fields.remove("format").unwrap().parse().unwrap(), offset: fields.remove("offset").unwrap().parse().unwrap(), stream: fields.remove("stream").unwrap().parse().unwrap(), }) } } impl FromValue for SubMesh { fn from_value(v: Value) -> Result { let mut fields = v.as_class("SubMesh").unwrap(); Ok(SubMesh { topology: fields.remove("topology").unwrap().parse().unwrap(), vertex_count: fields.remove("vertexCount").unwrap().parse().unwrap(), base_vertex: fields.remove("baseVertex").unwrap().parse().unwrap(), first_byte: fields.remove("firstByte").unwrap().parse().unwrap(), first_vertex: fields.remove("firstVertex").unwrap().parse().unwrap(), index_count: fields.remove("indexCount").unwrap().parse().unwrap(), }) } } #[repr(u8)] #[derive(Debug, Serialize, Clone, Copy, PartialEq)] pub enum VertexDataChannel { Position = 0, Normal = 1, Tangent = 2, Color = 3, TexCoord0 = 4, TexCoord1 = 5, TexCoord2 = 6, TexCoord3 = 7, TexCoord4 = 8, TexCoord5 = 9, TexCoord6 = 10, TexCoord7 = 11, BlendWeight = 12, BlendIndices = 13, }