use crate::packets::Resource; use anyhow::{Result, anyhow}; use log::warn; use std::io::{Read, Write}; #[derive(Debug, Default, Clone)] pub struct Prefab(pub Vec); #[derive(Debug, Default, Clone)] pub struct Part { pub vertex: Vec, pub index: Option, pub armature: Option, pub fragment_shader: Option, pub fragment_shader_data: Option, pub vertex_shader: Option, pub vertex_shader_data: Option, pub texture: Option, } #[derive(Debug, Default, Clone)] pub struct VertexAttributes(pub Vec); #[derive(Debug, Default, Clone)] pub struct Indecies(pub Vec<[u16; 3]>); impl Prefab { pub fn serialize(&self, w: &mut Vec) -> Result<()> { for x in self.0.clone() { w.write_all(&x.0)?; } Ok(()) } pub fn deserialize(r: &[u8]) -> Result { let mut s = Prefab::default(); for x in r.iter().array_chunks::<32>() { s.0.push(Resource(x.map(|x| *x))) } Ok(s) } } impl Indecies { pub fn serialize(&self, w: &mut Vec) -> Result<()> { for x in self.0.clone() { w.write_all(x.map(|x| x.to_be_bytes()).as_flattened())?; } Ok(()) } pub fn deserialize(r: &[u8]) -> Result { let mut s = Self(Vec::new()); for x in r.iter().array_chunks::<2>().array_chunks::<3>() { s.0.push(x.map(|x| u16::from_be_bytes(x.map(|x| *x)))) } Ok(s) } } impl VertexAttributes { pub fn serialize(&self, w: &mut Vec) -> Result<()> { for x in self.0.clone() { w.write_all(&x.to_be_bytes())?; } Ok(()) } pub fn deserialize(r: &[u8]) -> Result { let mut s = Self(Vec::new()); for x in r.iter().array_chunks::<4>() { s.0.push(f32::from_be_bytes(x.map(|x| *x))) } Ok(s) } } impl Part { pub fn serialize(&self, w: &mut Vec) -> Result<()> { for x in &self.vertex { write_kv(w, b"vertex", &x.0); } if let Some(x) = &self.index { write_kv(w, b"index", &x.0); } if let Some(x) = &self.armature { write_kv(w, b"armature", &x.0); } if let Some(x) = &self.fragment_shader { write_kv(w, b"fragment_shader", &x.0); } if let Some(x) = &self.fragment_shader_data { write_kv(w, b"fragment_shader_data", &x.0); } if let Some(x) = &self.vertex_shader { write_kv(w, b"vertex_shader", &x.0); } if let Some(x) = &self.vertex_shader_data { write_kv(w, b"vertex_shader_data", &x.0); } if let Some(x) = &self.texture { write_kv(w, b"texture", &x.0); } Ok(()) } pub fn deserialize(mut r: &[u8]) -> Result { let mut s = Self::default(); while !r.is_empty() { let (k, v) = read_kv(&mut r)?; match k.as_slice() { b"vertex" => s.vertex.push(slice_to_res(&v)?), b"index" => s.index = Some(slice_to_res(&v)?), b"armature" => s.armature = Some(slice_to_res(&v)?), b"fragment_shader" => s.fragment_shader = Some(slice_to_res(&v)?), b"fragment_shader_data" => s.fragment_shader_data = Some(slice_to_res(&v)?), b"vertex_shader" => s.vertex_shader = Some(slice_to_res(&v)?), b"vertex_shader_data" => s.vertex_shader_data = Some(slice_to_res(&v)?), b"texture" => s.texture = Some(slice_to_res(&v)?), _ => warn!("unknown part key"), } } Ok(s) } } fn slice_to_res(s: &[u8]) -> Result { Ok(Resource( s.try_into() .map_err(|_| anyhow!("resource length incorrect"))?, )) } fn read_kv(r: &mut &[u8]) -> Result<(Vec, Vec)> { let mut key_size = [0; 2]; let mut value_size = [0; 2]; r.read_exact(&mut key_size)?; r.read_exact(&mut value_size)?; let key_size = u16::from_be_bytes(key_size); let value_size = u16::from_be_bytes(value_size); let mut key = vec![0; key_size as usize]; let mut value = vec![0; value_size as usize]; r.read_exact(&mut value)?; r.read_exact(&mut key)?; Ok((key, value)) } fn write_kv(w: &mut Vec, key: &[u8], value: &[u8]) { w.extend(&(key.len() as u16).to_be_bytes()); w.extend(&(value.len() as u16).to_be_bytes()); w.extend(key); w.extend(value); }