use loader crate

This commit is contained in:
Robin Appelman 2023-12-20 17:38:11 +01:00
commit d8cb4acc49
8 changed files with 247 additions and 163 deletions

225
Cargo.lock generated
View file

@ -39,6 +39,18 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "aes"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
"opaque-debug",
]
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.6" version = "0.8.6"
@ -196,6 +208,12 @@ dependencies = [
"backtrace", "backtrace",
] ]
[[package]]
name = "base64ct"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]] [[package]]
name = "beef" name = "beef"
version = "0.5.2" version = "0.5.2"
@ -338,6 +356,27 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bzip2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.11+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "calloop" name = "calloop"
version = "0.10.6" version = "0.10.6"
@ -393,6 +432,15 @@ dependencies = [
"num-traits 0.2.17", "num-traits 0.2.17",
] ]
[[package]]
name = "cipher"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.4.11" version = "4.4.11"
@ -445,6 +493,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.4" version = "0.9.4"
@ -577,12 +631,12 @@ dependencies = [
] ]
[[package]] [[package]]
name = "delaunator" name = "deranged"
version = "1.0.2" version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab46e386c7a38300a0d93b0f3e484bc2ee0aded66c47b14762ec9ab383934fa" checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc"
dependencies = [ dependencies = [
"robust", "powerfmt",
] ]
[[package]] [[package]]
@ -593,6 +647,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [ dependencies = [
"block-buffer", "block-buffer",
"crypto-common", "crypto-common",
"subtle",
] ]
[[package]] [[package]]
@ -952,6 +1007,15 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]] [[package]]
name = "image" name = "image"
version = "0.23.14" version = "0.23.14"
@ -1634,6 +1698,12 @@ 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 = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]] [[package]]
name = "orbclient" name = "orbclient"
version = "0.3.47" version = "0.3.47"
@ -1713,12 +1783,35 @@ dependencies = [
"syn 2.0.41", "syn 2.0.41",
] ]
[[package]]
name = "password-hash"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
dependencies = [
"base64ct",
"rand_core",
"subtle",
]
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.14" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "pbkdf2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
dependencies = [
"digest",
"hmac",
"password-hash",
"sha2",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.1" version = "2.3.1"
@ -1807,6 +1900,12 @@ dependencies = [
"miniz_oxide 0.7.1", "miniz_oxide 0.7.1",
] ]
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]] [[package]]
name = "proc-macro-crate" name = "proc-macro-crate"
version = "1.3.1" version = "1.3.1"
@ -1869,6 +1968,12 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]] [[package]]
name = "raw-window-handle" name = "raw-window-handle"
version = "0.5.2" version = "0.5.2"
@ -1974,12 +2079,6 @@ 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 = "robust"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5864e7ef1a6b7bcf1d6ca3f655e65e724ed3b52546a0d0a663c991522f552ea"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.23"
@ -2095,6 +2194,17 @@ dependencies = [
"syn 2.0.41", "syn 2.0.41",
] ]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.8" version = "0.10.8"
@ -2245,6 +2355,12 @@ dependencies = [
"syn 2.0.41", "syn 2.0.41",
] ]
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]] [[package]]
name = "supports-color" name = "supports-color"
version = "2.1.0" version = "2.1.0"
@ -2348,6 +2464,20 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "tf-asset-loader"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d19874714b7454f34d6142f9a2e2521b6e48ff4b3929cbac7acc72f161baf7bf"
dependencies = [
"steamlocate",
"thiserror",
"tracing",
"vbsp",
"vpk",
"zip-lzma",
]
[[package]] [[package]]
name = "tf-demo-parser" name = "tf-demo-parser"
version = "0.4.0" version = "0.4.0"
@ -2402,6 +2532,8 @@ dependencies = [
[[package]] [[package]]
name = "three-d" name = "three-d"
version = "0.16.3" version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2db9010227411ab0aa5948e770304e807e5c9b6d5d0719c3de248bae7be7096"
dependencies = [ dependencies = [
"cgmath", "cgmath",
"egui", "egui",
@ -2443,6 +2575,35 @@ dependencies = [
"weezl", "weezl",
] ]
[[package]]
name = "time"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e"
dependencies = [
"deranged",
"itoa",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f"
dependencies = [
"time-core",
]
[[package]] [[package]]
name = "tiny-skia" name = "tiny-skia"
version = "0.8.4" version = "0.8.4"
@ -2672,13 +2833,12 @@ version = "0.1.0"
dependencies = [ dependencies = [
"cgmath", "cgmath",
"clap", "clap",
"delaunator",
"image", "image",
"itertools 0.10.5", "itertools 0.12.0",
"miette", "miette",
"splines", "splines",
"steamid-ng", "steamid-ng",
"steamlocate", "tf-asset-loader",
"tf-demo-parser", "tf-demo-parser",
"thiserror", "thiserror",
"three-d", "three-d",
@ -2689,7 +2849,6 @@ dependencies = [
"vbsp", "vbsp",
"vmdl", "vmdl",
"vmt-parser", "vmt-parser",
"vpk",
"vtf", "vtf",
] ]
@ -3273,8 +3432,46 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b480cb31fccfb2786565c0e0712865fd6f1ea0ea850c50316f643c3948196e63" checksum = "b480cb31fccfb2786565c0e0712865fd6f1ea0ea850c50316f643c3948196e63"
dependencies = [ dependencies = [
"aes",
"byteorder 1.5.0", "byteorder 1.5.0",
"bzip2",
"constant_time_eq",
"crc32fast", "crc32fast",
"crossbeam-utils", "crossbeam-utils",
"flate2",
"hmac",
"lzma", "lzma",
"pbkdf2",
"sha1",
"time",
"zstd",
]
[[package]]
name = "zstd"
version = "0.10.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "4.1.6+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb"
dependencies = [
"libc",
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "1.6.3+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8"
dependencies = [
"cc",
"libc",
] ]

View file

@ -6,17 +6,13 @@ authors = ["Robin Appelman <robin@icewind.nl>"]
license = "MIT" license = "MIT"
[dependencies] [dependencies]
#three-d = { version = "0.16.3", features = ["egui-gui"] } three-d = { version = "0.16.3", features = ["egui-gui"] }
three-d = { version = "0.16.3", features = ["egui-gui"], path = "../rust/three-d" }
three-d-asset = { version = "0.6" } three-d-asset = { version = "0.6" }
vbsp = { version = "0.3.0", git = "https://github.com/icewind1991/vbsp" } vbsp = { version = "0.3.0", git = "https://github.com/icewind1991/vbsp" }
#vbsp = { version = "0.3.0", path = "../bsp" } #vbsp = { version = "0.3.0", path = "../bsp" }
miette = { version = "5.5.0", features = ["fancy"] } miette = { version = "5.5.0", features = ["fancy"] }
thiserror = "1.0.37" thiserror = "1.0.37"
delaunator = "1.0.1" itertools = "0.12.0"
itertools = "0.10.5"
steamlocate = "=2.0.0-alpha.0"
vpk = "0.2.0"
vmdl = { version = "*", git = "https://github.com/icewind1991/vmdl" } vmdl = { version = "*", git = "https://github.com/icewind1991/vmdl" }
#vmdl = { version = "*", path = "../vmdl" } #vmdl = { version = "*", path = "../vmdl" }
tracing = "0.1.37" tracing = "0.1.37"
@ -30,6 +26,12 @@ splines = { version = "4.1.1", features = ["cgmath"] }
vtf = "0.1.6" vtf = "0.1.6"
vmt-parser = { version = "0.1", git = "https://github.com/icewind1991/vmt-parser" } vmt-parser = { version = "0.1", git = "https://github.com/icewind1991/vmt-parser" }
image = "0.23.14" image = "0.23.14"
tf-asset-loader = { version = "0.1", features = ["bsp"] }
# make tf-asset-loader use the same vbsp version
[patch.crates-io]
#vbsp = { version = "0.3.0", path = "../bsp" }
vbsp = { version = "0.3.0", git = "https://github.com/icewind1991/vbsp" }
[profile.dev.package."*"] [profile.dev.package."*"]
opt-level = 2 opt-level = 2

View file

@ -1,9 +1,10 @@
use crate::material::{convert_material, load_material_fallback}; use crate::material::{convert_material, load_material_fallback};
use crate::prop::load_props; use crate::prop::load_props;
use crate::{Error, Loader}; use crate::Error;
use cgmath::Matrix4; use cgmath::Matrix4;
use itertools::Itertools; use itertools::Itertools;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use tf_asset_loader::Loader;
use three_d::{CpuModel, Positions, Vec3}; use three_d::{CpuModel, Positions, Vec3};
use three_d_asset::{Geometry, Primitive, TriMesh}; use three_d_asset::{Geometry, Primitive, TriMesh};
use vbsp::{Bsp, Handle}; use vbsp::{Bsp, Handle};
@ -98,7 +99,7 @@ fn model_to_model(model: Handle<vbsp::data::Model>, loader: &Loader) -> CpuModel
fn load_world(data: &[u8], loader: &mut Loader) -> Result<(CpuModel, Bsp), Error> { fn load_world(data: &[u8], loader: &mut Loader) -> Result<(CpuModel, Bsp), Error> {
let bsp = Bsp::read(data)?; let bsp = Bsp::read(data)?;
loader.set_pack(bsp.pack.clone()); loader.add_source(bsp.pack.clone());
let world_model = bsp let world_model = bsp
.models() .models()

View file

@ -1,126 +0,0 @@
use crate::Error;
use std::fmt::{Debug, Formatter};
use std::fs;
use std::path::PathBuf;
use steamlocate::SteamDir;
use tracing::debug;
use vbsp::Packfile;
use vpk::VPK;
pub struct Loader {
pack: Option<Packfile>,
tf_dir: PathBuf,
download: PathBuf,
vpks: Vec<VPK>,
}
impl Debug for Loader {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Loader")
.field("tf_dir", &self.tf_dir)
.finish_non_exhaustive()
}
}
impl Loader {
pub fn new() -> Result<Self, Error> {
let tf2_dir = SteamDir::locate()
.ok_or("Can't find steam directory")?
.app(&440)
.ok_or("Can't find tf2 directory")?
.path
.clone();
let tf_dir = tf2_dir.join("tf");
let hl_dir = tf2_dir.join("hl2");
let download = tf_dir.join("download");
let vpks = tf_dir
.read_dir()?
.chain(hl_dir.read_dir()?)
.filter_map(|item| item.ok())
.filter_map(|item| Some(item.path().to_str()?.to_string()))
.filter(|path| path.ends_with("dir.vpk"))
.map(|path| vpk::from_path(&path))
.filter_map(|res| res.ok())
.collect();
Ok(Loader {
tf_dir,
download,
vpks,
pack: None,
})
}
pub fn set_pack(&mut self, pack: Packfile) {
self.pack = Some(pack);
}
#[tracing::instrument]
pub fn exists(&self, name: &str) -> bool {
debug!("loading {}", name);
if name.ends_with("bsp") {
let path = self.tf_dir.join(name);
if path.exists() {
return true;
}
let path = self.download.join(name);
if path.exists() {
return true;
}
}
for vpk in self.vpks.iter() {
if vpk.tree.contains_key(name) {
return true;
}
}
if let Some(pack) = &self.pack {
if pack.get(name).ok().flatten().is_some() {
return true;
}
}
false
}
#[tracing::instrument]
pub fn load(&self, name: &str) -> Result<Vec<u8>, Error> {
debug!("loading {}", name);
if name.ends_with("bsp") {
let path = self.tf_dir.join(name);
if path.exists() {
debug!("found in tf2 dir");
return Ok(fs::read(path)?);
}
let path = self.download.join(name);
if path.exists() {
debug!("found in download dir");
return Ok(fs::read(path)?);
}
}
if let Some(pack) = &self.pack {
if let Some(data) = pack.get(name)? {
debug!("got {} bytes from packfile", data.len());
return Ok(data);
}
}
for vpk in self.vpks.iter() {
if let Some(entry) = vpk.tree.get(name) {
let data = entry.get()?.into_owned();
debug!("got {} bytes from vpk", data.len());
return Ok(data);
}
}
Err(Error::ResourceNotFound(name.to_string()))
}
pub fn find_in_paths(&self, name: &str, paths: &[String]) -> Option<String> {
for path in paths {
let full_path = format!("{}{}", path, name);
if self.exists(&full_path) {
return Some(full_path);
}
}
None
}
}

View file

@ -1,7 +1,6 @@
mod bsp; mod bsp;
mod control; mod control;
mod demo; mod demo;
mod loader;
mod material; mod material;
mod prop; mod prop;
mod renderer; mod renderer;
@ -11,6 +10,7 @@ mod wrapping;
use clap::Parser; use clap::Parser;
use std::fs; use std::fs;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use tf_asset_loader::{Loader, LoaderError};
use crate::bsp::load_map; use crate::bsp::load_map;
use crate::control::{Control, DemoCamera}; use crate::control::{Control, DemoCamera};
@ -18,7 +18,6 @@ use crate::demo::DemoInfo;
use crate::renderer::Renderer; use crate::renderer::Renderer;
use crate::ui::DebugUI; use crate::ui::DebugUI;
use control::FirstPerson; use control::FirstPerson;
use loader::Loader;
use thiserror::Error; use thiserror::Error;
use three_d::*; use three_d::*;
use tracing_subscriber::{prelude::*, EnvFilter}; use tracing_subscriber::{prelude::*, EnvFilter};
@ -44,8 +43,6 @@ pub enum Error {
#[error(transparent)] #[error(transparent)]
IO(#[from] std::io::Error), IO(#[from] std::io::Error),
#[error(transparent)] #[error(transparent)]
Vpk(#[from] vpk::Error),
#[error(transparent)]
Vtf(#[from] vtf::Error), Vtf(#[from] vtf::Error),
#[error(transparent)] #[error(transparent)]
Vdf(#[from] VdfError), Vdf(#[from] VdfError),
@ -61,6 +58,8 @@ pub enum Error {
Render(#[from] RendererError), Render(#[from] RendererError),
#[error(transparent)] #[error(transparent)]
String(#[from] FromUtf8Error), String(#[from] FromUtf8Error),
#[error(transparent)]
Loader(#[from] LoaderError),
#[error("resource {0} not found in vpks or pack")] #[error("resource {0} not found in vpks or pack")]
ResourceNotFound(String), ResourceNotFound(String),
} }
@ -98,7 +97,9 @@ fn main() -> Result<(), Error> {
if args.path.ends_with(".dem") { if args.path.ends_with(".dem") {
let demo = DemoInfo::new(args.path, &args.player.unwrap_or_default())?; let demo = DemoInfo::new(args.path, &args.player.unwrap_or_default())?;
let mut loader = Loader::new()?; let mut loader = Loader::new()?;
let map = loader.load(&format!("maps/{}.bsp", demo.map))?; let map = loader
.load(&format!("maps/{}.bsp", demo.map))?
.ok_or(Error::ResourceNotFound(demo.map.clone()))?;
let models = load_map(&map, &mut loader)?; let models = load_map(&map, &mut loader)?;
play(window, DemoCamera::new(demo), models) play(window, DemoCamera::new(demo), models)

View file

@ -1,6 +1,6 @@
use crate::loader::Loader;
use crate::Error; use crate::Error;
use image::{DynamicImage, GenericImageView}; use image::{DynamicImage, GenericImageView};
use tf_asset_loader::Loader;
use three_d::{CpuMaterial, CpuTexture}; use three_d::{CpuMaterial, CpuTexture};
use three_d_asset::Srgba; use three_d_asset::Srgba;
use tracing::{error, instrument}; use tracing::{error, instrument};
@ -58,7 +58,9 @@ pub fn load_material(
let path = loader let path = loader
.find_in_paths(&path, &dirs) .find_in_paths(&path, &dirs)
.ok_or(Error::ResourceNotFound(path))?; .ok_or(Error::ResourceNotFound(path))?;
let raw = loader.load(&path)?; let raw = loader
.load(&path)?
.ok_or_else(|| Error::ResourceNotFound(path.clone()))?;
let vdf = String::from_utf8(raw)?; let vdf = String::from_utf8(raw)?;
let material = from_str(&vdf).map_err(|e| { let material = from_str(&vdf).map_err(|e| {
@ -67,7 +69,9 @@ pub fn load_material(
Error::Other(format!("Failed to load material {}", path)) Error::Other(format!("Failed to load material {}", path))
})?; })?;
let material = material.resolve(|path| { let material = material.resolve(|path| {
let data = loader.load(path)?; let data = loader
.load(path)?
.ok_or(Error::ResourceNotFound(path.into()))?;
let vdf = String::from_utf8(data)?; let vdf = String::from_utf8(data)?;
Ok::<_, Error>(vdf) Ok::<_, Error>(vdf)
})?; })?;
@ -120,7 +124,7 @@ fn load_texture(name: &str, loader: &Loader) -> Result<DynamicImage, Error> {
"materials/{}.vtf", "materials/{}.vtf",
name.trim_end_matches(".vtf").trim_start_matches('/') name.trim_end_matches(".vtf").trim_start_matches('/')
); );
let mut raw = loader.load(&path)?; let mut raw = loader.load(&path)?.ok_or(Error::ResourceNotFound(path))?;
let vtf = VTF::read(&mut raw)?; let vtf = VTF::read(&mut raw)?;
let image = vtf.highres_image.decode(0)?; let image = vtf.highres_image.decode(0)?;
Ok(image) Ok(image)

View file

@ -1,6 +1,7 @@
use crate::bsp::map_coords; use crate::bsp::map_coords;
use crate::material::{convert_material, load_material_fallback}; use crate::material::{convert_material, load_material_fallback};
use crate::{Error, Loader}; use crate::Error;
use tf_asset_loader::Loader;
use three_d::{CpuMaterial, CpuModel, Mat4, Positions, Vec2, Vec3, Vec4}; use three_d::{CpuMaterial, CpuModel, Mat4, Positions, Vec2, Vec3, Vec4};
use three_d_asset::{Geometry, Primitive, TriMesh}; use three_d_asset::{Geometry, Primitive, TriMesh};
use tracing::{error, warn}; use tracing::{error, warn};
@ -11,9 +12,14 @@ use vmdl::vvd::Vvd;
#[tracing::instrument(skip(loader))] #[tracing::instrument(skip(loader))]
pub fn load_prop(loader: &Loader, name: &str) -> Result<vmdl::Model, Error> { pub fn load_prop(loader: &Loader, name: &str) -> Result<vmdl::Model, Error> {
let mdl = Mdl::read(&loader.load(name)?)?; let load = |name: &str| -> Result<Vec<u8>, Error> {
let vtx = Vtx::read(&loader.load(&name.replace(".mdl", ".dx90.vtx"))?)?; loader
let vvd = Vvd::read(&loader.load(&name.replace(".mdl", ".vvd"))?)?; .load(name)?
.ok_or(Error::ResourceNotFound(name.into()))
};
let mdl = Mdl::read(&load(name)?)?;
let vtx = Vtx::read(&load(&name.replace(".mdl", ".dx90.vtx"))?)?;
let vvd = Vvd::read(&load(&name.replace(".mdl", ".vvd"))?)?;
Ok(vmdl::Model::from_parts(mdl, vtx, vvd)) Ok(vmdl::Model::from_parts(mdl, vtx, vvd))
} }

View file

@ -1,12 +1,11 @@
use crate::control::{Control, DebugToggle}; use crate::control::{Control, DebugToggle};
use crate::ui::DebugType; use crate::ui::DebugType;
use crate::DebugUI; use crate::DebugUI;
use std::sync::Arc;
use three_d::*; use three_d::*;
pub struct Renderer<C: Control> { pub struct Renderer<C: Control> {
gui: DebugUI, gui: DebugUI,
pub models: Vec<Model<Arc<PhysicalMaterial>>>, pub models: Vec<Model<PhysicalMaterial>>,
ambient_lights: Vec<AmbientLight>, ambient_lights: Vec<AmbientLight>,
directional_lights: Vec<DirectionalLight>, directional_lights: Vec<DirectionalLight>,
pub context: Context, pub context: Context,