load brush entities

This commit is contained in:
Robin Appelman 2023-12-20 19:44:58 +01:00
commit 9a19b72a92
3 changed files with 50 additions and 22 deletions

14
Cargo.lock generated
View file

@ -1871,9 +1871,9 @@ checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.27" version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
[[package]] [[package]]
name = "png" name = "png"
@ -2466,9 +2466,9 @@ dependencies = [
[[package]] [[package]]
name = "tf-asset-loader" name = "tf-asset-loader"
version = "0.1.0" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d19874714b7454f34d6142f9a2e2521b6e48ff4b3929cbac7acc72f161baf7bf" checksum = "8b1d0b394de3284708b0e78c1a91e420219d425c14bbf1276c23f97a2e96b123"
dependencies = [ dependencies = [
"steamlocate", "steamlocate",
"thiserror", "thiserror",
@ -2797,8 +2797,8 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]] [[package]]
name = "vbsp" name = "vbsp"
version = "0.3.0" version = "0.4.0"
source = "git+https://github.com/icewind1991/vbsp#7a491f86272a30a7022aa96c8ff44291bf57238e" source = "git+https://github.com/icewind1991/vbsp#dde4ec2a83ef0acdbcf4c3003573701c3d9ecf64"
dependencies = [ dependencies = [
"ahash", "ahash",
"arrayvec", "arrayvec",
@ -2818,7 +2818,7 @@ dependencies = [
[[package]] [[package]]
name = "vbsp-derive" name = "vbsp-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/icewind1991/vbsp#7a491f86272a30a7022aa96c8ff44291bf57238e" source = "git+https://github.com/icewind1991/vbsp#dde4ec2a83ef0acdbcf4c3003573701c3d9ecf64"
dependencies = [ dependencies = [
"merge", "merge",
"proc-macro2", "proc-macro2",

View file

@ -8,8 +8,7 @@ license = "MIT"
[dependencies] [dependencies]
three-d = { version = "0.16.3", features = ["egui-gui"] } three-d = { version = "0.16.3", features = ["egui-gui"] }
three-d-asset = { version = "0.6" } three-d-asset = { version = "0.6" }
vbsp = { version = "0.3.0", git = "https://github.com/icewind1991/vbsp" } vbsp = "0.4.0"
#vbsp = { version = "0.3.0", path = "../bsp" }
miette = { version = "5.5.0", features = ["fancy"] } miette = { version = "5.5.0", features = ["fancy"] }
thiserror = "1.0.37" thiserror = "1.0.37"
itertools = "0.12.0" itertools = "0.12.0"
@ -30,8 +29,8 @@ tf-asset-loader = { version = "0.1", features = ["bsp"] }
# make tf-asset-loader use the same vbsp version # make tf-asset-loader use the same vbsp version
[patch.crates-io] [patch.crates-io]
#vbsp = { version = "0.3.0", path = "../bsp" } #vbsp = { version = "0.4.0", path = "../bsp" }
vbsp = { version = "0.3.0", git = "https://github.com/icewind1991/vbsp" } vbsp = { version = "0.4.0", git = "https://github.com/icewind1991/vbsp" }
[profile.dev.package."*"] [profile.dev.package."*"]
opt-level = 2 opt-level = 2

View file

@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet};
use tf_asset_loader::Loader; use tf_asset_loader::Loader;
use three_d::{CpuModel, Positions, Vec3}; use three_d::{CpuModel, Positions, Vec3};
use three_d_asset::{Geometry, Primitive, TriMesh}; use three_d_asset::{Geometry, Primitive, TriMesh};
use vbsp::{Bsp, Handle}; use vbsp::{Bsp, Entity, Handle, Vector};
pub fn load_map(data: &[u8], loader: &mut Loader, props: bool) -> Result<Vec<CpuModel>, Error> { pub fn load_map(data: &[u8], loader: &mut Loader, props: bool) -> Result<Vec<CpuModel>, Error> {
let (world, bsp) = load_world(data, loader)?; let (world, bsp) = load_world(data, loader)?;
@ -32,14 +32,19 @@ pub fn map_coords<C: Into<Vec3>>(vec: C) -> Vec3 {
// 1 hammer unit is ~1.905cm // 1 hammer unit is ~1.905cm
pub const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0); pub const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0);
fn model_to_model(model: Handle<vbsp::data::Model>, loader: &Loader) -> CpuModel { fn model_to_model(models: &[(Handle<vbsp::data::Model>, Vector)], loader: &Loader) -> CpuModel {
let textures: HashSet<&str> = model.textures().map(|texture| texture.name()).collect(); let textures: HashSet<&str> = models
.iter()
.flat_map(|(model, _)| model.textures())
.map(|texture| texture.name())
.collect();
let textures: Vec<&str> = textures.into_iter().collect(); let textures: Vec<&str> = textures.into_iter().collect();
let faces_by_texture: HashMap<&str, _> = model let faces_by_texture: HashMap<&str, _> = models
.faces() .iter()
.filter(|face| face.is_visible()) .flat_map(|(model, origin)| model.faces().map(|face| (face, *origin)))
.map(|face| (face.texture().name(), face)) .filter(|(face, _)| face.is_visible())
.map(|(face, origin)| (face.texture().name(), (face, origin)))
.into_group_map(); .into_group_map();
let geometries: Vec<_> = faces_by_texture let geometries: Vec<_> = faces_by_texture
@ -47,13 +52,13 @@ fn model_to_model(model: Handle<vbsp::data::Model>, loader: &Loader) -> CpuModel
.map(|faces| { .map(|faces| {
let positions: Vec<_> = faces let positions: Vec<_> = faces
.iter() .iter()
.flat_map(|face| face.vertex_positions()) .flat_map(|(face, origin)| face.vertex_positions().map(|pos| pos + *origin))
.map(map_coords) .map(map_coords)
.collect(); .collect();
let uvs: Vec<_> = faces let uvs: Vec<_> = faces
.iter() .iter()
.flat_map(|face| { .flat_map(|(face, _)| {
let texture = face.texture(); let texture = face.texture();
face.vertex_positions() face.vertex_positions()
.map(move |position| texture.uv(position)) .map(move |position| texture.uv(position))
@ -69,7 +74,7 @@ fn model_to_model(model: Handle<vbsp::data::Model>, loader: &Loader) -> CpuModel
mesh.compute_normals(); mesh.compute_normals();
mesh.compute_tangents(); mesh.compute_tangents();
let texture = faces.first().unwrap().texture().name(); let texture = faces.first().unwrap().0.texture().name();
let material_index = textures let material_index = textures
.iter() .iter()
.enumerate() .enumerate()
@ -108,5 +113,29 @@ fn load_world(data: &[u8], loader: &mut Loader) -> Result<(CpuModel, Bsp), Error
.next() .next()
.ok_or(Error::Other("No world model".into()))?; .ok_or(Error::Other("No world model".into()))?;
Ok((model_to_model(world_model, loader), bsp)) let mut models: Vec<_> = bsp
.entities
.iter()
.flat_map(|ent| ent.parse())
.filter_map(|ent| match ent {
Entity::Brush(ent)
| Entity::BrushIllusionary(ent)
| Entity::BrushWall(ent)
| Entity::BrushWallToggle(ent) => Some(ent),
_ => None,
})
.flat_map(|brush| Some((brush.model[1..].parse::<usize>().ok()?, brush.origin)))
.flat_map(|(index, origin)| Some((bsp.models().nth(index)?, origin)))
.collect();
models.push((
world_model,
Vector {
x: 0.0,
y: 0.0,
z: 0.0,
},
));
let world_model = model_to_model(&models, loader);
Ok((world_model, bsp))
} }