use std::convert::TryInto; use super::Q3BspFile; use crate::coords::CoordSystem; use crate::helpers::{slice_to_u32, slice_to_vec3}; use crate::traits::vertices::*; use crate::types::{ParseError, Result, Rgba}; /// The size of one vertex const VERTEX_SIZE: usize = (4 * 3) + (2 * 2 * 4) + (4 * 3) + 4; /// Parse a Vertices data from the data in a BSP file. pub fn verts_from_data(data: &[u8]) -> Result> { if data.len() % VERTEX_SIZE != 0 { return Err(ParseError::Invalid); } let length = data.len() / VERTEX_SIZE; let mut vertices = Vec::with_capacity(length as usize); for n in 0..length { let offset = n * VERTEX_SIZE; let vertex = &data[offset..offset + VERTEX_SIZE]; vertices.push(Vertex { position: slice_to_vec3(&vertex[0..12]), tex: TexCoord::from_bytes(&vertex[12..28].try_into().unwrap()), normal: slice_to_vec3(&vertex[28..40]), color: Rgba::from_slice(&vertex[40..44]), }) } Ok(vertices.into_boxed_slice()) } /// Parse the given data as a list of MeshVerts. pub fn meshverts_from_data(data: &[u8]) -> Result> { if data.len() % 4 != 0 { return Err(ParseError::Invalid); } let length = data.len() / 4; let mut meshverts = Vec::with_capacity(length as usize); for n in 0..length { meshverts.push(slice_to_u32(&data[n * 4..(n + 1) * 4])) } Ok(meshverts.into_boxed_slice()) } impl HasVertices for Q3BspFile { type VerticesIter<'a> = std::slice::Iter<'a, Vertex>; fn vertices_iter(&self) -> Self::VerticesIter<'_> { self.vertices.iter() } fn get_vertex(&self, index: u32) -> &Vertex { &self.vertices[index as usize] } } impl HasMeshVerts for Q3BspFile { type MeshVertsIter<'a> = std::slice::Iter<'a, MeshVert>; fn meshverts_iter(&self) -> Self::MeshVertsIter<'_> { self.meshverts.iter() } fn get_meshvert<'a>(&self, index: u32) -> MeshVert { self.meshverts[index as usize] } }