fix material collisions, ruin loading performance

This commit is contained in:
Robin Appelman 2023-12-15 22:31:20 +01:00
commit e922bd3a20
4 changed files with 28 additions and 45 deletions

1
Cargo.lock generated
View file

@ -2694,7 +2694,6 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vmdl"
version = "0.1.0"
source = "git+https://github.com/icewind1991/vmdl#922699a0898fcfc324f3ddb0db7af06bccf52124"
dependencies = [
"arrayvec",
"bitflags 1.3.2",

View file

@ -16,8 +16,8 @@ delaunator = "1.0.1"
itertools = "0.10.5"
steamlocate = "2.0.0-alpha.0"
vpk = "0.2.0"
vmdl = { version = "*", git = "https://github.com/icewind1991/vmdl" }
#vmdl = { version = "*", path = "../vmdl" }
#vmdl = { version = "*", git = "https://github.com/icewind1991/vmdl" }
vmdl = { version = "*", path = "../vmdl" }
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
tracing-tree = "0.2.2"

View file

@ -11,7 +11,10 @@ use vbsp::{Bsp, Handle};
pub fn load_map(data: &[u8], loader: &mut Loader) -> Result<Vec<CpuModel>, Error> {
let (world, bsp) = load_world(data, loader)?;
let props = load_props(loader, bsp.static_props())?;
Ok(vec![world, props])
let mut models = Vec::with_capacity(props.len() + 1);
models.push(world);
models.extend(props.into_iter());
Ok(models)
}
pub fn map_coords<C: Into<Vec3>>(vec: C) -> Vec3 {

View file

@ -1,7 +1,6 @@
use crate::bsp::map_coords;
use crate::material::load_material_fallback;
use crate::{Error, Loader};
use std::collections::HashMap;
use three_d::{CpuMaterial, CpuModel, Mat4, Positions, Vec2, Vec3, Vec4};
use three_d_asset::{Geometry, Primitive, TriMesh};
use tracing::{error, warn};
@ -21,8 +20,8 @@ pub fn load_prop(loader: &Loader, name: &str) -> Result<vmdl::Model, Error> {
pub fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
loader: &Loader,
props: I,
) -> Result<CpuModel, Error> {
let props: Vec<PropData> = props
) -> Result<Vec<CpuModel>, Error> {
let props = props
.filter_map(|prop| match load_prop(loader, prop.model()) {
Ok(model) => Some((prop, model)),
Err(e) => {
@ -39,31 +38,25 @@ pub fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
transform,
skin: prop.skin,
}
});
props
.map(|prop| {
let geometries: Vec<_> = prop_to_meshes(&prop).collect();
let materials: Vec<_> = prop
.model
.textures()
.iter()
.map(|tex| prop_texture_to_material(tex, loader))
.collect();
Ok(CpuModel {
name: prop.name.into(),
geometries,
materials,
})
})
.collect();
let materials: HashMap<_, _> = props
.iter()
.flat_map(|prop| prop.model.textures())
.map(|tex| (tex.name.as_str(), tex))
.collect();
let materials: Vec<_> = materials.into_values().collect();
let geometries = props
.iter()
.flat_map(|prop| prop_to_meshes(prop, materials.as_slice()))
.collect();
let materials: Vec<_> = materials
.into_iter()
.map(|tex| prop_texture_to_material(tex, loader))
.collect();
Ok(CpuModel {
name: "props".into(),
geometries,
materials,
})
.collect()
}
struct PropData<'a> {
@ -73,10 +66,7 @@ struct PropData<'a> {
skin: i32,
}
fn prop_to_meshes<'a>(
prop: &'a PropData,
textures: &'a [&TextureInfo],
) -> impl Iterator<Item = Primitive> + 'a {
fn prop_to_meshes<'a>(prop: &'a PropData) -> impl Iterator<Item = Primitive> + 'a {
let transform = prop.transform;
let model = &prop.model;
@ -89,23 +79,15 @@ fn prop_to_meshes<'a>(
};
model.meshes().map(move |mesh| {
let texture = skin
.texture(mesh.material_index())
.expect("texture out of bounds");
let material_index = textures
.iter()
.enumerate()
.find_map(|(i, texture_info)| (texture_info.name == texture).then_some(i));
let material_index = skin.texture_index(mesh.material_index());
let positions: Vec<Vec3> = mesh
.vertices()
.map(|vertex| map_coords(vertex.position))
// .map(|v| apply_transform(v, transform))
.collect();
let normals: Vec<Vec3> = mesh
.vertices()
.map(|vertex| map_coords(vertex.normal))
// .map(|v| apply_transform(v, normal_transform))
.collect();
let uvs: Vec<Vec2> = mesh
.vertices()
@ -116,11 +98,10 @@ fn prop_to_meshes<'a>(
let geometry = Geometry::Triangles(TriMesh {
positions: Positions::F32(positions),
indices: Default::default(),
normals: Some(normals),
uvs: Some(uvs),
tangents: Some(tangents),
colors: None,
..TriMesh::default()
});
Primitive {