From 8eca99fd9c00af217ba93d59d1e0d9ec3abc2abc Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Mon, 3 Feb 2025 17:09:10 -0800 Subject: [PATCH] bsp_loader: rewrite world models to use mesh builder --- lib/bsp_loader/src/bsp.rs | 79 +++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/lib/bsp_loader/src/bsp.rs b/lib/bsp_loader/src/bsp.rs index 12bd173..ca203c5 100644 --- a/lib/bsp_loader/src/bsp.rs +++ b/lib/bsp_loader/src/bsp.rs @@ -7,6 +7,31 @@ use strafesnet_deferred_loader::texture::{RenderConfigs,Texture}; use crate::valve_transform; +fn ingest_vertex( + mb:&mut model::MeshBuilder, + world_position:vbsp::Vector, + texture_transform_u:glam::Vec4, + texture_transform_v:glam::Vec4, + normal:model::NormalId, + color:model::ColorId, +)->model::VertexId{ + //world_model.origin seems to always be 0,0,0 + let vertex_xyz=world_position.into(); + let pos=mb.acquire_pos_id(valve_transform(vertex_xyz)); + + //calculate texture coordinates + let pos_4d=glam::Vec3::from_array(vertex_xyz).extend(1.0); + let tex=glam::vec2(texture_transform_u.dot(pos_4d),texture_transform_v.dot(pos_4d)); + let tex=mb.acquire_tex_id(tex); + + mb.acquire_vertex_id(model::IndexedVertex{ + pos, + tex, + normal, + color, + }) +} + pub fn convert<'a>( bsp:&'a crate::Bsp, render_config_deferred_loader:&mut RenderConfigDeferredLoader<Cow<'a,str>>, @@ -48,11 +73,9 @@ pub fn convert<'a>( //the generated MeshIds in here will collide with the Loader Mesh Ids //but I can't think of a good workaround other than just remapping one later. let world_meshes:Vec<model::Mesh>=bsp.models().map(|world_model|{ - //non-deduplicated - let mut spam_pos=Vec::new(); - let mut spam_tex=Vec::new(); - let mut spam_normal=Vec::new(); - let mut spam_vertices=Vec::new(); + let mut mb=model::MeshBuilder::new(); + + let color=mb.acquire_color_id(glam::Vec4::ONE); let mut graphics_groups=Vec::new(); let mut physics_group=model::IndexedPhysicsGroup::default(); let polygon_groups=world_model.faces().enumerate().map(|(polygon_group_id,face)|{ @@ -68,36 +91,20 @@ pub fn convert<'a>( let render_id=render_config_deferred_loader.acquire_render_config_id(Some(Cow::Borrowed(face_texture_data.name()))); //normal - let normal=face.normal(); - let normal_idx=spam_normal.len() as u32; - spam_normal.push(valve_transform(normal.into())); - let mut polygon_iter=face.vertex_positions().map(|vertex_position|{ - //world_model.origin seems to always be 0,0,0 - let vertex_xyz=(world_model.origin+vertex_position).into(); - let pos_idx=spam_pos.len(); - spam_pos.push(valve_transform(vertex_xyz)); - - //calculate texture coordinates - let pos=glam::Vec3::from_array(vertex_xyz).extend(1.0); - let tex=glam::vec2(texture_transform_u.dot(pos),texture_transform_v.dot(pos)); - let tex_idx=spam_tex.len() as u32; - spam_tex.push(tex); - - let vertex_id=model::VertexId::new(spam_vertices.len() as u32); - spam_vertices.push(model::IndexedVertex{ - pos:model::PositionId::new(pos_idx as u32), - tex:model::TextureCoordinateId::new(tex_idx as u32), - normal:model::NormalId::new(normal_idx), - color:model::ColorId::new(0), - }); - vertex_id - }); + let normal=mb.acquire_normal_id(valve_transform(face.normal().into())); + let mut polygon_iter=face.vertex_positions().map(|vertex_position| + world_model.origin+vertex_position + ); let polygon_list=std::iter::from_fn(move||{ match (polygon_iter.next(),polygon_iter.next(),polygon_iter.next()){ - (Some(v1),Some(v2),Some(v3))=>Some(vec![v1,v2,v3]), + (Some(v1),Some(v2),Some(v3))=>Some([v1,v2,v3]), //ignore extra vertices, not sure what to do in this case, failing the whole conversion could be appropriate _=>None, } + }).map(|triplet|{ + triplet.map(|world_position| + ingest_vertex(&mut mb,world_position,texture_transform_u,texture_transform_v,normal,color) + ).to_vec() }).collect(); if face.is_visible(){ //TODO: deduplicate graphics groups by render id @@ -109,16 +116,8 @@ pub fn convert<'a>( physics_group.groups.push(polygon_group_id); model::PolygonGroup::PolygonList(model::PolygonList::new(polygon_list)) }).collect(); - model::Mesh{ - unique_pos:spam_pos, - unique_tex:spam_tex, - unique_normal:spam_normal, - unique_color:vec![glam::Vec4::ONE], - unique_vertices:spam_vertices, - polygon_groups, - graphics_groups, - physics_groups:vec![physics_group], - } + + mb.build(polygon_groups,graphics_groups,vec![physics_group]) }).collect(); let world_models:Vec<model::Model>=