134 lines
3.7 KiB
Rust
134 lines
3.7 KiB
Rust
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)
|
|
}
|
|
}
|