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]] [[package]]
name = "vmdl" name = "vmdl"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/icewind1991/vmdl#922699a0898fcfc324f3ddb0db7af06bccf52124"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"bitflags 1.3.2", "bitflags 1.3.2",

View file

@ -16,8 +16,8 @@ delaunator = "1.0.1"
itertools = "0.10.5" itertools = "0.10.5"
steamlocate = "2.0.0-alpha.0" steamlocate = "2.0.0-alpha.0"
vpk = "0.2.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"
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"

View file

@ -11,7 +11,10 @@ use vbsp::{Bsp, Handle};
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 (world, bsp) = load_world(data, loader)?; let (world, bsp) = load_world(data, loader)?;
let props = load_props(loader, bsp.static_props())?; 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 { pub fn map_coords<C: Into<Vec3>>(vec: C) -> Vec3 {

View file

@ -1,7 +1,6 @@
use crate::bsp::map_coords; use crate::bsp::map_coords;
use crate::material::load_material_fallback; use crate::material::load_material_fallback;
use crate::{Error, Loader}; use crate::{Error, Loader};
use std::collections::HashMap;
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};
@ -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>>>( pub fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
loader: &Loader, loader: &Loader,
props: I, props: I,
) -> Result<CpuModel, Error> { ) -> Result<Vec<CpuModel>, Error> {
let props: Vec<PropData> = props let props = props
.filter_map(|prop| match load_prop(loader, prop.model()) { .filter_map(|prop| match load_prop(loader, prop.model()) {
Ok(model) => Some((prop, model)), Ok(model) => Some((prop, model)),
Err(e) => { Err(e) => {
@ -39,31 +38,25 @@ pub fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
transform, transform,
skin: prop.skin, skin: prop.skin,
} }
}) });
.collect();
let materials: HashMap<_, _> = props props
.map(|prop| {
let geometries: Vec<_> = prop_to_meshes(&prop).collect();
let materials: Vec<_> = prop
.model
.textures()
.iter() .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)) .map(|tex| prop_texture_to_material(tex, loader))
.collect(); .collect();
Ok(CpuModel { Ok(CpuModel {
name: "props".into(), name: prop.name.into(),
geometries, geometries,
materials, materials,
}) })
})
.collect()
} }
struct PropData<'a> { struct PropData<'a> {
@ -73,10 +66,7 @@ struct PropData<'a> {
skin: i32, skin: i32,
} }
fn prop_to_meshes<'a>( fn prop_to_meshes<'a>(prop: &'a PropData) -> impl Iterator<Item = Primitive> + 'a {
prop: &'a PropData,
textures: &'a [&TextureInfo],
) -> impl Iterator<Item = Primitive> + 'a {
let transform = prop.transform; let transform = prop.transform;
let model = &prop.model; let model = &prop.model;
@ -89,23 +79,15 @@ fn prop_to_meshes<'a>(
}; };
model.meshes().map(move |mesh| { model.meshes().map(move |mesh| {
let texture = skin let material_index = skin.texture_index(mesh.material_index());
.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 positions: Vec<Vec3> = mesh let positions: Vec<Vec3> = mesh
.vertices() .vertices()
.map(|vertex| map_coords(vertex.position)) .map(|vertex| map_coords(vertex.position))
// .map(|v| apply_transform(v, transform))
.collect(); .collect();
let normals: Vec<Vec3> = mesh let normals: Vec<Vec3> = mesh
.vertices() .vertices()
.map(|vertex| map_coords(vertex.normal)) .map(|vertex| map_coords(vertex.normal))
// .map(|v| apply_transform(v, normal_transform))
.collect(); .collect();
let uvs: Vec<Vec2> = mesh let uvs: Vec<Vec2> = mesh
.vertices() .vertices()
@ -116,11 +98,10 @@ fn prop_to_meshes<'a>(
let geometry = Geometry::Triangles(TriMesh { let geometry = Geometry::Triangles(TriMesh {
positions: Positions::F32(positions), positions: Positions::F32(positions),
indices: Default::default(),
normals: Some(normals), normals: Some(normals),
uvs: Some(uvs), uvs: Some(uvs),
tangents: Some(tangents), tangents: Some(tangents),
colors: None, ..TriMesh::default()
}); });
Primitive { Primitive {