new loading api

This commit is contained in:
Quaternions 2024-02-14 23:45:16 -08:00
parent f3174cd191
commit a2eac57282
7 changed files with 637 additions and 60 deletions

425
Cargo.lock generated
View File

@ -2,6 +2,19 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "ahash"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.1.2" version = "1.1.2"
@ -11,12 +24,177 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "approx"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278"
dependencies = [
"num-traits",
]
[[package]]
name = "array-init"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc"
[[package]]
name = "arrayvec"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "binrw"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "173901312e9850391d4d7c1318c4e099fdc037d61870fca427429830efdb4e5f"
dependencies = [
"array-init",
"binrw_derive",
"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 = "bitflags"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "bv"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340"
dependencies = [
"feature-probe",
]
[[package]]
name = "bytemuck"
version = "1.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f"
[[package]]
name = "byteorder"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cgmath"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317"
dependencies = [
"approx",
"num-traits",
]
[[package]]
name = "crc"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
dependencies = [
"crc-catalog",
]
[[package]]
name = "crc-catalog"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crc32fast"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "either"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "feature-probe"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da"
[[package]]
name = "getrandom"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "glam" name = "glam"
version = "0.25.0" version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]] [[package]]
name = "id" name = "id"
version = "0.1.0" version = "0.1.0"
@ -24,7 +202,26 @@ source = "git+https://git.itzana.me/Quaternions/id?rev=1f710976cc786c8853dab73d6
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.48",
]
[[package]]
name = "indexmap"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
] ]
[[package]] [[package]]
@ -47,7 +244,32 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"regex", "regex",
"syn", "syn 2.0.48",
]
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "lzma"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "782ba3f542e8bc1349386c15e9dc3119ae6da96479f96b3863cc7a88bbdfd4e4"
dependencies = [
"byteorder 0.5.3",
]
[[package]]
name = "lzma-rs"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e"
dependencies = [
"byteorder 1.5.0",
"crc",
] ]
[[package]] [[package]]
@ -56,12 +278,57 @@ version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "num_enum"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845"
dependencies = [
"num_enum_derive",
]
[[package]]
name = "num_enum_derive"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.19.0" version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "owo-colors"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "proc-macro-crate"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
dependencies = [
"toml_edit",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.78" version = "1.0.78"
@ -109,10 +376,16 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "strafesnet_common" name = "strafesnet_common"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.itzana.me/StrafesNET/common?rev=47cdea0c8a5d10a2440ca6270a975d560aa3642d#47cdea0c8a5d10a2440ca6270a975d560aa3642d" source = "git+https://git.itzana.me/StrafesNET/common?rev=093a54c527134ef7020a22a0f5778df8cba60228#093a54c527134ef7020a22a0f5778df8cba60228"
dependencies = [ dependencies = [
"glam", "glam",
"id", "id",
@ -124,6 +397,18 @@ version = "0.2.0"
dependencies = [ dependencies = [
"lazy-regex", "lazy-regex",
"strafesnet_common", "strafesnet_common",
"vbsp",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
] ]
[[package]] [[package]]
@ -137,8 +422,142 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "syn_util"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6754c4559b79657554e9d8a0d56e65e490c76d382b9c23108364ec4125dea23c"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "thiserror"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
[[package]]
name = "toml_edit"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "vbsp"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9267540dab0c93bb5201c40ba3b2d027e2717bf355a8f9bf25377b06a5b32f6"
dependencies = [
"ahash",
"arrayvec",
"binrw",
"bitflags",
"bv",
"cgmath",
"itertools",
"lzma-rs",
"num_enum",
"static_assertions",
"thiserror",
"vbsp-derive",
"zip-lzma",
]
[[package]]
name = "vbsp-derive"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ade687fadf34b1b7502387fc9eb7b4032ddc9b93022d31356e9984c957abaad"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn_util",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winnow"
version = "0.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
dependencies = [
"memchr",
]
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "zip-lzma"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b480cb31fccfb2786565c0e0712865fd6f1ea0ea850c50316f643c3948196e63"
dependencies = [
"byteorder 1.5.0",
"crc32fast",
"crossbeam-utils",
"lzma",
]

View File

@ -6,10 +6,11 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features] [features]
legacy = ["dep:lazy-regex"] legacy = ["dep:lazy-regex", "dep:vbsp"]
#roblox = [] #roblox = ["dep:lazy-regex"]
#source = [] #source = ["dep:vbsp"]
[dependencies] [dependencies]
lazy-regex = { version = "3.1.0", optional = true } lazy-regex = { version = "3.1.0", optional = true }
strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "47cdea0c8a5d10a2440ca6270a975d560aa3642d" } strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "093a54c527134ef7020a22a0f5778df8cba60228" }
vbsp = { version = "0.5.0", optional = true }

