use strafesnet_deferred_loader::deferred_loader::{LoadFailureMode,MeshDeferredLoader,RenderConfigDeferredLoader}; mod bsp; mod mesh; mod brush; pub mod loader; const VALVE_SCALE:f32=1.0/16.0; pub(crate) fn valve_transform_dist(d:f32)->strafesnet_common::integer::Planar64{ (d*VALVE_SCALE).try_into().unwrap() } pub(crate) fn valve_transform_normal([x,y,z]:[f32;3])->strafesnet_common::integer::Planar64Vec3{ strafesnet_common::integer::vec3::try_from_f32_array([x,z,-y]).unwrap() } pub(crate) fn valve_transform([x,y,z]:[f32;3])->strafesnet_common::integer::Planar64Vec3{ strafesnet_common::integer::vec3::try_from_f32_array([x*VALVE_SCALE,z*VALVE_SCALE,-y*VALVE_SCALE]).unwrap() } #[derive(Debug)] pub enum ReadError{ Bsp(vbsp::BspError), Io(std::io::Error), } impl std::fmt::Display for ReadError{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ write!(f,"{self:?}") } } impl std::error::Error for ReadError{} #[derive(Debug)] pub enum LoadError{ Texture(loader::TextureError), Mesh(loader::MeshError), } impl std::fmt::Display for LoadError{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ write!(f,"{self:?}") } } impl std::error::Error for LoadError{} impl From<loader::TextureError> for LoadError{ fn from(value:loader::TextureError)->Self{ Self::Texture(value) } } impl From<loader::MeshError> for LoadError{ fn from(value:loader::MeshError)->Self{ Self::Mesh(value) } } pub struct Bsp{ bsp:vbsp::Bsp, case_folded_file_names:std::collections::HashMap<String,String>, } impl AsRef<vbsp::Bsp> for Bsp{ fn as_ref(&self)->&vbsp::Bsp{ &self.bsp } } pub fn read<R:std::io::Read>(mut input:R)->Result<Bsp,ReadError>{ let mut s=Vec::new(); //TODO: mmap input.read_to_end(&mut s).map_err(ReadError::Io)?; vbsp::Bsp::read(s.as_slice()).map(Bsp::new).map_err(ReadError::Bsp) } impl Bsp{ pub fn new(bsp:vbsp::Bsp)->Self{ let case_folded_file_names=bsp.pack.clone().into_zip().lock().unwrap().file_names().map(|s|{ (s.to_lowercase(),s.to_owned()) }).collect(); Self{ bsp, case_folded_file_names, } } pub fn pack_get(&self,name_lowercase:&str)->Result<Option<Vec<u8>>,vbsp::BspError>{ match self.case_folded_file_names.get(name_lowercase){ Some(name_folded)=>self.bsp.pack.get(name_folded), None=>Ok(None), } } pub fn to_snf(&self,failure_mode:LoadFailureMode,vpk_list:&[Vpk])->Result<strafesnet_common::map::CompleteMap,LoadError>{ let mut texture_deferred_loader=RenderConfigDeferredLoader::new(); let mut mesh_deferred_loader=MeshDeferredLoader::new(); let map_step1=bsp::convert( self, &mut texture_deferred_loader, &mut mesh_deferred_loader, ); let mut mesh_loader=loader::MeshLoader::new(loader::BspFinder{bsp:self,vpks:vpk_list},&mut texture_deferred_loader); let prop_meshes=mesh_deferred_loader.into_meshes(&mut mesh_loader,failure_mode).map_err(LoadError::Mesh)?; let map_step2=map_step1.add_prop_meshes(prop_meshes); let mut texture_loader=loader::TextureLoader::new(); let render_configs=texture_deferred_loader.into_render_configs(&mut texture_loader,failure_mode).map_err(LoadError::Texture)?; let map=map_step2.add_render_configs_and_textures(render_configs); Ok(map) } } pub struct Vpk{ vpk:vpk::VPK, case_folded_file_names:std::collections::HashMap<String,String>, } impl AsRef<vpk::VPK> for Vpk{ fn as_ref(&self)->&vpk::VPK{ &self.vpk } } impl Vpk{ pub fn new(vpk:vpk::VPK)->Vpk{ let case_folded_file_names=vpk.tree.keys().map(|s|{ (s.to_lowercase(),s.to_owned()) }).collect(); Vpk{ vpk, case_folded_file_names, } } pub fn tree_get(&self,name_lowercase:&str)->Option<&vpk::entry::VPKEntry>{ let name_folded=self.case_folded_file_names.get(name_lowercase)?; self.vpk.tree.get(name_folded) } }