mirror of
https://codeberg.org/icewind/vbspview.git
synced 2026-06-03 10:14:10 +02:00
dynamic props
This commit is contained in:
parent
7ef052f4df
commit
9689dbf7ae
7 changed files with 476 additions and 413 deletions
792
Cargo.lock
generated
792
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
10
Cargo.toml
10
Cargo.toml
|
|
@ -8,12 +8,11 @@ license = "MIT"
|
|||
[dependencies]
|
||||
three-d = { version = "0.16.3", features = ["egui-gui"] }
|
||||
three-d-asset = { version = "0.6" }
|
||||
vbsp = "0.4.0"
|
||||
vbsp = "0.5.0"
|
||||
miette = { version = "5.5.0", features = ["fancy"] }
|
||||
thiserror = "1.0.37"
|
||||
itertools = "0.12.0"
|
||||
vmdl = "0.1.0"
|
||||
#vmdl = { version = "*", path = "../vmdl" }
|
||||
vmdl = "0.2.0"
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
||||
tracing-tree = "0.3.0"
|
||||
|
|
@ -30,9 +29,12 @@ rayon = "1.8.0"
|
|||
bytemuck = "1.14.0"
|
||||
texpresso = { version = "2.0.1", features = ["rayon"] }
|
||||
|
||||
[patch.crates-io]
|
||||
vbsp = { path = "../bsp" }
|
||||
vmdl = { path = "../vmdl" }
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 2
|
||||
|
||||
[features]
|
||||
dump_materials = []
|
||||
dump_materials = []
|
||||
|
|
|
|||
35
flake.lock
generated
35
flake.lock
generated
|
|
@ -10,11 +10,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1689107909,
|
||||
"narHash": "sha256-fb+zxf7AWesECHx1foXOM3NcKHLrdeXzGb6s2AhT6pE=",
|
||||
"lastModified": 1717704286,
|
||||
"narHash": "sha256-zrLB/FTKODEAlJjgO8TwbK7teTseYbjLESp8QJ/FJYc=",
|
||||
"owner": "icewind1991",
|
||||
"repo": "cross-naersk",
|
||||
"rev": "51de54599de569e6faa2ee33dd659c5c028d9911",
|
||||
"rev": "9068daceb8f0d248dcf629944f60e92b81391bdb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -30,11 +30,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1698420672,
|
||||
"narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
|
||||
"lastModified": 1721727458,
|
||||
"narHash": "sha256-r/xppY958gmZ4oTfLiHN0ZGuQ+RSTijDblVgVLFi1mw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "aeb58d5e8faead8980a807c840232697982d47b9",
|
||||
"rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -45,16 +45,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1703467016,
|
||||
"narHash": "sha256-/5A/dNPhbQx/Oa2d+Get174eNI3LERQ7u6WTWOlR1eQ=",
|
||||
"lastModified": 1724316499,
|
||||
"narHash": "sha256-Qb9MhKBUTCfWg/wqqaxt89Xfi6qTD3XpTzQ9eXi3JmE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d02d818f22c777aa4e854efc3242ec451e5d462a",
|
||||
"rev": "797f7dc49e0bc7fab4b57c021cdf68f595e47841",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-23.11",
|
||||
"ref": "nixos-24.05",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
|
|
@ -69,19 +69,16 @@
|
|||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1703643208,
|
||||
"narHash": "sha256-UL4KO8JxnD5rOycwHqBAf84lExF1/VnYMDC7b/wpPDU=",
|
||||
"lastModified": 1724638882,
|
||||
"narHash": "sha256-ap2jIQi/FuUHR6HCht6ASWhoz8EiB99XmI8Esot38VE=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "ce117f3e0de8262be8cd324ee6357775228687cf",
|
||||
"rev": "19b70f147b9c67a759e35824b241f1ed92e46694",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -110,11 +107,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-23.11";
|
||||
nixpkgs.url = "nixpkgs/nixos-24.05";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
naersk.url = "github:nix-community/naersk";
|
||||
naersk.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
|
|
|||
17
src/bsp.rs
17
src/bsp.rs
|
|
@ -18,8 +18,21 @@ pub fn load_map(
|
|||
let (world, bsp) = load_world(data, loader, textures)?;
|
||||
let mut models = Vec::with_capacity(bsp.static_props().count() + 1);
|
||||
models.push(world);
|
||||
// println!("{:#?}", bsp.entities);
|
||||
let entity_props =
|
||||
bsp.entities
|
||||
.iter()
|
||||
.flat_map(|ent| ent.parse())
|
||||
.filter_map(|ent| match ent {
|
||||
Entity::PropDynamic(prop) => Some(prop.as_prop_placement()),
|
||||
Entity::PropPhysics(prop) => Some(prop.as_prop_placement()),
|
||||
Entity::PropDynamicOverride(prop) => Some(prop.as_prop_placement()),
|
||||
_ => None,
|
||||
});
|
||||
let static_props = bsp.static_props().map(|prop| prop.as_prop_placement());
|
||||
|
||||
if props {
|
||||
let props = load_props(loader, bsp.static_props(), textures)?;
|
||||
let props = load_props(loader, static_props.chain(entity_props), textures)?;
|
||||
models.extend(props);
|
||||
}
|
||||
Ok(models)
|
||||
|
|
@ -119,7 +132,7 @@ fn model_to_model(
|
|||
fn load_world(data: &[u8], loader: &mut Loader, textures: bool) -> Result<(CpuModel, Bsp), Error> {
|
||||
let bsp = Bsp::read(data)?;
|
||||
|
||||
loader.add_source(bsp.pack.clone());
|
||||
loader.add_source(bsp.pack.clone().into_zip());
|
||||
|
||||
let world_model = bsp
|
||||
.models()
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use three_d::{CpuMaterial, CpuTexture};
|
|||
use three_d_asset::Srgba;
|
||||
use tracing::{error, instrument};
|
||||
use vmdl::mdl::TextureInfo;
|
||||
use vmt_parser::from_str;
|
||||
use vmt_parser::material::{Material, WaterMaterial};
|
||||
use vmt_parser::{from_str, TextureTransform};
|
||||
use vtf::vtf::VTF;
|
||||
|
||||
pub fn load_material_fallback(name: &str, loader: &Loader) -> MaterialData {
|
||||
|
|
@ -32,6 +32,7 @@ pub struct MaterialData {
|
|||
pub alpha_test: Option<f32>,
|
||||
pub bump_map: Option<TextureData>,
|
||||
pub translucent: bool,
|
||||
pub transform: Option<TextureTransform>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -75,10 +76,8 @@ pub fn load_material(path: &str, loader: &Loader) -> Result<MaterialData, Error>
|
|||
return Ok(MaterialData {
|
||||
color: [82, 180, 217, 128],
|
||||
path,
|
||||
texture: None,
|
||||
bump_map: None,
|
||||
alpha_test: None,
|
||||
translucent: true,
|
||||
..MaterialData::default()
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +97,11 @@ pub fn load_material(path: &str, loader: &Loader) -> Result<MaterialData, Error>
|
|||
})
|
||||
});
|
||||
|
||||
let transform = material
|
||||
.base_texture_transform()
|
||||
.filter(|transform| **transform != TextureTransform::default())
|
||||
.cloned();
|
||||
|
||||
Ok(MaterialData {
|
||||
color: [255; 4],
|
||||
path,
|
||||
|
|
@ -108,6 +112,7 @@ pub fn load_material(path: &str, loader: &Loader) -> Result<MaterialData, Error>
|
|||
bump_map,
|
||||
alpha_test,
|
||||
translucent: translucent | glass,
|
||||
transform,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
24
src/prop.rs
24
src/prop.rs
|
|
@ -1,3 +1,4 @@
|
|||
use cgmath::Matrix4;
|
||||
use crate::bsp::map_coords;
|
||||
use crate::material::{convert_material, load_material_fallback, MaterialSet};
|
||||
use crate::Error;
|
||||
|
|
@ -6,10 +7,11 @@ use tf_asset_loader::Loader;
|
|||
use three_d::{CpuMaterial, CpuModel, Mat4, Positions, Vec2, Vec3, Vec4};
|
||||
use three_d_asset::{Geometry, Primitive, TriMesh};
|
||||
use tracing::{error, warn};
|
||||
use vbsp::{Handle, StaticPropLump};
|
||||
use vbsp::PropPlacement;
|
||||
use vmdl::mdl::Mdl;
|
||||
use vmdl::vtx::Vtx;
|
||||
use vmdl::vvd::Vvd;
|
||||
use cgmath::SquareMatrix;
|
||||
|
||||
#[tracing::instrument(skip(loader))]
|
||||
pub fn load_prop(loader: &Loader, name: &str) -> Result<vmdl::Model, Error> {
|
||||
|
|
@ -24,24 +26,29 @@ pub fn load_prop(loader: &Loader, name: &str) -> Result<vmdl::Model, Error> {
|
|||
|
||||
Ok(vmdl::Model::from_parts(mdl, vtx, vvd))
|
||||
}
|
||||
pub fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
|
||||
pub fn load_props<'a, I: Iterator<Item = PropPlacement<'a>>>(
|
||||
loader: &Loader,
|
||||
props: I,
|
||||
show_textures: bool,
|
||||
) -> Result<Vec<CpuModel>, Error> {
|
||||
let props: Vec<_> = props
|
||||
.filter_map(|prop| match load_prop(loader, prop.model()) {
|
||||
.filter_map(|prop| match load_prop(loader, prop.model) {
|
||||
Ok(model) => Some((prop, model)),
|
||||
Err(e) => {
|
||||
error!(error = ?e, prop = prop.model(), "Failed to load prop");
|
||||
error!(error = ?e, prop = prop.model, "Failed to load prop");
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|(prop, model)| {
|
||||
let transform =
|
||||
Mat4::from_translation(map_coords(prop.origin)) * Mat4::from(prop.rotation());
|
||||
let root_transform = model.root_transform();
|
||||
if !root_transform.is_identity() {
|
||||
eprintln!("{}: {:?}", model.name(), root_transform);
|
||||
}
|
||||
let transform = Mat4::from_translation(map_coords(prop.origin))
|
||||
* Mat4::from(prop.rotation)
|
||||
* Mat4::from_scale(prop.scale);
|
||||
PropData {
|
||||
name: prop.model(),
|
||||
name: prop.model,
|
||||
model,
|
||||
transform,
|
||||
skin: prop.skin,
|
||||
|
|
@ -102,7 +109,8 @@ fn prop_to_meshes<'a>(
|
|||
|
||||
let positions: Vec<Vec3> = mesh
|
||||
.vertices()
|
||||
.map(|vertex| map_coords(vertex.position))
|
||||
.map(|vertex| model.vertex_to_world_space(vertex))
|
||||
.map(|vertex| map_coords(vertex))
|
||||
.collect();
|
||||
let normals: Vec<Vec3> = mesh
|
||||
.vertices()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue