rbx_mesh 0.8.0

Rust parser for Roblox mesh files.
Documentation
#[binrw::binrw]
#[brw(little)]
#[derive(Debug, Clone)]
pub enum Revision2 {
	#[brw(magic = b"version 2.00")]
	Version200,
}

#[binrw::binrw]
#[brw(little)]
#[derive(Debug, Clone)]
pub enum SizeOfVertex2 {
	#[brw(magic = 36u8)]
	Truncated,
	#[brw(magic = 40u8)]
	Full,
}

#[binrw::binrw]
#[brw(little)]
#[derive(Debug, Clone)]
pub struct Vertex2 {
	pub pos: [f32; 3],
	pub norm: [f32; 3],
	pub tex: [f32; 2],
	pub tangent: [i8; 4], // Tangent Vector & Bi-Normal Direction
	pub color: [u8; 4],
}

#[binrw::binrw]
#[brw(little)]
#[derive(Debug, Clone)]
pub struct Vertex2Truncated {
	pub pos: [f32; 3],
	pub norm: [f32; 3],
	pub tex: [f32; 2],
	pub tangent: [i8; 4], // Tangent Vector & Bi-Normal Direction
}

#[binrw::binrw]
#[brw(little)]
#[br(import(sizeof_vertex:&SizeOfVertex2,vertex_count:u32))]
#[derive(Debug, Clone)]
pub enum Vertices2 {
	#[br(pre_assert(matches!(sizeof_vertex,SizeOfVertex2::Full)))]
	Full(#[br(count=vertex_count)] Vec<Vertex2>),
	#[br(pre_assert(matches!(sizeof_vertex,SizeOfVertex2::Truncated)))]
	Truncated(#[br(count=vertex_count)] Vec<Vertex2Truncated>),
}
impl Vertices2 {
	pub(crate) fn size(&self) -> SizeOfVertex2 {
		match self {
			Vertices2::Full(_) => SizeOfVertex2::Full,
			Vertices2::Truncated(_) => SizeOfVertex2::Truncated,
		}
	}
	pub(crate) fn len(&self) -> usize {
		match self {
			Vertices2::Full(vertices) => vertices.len(),
			Vertices2::Truncated(vertices_truncated) => vertices_truncated.len(),
		}
	}
}

#[binrw::binrw]
#[brw(little)]
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct VertexId2(pub u32);

#[binrw::binrw]
#[brw(little)]
#[derive(Debug, Clone)]
pub struct Face2(pub [VertexId2; 3]);

#[binrw::binrw]
#[brw(little)]
#[derive(Debug, Clone)]
pub struct Mesh2 {
	pub revision: Revision2,
	#[br(temp)]
	#[bw(ignore)]
	#[brw(magic = b"\n")]
	_newline: (),
	#[br(temp)]
	#[bw(ignore)]
	#[brw(magic = 12u16)]
	_sizeof_header: (),
	#[br(temp)]
	#[bw(calc = vertices.size())]
	sizeof_vertex: SizeOfVertex2,
	#[br(temp)]
	#[bw(ignore)]
	#[brw(magic = 12u8)]
	_sizeof_face: (),
	#[br(temp)]
	#[bw(try_calc=vertices.len().try_into())]
	pub vertex_count: u32,
	#[br(temp)]
	#[bw(try_calc=faces.len().try_into())]
	pub face_count: u32,
	#[br(args(&sizeof_vertex, vertex_count))]
	pub vertices: Vertices2,
	#[br(count=face_count)]
	pub faces: Vec<Face2>,
}