View File

@ -8,6 +8,7 @@ mod roblox;
mod source; mod source;
pub mod texture; pub mod texture;
pub mod valve_mesh;
#[cfg(feature="legacy")] #[cfg(feature="legacy")]
pub fn roblox_legacy()->roblox_legacy::Loader{ pub fn roblox_legacy()->roblox_legacy::Loader{

View File

@ -1,7 +1,7 @@
use std::io::Read; use std::io::Read;
use std::collections::HashMap; use std::collections::HashMap;
use crate::texture::{Texture,Textures}; use crate::texture::{Texture,RenderConfigs};
use strafesnet_common::model::TextureId; use strafesnet_common::model::{TextureId,RenderConfigId,RenderConfig};
#[derive(Hash,Eq,PartialEq)] #[derive(Hash,Eq,PartialEq)]
struct RobloxAssetId(u64); struct RobloxAssetId(u64);
@ -29,30 +29,65 @@ impl std::fmt::Display for RobloxAssetIdParseErr{
impl std::error::Error for RobloxAssetIdParseErr{} impl std::error::Error for RobloxAssetIdParseErr{}
pub struct Loader{ pub struct Loader{
texture_names:HashMap<RobloxAssetId,TextureId>, texture_count:u32,
render_configs:Vec<RenderConfig>,
render_config_id_from_asset_id:HashMap<Option<RobloxAssetId>,RenderConfigId>,
} }
impl Loader{ impl Loader{
pub fn new()->Self{ pub fn new()->Self{
Self{ Self{
texture_names:HashMap::new(), texture_count:0,
render_configs:Vec::new(),
render_config_id_from_asset_id:HashMap::new(),
} }
} }
} }
impl Loader{ impl Loader{
pub fn acquire_texture_id(&mut self,name:&str)->Result<TextureId,RobloxAssetIdParseErr>{ pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{
let texture_id=TextureId::new(self.texture_names.len() as u32); let render_id=RenderConfigId::new(self.render_config_id_from_asset_id.len() as u32);
Ok(*self.texture_names.entry(name.parse::<RobloxAssetId>()?).or_insert(texture_id)) let index=name.and_then(|name|{
match name.parse::<RobloxAssetId>(){
Ok(asset_id)=>Some(asset_id),
Err(e)=>{
println!("Failed to parse AssetId: {e}");
None
},
}
});
*self.render_config_id_from_asset_id.entry(index).or_insert_with(||{
//create the render config.
let render_config=if name.is_some(){
let render_config=RenderConfig::texture(TextureId::new(self.texture_count));
self.texture_count+=1;
render_config
}else{
RenderConfig::default()
};
self.render_configs.push(render_config);
render_id
})
} }
pub fn load_textures(&self)->Result<Textures,std::io::Error>{ pub fn into_render_configs(mut self)->Result<RenderConfigs,std::io::Error>{
let mut texture_data=vec![Vec::<u8>::new();self.texture_names.len()]; let mut sorted_textures=vec![None;self.texture_count as usize];
for (texture_name,texture_id) in &self.texture_names{ for (asset_id,render_config_id) in self.render_config_id_from_asset_id{
let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_name.0)); let render_config=self.render_configs.get_mut(render_config_id.get() as usize).unwrap();
if let Ok(mut file)=std::fs::File::open(path){ if let (Some(asset_id),Some(texture_id))=(asset_id,render_config.texture){
//TODO: parallel let path=std::path::PathBuf::from(format!("textures/{}.dds",asset_id.0));
file.read_to_end(texture_data.get_mut(texture_id.get() as usize).unwrap())?; if let Ok(mut file)=std::fs::File::open(path){
//TODO: parallel
let mut data=Vec::<u8>::new();
file.read_to_end(&mut data)?;
sorted_textures[texture_id.get() as usize]=Some(Texture::ImageDDS(data));
}else{
//texture failed to load
render_config.texture=None;
}
} }
} }
Ok(Textures::new(texture_data.into_iter().map(Texture::ImageDDS).collect())) Ok(RenderConfigs::new(
sorted_textures,
self.render_configs,
))
} }
} }

View File

@ -1,15 +1,29 @@
use std::io::Read; use std::io::Read;
use std::collections::HashMap; use std::collections::HashMap;
use crate::texture::{Texture,Textures}; use crate::valve_mesh;
use strafesnet_common::model::{MeshId,TextureId}; use crate::texture::{Texture,RenderConfigs};
use strafesnet_common::model::{MeshId,TextureId,RenderConfig,RenderConfigId};
pub struct TextureLoader{ pub struct RenderConfigLoader{
texture_paths:HashMap<Box<str>,TextureId>, texture_count:u32,
render_configs:Vec<RenderConfig>,
texture_paths:HashMap<Option<Box<str>>,RenderConfigId>,
} }
impl TextureLoader{ impl RenderConfigLoader{
pub fn acquire_texture_id(&mut self,name:&str)->TextureId{ pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{
let texture_id=TextureId::new(self.texture_paths.len() as u32); let render_id=RenderConfigId::new(self.texture_paths.len() as u32);
*self.texture_paths.entry(name.into()).or_insert(texture_id) *self.texture_paths.entry(name.map(Into::into)).or_insert_with(||{
//create the render config.
let render_config=if name.is_some(){
let render_config=RenderConfig::texture(TextureId::new(self.texture_count));
self.texture_count+=1;
render_config
}else{
RenderConfig::default()
};
self.render_configs.push(render_config);
render_id
})
} }
} }
pub struct MeshLoader{ pub struct MeshLoader{
@ -17,42 +31,79 @@ pub struct MeshLoader{
} }
impl MeshLoader{ impl MeshLoader{
pub fn acquire_mesh_id(&mut self,name:&str)->MeshId{ pub fn acquire_mesh_id(&mut self,name:&str)->MeshId{
let texture_id=MeshId::new(self.mesh_paths.len() as u32); let mesh_id=MeshId::new(self.mesh_paths.len() as u32);
*self.mesh_paths.entry(name.into()).or_insert(texture_id) *self.mesh_paths.entry(name.into()).or_insert(mesh_id)
}
//load_meshes should look like load_textures
pub fn load_meshes(&mut self,bsp:&vbsp::Bsp)->valve_mesh::Meshes{
let mut mesh_data=vec![None;self.mesh_paths.len()];
for (mesh_path,mesh_id) in &self.mesh_paths{
let mesh_path_lower=mesh_path.to_lowercase();
//.mdl, .vvd, .dx90.vtx
let mut path=std::path::PathBuf::from(mesh_path_lower.as_str());
let file_name=std::path::PathBuf::from(path.file_stem().unwrap());
path.pop();
path.push(file_name);
let mut vvd_path=path.clone();
let mut vtx_path=path.clone();
vvd_path.set_extension("vvd");
vtx_path.set_extension("dx90.vtx");
match (bsp.pack.get(mesh_path_lower.as_str()),bsp.pack.get(vvd_path.as_os_str().to_str().unwrap()),bsp.pack.get(vtx_path.as_os_str().to_str().unwrap())){
(Ok(Some(mdl_file)),Ok(Some(vvd_file)),Ok(Some(vtx_file)))=>{
mesh_data[mesh_id.get() as usize]=Some(valve_mesh::ModelData{
mdl:valve_mesh::MdlData::new(mdl_file),
vtx:valve_mesh::VtxData::new(vtx_file),
vvd:valve_mesh::VvdData::new(vvd_file),
});
},
_=>println!("no model name={}",mesh_path),
}
}
valve_mesh::Meshes::new(mesh_data)
} }
} }
pub struct Loader{ pub struct Loader{
texture_loader:TextureLoader, render_config_loader:RenderConfigLoader,
mesh_loader:MeshLoader, mesh_loader:MeshLoader,
} }
impl Loader{ impl Loader{
pub fn new()->Self{ pub fn new()->Self{
Self{ Self{
texture_loader:TextureLoader{texture_paths:HashMap::new()}, render_config_loader:RenderConfigLoader{
texture_count:0,
texture_paths:HashMap::new(),
render_configs:Vec::new(),
},
mesh_loader:MeshLoader{mesh_paths:HashMap::new()}, mesh_loader:MeshLoader{mesh_paths:HashMap::new()},
} }
} }
pub fn get_inner_mut(&mut self)->(&mut TextureLoader,&mut MeshLoader){ pub fn get_inner_mut(&mut self)->(&mut RenderConfigLoader,&mut MeshLoader){
(&mut self.texture_loader,&mut self.mesh_loader) (&mut self.render_config_loader,&mut self.mesh_loader)
} }
} }
impl Loader{ impl Loader{
pub fn load_textures(&self)->Result<Textures,std::io::Error>{ pub fn into_render_configs(mut self)->Result<RenderConfigs,std::io::Error>{
let mut texture_data=vec![Vec::<u8>::new();self.texture_loader.texture_paths.len()]; let mut sorted_textures=vec![None;self.render_config_loader.texture_count as usize];
for (texture_path,texture_id) in &self.texture_loader.texture_paths{ for (texture_path,render_config_id) in self.render_config_loader.texture_paths{
let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_path)); let render_config=self.render_config_loader.render_configs.get_mut(render_config_id.get() as usize).unwrap();
if let Ok(mut file)=std::fs::File::open(path){ if let (Some(texture_path),Some(texture_id))=(texture_path,render_config.texture){
//TODO: parallel let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_path));
file.read_to_end(texture_data.get_mut(texture_id.get() as usize).unwrap())?; if let Ok(mut file)=std::fs::File::open(path){
//TODO: parallel
let mut data=Vec::<u8>::new();
file.read_to_end(&mut data)?;
sorted_textures[texture_id.get() as usize]=Some(Texture::ImageDDS(data));
}else{
//texture failed to load
render_config.texture=None;
}
} }
} }
Ok(Textures::new(texture_data.into_iter().map(Texture::ImageDDS).collect())) Ok(RenderConfigs::new(
sorted_textures,
self.render_config_loader.render_configs,
))
} }
//load_meshes should look like load_textures
/*
pub fn load_meshes(&mut self)->Result<Meshes,std::io::Error>{
}
*/
} }

