mirror of
https://codeberg.org/icewind/vbspview.git
synced 2026-06-03 18:24:09 +02:00
dedup materials
This commit is contained in:
parent
d2a54cec8b
commit
6b70a04675
3 changed files with 81 additions and 85 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -3014,7 +3014,6 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vmdl"
|
name = "vmdl"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/icewind1991/vmdl#70a6adebdd8f6b7d60625c2539aa3e68403526fb"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.7.4",
|
"arrayvec 0.7.4",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ delaunator = "1.0.1"
|
||||||
itertools = "0.10.5"
|
itertools = "0.10.5"
|
||||||
steamlocate = "1.1.0"
|
steamlocate = "1.1.0"
|
||||||
vpk = { version = "0.1.4", git = "https://github.com/icewind1991/vpk-rs", branch = "perf" }
|
vpk = { version = "0.1.4", git = "https://github.com/icewind1991/vpk-rs", branch = "perf" }
|
||||||
vmdl = { version = "*", git = "https://github.com/icewind1991/vmdl" }
|
#vmdl = { version = "*", git = "https://github.com/icewind1991/vmdl" }
|
||||||
|
vmdl = { version = "*", path = "../vmdl" }
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
||||||
tracing-tree = "0.2.2"
|
tracing-tree = "0.2.2"
|
||||||
|
|
|
||||||
72
src/bsp.rs
72
src/bsp.rs
|
|
@ -2,21 +2,19 @@ use crate::{Error, Loader};
|
||||||
use cgmath::{vec4, Matrix, SquareMatrix};
|
use cgmath::{vec4, Matrix, SquareMatrix};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use three_d::{
|
use three_d::{
|
||||||
Color, CpuMaterial, CpuMesh, CpuModel, CpuTexture, Indices, Mat4, Positions, TextureData, Vec2,
|
Color, CpuMaterial, CpuMesh, CpuModel, CpuTexture, Mat4, Positions, TextureData, Vec2, Vec3,
|
||||||
Vec3,
|
|
||||||
};
|
};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use vbsp::{Bsp, Face, Handle, StaticPropLump};
|
use vbsp::{Bsp, Face, Handle, StaticPropLump};
|
||||||
use vmdl::mdl::Mdl;
|
use vmdl::mdl::{Mdl, TextureInfo};
|
||||||
use vmdl::vtx::Vtx;
|
use vmdl::vtx::Vtx;
|
||||||
use vmdl::vvd::Vvd;
|
use vmdl::vvd::Vvd;
|
||||||
use vtf::vtf::VTF;
|
use vtf::vtf::VTF;
|
||||||
|
|
||||||
pub fn load_map(data: &[u8], loader: &mut Loader) -> Result<Vec<CpuModel>, Error> {
|
pub fn load_map(data: &[u8], loader: &mut Loader) -> Result<Vec<CpuModel>, Error> {
|
||||||
let (cpu_model, bsp) = load_world(data, loader)?;
|
let (world, bsp) = load_world(data, loader)?;
|
||||||
let mut props = load_props(loader, bsp.static_props())?;
|
let props = load_props(loader, bsp.static_props())?;
|
||||||
props.insert(0, cpu_model);
|
Ok(vec![world, props])
|
||||||
Ok(props)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_transform<C: Into<Vec3>>(coord: C, transform: Mat4) -> Vec3 {
|
fn apply_transform<C: Into<Vec3>>(coord: C, transform: Mat4) -> Vec3 {
|
||||||
|
|
@ -128,21 +126,35 @@ fn model_to_model(model: Handle<vbsp::data::Model>, loader: &Loader) -> CpuModel
|
||||||
fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
|
fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
|
||||||
loader: &Loader,
|
loader: &Loader,
|
||||||
props: I,
|
props: I,
|
||||||
) -> Result<Vec<CpuModel>, Error> {
|
) -> Result<CpuModel, Error> {
|
||||||
let props = props.map(|prop| {
|
let props: Vec<ModelData> = props
|
||||||
|
.map(|prop| {
|
||||||
let model = load_prop(loader, prop.model())?;
|
let model = load_prop(loader, prop.model())?;
|
||||||
let transform =
|
let transform =
|
||||||
Mat4::from_translation(map_coords(prop.origin)) * Mat4::from(prop.rotation());
|
Mat4::from_translation(map_coords(prop.origin)) * Mat4::from(prop.rotation());
|
||||||
Ok(ModelData {
|
Ok::<_, Error>(ModelData {
|
||||||
model,
|
model,
|
||||||
transform,
|
transform,
|
||||||
skin: prop.skin,
|
skin: prop.skin,
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
props
|
let geometries = props.iter().flat_map(prop_to_meshes).collect();
|
||||||
.map(|res| res.map(|prop| prop_to_model(prop, loader)))
|
|
||||||
.collect::<Result<_, Error>>()
|
let textures: HashMap<_, _> = props
|
||||||
|
.iter()
|
||||||
|
.flat_map(|prop| prop.model.textures())
|
||||||
|
.map(|tex| (tex.name.as_str(), tex))
|
||||||
|
.collect();
|
||||||
|
let materials: Vec<_> = textures
|
||||||
|
.into_values()
|
||||||
|
.map(|tex| prop_texture_to_material(tex, loader))
|
||||||
|
.collect();
|
||||||
|
Ok(CpuModel {
|
||||||
|
geometries,
|
||||||
|
materials,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(loader))]
|
#[tracing::instrument(skip(loader))]
|
||||||
|
|
@ -160,10 +172,10 @@ struct ModelData {
|
||||||
skin: i32,
|
skin: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prop_to_model(prop: ModelData, loader: &Loader) -> CpuModel {
|
fn prop_to_meshes(prop: &ModelData) -> impl Iterator<Item = CpuMesh> + '_ {
|
||||||
let transform = prop.transform;
|
let transform = prop.transform;
|
||||||
let normal_transform = transform.invert().unwrap().transpose() * -1.0;
|
let normal_transform = transform.invert().unwrap().transpose() * -1.0;
|
||||||
let model = prop.model;
|
let model = &prop.model;
|
||||||
|
|
||||||
let skin = match model.skin_tables().nth(prop.skin as usize) {
|
let skin = match model.skin_tables().nth(prop.skin as usize) {
|
||||||
Some(skin) => skin,
|
Some(skin) => skin,
|
||||||
|
|
@ -173,9 +185,7 @@ fn prop_to_model(prop: ModelData, loader: &Loader) -> CpuModel {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let geometries = model
|
model.meshes().map(move |mesh| {
|
||||||
.meshes()
|
|
||||||
.map(|mesh| {
|
|
||||||
let texture = skin
|
let texture = skin
|
||||||
.texture(mesh.material_index())
|
.texture(mesh.material_index())
|
||||||
.expect("texture out of bounds");
|
.expect("texture out of bounds");
|
||||||
|
|
@ -192,10 +202,7 @@ fn prop_to_model(prop: ModelData, loader: &Loader) -> CpuModel {
|
||||||
.collect();
|
.collect();
|
||||||
let uvs: Vec<Vec2> = mesh
|
let uvs: Vec<Vec2> = mesh
|
||||||
.vertices()
|
.vertices()
|
||||||
.map(|vertex| Vec2 {
|
.map(|vertex| vertex.texture_coordinates.into())
|
||||||
x: vertex.texture_coordinates[0],
|
|
||||||
y: vertex.texture_coordinates[1],
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
CpuMesh {
|
CpuMesh {
|
||||||
|
|
@ -206,21 +213,17 @@ fn prop_to_model(prop: ModelData, loader: &Loader) -> CpuModel {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
}
|
||||||
|
|
||||||
let materials = model
|
fn prop_texture_to_material(texture: &TextureInfo, loader: &Loader) -> CpuMaterial {
|
||||||
.textures()
|
match load_texture(&texture.name, &texture.search_paths, loader) {
|
||||||
.iter()
|
|
||||||
.map(|texture| {
|
|
||||||
let dirs = model.texture_directories();
|
|
||||||
match load_texture(&texture.name, dirs, loader) {
|
|
||||||
Ok(texture) => CpuMaterial {
|
Ok(texture) => CpuMaterial {
|
||||||
albedo: Color::default(),
|
albedo: Color::default(),
|
||||||
name: texture.name.clone(),
|
name: texture.name.clone(),
|
||||||
albedo_texture: Some(texture),
|
albedo_texture: Some(texture),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Err(e) => CpuMaterial {
|
Err(_) => CpuMaterial {
|
||||||
albedo: Color {
|
albedo: Color {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 0,
|
g: 0,
|
||||||
|
|
@ -231,13 +234,6 @@ fn prop_to_model(prop: ModelData, loader: &Loader) -> CpuModel {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
CpuModel {
|
|
||||||
materials,
|
|
||||||
geometries,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_texture(name: &str, dirs: &[String], loader: &Loader) -> Result<CpuTexture, Error> {
|
fn load_texture(name: &str, dirs: &[String], loader: &Loader) -> Result<CpuTexture, Error> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue