split prop meshes

This commit is contained in:
Robin Appelman 2023-12-09 22:17:21 +01:00
commit 505d6d4844
2 changed files with 32 additions and 42 deletions

View file

@ -1,6 +1,6 @@
# vbspview # vbspview
tf2 map viewer tf2 map viewer based on [vbsp](https://github.com/icewind1991/vbsp)
## Usage ## Usage

View file

@ -2,8 +2,8 @@ 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::{
texture, Color, CpuMaterial, CpuMesh, CpuModel, CpuTexture, Indices, Mat4, Positions, Color, CpuMaterial, CpuMesh, CpuModel, CpuTexture, Indices, Mat4, Positions, TextureData, Vec2,
TextureData, Vec2, Vec3, Vec3,
}; };
use vbsp::{Bsp, Face, Handle, StaticPropLump}; use vbsp::{Bsp, Face, Handle, StaticPropLump};
use vmdl::mdl::Mdl; use vmdl::mdl::Mdl;
@ -136,15 +136,18 @@ fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
..Default::default() ..Default::default()
}; };
let mesh = merge_models(props.map(|prop| { let props = 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 { model, transform }) Ok(ModelData { model, transform })
}))?; });
let geometries = props
.map(|res| res.map(prop_to_mesh))
.collect::<Result<_, Error>>()?;
Ok(CpuModel { Ok(CpuModel {
geometries: vec![mesh], geometries,
materials: vec![material], materials: vec![material],
}) })
} }
@ -163,47 +166,34 @@ struct ModelData {
transform: Mat4, transform: Mat4,
} }
fn merge_models<I: Iterator<Item = Result<ModelData, Error>>>(props: I) -> Result<CpuMesh, Error> { fn prop_to_mesh(prop: ModelData) -> CpuMesh {
let mut positions = Vec::new();
let mut normals = Vec::new();
let mut indices = Vec::new();
for prop in props {
let prop = prop?;
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 offset = positions.len() as u32; let positions = model
positions.extend(
model
.vertices() .vertices()
.iter() .iter()
.map(|v| map_coords(v.position)) .map(|v| map_coords(v.position))
.map(|v| apply_transform(v, transform)), .map(|v| apply_transform(v, transform))
); .collect();
normals.extend( let normals = model
model
.vertices() .vertices()
.iter() .iter()
.map(|v| map_coords(v.normal)) .map(|v| map_coords(v.normal))
.map(|v| apply_transform(v, normal_transform)), .map(|v| apply_transform(v, normal_transform))
); .collect();
indices.extend( let indices = model
model
.vertex_strip_indices() .vertex_strip_indices()
.flat_map(|strip| strip.map(|index| index as u32)) .flat_map(|strip| strip.map(|index| index as u32))
.map(|index| index + offset), .collect();
);
}
Ok(CpuMesh { CpuMesh {
positions: Positions::F32(positions), positions: Positions::F32(positions),
normals: Some(normals), normals: Some(normals),
indices: Indices::U32(indices), indices: Indices::U32(indices),
..Default::default() ..Default::default()
}) }
} }
fn load_world(data: &[u8], loader: &mut Loader) -> Result<(CpuModel, Bsp), Error> { fn load_world(data: &[u8], loader: &mut Loader) -> Result<(CpuModel, Bsp), Error> {