View File

@ -1,5 +1,6 @@
use strafesnet_common::model::TextureId; use strafesnet_common::model::{TextureId,RenderConfigId,RenderConfig};
#[derive(Clone)]
pub enum Texture{ pub enum Texture{
ImageDDS(Vec<u8>), ImageDDS(Vec<u8>),
} }
@ -11,19 +12,28 @@ impl AsRef<[u8]> for Texture{
} }
} }
pub struct Textures{ pub struct RenderConfigs{
textures:Vec<Texture>, textures:Vec<Option<Texture>>,
render_configs:Vec<RenderConfig>,
} }
impl Textures{ impl RenderConfigs{
pub(crate) const fn new(textures:Vec<Texture>)->Self{ pub(crate) const fn new(textures:Vec<Option<Texture>>,render_configs:Vec<RenderConfig>)->Self{
Self{ Self{
textures, textures,
render_configs,
} }
} }
pub fn get_texture(&self,texture_id:TextureId)->Option<&Texture>{ pub fn consume(self)->(
self.textures.get(texture_id.get() as usize) impl Iterator<Item=(TextureId,Texture)>,
} impl Iterator<Item=(RenderConfigId,RenderConfig)>
pub fn into_iter(self)->impl Iterator<Item=(TextureId,Texture)>{ ){
self.textures.into_iter().enumerate().map(|(texture_id,texture)|(TextureId::new(texture_id as u32),texture)) (
self.textures.into_iter().enumerate().filter_map(|(texture_id,maybe_texture)|
maybe_texture.map(|texture|(TextureId::new(texture_id as u32),texture))
),
self.render_configs.into_iter().enumerate().map(|(render_id,render)|
(RenderConfigId::new(render_id as u32),render)
),
)
} }
} }

