From a2eac572824959e9ffe264e544431f0117da010b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 14 Feb 2024 23:45:16 -0800 Subject: [PATCH] new loading api --- Cargo.lock | 425 ++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 9 +- src/lib.rs | 1 + src/roblox_legacy.rs | 65 +++++-- src/source_legacy.rs | 105 ++++++++--- src/texture.rs | 32 ++-- src/valve_mesh.rs | 60 ++++++ 7 files changed, 637 insertions(+), 60 deletions(-) create mode 100644 src/valve_mesh.rs diff --git a/Cargo.lock b/Cargo.lock index ab45f8b..baa55d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,19 @@ # It is not intended for manual editing. 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]] name = "aho-corasick" version = "1.1.2" @@ -11,12 +24,177 @@ dependencies = [ "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]] name = "glam" version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "id" version = "0.1.0" @@ -24,7 +202,26 @@ source = "git+https://git.itzana.me/Quaternions/id?rev=1f710976cc786c8853dab73d6 dependencies = [ "proc-macro2", "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]] @@ -47,7 +244,32 @@ dependencies = [ "proc-macro2", "quote", "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]] @@ -56,12 +278,57 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "proc-macro2" version = "1.0.78" @@ -109,10 +376,16 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strafesnet_common" 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 = [ "glam", "id", @@ -124,6 +397,18 @@ version = "0.2.0" dependencies = [ "lazy-regex", "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]] @@ -137,8 +422,142 @@ dependencies = [ "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]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" 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", +] diff --git a/Cargo.toml b/Cargo.toml index f7e925f..9217831 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -legacy = ["dep:lazy-regex"] -#roblox = [] -#source = [] +legacy = ["dep:lazy-regex", "dep:vbsp"] +#roblox = ["dep:lazy-regex"] +#source = ["dep:vbsp"] [dependencies] 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 } diff --git a/src/lib.rs b/src/lib.rs index fec640b..4fed855 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ mod roblox; mod source; pub mod texture; +pub mod valve_mesh; #[cfg(feature="legacy")] pub fn roblox_legacy()->roblox_legacy::Loader{ diff --git a/src/roblox_legacy.rs b/src/roblox_legacy.rs index 50ae79a..5c67ffc 100644 --- a/src/roblox_legacy.rs +++ b/src/roblox_legacy.rs @@ -1,7 +1,7 @@ use std::io::Read; use std::collections::HashMap; -use crate::texture::{Texture,Textures}; -use strafesnet_common::model::TextureId; +use crate::texture::{Texture,RenderConfigs}; +use strafesnet_common::model::{TextureId,RenderConfigId,RenderConfig}; #[derive(Hash,Eq,PartialEq)] struct RobloxAssetId(u64); @@ -29,30 +29,65 @@ impl std::fmt::Display for RobloxAssetIdParseErr{ impl std::error::Error for RobloxAssetIdParseErr{} pub struct Loader{ - texture_names:HashMap, + texture_count:u32, + render_configs:Vec, + render_config_id_from_asset_id:HashMap,RenderConfigId>, } impl Loader{ pub fn new()->Self{ Self{ - texture_names:HashMap::new(), + texture_count:0, + render_configs:Vec::new(), + render_config_id_from_asset_id:HashMap::new(), } } } impl Loader{ - pub fn acquire_texture_id(&mut self,name:&str)->Result{ - let texture_id=TextureId::new(self.texture_names.len() as u32); - Ok(*self.texture_names.entry(name.parse::()?).or_insert(texture_id)) + pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{ + let render_id=RenderConfigId::new(self.render_config_id_from_asset_id.len() as u32); + let index=name.and_then(|name|{ + match name.parse::(){ + 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{ - let mut texture_data=vec![Vec::::new();self.texture_names.len()]; - for (texture_name,texture_id) in &self.texture_names{ - let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_name.0)); - if let Ok(mut file)=std::fs::File::open(path){ - //TODO: parallel - file.read_to_end(texture_data.get_mut(texture_id.get() as usize).unwrap())?; + pub fn into_render_configs(mut self)->Result{ + let mut sorted_textures=vec![None;self.texture_count as usize]; + for (asset_id,render_config_id) in self.render_config_id_from_asset_id{ + let render_config=self.render_configs.get_mut(render_config_id.get() as usize).unwrap(); + if let (Some(asset_id),Some(texture_id))=(asset_id,render_config.texture){ + let path=std::path::PathBuf::from(format!("textures/{}.dds",asset_id.0)); + if let Ok(mut file)=std::fs::File::open(path){ + //TODO: parallel + let mut data=Vec::::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, + )) } } \ No newline at end of file diff --git a/src/source_legacy.rs b/src/source_legacy.rs index c6eadd2..d24959f 100644 --- a/src/source_legacy.rs +++ b/src/source_legacy.rs @@ -1,15 +1,29 @@ use std::io::Read; use std::collections::HashMap; -use crate::texture::{Texture,Textures}; -use strafesnet_common::model::{MeshId,TextureId}; +use crate::valve_mesh; +use crate::texture::{Texture,RenderConfigs}; +use strafesnet_common::model::{MeshId,TextureId,RenderConfig,RenderConfigId}; -pub struct TextureLoader{ - texture_paths:HashMap,TextureId>, +pub struct RenderConfigLoader{ + texture_count:u32, + render_configs:Vec, + texture_paths:HashMap>,RenderConfigId>, } -impl TextureLoader{ - pub fn acquire_texture_id(&mut self,name:&str)->TextureId{ - let texture_id=TextureId::new(self.texture_paths.len() as u32); - *self.texture_paths.entry(name.into()).or_insert(texture_id) +impl RenderConfigLoader{ + pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{ + let render_id=RenderConfigId::new(self.texture_paths.len() as u32); + *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{ @@ -17,42 +31,79 @@ pub struct MeshLoader{ } impl MeshLoader{ pub fn acquire_mesh_id(&mut self,name:&str)->MeshId{ - let texture_id=MeshId::new(self.mesh_paths.len() as u32); - *self.mesh_paths.entry(name.into()).or_insert(texture_id) + let mesh_id=MeshId::new(self.mesh_paths.len() as u32); + *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{ - texture_loader:TextureLoader, + render_config_loader:RenderConfigLoader, mesh_loader:MeshLoader, } impl Loader{ pub fn new()->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()}, } } - pub fn get_inner_mut(&mut self)->(&mut TextureLoader,&mut MeshLoader){ - (&mut self.texture_loader,&mut self.mesh_loader) + pub fn get_inner_mut(&mut self)->(&mut RenderConfigLoader,&mut MeshLoader){ + (&mut self.render_config_loader,&mut self.mesh_loader) } } impl Loader{ - pub fn load_textures(&self)->Result{ - let mut texture_data=vec![Vec::::new();self.texture_loader.texture_paths.len()]; - for (texture_path,texture_id) in &self.texture_loader.texture_paths{ - let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_path)); - if let Ok(mut file)=std::fs::File::open(path){ - //TODO: parallel - file.read_to_end(texture_data.get_mut(texture_id.get() as usize).unwrap())?; + pub fn into_render_configs(mut self)->Result{ + let mut sorted_textures=vec![None;self.render_config_loader.texture_count as usize]; + for (texture_path,render_config_id) in self.render_config_loader.texture_paths{ + let render_config=self.render_config_loader.render_configs.get_mut(render_config_id.get() as usize).unwrap(); + if let (Some(texture_path),Some(texture_id))=(texture_path,render_config.texture){ + let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_path)); + if let Ok(mut file)=std::fs::File::open(path){ + //TODO: parallel + let mut data=Vec::::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{ - } - */ } diff --git a/src/texture.rs b/src/texture.rs index 59c9b6e..d737618 100644 --- a/src/texture.rs +++ b/src/texture.rs @@ -1,5 +1,6 @@ -use strafesnet_common::model::TextureId; +use strafesnet_common::model::{TextureId,RenderConfigId,RenderConfig}; +#[derive(Clone)] pub enum Texture{ ImageDDS(Vec), } @@ -11,19 +12,28 @@ impl AsRef<[u8]> for Texture{ } } -pub struct Textures{ - textures:Vec, +pub struct RenderConfigs{ + textures:Vec>, + render_configs:Vec, } -impl Textures{ - pub(crate) const fn new(textures:Vec)->Self{ +impl RenderConfigs{ + pub(crate) const fn new(textures:Vec>,render_configs:Vec)->Self{ Self{ textures, + render_configs, } } - pub fn get_texture(&self,texture_id:TextureId)->Option<&Texture>{ - self.textures.get(texture_id.get() as usize) + pub fn consume(self)->( + impl Iterator, + impl Iterator + ){ + ( + 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) + ), + ) } - pub fn into_iter(self)->impl Iterator{ - self.textures.into_iter().enumerate().map(|(texture_id,texture)|(TextureId::new(texture_id as u32),texture)) - } -} +} \ No newline at end of file diff --git a/src/valve_mesh.rs b/src/valve_mesh.rs new file mode 100644 index 0000000..15d7f40 --- /dev/null +++ b/src/valve_mesh.rs @@ -0,0 +1,60 @@ +use strafesnet_common::model::MeshId; + +//duplicate this code for now +#[derive(Clone)] +pub struct MdlData(Vec); +impl MdlData{ + pub const fn new(value:Vec)->Self{ + Self(value) + } + pub fn get(self)->Vec{ + self.0 + } +} +#[derive(Clone)] +pub struct VtxData(Vec); +impl VtxData{ + pub const fn new(value:Vec)->Self{ + Self(value) + } + pub fn get(self)->Vec{ + self.0 + } +} +#[derive(Clone)] +pub struct VvdData(Vec); +impl VvdData{ + pub const fn new(value:Vec)->Self{ + Self(value) + } + pub fn get(self)->Vec{ + 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>, +} +impl Meshes{ + pub(crate) const fn new(meshes:Vec>)->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{ + self.meshes.into_iter().enumerate().filter_map(|(mesh_id,maybe_mesh)| + maybe_mesh.map(|mesh|(MeshId::new(mesh_id as u32),mesh)) + ) + } +} \ No newline at end of file