bsp_loader: more powerful mesh locate ability

This commit is contained in:
Quaternions 2025-02-03 12:07:49 -08:00
parent f3d7d9b49f
commit b8aa93e70e
5 changed files with 71 additions and 17 deletions
Cargo.lock
lib/bsp_loader
strafe-client/src

44
Cargo.lock generated

@ -142,6 +142,17 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
[[package]]
name = "binrw"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "173901312e9850391d4d7c1318c4e099fdc037d61870fca427429830efdb4e5f"
dependencies = [
"array-init",
"binrw_derive 0.13.3",
"bytemuck",
]
[[package]]
name = "binrw"
version = "0.14.1"
@ -149,10 +160,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d4bca59c20d6f40c2cc0802afbe1e788b89096f61bdf7aeea6bf00f10c2909b"
dependencies = [
"array-init",
"binrw_derive",
"binrw_derive 0.14.1",
"bytemuck",
]
[[package]]
name = "binrw_derive"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb515fdd6f8d3a357c8e19b8ec59ef53880807864329b1cb1cba5c53bf76557e"
dependencies = [
"either",
"owo-colors",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "binrw_derive"
version = "0.14.1"
@ -1959,7 +1983,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36372fd7feb6d3c5780d2ada39d1397be9e196ddfbb23ba1d84e7a75cf790adb"
dependencies = [
"binrw",
"binrw 0.14.1",
"lazy-regex",
]
@ -2332,6 +2356,7 @@ dependencies = [
"strafesnet_deferred_loader",
"vbsp",
"vmdl",
"vpk",
]
[[package]]
@ -2422,7 +2447,7 @@ dependencies = [
name = "strafesnet_snf"
version = "0.2.0"
dependencies = [
"binrw",
"binrw 0.14.1",
"id",
"strafesnet_common",
]
@ -2704,7 +2729,7 @@ checksum = "f14a5685e0bb386aac9b9c6046a05152a46a0bc58d53afb3fbe577f1a1c2bb05"
dependencies = [
"ahash",
"arrayvec",
"binrw",
"binrw 0.14.1",
"bitflags 2.8.0",
"bv",
"cgmath",
@ -2755,6 +2780,17 @@ dependencies = [
"tracing",
]
[[package]]
name = "vpk"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60ec10e731515f58d5494d472f027d9c6fc8500fcb790ff55751031bcad87b6b"
dependencies = [
"ahash",
"binrw 0.13.3",
"thiserror 1.0.69",
]
[[package]]
name = "walkdir"
version = "2.5.0"

@ -15,3 +15,4 @@ strafesnet_common = { path = "../common", registry = "strafesnet" }
strafesnet_deferred_loader = { path = "../deferred_loader" }
vbsp = "0.6.0"
vmdl = "0.2.0"
vpk = "0.2.0"

@ -62,7 +62,7 @@ impl Bsp{
pub const fn new(value:vbsp::Bsp)->Self{
Self(value)
}
pub fn to_snf(&self,failure_mode:LoadFailureMode)->Result<strafesnet_common::map::CompleteMap,LoadError>{
pub fn to_snf(&self,failure_mode:LoadFailureMode,vpk_list:&[vpk::VPK])->Result<strafesnet_common::map::CompleteMap,LoadError>{
let mut texture_deferred_loader=RenderConfigDeferredLoader::new();
let mut mesh_deferred_loader=MeshDeferredLoader::new();
@ -72,7 +72,7 @@ impl Bsp{
&mut mesh_deferred_loader,
);
let mut mesh_loader=loader::MeshLoader::new(self,&mut texture_deferred_loader);
let mut mesh_loader=loader::MeshLoader::new(self,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);

@ -72,22 +72,40 @@ impl From<vbsp::BspError> for MeshError{
}
}
pub struct MeshLoader<'a,'b>{
pub struct MeshLoader<'a,'b,'c>{
bsp:&'a Bsp,
vpks:&'c [vpk::VPK],
deferred_loader:&'b mut strafesnet_deferred_loader::deferred_loader::RenderConfigDeferredLoader<Cow<'a,str>>,
}
impl MeshLoader<'_,'_>{
pub fn new<'a,'b>(
impl MeshLoader<'_,'_,'_>{
pub fn new<'a,'b,'c>(
bsp:&'a Bsp,
vpks:&'c [vpk::VPK],
deferred_loader:&'b mut strafesnet_deferred_loader::deferred_loader::RenderConfigDeferredLoader<Cow<'a,str>>,
)->MeshLoader<'a,'b>{
)->MeshLoader<'a,'b,'c>{
MeshLoader{
bsp,
vpks,
deferred_loader,
}
}
fn find(&self,path:&str)->Result<Option<Cow<[u8]>>,vbsp::BspError>{
// search bsp
if let Some(data)=self.bsp.as_ref().pack.get(path)?{
return Ok(Some(Cow::Owned(data)));
}
//search each vpk
for vpk in self.vpks{
if let Some(vpk_entry)=vpk.tree.get(path){
return Ok(Some(vpk_entry.get()?));
}
}
Ok(None)
}
}
impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_>{
impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_,'_>{
type Error=MeshError;
type Index=&'a str;
fn load(&mut self,index:Self::Index)->Result<vmdl::Model,Self::Error>{
@ -99,10 +117,9 @@ impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_>{
vvd_path.set_extension("vvd");
vtx_path.set_extension("dx90.vtx");
// TODO: search more packs, possibly using an index of multiple packs
let bsp=self.bsp.as_ref();
let mdl=bsp.pack.get(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl)?;
let vtx=bsp.pack.get(vtx_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVtx)?;
let vvd=bsp.pack.get(vvd_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVvd)?;
let mdl=self.find(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl)?;
let vtx=self.find(vtx_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVtx)?;
let vvd=self.find(vvd_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVvd)?;
Ok(vmdl::Model::from_parts(
vmdl::mdl::Mdl::read(mdl.as_ref())?,
vmdl::vtx::Vtx::read(vtx.as_ref())?,
@ -111,7 +128,7 @@ impl<'a> Loader<vmdl::Model> for MeshLoader<'a,'_>{
}
}
impl<'a> Loader<Mesh> for MeshLoader<'a,'_>{
impl<'a> Loader<Mesh> for MeshLoader<'a,'_,'_>{
type Error=MeshError;
type Index=&'a str;
fn load(&mut self,index:Self::Index)->Result<Mesh,Self::Error>{

@ -105,7 +105,7 @@ pub fn load<P:AsRef<std::path::Path>>(path:P)->Result<LoadFormat,LoadError>{
},
#[cfg(feature="source")]
ReadFormat::Source(bsp)=>Ok(LoadFormat::Map(
bsp.to_snf(LoadFailureMode::DefaultToNone).map_err(LoadError::LoadSource)?
bsp.to_snf(LoadFailureMode::DefaultToNone,&[]).map_err(LoadError::LoadSource)?
)),
}
}