60
src/valve_mesh.rs Normal file
View File

@ -0,0 +1,60 @@
use strafesnet_common::model::MeshId;
//duplicate this code for now
#[derive(Clone)]
pub struct MdlData(Vec<u8>);
impl MdlData{
pub const fn new(value:Vec<u8>)->Self{
Self(value)
}
pub fn get(self)->Vec<u8>{
self.0
}
}
#[derive(Clone)]
pub struct VtxData(Vec<u8>);
impl VtxData{
pub const fn new(value:Vec<u8>)->Self{
Self(value)
}
pub fn get(self)->Vec<u8>{
self.0
}
}
#[derive(Clone)]
pub struct VvdData(Vec<u8>);
impl VvdData{
pub const fn new(value:Vec<u8>)->Self{
Self(value)
}
pub fn get(self)->Vec<u8>{
self.0
}
}
#[derive(Clone)]
pub struct ModelData{
pub mdl:MdlData,
pub vtx:VtxData,
pub vvd:VvdData,
}
//meshes is more prone to failure
pub struct Meshes{
meshes:Vec<Option<ModelData>>,
}
impl Meshes{
pub(crate) const fn new(meshes:Vec<Option<ModelData>>)->Self{
Self{
meshes,
}
}
pub fn get_texture(&self,texture_id:MeshId)->Option<&ModelData>{
self.meshes.get(texture_id.get() as usize)?.as_ref()
}
pub fn into_iter(self)->impl Iterator<Item=(MeshId,ModelData)>{
self.meshes.into_iter().enumerate().filter_map(|(mesh_id,maybe_mesh)|
maybe_mesh.map(|mesh|(MeshId::new(mesh_id as u32),mesh))
)
}
}